From e4ff0e6eacbcbedacb33ab5b4293d34b29499528 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 19 May 2007 14:27:53 +0000 Subject: [PATCH] import fix to ITS#4964 --- CHANGES | 1 + servers/slapd/back-ldap/chain.c | 53 ++++++++------ servers/slapd/back-ldap/extended.c | 113 ++++++++++++++++++++++------- 3 files changed, 120 insertions(+), 47 deletions(-) diff --git a/CHANGES b/CHANGES index cdfc599ea2..f76c69f0c8 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ OpenLDAP 2.3.36 Engineering Fixed slapd mutex bug after failed startup (ITS#4957) Fixed slapd-config olcModuleLoad replace (ITS#4921) Fixed slapd-bdb no-op crasher (ITS#4925) + Fixed slapo-chain RFC3062 passwd exop handling (ITS#4964) Fixed libldap response code handling on rebind (ITS#4924) Fixed libldap SASL_MAX_BUFF_SIZE (ITS#4935) Documentation diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c index 08eeeb4f93..8301278e0e 100644 --- a/servers/slapd/back-ldap/chain.c +++ b/servers/slapd/back-ldap/chain.c @@ -418,7 +418,7 @@ ldap_chain_op( LDAPURLDesc *srv = NULL; struct berval save_req_dn = op->o_req_dn, save_req_ndn = op->o_req_ndn, - dn, + dn = BER_BVNULL, pdn = BER_BVNULL, ndn = BER_BVNULL; int temporary = 0; @@ -449,17 +449,24 @@ Document: RFC 4511 } /* normalize DN */ - ber_str2bv( srv->lud_dn, 0, 0, &dn ); - rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx ); - if ( rc == LDAP_SUCCESS ) { - /* remove DN essentially because later on - * ldap_initialize() will parse the URL - * as a comma-separated URL list */ + rc = LDAP_SUCCESS; + srv->lud_scope = LDAP_SCOPE_DEFAULT; + if ( srv->lud_dn != NULL ) { + ber_str2bv( srv->lud_dn, 0, 0, &dn ); + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx ); + if ( rc == LDAP_SUCCESS ) { + /* remove DN essentially because later on + * ldap_initialize() will parse the URL + * as a comma-separated URL list */ + srv->lud_dn = ""; + } + + } else { srv->lud_dn = ""; - srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.li_uri = ldap_url_desc2str( srv ); - srv->lud_dn = dn.bv_val; } + + li.li_uri = ldap_url_desc2str( srv ); + srv->lud_dn = dn.bv_val; ldap_free_urldesc( srv ); if ( rc != LDAP_SUCCESS ) { @@ -629,16 +636,19 @@ ldap_chain_search( } /* normalize DN */ - ber_str2bv( srv->lud_dn, 0, 0, &dn ); - rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx ); - if ( rc == LDAP_SUCCESS ) { - /* remove DN essentially because later on - * ldap_initialize() will parse the URL - * as a comma-separated URL list */ - srv->lud_dn = ""; - srv->lud_scope = LDAP_SCOPE_DEFAULT; - li.li_uri = ldap_url_desc2str( srv ); - srv->lud_dn = dn.bv_val; + rc = LDAP_INVALID_SYNTAX; + if ( srv->lud_dn != NULL ) { + ber_str2bv( srv->lud_dn, 0, 0, &dn ); + rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, op->o_tmpmemctx ); + if ( rc == LDAP_SUCCESS ) { + /* remove DN essentially because later on + * ldap_initialize() will parse the URL + * as a comma-separated URL list */ + srv->lud_dn = ""; + srv->lud_scope = LDAP_SCOPE_DEFAULT; + li.li_uri = ldap_url_desc2str( srv ); + srv->lud_dn = dn.bv_val; + } } ldap_free_urldesc( srv ); @@ -778,7 +788,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) slap_callback *sc = op->o_callback, sc2 = { 0 }; int rc = 0; - char *text = NULL; + const char *text = NULL; const char *matched; BerVarray ref; struct berval ndn = op->o_ndn; @@ -917,6 +927,7 @@ ldap_chain_response( Operation *op, SlapReply *rs ) * to send it... */ /* FIXME: what about chaining? */ if ( rc != SLAPD_ABANDON ) { + rs->sr_err = rc; send_ldap_extended( op, rs ); rc = LDAP_SUCCESS; } diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index c17cb5b7a2..68acea9789 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -28,19 +28,21 @@ #include "back-ldap.h" #include "lber_pvt.h" -static BI_op_extended ldap_back_exop_passwd; -static BI_op_extended ldap_back_exop_generic; +typedef int (ldap_back_exop_f)( Operation *op, SlapReply *rs, ldapconn_t **lc ); + +static ldap_back_exop_f ldap_back_exop_passwd; +static ldap_back_exop_f ldap_back_exop_generic; static struct exop { - struct berval oid; - BI_op_extended *extended; + struct berval oid; + ldap_back_exop_f *extended; } exop_table[] = { { BER_BVC(LDAP_EXOP_MODIFY_PASSWD), ldap_back_exop_passwd }, { BER_BVNULL, NULL } }; static int -ldap_back_extended_one( Operation *op, SlapReply *rs, BI_op_extended exop ) +ldap_back_extended_one( Operation *op, SlapReply *rs, ldap_back_exop_f exop ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; @@ -68,7 +70,7 @@ ldap_back_extended_one( Operation *op, SlapReply *rs, BI_op_extended exop ) goto done; } - rc = exop( op, rs ); + rc = exop( op, rs, &lc ); if ( op->o_ctrls && op->o_ctrls != oldctrls ) { free( op->o_ctrls[ 0 ] ); @@ -106,30 +108,83 @@ ldap_back_extended( static int ldap_back_exop_passwd( - Operation *op, - SlapReply *rs ) + Operation *op, + SlapReply *rs, + ldapconn_t **lcp ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; - ldapconn_t *lc = NULL; + ldapconn_t *lc = *lcp; req_pwdexop_s *qpw = &op->oq_pwdexop; LDAPMessage *res; ber_int_t msgid; - int rc, isproxy; + int rc, isproxy, freedn = 0; int do_retry = 1; - char *text = NULL; + char *text = NULL; + struct berval dn = op->o_req_dn, + ndn = op->o_req_ndn; - if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) { - return -1; + assert( lc != NULL ); + + if ( BER_BVISNULL( &ndn ) && op->ore_reqdata != NULL ) { + /* NOTE: most of this code is mutuated + * from slap_passwd_parse(); we can't call + * that function since now the request data + * has been destroyed by NULL-terminating + * the bervals. Luckily enough, we only need + * the first berval... */ + + ber_tag_t tag; + ber_len_t len = -1; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + + struct berval tmpid = BER_BVNULL; + + if ( op->ore_reqdata->bv_len == 0 ) { + return LDAP_PROTOCOL_ERROR; + } + + /* ber_init2 uses reqdata directly, doesn't allocate new buffers */ + ber_init2( ber, op->ore_reqdata, 0 ); + + tag = ber_scanf( ber, "{" /*}*/ ); + + if ( tag == LBER_ERROR ) { + return LDAP_PROTOCOL_ERROR; + } + + tag = ber_peek_tag( ber, &len ); + if ( tag == LDAP_TAG_EXOP_MODIFY_PASSWD_ID ) { + tag = ber_scanf( ber, "m", &tmpid ); + + if ( tag == LBER_ERROR ) { + return LDAP_PROTOCOL_ERROR; + } + } + + if ( !BER_BVISEMPTY( &tmpid ) ) { + rs->sr_err = dnPrettyNormal( NULL, &tmpid, &dn, + &ndn, op->o_tmpmemctx ); + if ( rs->sr_err != LDAP_SUCCESS ) { + /* should have been successfully parsed earlier! */ + return rs->sr_err; + } + freedn = 1; + + } else { + dn = op->o_dn; + ndn = op->o_ndn; + } } - isproxy = ber_bvcmp( &op->o_req_ndn, &op->o_ndn ); + isproxy = ber_bvcmp( &ndn, &op->o_ndn ); Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_passwd(\"%s\")%s\n", - op->o_req_dn.bv_val, isproxy ? " (proxy)" : "", 0 ); + dn.bv_val, isproxy ? " (proxy)" : "", 0 ); retry: - rc = ldap_passwd( lc->lc_ld, isproxy ? &op->o_req_dn : NULL, + rc = ldap_passwd( lc->lc_ld, isproxy ? &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 ); @@ -214,6 +269,11 @@ retry: ldap_back_quarantine( op, rs ); } + if ( freedn ) { + op->o_tmpfree( dn.bv_val, op->o_tmpmemctx ); + op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx ); + } + /* these have to be freed anyway... */ if ( rs->sr_matched ) { free( (char *)rs->sr_matched ); @@ -225,8 +285,9 @@ retry: rs->sr_text = NULL; } - if ( lc != NULL ) { - ldap_back_release_conn( li, lc ); + /* in case, cleanup handler */ + if ( lc == NULL ) { + *lcp = NULL; } return rc; @@ -235,20 +296,19 @@ retry: static int ldap_back_exop_generic( Operation *op, - SlapReply *rs ) + SlapReply *rs, + ldapconn_t **lcp ) { ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; - ldapconn_t *lc = NULL; + ldapconn_t *lc = *lcp; LDAPMessage *res; ber_int_t msgid; int rc; int do_retry = 1; - char *text = NULL; + char *text = NULL; - if ( !ldap_back_dobind( &lc, op, rs, LDAP_BACK_SENDERR ) ) { - return -1; - } + assert( lc != NULL ); Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_generic(%s, \"%s\")\n", op->ore_reqoid.bv_val, op->o_req_dn.bv_val, 0 ); @@ -335,8 +395,9 @@ retry: rs->sr_text = NULL; } - if ( lc != NULL ) { - ldap_back_release_conn( li, lc ); + /* in case, cleanup handler */ + if ( lc == NULL ) { + *lcp = NULL; } return rc; -- 2.39.5