Commit 467a1da7 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

add support for don't use copy in SASL auxprops lookup/store (ITS#6475; TODO:...

add support for don't use copy in SASL auxprops lookup/store (ITS#6475; TODO: document new directives)
parent 9d2e03f0
......@@ -854,6 +854,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
/* 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;
......@@ -947,6 +948,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
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? */
......@@ -974,7 +976,7 @@ cannot_chain:;
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 {
......@@ -992,7 +994,8 @@ cannot_chain:;
}
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 );
}
......
......@@ -179,6 +179,8 @@ enum {
CFG_LASTMOD,
CFG_AZPOLICY,
CFG_AZREGEXP,
CFG_AZDUC,
CFG_AZDUC_IGNORE,
CFG_SASLSECP,
CFG_SSTR_IF_MAX,
CFG_SSTR_IF_MIN,
......@@ -549,6 +551,24 @@ static ConfigTable config_back_cf_table[] = {
#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,
......@@ -792,7 +812,8 @@ static ConfigOCs cf_ocs[] = {
"olcPluginLogFile $ olcReadOnly $ olcReferral $ "
"olcReplogFile $ olcRequires $ olcRestrict $ olcReverseLookup $ "
"olcRootDSE $ "
"olcSaslAuxprops $ olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
"olcSaslAuxprops $ olcSaslAuxpropsDontUseCopy $ olcSaslAuxpropsDontUseCopyIgnore $ "
"olcSaslHost $ olcSaslRealm $ olcSaslSecProps $ "
"olcSecurity $ olcServerID $ olcSizeLimit $ "
"olcSockbufMaxIncoming $ olcSockbufMaxIncomingAuth $ "
"olcTCPBuffer $ "
......@@ -939,6 +960,47 @@ config_generic(ConfigArgs *c) {
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 );
......@@ -1221,6 +1283,35 @@ config_generic(ConfigArgs *c) {
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;
......@@ -1556,6 +1647,47 @@ config_generic(ConfigArgs *c) {
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] );
......
......@@ -1965,6 +1965,10 @@ LDAP_SLAPD_V (struct berval) global_host_bv;
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;
......
......@@ -149,6 +149,11 @@ static const char *slap_propnames[] = {
"*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=*)");
......@@ -179,7 +184,10 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
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;
......@@ -276,6 +284,10 @@ slap_auxprop_lookup(
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;
......@@ -312,6 +324,19 @@ slap_auxprop_lookup(
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 */
}
}
......@@ -386,8 +411,22 @@ slap_auxprop_lookup(
}
}
#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;
......@@ -408,7 +447,49 @@ slap_auxprop_lookup(
/* 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 */
}
}
}
......@@ -438,6 +519,10 @@ slap_auxprop_store(
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;
......@@ -462,6 +547,18 @@ slap_auxprop_store(
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;
......@@ -469,7 +566,15 @@ slap_auxprop_store(
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;
......@@ -518,7 +623,20 @@ slap_auxprop_store(
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 );
......@@ -1188,6 +1306,13 @@ int slap_sasl_destroy( void )
{
#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;
......
......@@ -65,6 +65,7 @@ LDAP_BEGIN_DECL
#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
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment