X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldap%2Fextended.c;h=070466ae0355ec1f3059dcfd83af98c6e37f1188;hb=00dae75f7b48b6bab23503d211deb7650aba8c1b;hp=caac505823872870fbc238d4d696794cc47e2283;hpb=a3d8cda2011920fae1e499e0f4c8c794f927138e;p=openldap diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index caac505823..070466ae03 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2003 The OpenLDAP Foundation. + * Copyright 2003-2005 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -18,7 +18,6 @@ * in OpenLDAP Software and subsequently enhanced by Pierangelo * Masarati. */ -/* This is an altered version */ #include "portable.h" @@ -32,7 +31,7 @@ BI_op_extended ldap_back_exop_passwd; static struct exop { - struct berval *oid; + struct berval *oid; BI_op_extended *extended; } exop_table[] = { { (struct berval *)&slap_EXOP_MODIFY_PASSWD, ldap_back_exop_passwd }, @@ -41,14 +40,52 @@ static struct exop { int ldap_back_extended( - Operation *op, - SlapReply *rs ) + Operation *op, + SlapReply *rs ) { - int i; + int i; + + for ( i = 0; exop_table[i].extended != NULL; i++ ) { + if ( bvmatch( exop_table[i].oid, &op->oq_extended.rs_reqoid ) ) + { + struct ldapconn *lc; + LDAPControl **oldctrls = NULL; + int rc; + + /* FIXME: this needs to be called here, so it is + * called twice; maybe we could avoid the + * ldap_back_dobind() call inside each extended() + * call ... */ + lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR ); + if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) { + return -1; + } + + oldctrls = op->o_ctrls; + if ( ldap_back_proxy_authz_ctrl( lc, op, rs, + &op->o_ctrls ) ) + { + op->o_ctrls = oldctrls; + send_ldap_result( op, rs ); + rs->sr_text = NULL; + rc = rs->sr_err; + goto done; + } + + rc = ( *exop_table[i].extended )( op, rs ); + + if ( op->o_ctrls && op->o_ctrls != oldctrls ) { + free( op->o_ctrls[ 0 ] ); + free( op->o_ctrls ); + } + op->o_ctrls = oldctrls; - for( i=0; exop_table[i].extended != NULL; i++ ) { - if( ber_bvcmp( exop_table[i].oid, &op->oq_extended.rs_reqoid ) == 0 ) { - return (exop_table[i].extended)( op, rs ); +done:; + if ( lc != NULL ) { + ldap_back_release_conn( op, rs, lc ); + } + + return rc; } } @@ -58,102 +95,90 @@ ldap_back_extended( int ldap_back_exop_passwd( - Operation *op, - SlapReply *rs ) + Operation *op, + SlapReply *rs ) { - struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; - struct ldapconn *lc; - struct berval id = { 0, NULL }; - struct berval old = { 0, NULL }; - struct berval new = { 0, NULL }; - struct berval dn, mdn = { 0, NULL }, newpw; - LDAPMessage *res; - ber_int_t msgid; - int rc; - dncookie dc; - - lc = ldap_back_getconn(op, rs); - if (!lc || !ldap_back_dobind(lc, op, rs) ) { + struct ldapconn *lc; + req_pwdexop_s *qpw = &op->oq_pwdexop; + LDAPMessage *res; + ber_int_t msgid; + int rc, isproxy; + int do_retry = 1; + + lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR ); + if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) { return -1; } - rc = slap_passwd_parse( op->oq_extended.rs_reqdata, &id, &old, &new, &rs->sr_text ); - if (rc != LDAP_SUCCESS) - return rc; - - if (id.bv_len) { - dn = id; - } else { - dn = op->o_dn; - } + isproxy = ber_bvcmp( &op->o_req_ndn, &op->o_ndn ); -#ifdef NEW_LOGGING - LDAP_LOG ( ACL, DETAIL1, "ldap_back_exop_passwd: \"%s\"%s\"\n", - dn.bv_val, id.bv_len ? " (proxy)" : "", 0 ); -#else - Debug( LDAP_DEBUG_TRACE, "ldap_back_exop_passwd: \"%s\"%s\n", - dn.bv_val, id.bv_len ? " (proxy)" : "", 0 ); -#endif - - if (dn.bv_len == 0) { - rs->sr_text = "No password is associated with the Root DSE"; - return LDAP_UNWILLING_TO_PERFORM; - } - if (id.bv_len) { - dc.rwmap = &li->rwmap; -#ifdef ENABLE_REWRITE - dc.conn = op->o_conn; - dc.rs = rs; - dc.ctx = "modifyPwd"; -#else - dc.tofrom = 1; - dc.normalized = 0; -#endif - if ( ldap_back_dn_massage( &dc, &dn, &mdn ) ) { - send_ldap_result( op, rs ); - return -1; - } - } + Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n", + op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 ); - rc = ldap_passwd(lc->ld, id.bv_len ? &mdn : NULL, old.bv_len ? &old : NULL, - new.bv_len ? &new : NULL, op->o_ctrls, NULL, &msgid); +retry: + rc = ldap_passwd( lc->lc_ld, isproxy ? &op->o_req_dn : NULL, + qpw->rs_old.bv_val ? &qpw->rs_old : NULL, + qpw->rs_new.bv_val ? &qpw->rs_new : NULL, + op->o_ctrls, NULL, &msgid ); - if (mdn.bv_val != dn.bv_val) { - free(mdn.bv_val); - } + if ( rc == LDAP_SUCCESS ) { + if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) { + ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc ); + ldap_back_freeconn( op, lc ); + lc = NULL; - if (rc == LDAP_SUCCESS) { - if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) { - ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc); } else { - /* sigh. parse twice, because parse_passwd doesn't give - * us the err / match / msg info. + /* sigh. parse twice, because parse_passwd + * doesn't give us the err / match / msg info. */ - rc = ldap_parse_result(lc->ld, res, &rs->sr_err, (char **)&rs->sr_matched, (char **)&rs->sr_text, - NULL, NULL, 0); - if (rc == LDAP_SUCCESS) { - if (rs->sr_err == LDAP_SUCCESS) { - rc = ldap_parse_passwd(lc->ld, res, &newpw); - if (rc == LDAP_SUCCESS && newpw.bv_val) { + rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err, + (char **)&rs->sr_matched, + (char **)&rs->sr_text, + NULL, NULL, 0 ); + if ( rc == LDAP_SUCCESS ) { + if ( rs->sr_err == LDAP_SUCCESS ) { + struct berval newpw; + + rc = ldap_parse_passwd( lc->lc_ld, res, + &newpw); + if ( rc == LDAP_SUCCESS && + !BER_BVISNULL( &newpw ) ) + { rs->sr_type = REP_EXTENDED; - rs->sr_rspdata = slap_passwd_return(&newpw); - free(newpw.bv_val); + rs->sr_rspdata = slap_passwd_return( &newpw ); + free( newpw.bv_val ); } + } else { rc = rs->sr_err; } } - ldap_msgfree(res); + ldap_msgfree( res ); } } - if (rc != LDAP_SUCCESS) { - rs->sr_err = ldap_back_map_result(rs); - send_ldap_result(op, rs); - if (rs->sr_matched) free((char *)rs->sr_matched); - if (rs->sr_text) free((char *)rs->sr_text); + if ( rc != LDAP_SUCCESS ) { + rs->sr_err = slap_map_api2result( rs ); + if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { + do_retry = 0; + if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { + goto retry; + } + } + send_ldap_result( op, rs ); + if ( rs->sr_matched ) { + free( (char *)rs->sr_matched ); + } + if ( rs->sr_text ) { + free( (char *)rs->sr_text ); + } rs->sr_matched = NULL; rs->sr_text = NULL; rc = -1; } + + if ( lc != NULL ) { + ldap_back_release_conn( op, rs, lc ); + } + return rc; }