diff --git a/clients/tools/ldapsearch.c b/clients/tools/ldapsearch.c index f295c3e613..068acb3e1b 100644 --- a/clients/tools/ldapsearch.c +++ b/clients/tools/ldapsearch.c @@ -1229,7 +1229,7 @@ getNextPage: if ( infile == NULL ) { rc = dosearch( ld, base, scope, NULL, filtpattern, - attrs, attrsonly, NULL, NULL, NULL, -1 ); + attrs, attrsonly, NULL, NULL, NULL, sizelimit ); } else { rc = 0; @@ -1242,7 +1242,7 @@ getNextPage: first = 0; } rc1 = dosearch( ld, base, scope, filtpattern, line, - attrs, attrsonly, NULL, NULL, NULL, -1 ); + attrs, attrsonly, NULL, NULL, NULL, sizelimit ); if ( rc1 != 0 ) { rc = rc1; @@ -1376,7 +1376,7 @@ static int dosearch( int sizelimit ) { char *filter; - int rc; + int rc, rc2 = LDAP_OTHER; int nresponses; int nentries; int nreferences; @@ -1439,8 +1439,7 @@ static int dosearch( } if( rc != LDAP_SUCCESS ) { - fprintf( stderr, _("%s: ldap_search_ext: %s (%d)\n"), - prog, ldap_err2string( rc ), rc ); + tool_perror( "ldap_search_ext", rc, NULL, NULL, NULL, NULL ); return( rc ); } @@ -1459,9 +1458,8 @@ static int dosearch( sortattr ? LDAP_MSG_ALL : LDAP_MSG_ONE, tvp, &res )) > 0 ) { - rc = tool_check_abandon( ld, msgid ); - if ( rc ) { - return rc; + if ( tool_check_abandon( ld, msgid ) ) { + return -1; } if( sortattr ) { @@ -1509,7 +1507,7 @@ static int dosearch( /* pagedResults stuff is dealt with * in tool_print_ctrls(), called by * print_results(). */ - rc = print_result( ld, msg, 1 ); + rc2 = print_result( ld, msg, 1 ); if ( ldapsync == LDAP_SYNC_REFRESH_AND_PERSIST ) { break; } @@ -1553,13 +1551,8 @@ static int dosearch( } done: - if ( tvp == NULL && rc == 0 ) { - ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&rc ); - } - - if ( rc != 0 ) { - tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL ); - return( rc ); + if ( tvp == NULL && rc != LDAP_RES_SEARCH_RESULT ) { + ldap_get_option( ld, LDAP_OPT_RESULT_CODE, (void *)&rc2 ); } ldap_msgfree( res ); @@ -1593,7 +1586,11 @@ done: if( nreferences ) printf( _("# numReferences: %d\n"), nreferences ); } - return( rc ); + if ( rc != LDAP_RES_SEARCH_RESULT ) { + tool_perror( "ldap_result", rc2, NULL, NULL, NULL, NULL ); + } + + return( rc2 ); } /* This is the proposed new way of doing things. diff --git a/doc/man/man5/slapo-ppolicy.5 b/doc/man/man5/slapo-ppolicy.5 index f3e0497713..c0bf32fe59 100644 --- a/doc/man/man5/slapo-ppolicy.5 +++ b/doc/man/man5/slapo-ppolicy.5 @@ -414,6 +414,23 @@ is set to "TRUE", or if the attribute is not present, users will be allowed to change their own passwords. If its value is "FALSE", users will not be allowed to change their own passwords. .LP +Note: this implies that when +.B pwdAllowUserChange +is set to "TRUE", +users will still be able to change the password of another user, +subjected to access control. +This restriction only applies to modifications of ones's own password. +It should also be noted that +.B pwdAllowUserChange +was defined in the specification to provide rough access control +to the password attribute in implementations that do not allow fine-grain +access control. +Since OpenLDAP provides fine-grain access control, the use of this attribute +is discouraged; ACLs should be used instead +(see +.BR slapd.access (5) +for details). +.LP .RS 4 ( 1.3.6.1.4.1.42.2.27.8.1.14 NAME 'pwdAllowUserChange' diff --git a/servers/slapd/backglue.c b/servers/slapd/backglue.c index 31afe2fff4..af46e71c72 100644 --- a/servers/slapd/backglue.c +++ b/servers/slapd/backglue.c @@ -258,6 +258,30 @@ glue_op_func ( Operation *op, SlapReply *rs ) return rc; } +static int +glue_op_abandon( Operation *op, SlapReply *rs ) +{ + slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; + glueinfo *gi = (glueinfo *)on->on_bi.bi_private; + BackendDB *b0 = op->o_bd; + BackendInfo *bi0 = op->o_bd->bd_info; + int i; + + b0->bd_info = on->on_info->oi_orig; + + for (i = gi->gi_nodes-1; i >= 0; i--) { + assert( gi->gi_n[i].gn_be->be_nsuffix != NULL ); + op->o_bd = gi->gi_n[i].gn_be; + if ( op->o_bd == b0 ) + continue; + if ( op->o_bd->bd_info->bi_op_abandon ) + op->o_bd->bd_info->bi_op_abandon( op, rs ); + } + op->o_bd = b0; + op->o_bd->bd_info = bi0; + return SLAP_CB_CONTINUE; +} + static int glue_response ( Operation *op, SlapReply *rs ) { @@ -1510,6 +1534,7 @@ glue_sub_init() glue.on_bi.bi_op_modrdn = glue_op_func; glue.on_bi.bi_op_add = glue_op_func; glue.on_bi.bi_op_delete = glue_op_func; + glue.on_bi.bi_op_abandon = glue_op_abandon; glue.on_bi.bi_extended = glue_op_func; glue.on_bi.bi_chk_referrals = glue_chk_referrals; diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c index 61901930ff..3a0b1890d7 100644 --- a/servers/slapd/bconfig.c +++ b/servers/slapd/bconfig.c @@ -7247,6 +7247,22 @@ config_tool_entry_put( BackendDB *be, Entry *e, struct berval *text ) return NOID; } } else { + if ( !strncmp( e->e_nname.bv_val + + STRLENOF( "olcDatabase" ), "=frontend", + STRLENOF( "=frontend" ) ) ) + { + struct berval rdn, pdn, ndn; + dnParent( &e->e_nname, &pdn ); + rdn.bv_val = ca.log; + rdn.bv_len = snprintf(rdn.bv_val, sizeof( ca.log ), + "%s=" SLAP_X_ORDERED_FMT "%s", + cfAd_database->ad_cname.bv_val, -1, + frontendDB->bd_info->bi_type ); + build_new_dn( &ndn, &pdn, &rdn, NULL ); + ber_memfree( e->e_name.bv_val ); + e->e_name = ndn; + ber_bvreplace( &e->e_nname, &e->e_name ); + } entry_put_got_frontend++; isFrontend = 1; } diff --git a/servers/slapd/connection.c b/servers/slapd/connection.c index aea3b39191..130838ced8 100644 --- a/servers/slapd/connection.c +++ b/servers/slapd/connection.c @@ -571,9 +571,9 @@ Connection * connection_init( slap_sasl_external( c, ssf, authid ); slapd_add_internal( s, 1 ); - ldap_pvt_thread_mutex_unlock( &c->c_mutex ); backend_connection_init(c); + ldap_pvt_thread_mutex_unlock( &c->c_mutex ); return c; } diff --git a/servers/slapd/operation.c b/servers/slapd/operation.c index f808320501..eff5f56429 100644 --- a/servers/slapd/operation.c +++ b/servers/slapd/operation.c @@ -128,6 +128,7 @@ slap_op_free( Operation *op, void *ctx ) BER_BVZERO( &op->o_req_ndn ); memset( &op->o_request, 0, sizeof( op->o_request )); memset( &op->o_do_not_cache, 0, sizeof( Operation ) - offsetof( Operation, o_do_not_cache )); + memset( opbuf->ob_controls, 0, sizeof( opbuf->ob_controls )); op->o_controls = opbuf->ob_controls; if ( ctx ) { diff --git a/servers/slapd/overlays/dds.c b/servers/slapd/overlays/dds.c index 56d299fdb0..661b30942b 100644 --- a/servers/slapd/overlays/dds.c +++ b/servers/slapd/overlays/dds.c @@ -156,7 +156,7 @@ dds_expire( void *ctx, dds_info_t *di ) op->ors_slimit = SLAP_NO_LIMIT; op->ors_attrs = slap_anlist_no_attrs; - expire = slap_get_time() + di->di_tolerance; + expire = slap_get_time() - di->di_tolerance; ts.bv_val = tsbuf; ts.bv_len = sizeof( tsbuf ); slap_timestamp( &expire, &ts ); diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index 6a693acde2..8889247f9e 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -1792,7 +1792,10 @@ ppolicy_modify( Operation *op, SlapReply *rs ) if (be_isroot( op )) goto do_modify; - if (!pp.pwdAllowUserChange) { + /* NOTE: according to draft-behera-ldap-password-policy + * pwdAllowUserChange == FALSE must only prevent pwd changes + * by the user the pwd belongs to (ITS#7021) */ + if (!pp.pwdAllowUserChange && dn_match(&op->o_req_ndn, &op->o_ndn)) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; rs->sr_text = "User alteration of password is not allowed"; pErr = PP_passwordModNotAllowed; diff --git a/servers/slapd/overlays/refint.c b/servers/slapd/overlays/refint.c index c27b506a20..bd2786e36f 100644 --- a/servers/slapd/overlays/refint.c +++ b/servers/slapd/overlays/refint.c @@ -526,6 +526,7 @@ refint_repair( { dependent_data *dp; SlapReply rs = {REP_RESULT}; + Operation op2; int rc; op->o_callback->sc_response = refint_search_cb; @@ -564,18 +565,14 @@ refint_repair( * */ + op2 = *op; for ( dp = rq->attrs; dp; dp = dp->next ) { - Operation op2 = *op; SlapReply rs2 = {REP_RESULT}; refint_attrs *ra; Modifications *m; if ( dp->attrs == NULL ) continue; /* TODO: Is this needed? */ - op2.o_tag = LDAP_REQ_MODIFY; - op2.orm_modlist = NULL; - op2.o_req_dn = dp->dn; - op2.o_req_ndn = dp->ndn; op2.o_bd = select_backend( &dp->ndn, 1 ); if ( !op2.o_bd ) { Debug( LDAP_DEBUG_TRACE, @@ -583,6 +580,13 @@ refint_repair( dp->dn.bv_val, 0, 0 ); continue; } + op2.o_tag = LDAP_REQ_MODIFY; + op2.orm_modlist = NULL; + op2.o_req_dn = dp->dn; + op2.o_req_ndn = dp->ndn; + /* Internal ops, never replicate these */ + op2.orm_no_opattrs = 1; + op2.o_dont_replicate = 1; /* Set our ModifiersName */ if ( SLAP_LASTMOD( op->o_bd ) ) { @@ -670,7 +674,6 @@ refint_repair( op2.o_dn = op2.o_bd->be_rootdn; op2.o_ndn = op2.o_bd->be_rootndn; - slap_op_time( &op2.o_time, &op2.o_tincr ); rc = op2.o_bd->be_modify( &op2, &rs2 ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, diff --git a/tests/scripts/test006-acls b/tests/scripts/test006-acls index 4a72ed5355..2db92d5381 100755 --- a/tests/scripts/test006-acls +++ b/tests/scripts/test006-acls @@ -69,7 +69,7 @@ echo "# Try to read an entry inside the Alumni Association container. # FIXME: temporarily remove the "No such object" message to make # the test succeed even if SLAP_ACL_HONOR_DISCLOSE is not #define'd $LDAPSEARCH -b "$JAJDN" -h $LOCALHOST -p $PORT1 "(objectclass=*)" \ - 2>&1 | grep -v "^No such object" >> $SEARCHOUT + 2>&1 | grep -v "No such object" >> $SEARCHOUT echo "# ... and should return all attributes if we're bound as anyone # under Example." \