From b480d7c9ff29109d43f6fbdcdb9d5af4075ba849 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 29 Feb 2004 19:04:34 +0000 Subject: [PATCH] Added pwdexop request structure to avoid redundant parsing --- servers/slapd/back-ldap/extended.c | 37 +++++-------- servers/slapd/passwd.c | 85 ++++++++++++++++-------------- servers/slapd/slap.h | 10 ++++ 3 files changed, 67 insertions(+), 65 deletions(-) diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index dde4c1ab2b..0223a0cebb 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -95,13 +95,11 @@ ldap_back_exop_passwd( { 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; + req_pwdexop_s *qpw = &op->oq_pwdexop; + struct berval mdn = { 0, NULL }, newpw; LDAPMessage *res; ber_int_t msgid; - int rc; + int rc, isproxy; dncookie dc; lc = ldap_back_getconn(op, rs); @@ -109,29 +107,17 @@ ldap_back_exop_passwd( 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 ); + op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 ); #else Debug( LDAP_DEBUG_TRACE, "ldap_back_exop_passwd: \"%s\"%s\n", - dn.bv_val, id.bv_len ? " (proxy)" : "", 0 ); + op->o_req_dn.bv_val, isproxy ? " (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) { + if (isproxy) { dc.rwmap = &li->rwmap; #ifdef ENABLE_REWRITE dc.conn = op->o_conn; @@ -141,16 +127,17 @@ ldap_back_exop_passwd( dc.tofrom = 1; dc.normalized = 0; #endif - if ( ldap_back_dn_massage( &dc, &dn, &mdn ) ) { + if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { send_ldap_result( op, rs ); return -1; } } - 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); + rc = ldap_passwd(lc->ld, isproxy ? &mdn : NULL, + qpw->rs_old.bv_len ? &qpw->rs_old : NULL, + qpw->rs_new.bv_len ? &qpw->rs_new : NULL, op->o_ctrls, NULL, &msgid); - if (mdn.bv_val != dn.bv_val) { + if (mdn.bv_val != op->o_req_dn.bv_val) { free(mdn.bv_val); } diff --git a/servers/slapd/passwd.c b/servers/slapd/passwd.c index 6b0bba4545..24d3e0552d 100644 --- a/servers/slapd/passwd.c +++ b/servers/slapd/passwd.c @@ -32,9 +32,9 @@ int passwd_extop( Operation *op, SlapReply *rs ) { - struct berval id = {0, NULL}, old = {0, NULL}, new = {0, NULL}, - dn, ndn, hash, vals[2], tmpbv, *rsp = NULL; - Modifications ml, **modtail; + struct berval id = {0, NULL}, hash, *rsp = NULL; + req_pwdexop_s *qpw = &op->oq_pwdexop; + Modifications *ml; Operation op2; slap_callback cb = { NULL, slap_null_cb, NULL, NULL }; slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL }; @@ -47,29 +47,30 @@ int passwd_extop( return LDAP_STRONG_AUTH_REQUIRED; } - if( op->oq_extended.rs_reqdata ) { - ber_dupbv_x( &tmpbv, op->oq_extended.rs_reqdata, op->o_tmpmemctx ); - } - rs->sr_err = slap_passwd_parse( - op->oq_extended.rs_reqdata ? &tmpbv : NULL, - &id, &old, &new, &rs->sr_text ); + qpw->rs_old.bv_val = NULL; + qpw->rs_new.bv_val = NULL; + qpw->rs_mods = NULL; + qpw->rs_modtail = NULL; + + rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id, &qpw->rs_old, + &qpw->rs_new, &rs->sr_text ); if ( rs->sr_err != LDAP_SUCCESS ) { return rs->sr_err; } if ( id.bv_len ) { - dn = id; + op->o_req_dn = id; /* ndn is in tmpmem, so we don't need to free it */ - rs->sr_err = dnNormalize( 0, NULL, NULL, &dn, &ndn, op->o_tmpmemctx ); + rs->sr_err = dnNormalize( 0, NULL, NULL, &id, &op->o_req_ndn, op->o_tmpmemctx ); if ( rs->sr_err != LDAP_SUCCESS ) { rs->sr_text = "Invalid DN"; return rs->sr_err; } - op->o_bd = select_backend( &ndn, 0, 0 ); + op->o_bd = select_backend( &op->o_req_ndn, 0, 0 ); } else { - dn = op->o_dn; - ndn = op->o_ndn; + op->o_req_dn = op->o_dn; + op->o_req_ndn = op->o_ndn; ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex ); op->o_bd = op->o_conn->c_authz_backend; ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex ); @@ -84,7 +85,7 @@ int passwd_extop( #endif } - if ( ndn.bv_len == 0 ) { + if ( op->o_req_ndn.bv_len == 0 ) { rs->sr_text = "no password is associated with the Root DSE"; return LDAP_UNWILLING_TO_PERFORM; } @@ -116,10 +117,23 @@ int passwd_extop( } #endif /* !SLAPD_MULTIMASTER */ + /* generate a new password if none was provided */ + if ( qpw->rs_new.bv_len == 0 ) { + slap_passwd_generate( &qpw->rs_new ); + if ( qpw->rs_new.bv_len ) { + rsp = slap_passwd_return( &qpw->rs_new ); + } + } + if ( qpw->rs_new.bv_len == 0 ) { + rs->sr_text = "password generation failed"; + return LDAP_OTHER; + } + /* Give the backend a chance to handle this itself */ if ( op->o_bd->be_extended ) { rs->sr_err = op->o_bd->be_extended( op, rs ); - if ( rs->sr_err != LDAP_UNWILLING_TO_PERFORM ) { + if ( rs->sr_err != LDAP_UNWILLING_TO_PERFORM && + rs->sr_err != SLAP_CB_CONTINUE ) { return rs->sr_err; } } @@ -130,17 +144,9 @@ int passwd_extop( return LDAP_UNWILLING_TO_PERFORM; } - if ( new.bv_len == 0 ) { - slap_passwd_generate( &new ); - rsp = slap_passwd_return( &new ); - } - if ( new.bv_len == 0 ) { - rs->sr_text = "password generation failed"; - return LDAP_OTHER; - } - slap_passwd_hash( &new, &hash, &rs->sr_text ); + slap_passwd_hash( &qpw->rs_new, &hash, &rs->sr_text ); if ( rsp ) { - free( new.bv_val ); + free( qpw->rs_new.bv_val ); } if ( hash.bv_len == 0 ) { if ( !rs->sr_text ) { @@ -148,23 +154,23 @@ int passwd_extop( } return LDAP_OTHER; } - vals[0] = hash; - vals[1].bv_val = NULL; - ml.sml_desc = slap_schema.si_ad_userPassword; - ml.sml_values = vals; - ml.sml_nvalues = NULL; - ml.sml_op = LDAP_MOD_REPLACE; - ml.sml_next = NULL; + ml = ch_malloc( sizeof(Modifications) ); + if ( !qpw->rs_modtail ) qpw->rs_modtail = &ml->sml_next; + ml->sml_values = ch_malloc( 2*sizeof(struct berval) ); + ml->sml_values[0] = hash; + ml->sml_values[1].bv_val = NULL; + ml->sml_desc = slap_schema.si_ad_userPassword; + ml->sml_nvalues = NULL; + ml->sml_op = LDAP_MOD_REPLACE; + ml->sml_next = qpw->rs_mods; + qpw->rs_mods = ml; op2 = *op; op2.o_tag = LDAP_REQ_MODIFY; op2.o_callback = &cb2; - op2.o_req_dn = dn; - op2.o_req_ndn = ndn; - op2.orm_modlist = &ml; + op2.orm_modlist = qpw->rs_mods; - modtail = &ml.sml_next; - rs->sr_err = slap_mods_opattrs( &op2, &ml, modtail, &rs->sr_text, + rs->sr_err = slap_mods_opattrs( &op2, ml, qpw->rs_modtail, &rs->sr_text, NULL, 0 ); if ( rs->sr_err == LDAP_SUCCESS ) { @@ -175,8 +181,7 @@ int passwd_extop( } else if ( rsp ) { ber_bvfree( rsp ); } - slap_mods_free( ml.sml_next ); - free( hash.bv_val ); + slap_mods_free( ml ); return rs->sr_err; } diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h index e925e47b0e..746c26a802 100644 --- a/servers/slapd/slap.h +++ b/servers/slapd/slap.h @@ -1605,6 +1605,14 @@ typedef struct req_extended_s { struct berval *rs_reqdata; } req_extended_s; +typedef struct req_pwdexop_s { + struct berval rs_reqoid; + struct berval rs_old; + struct berval rs_new; + Modifications *rs_mods; + Modifications **rs_modtail; +} req_pwdexop_s; + typedef enum slap_reply_e { REP_RESULT, REP_SASL, @@ -1932,6 +1940,7 @@ typedef struct slap_op { req_abandon_s oq_abandon; req_abandon_s oq_cancel; req_extended_s oq_extended; + req_pwdexop_s oq_pwdexop; } o_request; /* short hands for union members */ @@ -1944,6 +1953,7 @@ typedef struct slap_op { #define oq_abandon o_request.oq_abandon #define oq_cancel o_request.oq_cancel #define oq_extended o_request.oq_extended +#define oq_pwdexop o_request.oq_pwdexop /* short hands for inner request members */ #define orb_method oq_bind.rb_method -- 2.39.5