mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-18 11:05:48 +08:00
implement add/delete granularity in write access (ITS#3631)
This commit is contained in:
parent
5807c2b379
commit
4abbf9c610
@ -172,6 +172,7 @@ access_allowed_mask(
|
||||
#endif
|
||||
slap_mask_t mask;
|
||||
slap_control_t control;
|
||||
slap_access_t access_level;
|
||||
const char *attr;
|
||||
regmatch_t matches[MAXREMATCHES];
|
||||
int st_same_attr = 0;
|
||||
@ -179,7 +180,10 @@ access_allowed_mask(
|
||||
|
||||
assert( e != NULL );
|
||||
assert( desc != NULL );
|
||||
assert( access > ACL_NONE );
|
||||
|
||||
access_level = ACL_LEVEL( access );
|
||||
|
||||
assert( access_level > ACL_NONE );
|
||||
if ( maskp ) ACL_INVALIDATE( *maskp );
|
||||
|
||||
attr = desc->ad_cname.bv_val;
|
||||
@ -187,7 +191,7 @@ access_allowed_mask(
|
||||
assert( attr != NULL );
|
||||
|
||||
if( op && op->o_is_auth_check &&
|
||||
( access == ACL_SEARCH || access == ACL_READ ))
|
||||
( access_level == ACL_SEARCH || access_level == ACL_READ ))
|
||||
{
|
||||
access = ACL_AUTH;
|
||||
}
|
||||
@ -265,7 +269,7 @@ access_allowed_mask(
|
||||
* by ACL_WRITE checking as any found here are not provided
|
||||
* by the user
|
||||
*/
|
||||
if ( access >= ACL_WRITE && is_at_no_user_mod( desc->ad_type )
|
||||
if ( access_level >= ACL_WRITE && is_at_no_user_mod( desc->ad_type )
|
||||
&& desc != slap_schema.si_ad_entry
|
||||
&& desc != slap_schema.si_ad_children )
|
||||
{
|
||||
@ -280,9 +284,9 @@ access_allowed_mask(
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> access_allowed: backend default %s access %s to \"%s\"\n",
|
||||
access2str( access ),
|
||||
be->be_dfltaccess >= access ? "granted" : "denied",
|
||||
be->be_dfltaccess >= access_level ? "granted" : "denied",
|
||||
op->o_dn.bv_val ? op->o_dn.bv_val : "(anonymous)" );
|
||||
ret = be->be_dfltaccess >= access;
|
||||
ret = be->be_dfltaccess >= access_level;
|
||||
|
||||
if ( maskp ) {
|
||||
int i;
|
||||
@ -302,8 +306,8 @@ access_allowed_mask(
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> access_allowed: global default %s access %s to \"%s\"\n",
|
||||
access2str( access ),
|
||||
frontendDB->be_dfltaccess >= access ? "granted" : "denied", op->o_dn.bv_val );
|
||||
ret = frontendDB->be_dfltaccess >= access;
|
||||
frontendDB->be_dfltaccess >= access_level ? "granted" : "denied", op->o_dn.bv_val );
|
||||
ret = frontendDB->be_dfltaccess >= access_level;
|
||||
|
||||
if ( maskp ) {
|
||||
int i;
|
||||
@ -1929,7 +1933,7 @@ acl_check_modlist(
|
||||
* This prevents abuse from selfwriters.
|
||||
*/
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, NULL, ACL_WRITE, &state ) )
|
||||
mlist->sml_desc, NULL, ACL_WDEL, &state ) )
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
@ -1947,7 +1951,7 @@ acl_check_modlist(
|
||||
bv->bv_val != NULL; bv++ )
|
||||
{
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, bv, ACL_WRITE, &state ) )
|
||||
mlist->sml_desc, bv, ACL_WADD, &state ) )
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
@ -1958,7 +1962,7 @@ acl_check_modlist(
|
||||
case LDAP_MOD_DELETE:
|
||||
if ( mlist->sml_values == NULL ) {
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, NULL, ACL_WRITE, NULL ) )
|
||||
mlist->sml_desc, NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
@ -1970,7 +1974,7 @@ acl_check_modlist(
|
||||
bv->bv_val != NULL; bv++ )
|
||||
{
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, bv, ACL_WRITE, &state ) )
|
||||
mlist->sml_desc, bv, ACL_WDEL, &state ) )
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
|
@ -1816,6 +1816,12 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
|
||||
} else if ( ACL_LVL_IS_WRITE(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "write" );
|
||||
|
||||
} else if ( ACL_LVL_IS_WADD(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "add" );
|
||||
|
||||
} else if ( ACL_LVL_IS_WDEL(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "delete" );
|
||||
|
||||
} else if ( ACL_LVL_IS_MANAGE(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "manage" );
|
||||
|
||||
@ -1850,6 +1856,16 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
|
||||
*ptr++ = 'w';
|
||||
}
|
||||
|
||||
if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WADD) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'a';
|
||||
}
|
||||
|
||||
if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WDEL) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'z';
|
||||
}
|
||||
|
||||
if ( ACL_PRIV_ISSET(mask, ACL_PRIV_READ) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'r';
|
||||
@ -1877,7 +1893,7 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
|
||||
|
||||
if ( none && ACL_PRIV_ISSET(mask, ACL_PRIV_NONE) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'n';
|
||||
*ptr++ = '0';
|
||||
}
|
||||
|
||||
if ( none ) {
|
||||
@ -1922,6 +1938,12 @@ str2accessmask( const char *str )
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'w' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_WRITE);
|
||||
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'a' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_WADD);
|
||||
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'z' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_WDEL);
|
||||
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'r' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_READ);
|
||||
|
||||
@ -1964,6 +1986,12 @@ str2accessmask( const char *str )
|
||||
} else if ( strcasecmp( str, "read" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_READ(mask);
|
||||
|
||||
} else if ( strcasecmp( str, "add" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WADD(mask);
|
||||
|
||||
} else if ( strcasecmp( str, "delete" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WDEL(mask);
|
||||
|
||||
} else if ( strcasecmp( str, "write" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WRITE(mask);
|
||||
|
||||
@ -2008,8 +2036,8 @@ acl_usage( void )
|
||||
"<peernamestyle> ::= exact | regex | ip | path\n"
|
||||
"<domainstyle> ::= exact | regex | base(Object) | sub(tree)\n"
|
||||
"<access> ::= [[real]self]{<level>|<priv>}\n"
|
||||
"<level> ::= none|disclose|auth|compare|search|read|write|manage\n"
|
||||
"<priv> ::= {=|+|-}{0|d|x|c|s|r|w|m}+\n"
|
||||
"<level> ::= none|disclose|auth|compare|search|read|{write|add|delete}|manage\n"
|
||||
"<priv> ::= {=|+|-}{0|d|x|c|s|r|{w|a|z}|m}+\n"
|
||||
"<control> ::= [ stop | continue | break ]\n"
|
||||
);
|
||||
exit( EXIT_FAILURE );
|
||||
@ -2192,6 +2220,12 @@ access2str( slap_access_t access )
|
||||
} else if ( access == ACL_WRITE ) {
|
||||
return "write";
|
||||
|
||||
} else if ( access == ACL_WADD ) {
|
||||
return "add";
|
||||
|
||||
} else if ( access == ACL_WDEL ) {
|
||||
return "delete";
|
||||
|
||||
} else if ( access == ACL_MANAGE ) {
|
||||
return "manage";
|
||||
|
||||
@ -2224,6 +2258,12 @@ str2access( const char *str )
|
||||
} else if ( strcasecmp( str, "write" ) == 0 ) {
|
||||
return ACL_WRITE;
|
||||
|
||||
} else if ( strcasecmp( str, "add" ) == 0 ) {
|
||||
return ACL_WADD;
|
||||
|
||||
} else if ( strcasecmp( str, "delete" ) == 0 ) {
|
||||
return ACL_WDEL;
|
||||
|
||||
} else if ( strcasecmp( str, "manage" ) == 0 ) {
|
||||
return ACL_MANAGE;
|
||||
}
|
||||
|
@ -177,7 +177,7 @@ retry: /* transaction retry */
|
||||
}
|
||||
|
||||
rs->sr_err = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WADD, NULL );
|
||||
|
||||
if ( ! rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
@ -272,7 +272,7 @@ retry: /* transaction retry */
|
||||
}
|
||||
|
||||
rs->sr_err = access_allowed( op, op->oq_add.rs_e,
|
||||
entry, NULL, ACL_WRITE, NULL );
|
||||
entry, NULL, ACL_WADD, NULL );
|
||||
|
||||
if ( ! rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
|
@ -202,7 +202,7 @@ retry: /* transaction retry */
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rs->sr_err = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WDEL, NULL );
|
||||
|
||||
if ( !rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
@ -228,7 +228,7 @@ retry: /* transaction retry */
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rs->sr_err = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WDEL, NULL );
|
||||
|
||||
p = NULL;
|
||||
|
||||
@ -266,7 +266,7 @@ retry: /* transaction retry */
|
||||
}
|
||||
|
||||
rs->sr_err = access_allowed( op, e,
|
||||
entry, NULL, ACL_WRITE, NULL );
|
||||
entry, NULL, ACL_WDEL, NULL );
|
||||
|
||||
if ( !rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
|
@ -289,7 +289,10 @@ retry: /* transaction retry */
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rs->sr_err = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL,
|
||||
op->oq_modrdn.rs_newSup == NULL ?
|
||||
ACL_WRITE : ACL_WDEL,
|
||||
NULL );
|
||||
|
||||
if ( ! rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
@ -330,7 +333,10 @@ retry: /* transaction retry */
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rs->sr_err = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL,
|
||||
op->oq_modrdn.rs_newSup == NULL ?
|
||||
ACL_WRITE : ACL_WDEL,
|
||||
NULL );
|
||||
|
||||
p = NULL;
|
||||
|
||||
@ -437,7 +443,7 @@ retry: /* transaction retry */
|
||||
|
||||
/* check newSuperior for "children" acl */
|
||||
rs->sr_err = access_allowed( op, np, children,
|
||||
NULL, ACL_WRITE, NULL );
|
||||
NULL, ACL_WADD, NULL );
|
||||
|
||||
if( ! rs->sr_err ) {
|
||||
switch( opinfo.boi_err ) {
|
||||
@ -492,7 +498,7 @@ retry: /* transaction retry */
|
||||
|
||||
/* check parent for "children" acl */
|
||||
rs->sr_err = access_allowed( op, np,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WADD, NULL );
|
||||
|
||||
np = NULL;
|
||||
|
||||
|
@ -62,7 +62,7 @@ ldbm_back_add(
|
||||
#endif
|
||||
|
||||
if ( !access_allowed( op, op->oq_add.rs_e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
entry, NULL, ACL_WADD, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "no write access to entry\n", 0,
|
||||
0, 0 );
|
||||
@ -131,7 +131,7 @@ ldbm_back_add(
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
if ( ! access_allowed( op, p, children, NULL, ACL_WRITE, NULL ) ) {
|
||||
if ( ! access_allowed( op, p, children, NULL, ACL_WADD, NULL ) ) {
|
||||
/* free parent and writer lock */
|
||||
cache_return_entry_w( &li->li_cache, p );
|
||||
ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
|
||||
|
@ -77,8 +77,7 @@ ldbm_back_delete(
|
||||
}
|
||||
|
||||
/* check entry for "entry" acl */
|
||||
if ( ! access_allowed( op, e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
if ( ! access_allowed( op, e, entry, NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- ldbm_back_delete: no write access to entry\n", 0,
|
||||
@ -134,7 +133,7 @@ ldbm_back_delete(
|
||||
|
||||
/* check parent for "children" acl */
|
||||
if ( ! access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
children, NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- ldbm_back_delete: no access to parent\n", 0,
|
||||
@ -153,7 +152,7 @@ ldbm_back_delete(
|
||||
p = (Entry *)&slap_entry_root;
|
||||
|
||||
rc = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WDEL, NULL );
|
||||
p = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
|
@ -101,8 +101,7 @@ ldbm_back_modrdn(
|
||||
}
|
||||
|
||||
/* check entry for "entry" acl */
|
||||
if ( ! access_allowed( op, e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
if ( ! access_allowed( op, e, entry, NULL, ACL_WRITE, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<=- ldbm_back_modrdn: no write access to entry\n", 0,
|
||||
@ -163,8 +162,10 @@ ldbm_back_modrdn(
|
||||
}
|
||||
|
||||
/* check parent for "children" acl */
|
||||
if ( ! access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL ) )
|
||||
if ( ! access_allowed( op, p, children, NULL,
|
||||
op->oq_modrdn.rs_newSup != NULL ?
|
||||
ACL_WDEL : ACL_WRITE,
|
||||
NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, "no access to parent\n", 0,
|
||||
0, 0 );
|
||||
@ -197,7 +198,10 @@ ldbm_back_modrdn(
|
||||
p = (Entry *)&slap_entry_root;
|
||||
|
||||
can_access = access_allowed( op, p,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL,
|
||||
op->oq_modrdn.rs_newSup ?
|
||||
ACL_WDEL : ACL_WRITE,
|
||||
NULL );
|
||||
p = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
@ -270,7 +274,7 @@ ldbm_back_modrdn(
|
||||
|
||||
/* check newSuperior for "children" acl */
|
||||
if ( !access_allowed( op, np, children, NULL,
|
||||
ACL_WRITE, NULL ) )
|
||||
ACL_WADD, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"ldbm_back_modrdn: no wr to newSup children\n",
|
||||
@ -316,7 +320,7 @@ ldbm_back_modrdn(
|
||||
np = (Entry *)&slap_entry_root;
|
||||
|
||||
can_access = access_allowed( op, np,
|
||||
children, NULL, ACL_WRITE, NULL );
|
||||
children, NULL, ACL_WADD, NULL );
|
||||
np = NULL;
|
||||
|
||||
/* check parent for "children" acl */
|
||||
|
@ -55,7 +55,7 @@ shell_back_add(
|
||||
}
|
||||
|
||||
if ( ! access_allowed( op, op->oq_add.rs_e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
entry, NULL, ACL_WADD, NULL ) )
|
||||
{
|
||||
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
|
||||
return -1;
|
||||
|
@ -64,7 +64,7 @@ shell_back_delete(
|
||||
e.e_private = NULL;
|
||||
|
||||
if ( ! access_allowed( op, &e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
entry, NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
|
||||
return -1;
|
||||
|
@ -63,8 +63,9 @@ shell_back_modrdn(
|
||||
e.e_bv.bv_val = NULL;
|
||||
e.e_private = NULL;
|
||||
|
||||
if ( ! access_allowed( op, &e,
|
||||
entry, NULL, ACL_WRITE, NULL ) )
|
||||
if ( ! access_allowed( op, &e, entry, NULL,
|
||||
op->oq_modrdn.rs_newSup ? ACL_WDEL : ACL_WRITE,
|
||||
NULL ) )
|
||||
{
|
||||
send_ldap_error( op, rs, LDAP_INSUFFICIENT_ACCESS, NULL );
|
||||
return -1;
|
||||
|
@ -1152,7 +1152,7 @@ backsql_add( Operation *op, SlapReply *rs )
|
||||
|
||||
/* check "children" pseudo-attribute access to parent */
|
||||
if ( !access_allowed( op, &p, slap_schema.si_ad_children,
|
||||
NULL, ACL_WRITE, NULL ) )
|
||||
NULL, ACL_WADD, NULL ) )
|
||||
{
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
e = &p;
|
||||
@ -1170,7 +1170,7 @@ backsql_add( Operation *op, SlapReply *rs )
|
||||
|
||||
if ( !access_allowed_mask( op, op->ora_e,
|
||||
slap_schema.si_ad_entry,
|
||||
NULL, ACL_WRITE, NULL, &mask ) )
|
||||
NULL, ACL_WADD, NULL, &mask ) )
|
||||
{
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
e = op->ora_e;
|
||||
|
@ -162,7 +162,7 @@ backsql_delete( Operation *op, SlapReply *rs )
|
||||
}
|
||||
|
||||
if ( !access_allowed( op, &d, slap_schema.si_ad_entry,
|
||||
NULL, ACL_WRITE, NULL ) )
|
||||
NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
|
||||
"no write access to entry\n",
|
||||
@ -238,7 +238,7 @@ backsql_delete( Operation *op, SlapReply *rs )
|
||||
|
||||
/* check parent for "children" acl */
|
||||
if ( !access_allowed( op, &p, slap_schema.si_ad_children,
|
||||
NULL, ACL_WRITE, NULL ) )
|
||||
NULL, ACL_WDEL, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, " backsql_delete(): "
|
||||
"no write access to parent\n",
|
||||
|
@ -194,8 +194,9 @@ backsql_modrdn( Operation *op, SlapReply *rs )
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( !access_allowed( op, &p, slap_schema.si_ad_children,
|
||||
NULL, ACL_WRITE, NULL ) ) {
|
||||
if ( !access_allowed( op, &p, slap_schema.si_ad_children, NULL,
|
||||
newSuperior ? ACL_WDEL : ACL_WRITE, NULL ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_TRACE, " no access to parent\n", 0, 0, 0 );
|
||||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
goto done;
|
||||
@ -250,7 +251,7 @@ backsql_modrdn( Operation *op, SlapReply *rs )
|
||||
#endif /* ! BACKSQL_ARBITRARY_KEY */
|
||||
|
||||
if ( !access_allowed( op, &n, slap_schema.si_ad_children,
|
||||
NULL, ACL_WRITE, NULL ) ) {
|
||||
NULL, ACL_WADD, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE, " backsql_modrdn(): "
|
||||
"no access to new parent \"%s\"\n",
|
||||
new_pdn->bv_val, 0, 0 );
|
||||
|
@ -450,7 +450,7 @@ slap_modrdn2mods(
|
||||
|
||||
/* ACL check of newly added attrs */
|
||||
if ( op->o_bd && !access_allowed( op, e, desc,
|
||||
&new_rdn[a_cnt]->la_value, ACL_WRITE, NULL ) ) {
|
||||
&new_rdn[a_cnt]->la_value, ACL_WADD, NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"slap_modrdn2modlist: access to attr \"%s\" "
|
||||
"(new) not allowed\n",
|
||||
@ -500,9 +500,9 @@ slap_modrdn2mods(
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* ACL check of newly added attrs */
|
||||
/* ACL check of old rdn attrs removal */
|
||||
if ( op->o_bd && !access_allowed( op, e, desc,
|
||||
&old_rdn[d_cnt]->la_value, ACL_WRITE,
|
||||
&old_rdn[d_cnt]->la_value, ACL_WDEL,
|
||||
NULL ) ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"slap_modrdn2modlist: access "
|
||||
|
@ -1156,7 +1156,19 @@ typedef enum slap_access_e {
|
||||
ACL_SEARCH,
|
||||
ACL_READ,
|
||||
ACL_WRITE,
|
||||
ACL_MANAGE
|
||||
ACL_MANAGE,
|
||||
|
||||
/* ACL level mask and modifiers */
|
||||
ACL_LEVEL_MASK = 0x000f,
|
||||
ACL_QUALIFIER1 = 0x0100,
|
||||
ACL_QUALIFIER2 = 0x0200,
|
||||
ACL_QUALIFIER3 = 0x0400,
|
||||
ACL_QUALIFIER4 = 0x0800,
|
||||
ACL_QUALIFIER_MASK = 0x0f00,
|
||||
|
||||
/* write granularity */
|
||||
ACL_WADD = ACL_WRITE|ACL_QUALIFIER1,
|
||||
ACL_WDEL = ACL_WRITE|ACL_QUALIFIER2
|
||||
} slap_access_t;
|
||||
|
||||
typedef enum slap_control_e {
|
||||
@ -1246,7 +1258,11 @@ typedef struct slap_dn_access {
|
||||
typedef struct slap_access {
|
||||
slap_control_t a_type;
|
||||
|
||||
#define ACL_ACCESS2PRIV(access) (0x01U << (access))
|
||||
/* strip qualifiers */
|
||||
#define ACL_LEVEL(p) ((p) & ACL_LEVEL_MASK)
|
||||
#define ACL_QUALIFIERS(p) ((p) & ~ACL_LEVEL_MASK)
|
||||
|
||||
#define ACL_ACCESS2PRIV(access) ((0x01U << ACL_LEVEL((access))) | ACL_QUALIFIERS((access)))
|
||||
|
||||
#define ACL_PRIV_NONE ACL_ACCESS2PRIV( ACL_NONE )
|
||||
#define ACL_PRIV_DISCLOSE ACL_ACCESS2PRIV( ACL_DISCLOSE )
|
||||
@ -1254,10 +1270,13 @@ typedef struct slap_access {
|
||||
#define ACL_PRIV_COMPARE ACL_ACCESS2PRIV( ACL_COMPARE )
|
||||
#define ACL_PRIV_SEARCH ACL_ACCESS2PRIV( ACL_SEARCH )
|
||||
#define ACL_PRIV_READ ACL_ACCESS2PRIV( ACL_READ )
|
||||
#define ACL_PRIV_WRITE ACL_ACCESS2PRIV( ACL_WRITE )
|
||||
#define ACL_PRIV_WADD ACL_ACCESS2PRIV( ACL_WADD )
|
||||
#define ACL_PRIV_WDEL ACL_ACCESS2PRIV( ACL_WDEL )
|
||||
#define ACL_PRIV_WRITE ( ACL_PRIV_WADD | ACL_PRIV_WDEL )
|
||||
#define ACL_PRIV_MANAGE ACL_ACCESS2PRIV( ACL_MANAGE )
|
||||
|
||||
#define ACL_PRIV_MASK 0x00ffUL
|
||||
/* NOTE: always use the highest level; current: 0x00ffUL */
|
||||
#define ACL_PRIV_MASK ((ACL_PRIV_MANAGE - 1) | ACL_QUALIFIER_MASK)
|
||||
|
||||
/* priv flags */
|
||||
#define ACL_PRIV_LEVEL 0x1000UL
|
||||
@ -1289,6 +1308,8 @@ typedef struct slap_access {
|
||||
#define ACL_LVL_COMPARE (ACL_PRIV_COMPARE|ACL_LVL_AUTH)
|
||||
#define ACL_LVL_SEARCH (ACL_PRIV_SEARCH|ACL_LVL_COMPARE)
|
||||
#define ACL_LVL_READ (ACL_PRIV_READ|ACL_LVL_SEARCH)
|
||||
#define ACL_LVL_WADD (ACL_PRIV_WADD|ACL_LVL_READ)
|
||||
#define ACL_LVL_WDEL (ACL_PRIV_WDEL|ACL_LVL_READ)
|
||||
#define ACL_LVL_WRITE (ACL_PRIV_WRITE|ACL_LVL_READ)
|
||||
#define ACL_LVL_MANAGE (ACL_PRIV_MANAGE|ACL_LVL_WRITE)
|
||||
|
||||
@ -1299,6 +1320,8 @@ typedef struct slap_access {
|
||||
#define ACL_LVL_IS_COMPARE(m) ACL_LVL((m),ACL_LVL_COMPARE)
|
||||
#define ACL_LVL_IS_SEARCH(m) ACL_LVL((m),ACL_LVL_SEARCH)
|
||||
#define ACL_LVL_IS_READ(m) ACL_LVL((m),ACL_LVL_READ)
|
||||
#define ACL_LVL_IS_WADD(m) ACL_LVL((m),ACL_LVL_WADD)
|
||||
#define ACL_LVL_IS_WDEL(m) ACL_LVL((m),ACL_LVL_WDEL)
|
||||
#define ACL_LVL_IS_WRITE(m) ACL_LVL((m),ACL_LVL_WRITE)
|
||||
#define ACL_LVL_IS_MANAGE(m) ACL_LVL((m),ACL_LVL_MANAGE)
|
||||
|
||||
@ -1308,6 +1331,8 @@ typedef struct slap_access {
|
||||
#define ACL_LVL_ASSIGN_COMPARE(m) ACL_PRIV_ASSIGN((m),ACL_LVL_COMPARE)
|
||||
#define ACL_LVL_ASSIGN_SEARCH(m) ACL_PRIV_ASSIGN((m),ACL_LVL_SEARCH)
|
||||
#define ACL_LVL_ASSIGN_READ(m) ACL_PRIV_ASSIGN((m),ACL_LVL_READ)
|
||||
#define ACL_LVL_ASSIGN_WADD(m) ACL_PRIV_ASSIGN((m),ACL_LVL_WADD)
|
||||
#define ACL_LVL_ASSIGN_WDEL(m) ACL_PRIV_ASSIGN((m),ACL_LVL_WDEL)
|
||||
#define ACL_LVL_ASSIGN_WRITE(m) ACL_PRIV_ASSIGN((m),ACL_LVL_WRITE)
|
||||
#define ACL_LVL_ASSIGN_MANAGE(m) ACL_PRIV_ASSIGN((m),ACL_LVL_MANAGE)
|
||||
|
||||
|
@ -3364,6 +3364,7 @@ int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
|
||||
case SLAPI_ACL_DELETE:
|
||||
case SLAPI_ACL_ADD:
|
||||
case SLAPI_ACL_SELF:
|
||||
/* FIXME: handle ACL_WADD/ACL_WDEL */
|
||||
slap_access = ACL_WRITE;
|
||||
break;
|
||||
default:
|
||||
@ -4000,6 +4001,7 @@ int slapi_int_access_allowed( Operation *op,
|
||||
|
||||
switch ( access ) {
|
||||
case ACL_WRITE:
|
||||
/* FIXME: handle ACL_WADD/ACL_WDEL */
|
||||
slap_access |= SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_WRITE;
|
||||
break;
|
||||
case ACL_READ:
|
||||
|
@ -21,6 +21,22 @@ facsimileTelephoneNumber: +1 313 555 4332
|
||||
telephoneNumber: +1 313 555 0895
|
||||
|
||||
# Using ldapsearch to retrieve all the entries...
|
||||
dn: ou=Add/Delete,dc=example,dc=com
|
||||
objectClass: organizationalUnit
|
||||
ou: Add/Delete
|
||||
|
||||
dn: cn=Added by Bjorn (must succeed),ou=Add/Delete,dc=example,dc=com
|
||||
objectClass: inetOrgPerson
|
||||
cn: Added by Bjorn (must succeed)
|
||||
sn: None
|
||||
description: this attribute value has been added __after__entry creation
|
||||
description: Bjorn will try to delete this attribute value (should fail)
|
||||
|
||||
dn: cn=Added by Bjorn (renamed by Jaj),ou=Add/Delete,dc=example,dc=com
|
||||
objectClass: inetOrgPerson
|
||||
sn: None
|
||||
cn: Added by Bjorn (renamed by Jaj)
|
||||
|
||||
dn: cn=All Staff,ou=Groups,dc=example,dc=com
|
||||
member: cn=Manager,dc=example,dc=com
|
||||
member: cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=exam
|
||||
|
@ -95,6 +95,12 @@ access to dn.exact="cn=Alumni Assoc Staff,ou=Groups,dc=example,dc=com"
|
||||
access to filter="(name=X*Y*Z)"
|
||||
by * continue
|
||||
|
||||
access to dn.subtree="ou=Add/Delete,dc=example,dc=com"
|
||||
by dn.exact="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" add
|
||||
by dn.exact="cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" delete
|
||||
by dn.exact="cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com" write
|
||||
by * read
|
||||
|
||||
# fall into global ACLs
|
||||
|
||||
#monitor#database monitor
|
||||
|
@ -172,6 +172,103 @@ description: added by bjensen (should fail)
|
||||
-
|
||||
EOMODS6
|
||||
|
||||
$LDAPMODIFY -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD >> \
|
||||
$TESTOUT 2>&1 << EOMODS7
|
||||
dn: ou=Add/Delete,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: organizationalUnit
|
||||
ou: Add/Delete
|
||||
EOMODS7
|
||||
|
||||
$LDAPMODIFY -D "$BABSDN" -h $LOCALHOST -p $PORT1 -w bjensen >> \
|
||||
$TESTOUT 2>&1 << EOMODS8
|
||||
dn: cn=Added by Babs (must fail),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: inetOrgPerson
|
||||
cn: Added by Babs (must fail)
|
||||
sn: None
|
||||
EOMODS8
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -h $LOCALHOST -p $PORT1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS9
|
||||
dn: cn=Added by Bjorn (must succeed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: inetOrgPerson
|
||||
cn: Added by Bjorn (must succeed)
|
||||
sn: None
|
||||
|
||||
dn: cn=Added by Bjorn (will be deleted),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: inetOrgPerson
|
||||
cn: Added by Bjorn (will be deleted)
|
||||
sn: None
|
||||
|
||||
dn: cn=Added by Bjorn (will be renamed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: add
|
||||
objectClass: inetOrgPerson
|
||||
cn: Added by Bjorn (will be renamed)
|
||||
sn: None
|
||||
|
||||
dn: cn=Added by Bjorn (must succeed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modify
|
||||
add: description
|
||||
description: this attribute value has been added __after__entry creation
|
||||
description: this attribute value will be deleted by Babs (must succeed)
|
||||
description: Bjorn will try to delete this attribute value (should fail)
|
||||
-
|
||||
EOMODS9
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -h $LOCALHOST -p $PORT1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS10
|
||||
dn: cn=Added by Bjorn (will be deleted),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: delete
|
||||
EOMODS10
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -h $LOCALHOST -p $PORT1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS11
|
||||
dn: cn=Added by Bjorn (will be renamed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modrdn
|
||||
newrdn: cn=Added by Bjorn (renamed by Bjorn)
|
||||
deleteoldrdn: 1
|
||||
EOMODS11
|
||||
|
||||
$LDAPMODIFY -D "$BABSDN" -h $LOCALHOST -p $PORT1 -w bjensen >> \
|
||||
$TESTOUT 2>&1 << EOMODS12
|
||||
dn: cn=Added by Bjorn (will be renamed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modrdn
|
||||
newrdn: cn=Added by Bjorn (renamed by Babs)
|
||||
deleteoldrdn: 1
|
||||
EOMODS12
|
||||
|
||||
$LDAPMODIFY -D "$JAJDN" -h $LOCALHOST -p $PORT1 -w jaj >> \
|
||||
$TESTOUT 2>&1 << EOMODS13
|
||||
dn: cn=Added by Bjorn (will be renamed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modrdn
|
||||
newrdn: cn=Added by Bjorn (renamed by Jaj)
|
||||
deleteoldrdn: 1
|
||||
EOMODS13
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -h $LOCALHOST -p $PORT1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS14
|
||||
dn: cn=Added by Bjorn (must succeed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modify
|
||||
delete: description
|
||||
description: Bjorn will try to delete this attribute value (should fail)
|
||||
-
|
||||
EOMODS14
|
||||
|
||||
$LDAPMODIFY -D "$BABSDN" -h $LOCALHOST -p $PORT1 -w bjensen >> \
|
||||
$TESTOUT 2>&1 << EOMODS15
|
||||
dn: cn=Added by Bjorn (will be deleted),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: delete
|
||||
|
||||
dn: cn=Added by Bjorn (must succeed),ou=Add/Delete,dc=example,dc=com
|
||||
changetype: modify
|
||||
delete: description
|
||||
description: this attribute value will be deleted by Babs (must succeed)
|
||||
-
|
||||
EOMODS15
|
||||
|
||||
echo "Using ldapsearch to retrieve all the entries..."
|
||||
echo "# Using ldapsearch to retrieve all the entries..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
|
||||
|
Loading…
Reference in New Issue
Block a user