/* we need this to know if back-ldap returned any result */
lb.lb_lc = lc;
+ sc2.sc_next = sc->sc_next;
sc2.sc_private = &lb;
sc2.sc_response = ldap_chain_cb_response;
op->o_callback = &sc2;
case LDAP_SUCCESS:
case LDAP_REFERRAL:
+ sr_err = rs->sr_err;
/* slapd-ldap sent response */
if ( !op->o_abandon && lb.lb_status != LDAP_CH_RES ) {
/* FIXME: should we send response? */
default:
#endif /* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
if ( LDAP_CHAIN_RETURN_ERR( lc ) ) {
- rs->sr_err = rc;
+ sr_err = rs->sr_err = rc;
rs->sr_type = sr_type;
} else {
}
if ( lb.lb_status == LDAP_CH_NONE && rc != SLAPD_ABANDON ) {
- op->o_callback = NULL;
+ /* give the remaining callbacks a chance */
+ op->o_callback = sc->sc_next;
rc = rs->sr_err = slap_map_api2result( rs );
send_ldap_result( op, rs );
}
CFG_LASTMOD,
CFG_AZPOLICY,
CFG_AZREGEXP,
+ CFG_AZDUC,
+ CFG_AZDUC_IGNORE,
CFG_SASLSECP,
CFG_SSTR_IF_MAX,
CFG_SSTR_IF_MIN,
#endif
"( OLcfgGlAt:89 NAME 'olcSaslAuxprops' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
+ { "sasl-auxprops-dontusecopy", NULL, 2, 0, 0,
+#if defined(HAVE_CYRUS_SASL) && defined(SLAP_AUXPROP_DONTUSECOPY)
+ ARG_MAGIC|CFG_AZDUC, &config_generic,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:91 NAME 'olcSaslAuxpropsDontUseCopy' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
+ { "sasl-auxprops-dontusecopy-ignore", "true|FALSE", 2, 0, 0,
+#if defined(HAVE_CYRUS_SASL) && defined(SLAP_AUXPROP_DONTUSECOPY)
+ ARG_ON_OFF|CFG_AZDUC_IGNORE, &slap_dontUseCopy_ignore,
+#else
+ ARG_IGNORED, NULL,
+#endif
+ "( OLcfgGlAt:92 NAME 'olcSaslAuxpropsDontUseCopyIgnore' "
+ "EQUALITY booleanMatch "
+ "SYNTAX OMsBoolean SINGLE-VALUE )", NULL, NULL },
{ "sasl-host", "host", 2, 2, 0,
#ifdef HAVE_CYRUS_SASL
ARG_STRING|ARG_UNIQUE, &sasl_host,
"olcPluginLogFile $ olcReadOnly $ olcReferral $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
"olcRootDSE $ "
- "olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
+ "olcSaslAuxprops $ olcSaslAuxpropsDontUseCopy $ olcSaslAuxpropsDontUseCopyIgnore $ "
+ "olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
"olcSecurity $ olcServerID $ olcSizeLimit $ "
"olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
"olcTCPBuffer $ "
if ( !c->rvalue_vals ) rc = 1;
break;
#ifdef HAVE_CYRUS_SASL
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ case CFG_AZDUC: {
+ static int duc_done = 0;
+
+ /* take the opportunity to initialize with known values */
+ if ( !duc_done ) {
+ struct berval duc[] = { BER_BVC("cmusaslsecretOTP"), BER_BVNULL };
+ int i;
+
+ for ( i = 0; !BER_BVISNULL( &duc[ i ] ); i++ ) {
+ const char *text = NULL;
+ AttributeDescription *ad = NULL;
+
+ if ( slap_bv2ad( &duc[ i ], &ad, &text ) == LDAP_SUCCESS ) {
+ int gotit = 0;
+ if ( slap_dontUseCopy_propnames ) {
+ int j;
+
+ for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ] ); j++ ) {
+ if ( bvmatch( &slap_dontUseCopy_propnames[ j ], &ad->ad_cname ) ) {
+ gotit = 1;
+ }
+ }
+ }
+
+ if ( !gotit ) {
+ value_add_one( &slap_dontUseCopy_propnames, &ad->ad_cname );
+ }
+ }
+ }
+
+ duc_done = 1;
+ }
+
+ if ( slap_dontUseCopy_propnames != NULL ) {
+ ber_bvarray_dup_x( &c->rvalue_vals, slap_dontUseCopy_propnames, NULL );
+ } else {
+ rc = 1;
+ }
+ } break;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
case CFG_SASLSECP: {
struct berval bv = BER_BVNULL;
slap_sasl_secprops_unparse( &bv );
snprintf(c->log, sizeof( c->log ), "change requires slapd restart");
break;
+#if defined(HAVE_CYRUS_SASL) && defined(SLAP_AUXPROP_DONTUSECOPY)
+ case CFG_AZDUC:
+ if ( c->valx < 0 ) {
+ if ( slap_dontUseCopy_propnames != NULL ) {
+ ber_bvarray_free( slap_dontUseCopy_propnames );
+ slap_dontUseCopy_propnames = NULL;
+ }
+
+ } else {
+ int i;
+
+ if ( slap_dontUseCopy_propnames == NULL ) {
+ rc = 1;
+ break;
+ }
+
+ for ( i = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ i ] ) && i < c->valx; i++ );
+ if ( i < c->valx ) {
+ rc = 1;
+ break;
+ }
+ ber_memfree( slap_dontUseCopy_propnames[ i ].bv_val );
+ for ( ; !BER_BVISNULL( &slap_dontUseCopy_propnames[ i + 1 ] ); i++ ) {
+ slap_dontUseCopy_propnames[ i ] = slap_dontUseCopy_propnames[ i + 1 ];
+ }
+ BER_BVZERO( &slap_dontUseCopy_propnames[ i ] );
+ }
+ break;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
case CFG_SALT:
ch_free( passwd_salt );
passwd_salt = NULL;
break;
#ifdef HAVE_CYRUS_SASL
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ case CFG_AZDUC: {
+ int arg, cnt;
+
+ for ( arg = 1; arg < c->argc; arg++ ) {
+ int duplicate = 0, err;
+ AttributeDescription *ad = NULL;
+ const char *text = NULL;
+
+ err = slap_str2ad( c->argv[ arg ], &ad, &text );
+ if ( err != LDAP_SUCCESS ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s>: attr #%d (\"%s\") unknown (err=%d \"%s\"; ignored)",
+ c->argv[0], arg, c->argv[ arg ], err, text );
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+ c->log, c->cr_msg, 0 );
+
+ } else {
+ if ( slap_dontUseCopy_propnames != NULL ) {
+ for ( cnt = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ cnt ] ); cnt++ ) {
+ if ( bvmatch( &slap_dontUseCopy_propnames[ cnt ], &ad->ad_cname ) ) {
+ duplicate = 1;
+ break;
+ }
+ }
+ }
+
+ if ( duplicate ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s>: attr #%d (\"%s\") already defined (ignored)",
+ c->argv[0], arg, ad->ad_cname.bv_val);
+ Debug(LDAP_DEBUG_ANY, "%s: %s\n",
+ c->log, c->cr_msg, 0 );
+ continue;
+ }
+
+ value_add_one( &slap_dontUseCopy_propnames, &ad->ad_cname );
+ }
+ }
+
+ } break;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
case CFG_SASLSECP:
{
char *txt = slap_sasl_secprops( c->argv[1] );
LDAP_SLAPD_V (char *) global_realm;
LDAP_SLAPD_V (char *) sasl_host;
LDAP_SLAPD_V (char *) slap_sasl_auxprops;
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+LDAP_SLAPD_V (int) slap_dontUseCopy_ignore;
+LDAP_SLAPD_V (BerVarray) slap_dontUseCopy_propnames;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
LDAP_SLAPD_V (char **) default_passwd_hash;
LDAP_SLAPD_V (int) lber_debug;
LDAP_SLAPD_V (int) ldap_syslog;
"*slapConn", "*slapAuthcDNlen", "*slapAuthcDN",
"*slapAuthzDNlen", "*slapAuthzDN", NULL };
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+int slap_dontUseCopy_ignore;
+BerVarray slap_dontUseCopy_propnames;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
int rc, i;
lookup_info *sl = (lookup_info *)op->o_callback->sc_private;
- if (rs->sr_type != REP_SEARCH) return 0;
+ /* return the actual error code,
+ * to allow caller to handle specific errors
+ */
+ if (rs->sr_type != REP_SEARCH) return rs->sr_err;
for( i = 0; sl->list[i].name; i++ ) {
const char *name = sl->list[i].name;
Connection *conn = NULL;
lookup_info sl;
int rc = LDAP_SUCCESS;
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ int dontUseCopy = 0;
+ BackendDB *dontUseCopy_bd = NULL;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
sl.list = sparams->utils->prop_get( sparams->propctx );
sl.sparams = sparams;
break;
}
}
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( slap_dontUseCopy_propnames != NULL ) {
+ int j;
+ struct berval bv;
+ ber_str2bv( &sl.list[i].name[1], 0, 1, &bv );
+ for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ]); j++ ) {
+ if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) {
+ dontUseCopy = 1;
+ break;
+ }
+ }
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
}
}
}
}
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( SLAP_SHADOW( op->o_bd ) && dontUseCopy ) {
+ dontUseCopy_bd = op->o_bd;
+ op->o_bd = frontendDB;
+ }
+
+retry_dontUseCopy:;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
if ( op->o_bd->be_search ) {
SlapReply rs = {REP_RESULT};
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ LDAPControl **save_ctrls = NULL, c;
+ int save_dontUseCopy;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
op->o_hdr = conn->c_sasl_bindop->o_hdr;
op->o_controls = opbuf.ob_controls;
op->o_tag = LDAP_REQ_SEARCH;
/* FIXME: we want all attributes, right? */
op->ors_attrs = NULL;
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( dontUseCopy ) {
+ save_dontUseCopy = op->o_dontUseCopy;
+ if ( !op->o_dontUseCopy ) {
+ int cnt = 0;
+ save_ctrls = op->o_ctrls;
+ if ( op->o_ctrls ) {
+ for ( ; op->o_ctrls[ cnt ]; cnt++ )
+ ;
+ }
+ op->o_ctrls = op->o_tmpcalloc( sizeof(LDAPControl *), cnt + 2, op->o_tmpmemctx );
+ if ( cnt ) {
+ for ( cnt = 0; save_ctrls[ cnt ]; cnt++ ) {
+ op->o_ctrls[ cnt ] = save_ctrls[ cnt ];
+ }
+ }
+ c.ldctl_oid = LDAP_CONTROL_DONTUSECOPY;
+ c.ldctl_iscritical = 1;
+ BER_BVZERO( &c.ldctl_value );
+ op->o_ctrls[ cnt ] = &c;
+ }
+ op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
rc = op->o_bd->be_search( op, &rs );
+
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( dontUseCopy ) {
+ if ( save_ctrls != op->o_ctrls ) {
+ op->o_tmpfree( op->o_ctrls, op->o_tmpmemctx );
+ op->o_ctrls = save_ctrls;
+ op->o_dontUseCopy = save_dontUseCopy;
+ }
+
+ if ( rs.sr_err == LDAP_UNAVAILABLE && slap_dontUseCopy_ignore )
+ {
+ op->o_bd = dontUseCopy_bd;
+ dontUseCopy = 0;
+ goto retry_dontUseCopy;
+ }
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
}
}
}
char textbuf[SLAP_TEXT_BUFLEN];
const char *text;
size_t textlen = sizeof(textbuf);
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ int dontUseCopy = 0;
+ BackendDB *dontUseCopy_bd = NULL;
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
/* just checking if we are enabled */
if (!prctx) return SASL_OK;
if ( pr[i].values )
op.o_req_ndn.bv_val = (char *)pr[i].values[0];
}
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ {
+ struct berval bv;
+ ber_str2bv( &pr[i].name[1], 0, 1, &bv );
+ for ( j = 0; !BER_BVISNULL( &slap_dontUseCopy_propnames[ j ] ); j++ ) {
+ if ( bvmatch( &bv, &slap_dontUseCopy_propnames[ j ] ) ) {
+ dontUseCopy = 1;
+ break;
+ }
+ }
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
}
}
if (!conn || !op.o_req_ndn.bv_val) return SASL_BADPARAM;
op.o_bd = select_backend( &op.o_req_ndn, 1 );
if ( !op.o_bd || !op.o_bd->be_modify ) return SASL_FAIL;
-
+
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( SLAP_SHADOW( op.o_bd ) && dontUseCopy ) {
+ dontUseCopy_bd = op.o_bd;
+ op.o_bd = frontendDB;
+ op.o_dontUseCopy = SLAP_CONTROL_CRITICAL;
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
+
pr = sparams->utils->prop_get( prctx );
if (!pr) return SASL_BADPARAM;
op.o_req_dn = op.o_req_ndn;
op.orm_modlist = modlist;
+retry_dontUseCopy:;
rc = op.o_bd->be_modify( &op, &rs );
+
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( dontUseCopy &&
+ rs.sr_err == LDAP_UNAVAILABLE &&
+ slap_dontUseCopy_ignore )
+ {
+ op.o_bd = dontUseCopy_bd;
+ op.o_dontUseCopy = SLAP_CONTROL_NONE;
+ dontUseCopy = 0;
+ goto retry_dontUseCopy;
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
}
}
slap_mods_free( modlist, 1 );
{
#ifdef HAVE_CYRUS_SASL
sasl_done();
+
+#ifdef SLAP_AUXPROP_DONTUSECOPY
+ if ( slap_dontUseCopy_propnames ) {
+ ber_bvarray_free( slap_dontUseCopy_propnames );
+ slap_dontUseCopy_propnames = NULL;
+ }
+#endif /* SLAP_AUXPROP_DONTUSECOPY */
#endif
free( sasl_host );
sasl_host = NULL;
#define SLAP_CONTROL_X_SESSION_TRACKING
#define SLAP_CONTROL_X_WHATFAILED
#define SLAP_CONFIG_DELETE
+#define SLAP_AUXPROP_DONTUSECOPY
#ifndef SLAP_SCHEMA_EXPOSE
#define SLAP_SCHEMA_EXPOSE
#endif