mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-18 21:26:29 -05:00
ITS#9640 Introduce the increment privilege
This commit is contained in:
parent
8423637333
commit
b8df689969
8 changed files with 199 additions and 15 deletions
|
|
@ -760,8 +760,8 @@ field will have.
|
|||
Its component are defined as
|
||||
.LP
|
||||
.nf
|
||||
<level> ::= none|disclose|auth|compare|search|read|{write|add|delete}|manage
|
||||
<priv> ::= {=|+|\-}{0|d|x|c|s|r|{w|a|z}|m}+
|
||||
<level> ::= none|disclose|auth|compare|search|read|{write|add|delete|increment}|manage
|
||||
<priv> ::= {=|+|\-}{0|d|x|c|s|r|{w|a|z|i}|m}+
|
||||
.fi
|
||||
.LP
|
||||
The modifier
|
||||
|
|
@ -805,11 +805,12 @@ attribute that is defined as not user modifiable.
|
|||
The
|
||||
.BR write
|
||||
access is actually the combination of
|
||||
.BR add
|
||||
and
|
||||
.BR add ,
|
||||
.BR delete ,
|
||||
which respectively restrict the write privilege to add or delete
|
||||
the specified
|
||||
and
|
||||
.BR increment ,
|
||||
which respectively restrict the write privilege to add, delete or
|
||||
increment the specified
|
||||
.BR <what> .
|
||||
|
||||
.LP
|
||||
|
|
@ -852,6 +853,8 @@ for write,
|
|||
for add,
|
||||
.B z
|
||||
for delete,
|
||||
.B i
|
||||
for increment,
|
||||
.B r
|
||||
for read,
|
||||
.B s
|
||||
|
|
@ -866,7 +869,7 @@ More than one of the above privileges can be added in one statement.
|
|||
.B 0
|
||||
indicates no privileges and is used only by itself (e.g., +0).
|
||||
Note that
|
||||
.B +az
|
||||
.B +azi
|
||||
is equivalent to
|
||||
.BR +w .
|
||||
.LP
|
||||
|
|
@ -1013,6 +1016,8 @@ In detail,
|
|||
is required to add new values,
|
||||
.B delete (=z)
|
||||
is required to delete existing values,
|
||||
.B increment (=i)
|
||||
is required to increment values,
|
||||
and both
|
||||
.B delete
|
||||
and
|
||||
|
|
|
|||
|
|
@ -1967,8 +1967,21 @@ acl_check_modlist(
|
|||
}
|
||||
|
||||
switch ( mlist->sml_op ) {
|
||||
case LDAP_MOD_REPLACE:
|
||||
case LDAP_MOD_INCREMENT:
|
||||
assert( mlist->sml_values != NULL );
|
||||
assert( BER_BVISNULL( &mlist->sml_values[1] ) );
|
||||
|
||||
if ( ! access_allowed( op, e,
|
||||
mlist->sml_desc, &mlist->sml_values[0],
|
||||
( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WINCR,
|
||||
&state ) )
|
||||
{
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
break;
|
||||
|
||||
case LDAP_MOD_REPLACE:
|
||||
/*
|
||||
* We must check both permission to delete the whole
|
||||
* attribute and permission to add the specific attributes.
|
||||
|
|
|
|||
|
|
@ -1961,6 +1961,9 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
|
|||
} else if ( ACL_LVL_IS_WDEL(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "delete" );
|
||||
|
||||
} else if ( ACL_LVL_IS_WINCR(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "increment" );
|
||||
|
||||
} else if ( ACL_LVL_IS_MANAGE(mask) ) {
|
||||
ptr = lutil_strcopy( ptr, "manage" );
|
||||
|
||||
|
|
@ -2001,6 +2004,10 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
|
|||
} else if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WDEL) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'z';
|
||||
|
||||
} else if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WINCR) ) {
|
||||
none = 0;
|
||||
*ptr++ = 'i';
|
||||
}
|
||||
|
||||
if ( ACL_PRIV_ISSET(mask, ACL_PRIV_READ) ) {
|
||||
|
|
@ -2081,6 +2088,9 @@ str2accessmask( const char *str )
|
|||
} else if( TOLOWER((unsigned char) str[i]) == 'z' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_WDEL);
|
||||
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'i' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_WINCR);
|
||||
|
||||
} else if( TOLOWER((unsigned char) str[i]) == 'r' ) {
|
||||
ACL_PRIV_SET(mask, ACL_PRIV_READ);
|
||||
|
||||
|
|
@ -2132,6 +2142,9 @@ str2accessmask( const char *str )
|
|||
} else if ( strcasecmp( str, "delete" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WDEL(mask);
|
||||
|
||||
} else if ( strcasecmp( str, "increment" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WINCR(mask);
|
||||
|
||||
} else if ( strcasecmp( str, "write" ) == 0 ) {
|
||||
ACL_LVL_ASSIGN_WRITE(mask);
|
||||
|
||||
|
|
@ -2177,8 +2190,8 @@ acl_usage(void)
|
|||
"<peernamestyle> ::= exact | regex | ip | ipv6 | path\n"
|
||||
"<domainstyle> ::= exact | regex | base(Object) | sub(tree)\n"
|
||||
"<access> ::= [[real]self]{<level>|<priv>}\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"
|
||||
"<level> ::= none|disclose|auth|compare|search|read|{write|add|delete|increment}|manage\n"
|
||||
"<priv> ::= {=|+|-}{0|d|x|c|s|r|{w|a|z|i}|m}+\n"
|
||||
"<control> ::= [ stop | continue | break ]\n"
|
||||
#ifdef SLAP_DYNACL
|
||||
#ifdef SLAPD_ACI_ENABLED
|
||||
|
|
@ -2404,6 +2417,9 @@ access2str( slap_access_t access )
|
|||
} else if ( access == ACL_WDEL ) {
|
||||
return "delete";
|
||||
|
||||
} else if ( access == ACL_WDEL ) {
|
||||
return "increment";
|
||||
|
||||
} else if ( access == ACL_MANAGE ) {
|
||||
return "manage";
|
||||
|
||||
|
|
@ -2442,6 +2458,9 @@ str2access( const char *str )
|
|||
} else if ( strcasecmp( str, "delete" ) == 0 ) {
|
||||
return ACL_WDEL;
|
||||
|
||||
} else if ( strcasecmp( str, "increment" ) == 0 ) {
|
||||
return ACL_WDEL;
|
||||
|
||||
} else if ( strcasecmp( str, "manage" ) == 0 ) {
|
||||
return ACL_MANAGE;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1069,7 +1069,8 @@ constraint_update( Operation *op, SlapReply *rs )
|
|||
|
||||
if ((( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_ADD) &&
|
||||
(( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_REPLACE) &&
|
||||
(( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_DELETE))
|
||||
(( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_DELETE) &&
|
||||
(( m->sml_op & LDAP_MOD_OP ) != LDAP_MOD_INCREMENT))
|
||||
continue;
|
||||
/* we only care about ADD and REPLACE modifications */
|
||||
/* and DELETE are used to track attribute count */
|
||||
|
|
|
|||
|
|
@ -1280,8 +1280,9 @@ typedef enum slap_access_t {
|
|||
/* write granularity */
|
||||
ACL_WADD = ACL_WRITE_|ACL_QUALIFIER1,
|
||||
ACL_WDEL = ACL_WRITE_|ACL_QUALIFIER2,
|
||||
ACL_WINCR = ACL_WRITE_|ACL_QUALIFIER3,
|
||||
|
||||
ACL_WRITE = ACL_WADD|ACL_WDEL
|
||||
ACL_WRITE = ACL_WADD|ACL_WDEL|ACL_WINCR
|
||||
} slap_access_t;
|
||||
|
||||
typedef enum slap_control_e {
|
||||
|
|
@ -1390,7 +1391,8 @@ typedef struct Access {
|
|||
#define ACL_PRIV_READ ACL_ACCESS2PRIV( ACL_READ )
|
||||
#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_WINCR ACL_ACCESS2PRIV( ACL_WINCR )
|
||||
#define ACL_PRIV_WRITE ( ACL_PRIV_WADD | ACL_PRIV_WDEL | ACL_PRIV_WINCR )
|
||||
#define ACL_PRIV_MANAGE ACL_ACCESS2PRIV( ACL_MANAGE )
|
||||
|
||||
/* NOTE: always use the highest level; current: 0x00ffUL */
|
||||
|
|
@ -1428,6 +1430,7 @@ typedef struct Access {
|
|||
#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_WINCR (ACL_PRIV_WINCR|ACL_LVL_READ)
|
||||
#define ACL_LVL_WRITE (ACL_PRIV_WRITE|ACL_LVL_READ)
|
||||
#define ACL_LVL_MANAGE (ACL_PRIV_MANAGE|ACL_LVL_WRITE)
|
||||
|
||||
|
|
@ -1440,6 +1443,7 @@ typedef struct Access {
|
|||
#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_WINCR(m) ACL_LVL((m),ACL_LVL_WINCR)
|
||||
#define ACL_LVL_IS_WRITE(m) ACL_LVL((m),ACL_LVL_WRITE)
|
||||
#define ACL_LVL_IS_MANAGE(m) ACL_LVL((m),ACL_LVL_MANAGE)
|
||||
|
||||
|
|
@ -1451,6 +1455,7 @@ typedef struct Access {
|
|||
#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_WINCR(m) ACL_PRIV_ASSIGN((m),ACL_LVL_WINCR)
|
||||
#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)
|
||||
|
||||
|
|
|
|||
|
|
@ -362,6 +362,6 @@ dn: ou=People,dc=example,dc=com
|
|||
objectClass: organizationalUnit
|
||||
objectClass: extensibleObject
|
||||
ou: People
|
||||
uidNumber: 0
|
||||
gidNumber: 0
|
||||
uidNumber: 56
|
||||
gidNumber: 50
|
||||
|
||||
|
|
|
|||
|
|
@ -137,6 +137,18 @@ access to dn.subtree="ou=Add & Delete,dc=example,dc=com"
|
|||
by dn.exact="cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com" write
|
||||
by * read
|
||||
|
||||
access to dn="ou=People,dc=example,dc=com"
|
||||
by dn.exact="cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com" write continue
|
||||
by dn.exact="cn=James A Jones 1,ou=Alumni Association,ou=People,dc=example,dc=com" -i
|
||||
by * break
|
||||
|
||||
access to dn="ou=People,dc=example,dc=com" attrs=uidNumber val.regex="^5*$"
|
||||
by dn.exact="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" increment
|
||||
by * break
|
||||
|
||||
access to dn="ou=People,dc=example,dc=com" attrs=uidNumber val="1"
|
||||
by dn.exact="cn=Barbara Jensen,ou=Information Technology Division,ou=People,dc=example,dc=com" increment
|
||||
|
||||
# fall into global ACLs
|
||||
|
||||
database monitor
|
||||
|
|
|
|||
|
|
@ -635,6 +635,135 @@ case $RC in
|
|||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$JAJDN" -H $URI1 -w jaj >> \
|
||||
$TESTOUT 2>&1 << EOMODS16
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
increment: uidNumber
|
||||
uidNumber: 50
|
||||
-
|
||||
EOMODS16
|
||||
RC=$?
|
||||
case $RC in
|
||||
50)
|
||||
;;
|
||||
0)
|
||||
echo "ldapmodify should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$JAJDN" -H $URI1 -w jaj >> \
|
||||
$TESTOUT 2>&1 << EOMODS17
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
replace: gidNumber
|
||||
gidNumber: 50
|
||||
-
|
||||
EOMODS17
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -H $URI1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS18
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
increment: uidNumber
|
||||
uidNumber: 55
|
||||
-
|
||||
EOMODS18
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$BABSDN" -H $URI1 -w bjensen >> \
|
||||
$TESTOUT 2>&1 << EOMODS19
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
increment: uidNumber
|
||||
uidNumber: -1
|
||||
-
|
||||
EOMODS19
|
||||
RC=$?
|
||||
case $RC in
|
||||
50)
|
||||
;;
|
||||
0)
|
||||
echo "ldapmodify should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$BABSDN" -H $URI1 -w bjensen >> \
|
||||
$TESTOUT 2>&1 << EOMODS20
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
increment: uidNumber
|
||||
uidNumber: 1
|
||||
-
|
||||
EOMODS20
|
||||
RC=$?
|
||||
case $RC in
|
||||
0)
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
$LDAPMODIFY -D "$BJORNSDN" -H $URI1 -w bjorn >> \
|
||||
$TESTOUT 2>&1 << EOMODS21
|
||||
dn: ou=People,dc=example,dc=com
|
||||
changetype: modify
|
||||
replace: uidNumber
|
||||
uidNumber: 55
|
||||
-
|
||||
EOMODS21
|
||||
RC=$?
|
||||
case $RC in
|
||||
50)
|
||||
;;
|
||||
0)
|
||||
echo "ldapmodify should have failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo "ldapmodify failed ($RC)!"
|
||||
test $KILLSERVERS != no && kill -HUP $KILLPIDS
|
||||
exit $RC
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "Using ldapsearch to retrieve all the entries..."
|
||||
echo "# Using ldapsearch to retrieve all the entries..." >> $SEARCHOUT
|
||||
$LDAPSEARCH -S "" -b "$BASEDN" -H $URI1 \
|
||||
|
|
|
|||
Loading…
Reference in a new issue