disallows the StartTLS operation if authenticated (see also
.BR tls_2_anon ).
.TP
+.B olcExtraAttrs: <attr>
+Lists what attributes need to be added to search requests.
+Local storage backends return the entire entry to the frontend.
+The frontend takes care of only returning the requested attributes
+that are allowed by ACLs.
+However, features like access checking and so may need specific
+attributes that are not automatically returned by remote storage
+backends, like proxy backends and so on.
+.B <attr>
+is an attribute that is needed for internal purposes
+and thus always needs to be collected, even when not explicitly
+requested by clients.
+This attribute is multi-valued.
+.TP
.B olcGentleHUP: { TRUE | FALSE }
A SIGHUP signal will only cause a 'gentle' shutdown-attempt:
.B Slapd
manual page for more details on ACL requirements for
Add operations.
.TP
+.B extra_attrs <attrlist>
+Lists what attributes need to be added to search requests.
+Local storage backends return the entire entry to the frontend.
+The frontend takes care of only returning the requested attributes
+that are allowed by ACLs.
+However, features like access checking and so may need specific
+attributes that are not automatically returned by remote storage
+backends, like proxy backends and so on.
+.B <attrlist>
+is a list of attributes that are needed for internal purposes
+and thus always need to be collected, even when not explicitly
+requested by clients.
+.TP
.B hidden on | off
Controls whether the database will be used to answer
queries. A database that is hidden will never be
msgid;
struct berval match = BER_BVNULL,
filter = BER_BVNULL;
- int i;
+ int i, x;
char **attrs = NULL;
int freetext = 0, freefilter = 0;
int do_retry = 1, dont_retry = 0;
LDAP_BACK_TV_SET( &tv );
}
+ i = 0;
if ( op->ors_attrs ) {
- for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ )
+ for ( ; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ )
/* just count attrs */ ;
+ }
+
+ x = 0;
+ if ( op->o_bd->be_extra_anlist ) {
+ for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+ /* just count attrs */ ;
+ }
- attrs = op->o_tmpalloc( ( i + 1 )*sizeof( char * ),
+ if ( i > 0 || x > 0 ) {
+ int j = 0;
+
+ attrs = op->o_tmpalloc( ( i + x + 1 )*sizeof( char * ),
op->o_tmpmemctx );
if ( attrs == NULL ) {
rs->sr_err = LDAP_NO_MEMORY;
rc = -1;
goto finish;
}
-
- for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++ ) {
- attrs[ i ] = op->ors_attrs[i].an_name.bv_val;
+
+ if ( i > 0 ) {
+ for ( i = 0; !BER_BVISNULL( &op->ors_attrs[i].an_name ); i++, j++ ) {
+ attrs[ j ] = op->ors_attrs[i].an_name.bv_val;
+ }
+ }
+
+ if ( x > 0 ) {
+ for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++, j++ ) {
+ if ( op->o_bd->be_extra_anlist[x].an_desc &&
+ ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, op->ors_attrs ) )
+ {
+ continue;
+ }
+
+ attrs[ j ] = op->o_bd->be_extra_anlist[x].an_name.bv_val;
+ }
}
- attrs[ i ] = NULL;
+
+ attrs[ j ] = NULL;
}
ctrls = op->o_ctrls;
int
ldap_back_map_attrs(
+ Operation *op,
struct ldapmap *at_map,
AttributeName *a,
int remap,
- char ***mapped_attrs,
- void *memctx );
+ char ***mapped_attrs );
extern int ldap_back_map_config(
struct ldapmap *oc_map,
int
ldap_back_map_attrs(
+ Operation *op,
struct ldapmap *at_map,
AttributeName *an,
int remap,
- char ***mapped_attrs,
- void *memctx )
+ char ***mapped_attrs )
{
- int i, j;
+ int i, x, j;
char **na;
struct berval mapped;
- if ( an == NULL ) {
+ if ( an == NULL && op->o_bd->be_extra_anlist == NULL ) {
*mapped_attrs = NULL;
return LDAP_SUCCESS;
}
- for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
- /* */ ;
+ i = 0;
+ if ( an != NULL ) {
+ for ( ; !BER_BVISNULL( &an[i].an_name ); i++ )
+ /* */ ;
+ }
+
+ x = 0;
+ if ( op->o_bd->be_extra_anlist != NULL ) {
+ for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+ /* */ ;
+ }
- na = (char **)ber_memcalloc_x( i + 1, sizeof(char *), memctx );
+ assert( i > 0 || x > 0 );
+
+ na = (char **)ber_memcalloc_x( i + x + 1, sizeof(char *), op->o_tmpmemctx );
if ( na == NULL ) {
*mapped_attrs = NULL;
return LDAP_NO_MEMORY;
}
- for ( i = j = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
- ldap_back_map( at_map, &an[i].an_name, &mapped, remap );
- if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
- na[j++] = mapped.bv_val;
+ j = 0;
+ if ( i > 0 ) {
+ for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ ) {
+ ldap_back_map( at_map, &an[i].an_name, &mapped, remap );
+ if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
+ na[j++] = mapped.bv_val;
+ }
+ }
+ }
+
+ if ( x > 0 ) {
+ for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) {
+ if ( op->o_bd->be_extra_anlist[x].an_desc &&
+ ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, an ) )
+ {
+ continue;
+ }
+
+ ldap_back_map( at_map, &op->o_bd->be_extra_anlist[x].an_name, &mapped, remap );
+ if ( !BER_BVISNULL( &mapped ) && !BER_BVISEMPTY( &mapped ) ) {
+ na[j++] = mapped.bv_val;
+ }
}
}
- if ( j == 0 && i != 0 ) {
+
+ if ( j == 0 && ( i > 0 || x > 0 ) ) {
na[j++] = LDAP_NO_ATTRS;
}
na[j] = NULL;
*mapped_attrs = na;
+
return LDAP_SUCCESS;
}
/*
* Maps required attributes
*/
- rc = ldap_back_map_attrs( &mt->mt_rwmap.rwm_at,
- op->ors_attrs, BACKLDAP_MAP, &mapped_attrs,
- op->o_tmpmemctx );
+ rc = ldap_back_map_attrs( op, &mt->mt_rwmap.rwm_at,
+ op->ors_attrs, BACKLDAP_MAP, &mapped_attrs );
if ( rc != LDAP_SUCCESS ) {
/*
* this target is no longer candidate
}
acl_destroy( bd->be_acl );
limits_destroy( bd->be_limits );
+ if ( bd->be_extra_anlist ) {
+ anlist_free( bd->be_extra_anlist, 1, NULL );
+ }
if ( !BER_BVISNULL( &bd->be_update_ndn ) ) {
ch_free( bd->be_update_ndn.bv_val );
}
static ConfigDriver config_loglevel;
static ConfigDriver config_updatedn;
static ConfigDriver config_updateref;
+static ConfigDriver config_extra_attrs;
static ConfigDriver config_include;
static ConfigDriver config_obsolete;
#ifdef HAVE_TLS
"EQUALITY caseIgnoreMatch "
"SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",
NULL, NULL },
+ { "extra_attrs", "attrlist", 2, 2, 0, ARG_DB|ARG_MAGIC,
+ &config_extra_attrs, "( OLcfgDbAt:0.20 NAME 'olcExtraAttrs' "
+ "EQUALITY caseIgnoreMatch "
+ "SYNTAX OMsDirectoryString )", NULL, NULL },
{ "gentlehup", "on|off", 2, 2, 0,
#ifdef SIGHUP
ARG_ON_OFF, &global_gentlehup,
"olcReplogFile $ olcRequires $ olcRestrict $ olcRootDN $ olcRootPW $ "
"olcSchemaDN $ olcSecurity $ olcSizeLimit $ olcSyncUseSubentry $ olcSyncrepl $ "
"olcTimeLimit $ olcUpdateDN $ olcUpdateRef $ olcMirrorMode $ "
- "olcMonitoring ) )",
+ "olcMonitoring $ olcExtraAttrs ) )",
Cft_Database, NULL, cfAddDatabase },
{ "( OLcfgGlOc:5 "
"NAME 'olcOverlayConfig' "
return(0);
}
+static int
+config_extra_attrs(ConfigArgs *c)
+{
+ assert( c->be != NULL );
+
+ if ( c->op == SLAP_CONFIG_EMIT ) {
+ int i;
+
+ if ( c->be->be_extra_anlist == NULL ) {
+ return 1;
+ }
+
+ for ( i = 0; !BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ); i++ ) {
+ value_add_one( &c->rvalue_vals, &c->be->be_extra_anlist[i].an_name );
+ }
+
+ } else if ( c->op == LDAP_MOD_DELETE ) {
+ if ( c->be->be_extra_anlist == NULL ) {
+ return 1;
+ }
+
+ if ( c->valx < 0 ) {
+ anlist_free( c->be->be_extra_anlist, 1, NULL );
+ c->be->be_extra_anlist = NULL;
+
+ } else {
+ int i;
+
+ for ( i = 0; i < c->valx && !BER_BVISNULL( &c->be->be_extra_anlist[i + 1].an_name ); i++ )
+ ;
+
+ if ( BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ) ) {
+ return 1;
+ }
+
+ ch_free( c->be->be_extra_anlist[i].an_name.bv_val );
+
+ for ( ; !BER_BVISNULL( &c->be->be_extra_anlist[i].an_name ); i++ ) {
+ c->be->be_extra_anlist[i] = c->be->be_extra_anlist[i + 1];
+ }
+ }
+
+ } else {
+ c->be->be_extra_anlist = str2anlist( c->be->be_extra_anlist, c->argv[1], " ,\t" );
+ if ( c->be->be_extra_anlist == NULL ) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
static slap_verbmasks *loglevel_ops;
static int
AttributeName **anp,
int remap )
{
- int i, j;
+ int i, j, x;
assert( anp != NULL );
*anp = NULL;
- if ( an == NULL ) {
+ if ( an == NULL && op->o_bd->be_extra_anlist == NULL ) {
return LDAP_SUCCESS;
}
- for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
- /* just count */ ;
- *anp = op->o_tmpalloc( ( i + 1 )* sizeof( AttributeName ),
+ i = 0;
+ if ( an != NULL ) {
+ for ( i = 0; !BER_BVISNULL( &an[i].an_name ); i++ )
+ /* just count */ ;
+ }
+
+ x = 0;
+ if ( op->o_bd->be_extra_anlist ) {
+ for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
+ /* just count */ ;
+ }
+
+ assert( i > 0 || x > 0 );
+ *anp = op->o_tmpalloc( ( i + x + 1 )* sizeof( AttributeName ),
op->o_tmpmemctx );
if ( *anp == NULL ) {
return LDAP_NO_MEMORY;
}
}
- if ( j == 0 && i != 0 ) {
+ if ( op->o_bd->be_extra_anlist != NULL ) {
+ /* we assume be_extra_anlist are already mapped */
+ for ( x = 0; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ ) {
+ BER_BVZERO( &(*anp)[j].an_name );
+ if ( op->o_bd->be_extra_anlist[x].an_desc &&
+ ad_inlist( op->o_bd->be_extra_anlist[x].an_desc, *anp ) )
+ {
+ continue;
+ }
+
+ (*anp)[j] = op->o_bd->be_extra_anlist[x];
+ j++;
+ }
+ }
+
+ if ( j == 0 && ( i != 0 || x != 0 ) ) {
memset( &(*anp)[0], 0, sizeof( AttributeName ) );
(*anp)[0].an_name = *slap_bv_no_attrs;
j = 1;
struct slap_limits **be_limits; /* regex-based size and time limits */
AccessControl *be_acl; /* access control list for this backend */
slap_access_t be_dfltaccess; /* access given if no acl matches */
+ AttributeName *be_extra_anlist; /* attributes that need to be added to search requests (ITS#6513) */
/* Replica Information */
struct berval be_update_ndn; /* allowed to make changes (in replicas) */