/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1999-2013 The OpenLDAP Foundation.
+ * Copyright 1999-2017 The OpenLDAP Foundation.
* Portions Copyright 1999-2003 Howard Chu.
* Portions Copyright 2000-2003 Pierangelo Masarati.
* All rights reserved.
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=*))
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 */
} else {
/* only touch when activity actually took place... */
- if ( li->li_idle_timeout && lc ) {
+ if ( li->li_idle_timeout ) {
lc->lc_time = op->o_time;
}
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;
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;
}
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 );
!= 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: "
/* 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;
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;
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;
}
}
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;
}
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;
}
}
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 );
}
cleanup:
- (void)ldap_back_controls_free( op, &rs, &ctrls );
+ (void)ldap_back_controls_free( &op2, &rs, &ctrls );
if ( result ) {
ldap_msgfree( result );