mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-04 06:01:23 -05:00
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)
This commit is contained in:
parent
a3a603eca6
commit
9d2e03f052
10 changed files with 201 additions and 31 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1216,6 +1216,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
|
||||
|
|
|
|||
|
|
@ -163,7 +163,7 @@ ldap_back_search(
|
|||
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;
|
||||
|
|
@ -191,22 +191,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 */ ;
|
||||
}
|
||||
|
||||
attrs = op->o_tmpalloc( ( i + 1 )*sizeof( char * ),
|
||||
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 */ ;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
attrs[ i ] = NULL;
|
||||
|
||||
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[ j ] = NULL;
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
|
|
|
|||
|
|
@ -114,11 +114,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,
|
||||
|
|
|
|||
|
|
@ -174,42 +174,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++ )
|
||||
/* */ ;
|
||||
}
|
||||
|
||||
na = (char **)ber_memcalloc_x( i + 1, sizeof(char *), memctx );
|
||||
x = 0;
|
||||
if ( op->o_bd->be_extra_anlist != NULL ) {
|
||||
for ( ; !BER_BVISNULL( &op->o_bd->be_extra_anlist[x].an_name ); x++ )
|
||||
/* */ ;
|
||||
}
|
||||
|
||||
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 ( j == 0 && i != 0 ) {
|
||||
|
||||
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 || x > 0 ) ) {
|
||||
na[j++] = LDAP_NO_ATTRS;
|
||||
}
|
||||
na[j] = NULL;
|
||||
|
||||
*mapped_attrs = na;
|
||||
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -573,9 +573,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
|
||||
|
|
@ -362,6 +363,10 @@ static ConfigTable config_back_cf_table[] = {
|
|||
"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,
|
||||
|
|
@ -822,7 +827,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' "
|
||||
|
|
@ -3139,6 +3144,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;
|
||||
|
|
|
|||
|
|
@ -1936,6 +1936,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) */
|
||||
|
|
|
|||
Loading…
Reference in a new issue