]> git.sur5r.net Git - openldap/commitdiff
ITS#4292,94,95 fixes from HEAD
authorKurt Zeilenga <kurt@openldap.org>
Mon, 2 Jan 2006 17:57:27 +0000 (17:57 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Mon, 2 Jan 2006 17:57:27 +0000 (17:57 +0000)
CHANGES
include/ac/string.h
servers/slapd/back-ldap/extended.c
servers/slapd/passwd.c
servers/slapd/slap.h

diff --git a/CHANGES b/CHANGES
index 2628d14170a64c2ddcebddbfbd2a3def96e4c29f..dea2649ee16cc2945ed5f83560f06d7a24df9a32 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
 OpenLDAP 2.3 Change Log
 
 OpenLDAP 2.3.15 Engineering
+       Fixed slapd strerror logging bug (ITS#4292)
+       Fixed slapd-ldap password modify exop password return (ITS#4294)
+       Fixed slapd ACL add/delete fraction issue (ITS#4295)
 
 OpenLDAP 2.3.14 Release
        Fixed slapd assertion control restrictions
index f91f04035cd303252afda46d5629aa12c92de406..49075a2782a240d75434df2beef63844f265f1ac 100644 (file)
@@ -106,14 +106,14 @@ void * memrchr(const void *b, int c, size_t len);
 #if defined( HAVE_NONPOSIX_STRERROR_R )
 #      define AC_STRERROR_R(e,b,l)             (strerror_r((e), (b), (l)))
 #elif defined( HAVE_STRERROR_R )
-#      define AC_STRERROR_R(e,b,l)             (strerror_r((e), (b), (l)) ? (b) : "")
+#      define AC_STRERROR_R(e,b,l)             (strerror_r((e), (b), (l)) == 0 ? (b) : "Unknown error")
 #elif defined( HAVE_SYS_ERRLIST )
 #      define AC_STRERROR_R(e,b,l)             ((e) > -1 && (e) < sys_nerr \
-                                                                               ? sys_errlist[(e)] : "" )
+                                                       ? sys_errlist[(e)] : "Unknown error" )
 #elif defined( HAVE_STRERROR )
-#      define AC_STRERROR_R(e,b,l)             (strerror(e))
+#      define AC_STRERROR_R(e,b,l)             (strerror(e))   /* NOTE: may be NULL */
 #else
-#      define AC_STRERROR_R(e,b,l)             ("")
+#      define AC_STRERROR_R(e,b,l)             ("Unknown error")
 #endif
 
 #endif /* _AC_STRING_H */
index 5c631ba4a1caebcf2071cfc14f7beaf10166d750..21a4bd17f2ef148f532330071884316b8ebd5854 100644 (file)
 #include "back-ldap.h"
 #include "lber_pvt.h"
 
-BI_op_extended ldap_back_exop_passwd;
+static BI_op_extended ldap_back_exop_passwd;
+static BI_op_extended ldap_back_exop_generic;
 
 static struct exop {
        struct berval   oid;
        BI_op_extended  *extended;
 } exop_table[] = {
-       { BER_BVC(LDAP_EXOP_MODIFY_PASSWD), ldap_back_exop_passwd },
+       { 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 )
+{
+       ldapconn_t      *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_extended( op, rs );
+               rs->sr_text = NULL;
+               /* otherwise frontend resends result */
+               rc = rs->sr_err = SLAPD_ABANDON;
+               goto done;
+       }
+
+       rc = exop( op, rs );
+
+       if ( op->o_ctrls && op->o_ctrls != oldctrls ) {
+               free( op->o_ctrls[ 0 ] );
+               free( op->o_ctrls );
+       }
+       op->o_ctrls = oldctrls;
+
+done:;
+       if ( lc != NULL ) {
+               ldap_back_release_conn( op, rs, lc );
+       }
+                       
+       return rc;
+}
+
 int
 ldap_back_extended(
                Operation       *op,
@@ -48,52 +91,17 @@ ldap_back_extended(
        for ( i = 0; exop_table[i].extended != NULL; i++ ) {
                if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
                {
-                       ldapconn_t      *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;
-
-done:;
-                       if ( lc != NULL ) {
-                               ldap_back_release_conn( op, rs, lc );
-                       }
-                       
-                       return rc;
+                       return ldap_back_extended_one( op, rs, exop_table[i].extended );
                }
        }
 
-       rs->sr_text = "not supported within naming context";
-       return LDAP_UNWILLING_TO_PERFORM;
+       /* if we get here, the exop is known; the best that we can do
+        * is pass it thru as is */
+       /* FIXME: maybe a list of OIDs to pass thru would be safer */
+       return ldap_back_extended_one( op, rs, ldap_back_exop_generic );
 }
 
-int
+static int
 ldap_back_exop_passwd(
                Operation       *op,
                SlapReply       *rs )
@@ -145,12 +153,20 @@ retry:
                                rs->sr_text = NULL;
                        }
 #endif /* LDAP_NULL_IS_NULL */
+
                        if ( rc == LDAP_SUCCESS ) {
                                if ( rs->sr_err == LDAP_SUCCESS ) {
                                        struct berval   newpw;
-                                       
+
+                                       /* this never happens because 
+                                        * the frontend is generating 
+                                        * the new password, so when
+                                        * the passwd exop is proxied,
+                                        * it never delegates password
+                                        * generation to the remote server
+                                        */
                                        rc = ldap_parse_passwd( lc->lc_ld, res,
-                                                       &newpw);
+                                                       &newpw );
                                        if ( rc == LDAP_SUCCESS &&
                                                        !BER_BVISNULL( &newpw ) )
                                        {
@@ -174,8 +190,9 @@ retry:
                                goto retry;
                        }
                }
-               send_ldap_result( op, rs );
-               rc = -1;
+               send_ldap_extended( op, rs );
+               /* otherwise frontend resends result */
+               rc = rs->sr_err = SLAPD_ABANDON;
        }
 
        /* these have to be freed anyway... */
@@ -194,3 +211,97 @@ retry:
 
        return rc;
 }
+
+static int
+ldap_back_exop_generic(
+       Operation       *op,
+       SlapReply       *rs )
+{
+       ldapconn_t      *lc;
+       LDAPMessage     *res;
+       ber_int_t       msgid;
+       int             rc;
+       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;
+       }
+
+       Debug( LDAP_DEBUG_ARGS, "==> ldap_back_exop_generic(%s, \"%s\")\n",
+               op->ore_reqoid.bv_val, op->o_req_dn.bv_val, 0 );
+
+retry:
+       rc = ldap_extended_operation( lc->lc_ld,
+               op->ore_reqoid.bv_val, op->ore_reqdata,
+               op->o_ctrls, NULL, &msgid );
+
+       if ( rc == LDAP_SUCCESS ) {
+               if ( ldap_result( lc->lc_ld, msgid, LDAP_MSG_ALL, NULL, &res ) == -1 ) {
+                       ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
+                       ldap_back_freeconn( op, lc, 0 );
+                       lc = NULL;
+
+               } else {
+                       /* sigh. parse twice, because parse_passwd
+                        * doesn't give us the err / match / msg info.
+                        */
+                       rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
+                                       (char **)&rs->sr_matched,
+                                       (char **)&rs->sr_text,
+                                       NULL, NULL, 0 );
+#ifndef LDAP_NULL_IS_NULL
+                       if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
+                               free( (char *)rs->sr_matched );
+                               rs->sr_matched = NULL;
+                       }
+                       if ( rs->sr_text && rs->sr_text[ 0 ] == '\0' ) {
+                               free( (char *)rs->sr_text );
+                               rs->sr_text = NULL;
+                       }
+#endif /* LDAP_NULL_IS_NULL */
+                       if ( rc == LDAP_SUCCESS ) {
+                               if ( rs->sr_err == LDAP_SUCCESS ) {
+                                       rc = ldap_parse_extended_result( lc->lc_ld, res,
+                                                       (char **)&rs->sr_rspoid, &rs->sr_rspdata, 0 );
+                                       if ( rc == LDAP_SUCCESS ) {
+                                               rs->sr_type = REP_EXTENDED;
+                                       }
+
+                               } else {
+                                       rc = rs->sr_err;
+                               }
+                       }
+                       ldap_msgfree( res );
+               }
+       }
+       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_extended( op, rs );
+               /* otherwise frontend resends result */
+               rc = rs->sr_err = SLAPD_ABANDON;
+       }
+
+       /* these have to be freed anyway... */
+       if ( rs->sr_matched ) {
+               free( (char *)rs->sr_matched );
+               rs->sr_matched = NULL;
+       }
+       if ( rs->sr_text ) {
+               free( (char *)rs->sr_text );
+               rs->sr_text = NULL;
+       }
+
+       if ( lc != NULL ) {
+               ldap_back_release_conn( op, rs, lc );
+       }
+
+       return rc;
+}
+
index af39674c1c8e5969848bae6df5cdb55154d58179..b79f26127e9157695487b78fc0059f684bb5fd55 100644 (file)
@@ -54,8 +54,9 @@ int passwd_extop(
        slap_callback cb2 = { NULL, slap_replog_cb, NULL, NULL };
        int i, nhash;
        char **hashes;
-       int     rc;
+       int rc;
        BackendDB *op_be;
+       int freenewpw = 0;
 
        cb2.sc_next = &cb;
 
@@ -183,6 +184,7 @@ int passwd_extop(
                slap_passwd_generate( &qpw->rs_new );
                if ( qpw->rs_new.bv_len ) {
                        rsp = slap_passwd_return( &qpw->rs_new );
+                       freenewpw = 1;
                }
        }
        if ( qpw->rs_new.bv_len == 0 ) {
@@ -197,8 +199,13 @@ int passwd_extop(
        if ( op->o_bd->be_extended ) {
                rs->sr_err = op->o_bd->be_extended( op, rs );
                if ( rs->sr_err != LDAP_UNWILLING_TO_PERFORM &&
-                       rs->sr_err != SLAP_CB_CONTINUE ) {
+                       rs->sr_err != SLAP_CB_CONTINUE )
+               {
                        rc = rs->sr_err;
+                       if ( rsp ) {
+                               rs->sr_rspdata = rsp;
+                               rsp = NULL;
+                       }
                        goto error_return;
                }
        }
@@ -279,19 +286,22 @@ old_good:
                        rs->sr_rspdata = rsp;
                } else if ( rsp ) {
                        ber_bvfree( rsp );
+                       rsp = NULL;
                }
                op->o_tag = LDAP_REQ_EXTENDED;
                op->o_callback = sc;
        }
-       slap_mods_free( qpw->rs_mods, 1 );
-       if ( rsp ) {
-               free( qpw->rs_new.bv_val );
-       }
 
        rc = rs->sr_err;
        op->oq_extended = qext;
 
 error_return:;
+       if ( qpw->rs_mods ) {
+               slap_mods_free( qpw->rs_mods, 1 );
+       }
+       if ( freenewpw ) {
+               free( qpw->rs_new.bv_val );
+       }
        if ( !BER_BVISNULL( &op->o_req_dn ) ) {
                op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
                BER_BVZERO( &op->o_req_dn );
index 9564bdbfa610a149459926f13af0f8caaaf6b026..53ecc0b66864af76a64fb1e5beb467196cbb0389 100644 (file)
@@ -1215,7 +1215,7 @@ typedef enum slap_access_e {
        ACL_COMPARE,
        ACL_SEARCH,
        ACL_READ,
-       ACL_WRITE,
+       ACL_WRITE_,
        ACL_MANAGE,
 
        /* always leave at end of levels but not greater than ACL_LEVEL_MASK */
@@ -1230,8 +1230,10 @@ typedef enum slap_access_e {
        ACL_QUALIFIER_MASK = 0x0f00,
 
        /* write granularity */
-       ACL_WADD = ACL_WRITE|ACL_QUALIFIER1,
-       ACL_WDEL = ACL_WRITE|ACL_QUALIFIER2
+       ACL_WADD = ACL_WRITE_|ACL_QUALIFIER1,
+       ACL_WDEL = ACL_WRITE_|ACL_QUALIFIER2,
+
+       ACL_WRITE = ACL_WADD|ACL_WDEL
 } slap_access_t;
 
 typedef enum slap_control_e {