X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldap%2Fsearch.c;h=3fad39c62b33761639842293fef0964ead92a854;hb=59e9ff6243465640956b58ad1756a3ede53eca7c;hp=41cb685e18744f171a6c09c55357cd60cecfbdad;hpb=b500b9148c873e645846b9c96456d3b9d6cc0f9b;p=openldap diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 41cb685e18..3fad39c62b 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 1999-2015 The OpenLDAP Foundation. + * Copyright 1999-2018 The OpenLDAP Foundation. * Portions Copyright 1999-2003 Howard Chu. * Portions Copyright 2000-2003 Pierangelo Masarati. * All rights reserved. @@ -37,7 +37,22 @@ static int ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn ); + struct berval *bdn, int remove_unknown_schema ); + + +static ObjectClass * +oc_bvfind_undef_ex( struct berval *ocname, int flag ) +{ + ObjectClass *oc = oc_bvfind( ocname ); + + if ( oc || flag ) { + /* oc defined or remove-unknown-schema flag set */ + return oc; + } + + return oc_bvfind_undef( ocname ); +} + /* * replaces (&) with (objectClass=*) and (|) with (!(objectClass=*)) @@ -147,6 +162,8 @@ ldap_back_search( int do_retry = 1, dont_retry = 0; LDAPControl **ctrls = NULL; char **references = NULL; + int remove_unknown_schema = + LDAP_BACK_OMIT_UNKNOWN_SCHEMA (li); rs_assert_ready( rs ); rs->sr_flags &= ~REP_ENTRY_MASK; /* paranoia, we can set rs = non-entry */ @@ -354,7 +371,8 @@ retry: do_retry = 0; e = ldap_first_entry( lc->lc_ld, res ); - rc = ldap_build_entry( op, e, &ent, &bdn ); + rc = ldap_build_entry( op, e, &ent, &bdn, + remove_unknown_schema); if ( rc == LDAP_SUCCESS ) { ldap_get_entry_controls( lc->lc_ld, res, &rs->sr_ctrls ); rs->sr_entry = &ent; @@ -645,6 +663,13 @@ finish:; ldap_back_release_conn( li, lc ); } + if ( rs->sr_err == LDAP_UNAVAILABLE && + /* if we originally bound and wanted rebind-as-user, must drop + * the connection now because we just discarded the credentials. + * ITS#7464, #8142 + */ + LDAP_BACK_SAVECRED( li ) && SLAP_IS_AUTHZ_BACKEND( op ) ) + rs->sr_err = SLAPD_DISCONNECT; return rs->sr_err; } @@ -653,7 +678,8 @@ ldap_build_entry( Operation *op, LDAPMessage *e, Entry *ent, - struct berval *bdn ) + struct berval *bdn, + int remove_unknown_schema) { struct berval a; BerElement ber = *ldap_get_message_ber( e ); @@ -707,7 +733,7 @@ ldap_build_entry( != LDAP_SUCCESS ) { if ( slap_bv2undef_ad( &a, &attr->a_desc, &text, - SLAP_AD_PROXIED ) != LDAP_SUCCESS ) + (remove_unknown_schema ? SLAP_AD_NOINSERT : SLAP_AD_PROXIED )) != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "%s ldap_build_entry: " @@ -785,7 +811,8 @@ ldap_build_entry( /* check if, by chance, it's an undefined objectClass */ if ( attr->a_desc == slap_schema.si_ad_objectClass && - ( oc = oc_bvfind_undef( &attr->a_vals[i] ) ) != NULL ) + ( oc = oc_bvfind_undef_ex( &attr->a_vals[i], + remove_unknown_schema ) ) != NULL ) { ber_dupbv( &pval, &oc->soc_cname ); rc = LDAP_SUCCESS; @@ -900,9 +927,7 @@ ldap_back_entry_get( ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private; ldapconn_t *lc = NULL; - int rc, - do_not_cache; - ber_tag_t tag; + int rc; struct berval bdn; LDAPMessage *result = NULL, *e = NULL; @@ -911,20 +936,22 @@ ldap_back_entry_get( SlapReply rs; int do_retry = 1; LDAPControl **ctrls = NULL; + Operation op2 = *op; + int remove_unknown_schema = + LDAP_BACK_OMIT_UNKNOWN_SCHEMA (li); *ent = NULL; /* Tell getconn this is a privileged op */ - do_not_cache = op->o_do_not_cache; - tag = op->o_tag; - /* do not cache */ - op->o_do_not_cache = 1; + op2.o_do_not_cache = 1; + /* use rootdn to be doubly explicit this is privileged */ + op2.o_dn = op->o_bd->be_rootdn; + op2.o_ndn = op->o_bd->be_rootndn; /* ldap_back_entry_get() is an entry lookup, so it does not need * to know what the entry is being looked up for */ - op->o_tag = LDAP_REQ_SEARCH; - rc = ldap_back_dobind( &lc, op, &rs, LDAP_BACK_DONTSEND ); - op->o_do_not_cache = do_not_cache; - op->o_tag = tag; + op2.o_tag = LDAP_REQ_SEARCH; + op2.o_ctrls = NULL; + rc = ldap_back_dobind( &lc, &op2, &rs, LDAP_BACK_DONTSEND ); if ( !rc ) { return rs.sr_err; } @@ -954,8 +981,8 @@ ldap_back_entry_get( } retry: - ctrls = op->o_ctrls; - rc = ldap_back_controls_add( op, &rs, lc, &ctrls ); + ctrls = NULL; + rc = ldap_back_controls_add( &op2, &rs, lc, &ctrls ); if ( rc != LDAP_SUCCESS ) { goto cleanup; } @@ -967,9 +994,9 @@ retry: if ( rc != LDAP_SUCCESS ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) { do_retry = 0; - if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) { + if ( ldap_back_retry( &lc, &op2, &rs, LDAP_BACK_DONTSEND ) ) { /* if the identity changed, there might be need to re-authz */ - (void)ldap_back_controls_free( op, &rs, &ctrls ); + (void)ldap_back_controls_free( &op2, &rs, &ctrls ); goto retry; } } @@ -988,7 +1015,7 @@ retry: goto cleanup; } - rc = ldap_build_entry( op, e, *ent, &bdn ); + rc = ldap_build_entry( op, e, *ent, &bdn, remove_unknown_schema ); if ( rc != LDAP_SUCCESS ) { entry_free( *ent ); @@ -996,7 +1023,7 @@ retry: } cleanup: - (void)ldap_back_controls_free( op, &rs, &ctrls ); + (void)ldap_back_controls_free( &op2, &rs, &ctrls ); if ( result ) { ldap_msgfree( result );