]> git.sur5r.net Git - openldap/commitdiff
import fix to ITS#4964
authorPierangelo Masarati <ando@openldap.org>
Sat, 19 May 2007 14:27:53 +0000 (14:27 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sat, 19 May 2007 14:27:53 +0000 (14:27 +0000)
CHANGES
servers/slapd/back-ldap/chain.c
servers/slapd/back-ldap/extended.c

diff --git a/CHANGES b/CHANGES
index cdfc599ea26d21e29dd46f2bbd6ec7a2a49a0b56..f76c69f0c83ff1b93a1dfc58d0c1d049a1e89692 100644 (file)
--- 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
index 08eeeb4f9381dd94cd8d6ccacbfd88b58c4a02d2..8301278e0e76d09dcc26681c97008d32682854dd 100644 (file)
@@ -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;
                }
index c17cb5b7a25177be136ce3f640c26495215ecf8e..68acea97890ae55a0f442d1327a5e4718cd81233 100644 (file)
 #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;