Commit bcf9571e authored by Pierangelo Masarati's avatar Pierangelo Masarati Committed by Quanah Gibson-Mount
Browse files

allow to specify a per-database list of attributes that need to be always...

allow to specify a per-database list of attributes that need to be always collected, even if not explicitly requested by clients (addresses ITS#6513)
parent 0b31b03f
......@@ -446,6 +446,20 @@ upon StartTLS operation receipt.
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
......
......@@ -1278,6 +1278,19 @@ by default. See the
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
......
......@@ -141,7 +141,7 @@ ldap_back_search(
msgid;
struct berval match = BER_BVNULL,
filter = BER_BVNULL;
int i;
int i, x;
char **attrs = NULL;
int freetext = 0, filter_undef = 0;
int do_retry = 1, dont_retry = 0;
......@@ -169,22 +169,48 @@ ldap_back_search(
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;
......
......@@ -118,11 +118,11 @@ ldap_back_map_filter(
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,
......
......@@ -171,42 +171,73 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
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;
}
......
......@@ -603,9 +603,8 @@ meta_back_search_start(
/*
* 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
......
......@@ -464,6 +464,9 @@ void backend_destroy_one( BackendDB *bd, int dynamic )
}
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 );
}
......
......@@ -135,6 +135,7 @@ static ConfigDriver config_referral;
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
......@@ -366,6 +367,10 @@ static ConfigTable config_back_cf_table[] = {
"SUBSTR caseIgnoreSubstringsMatch "
"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,
......@@ -837,7 +842,7 @@ static ConfigOCs cf_ocs[] = {
"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' "
......@@ -3174,6 +3179,58 @@ config_requires(ConfigArgs *c) {
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
......
......@@ -186,19 +186,30 @@ rwm_map_attrnames(
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;
......@@ -321,7 +332,22 @@ rwm_map_attrnames(
}
}
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;
......
......@@ -1939,6 +1939,7 @@ struct BackendDB {
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) */
......
Markdown is supported
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