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
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
for add,
.B z
for delete,
+.B i
+for increment,
.B r
for read,
.B s
.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
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
}
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.
} 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" );
} 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) ) {
} 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);
} 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);
"<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
} else if ( access == ACL_WDEL ) {
return "delete";
+ } else if ( access == ACL_WDEL ) {
+ return "increment";
+
} else if ( access == ACL_MANAGE ) {
return "manage";
} 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;
}
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 */
/* 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 {
#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 */
#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)
#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)
#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)
objectClass: organizationalUnit
objectClass: extensibleObject
ou: People
-uidNumber: 0
-gidNumber: 0
+uidNumber: 56
+gidNumber: 50
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
;;
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 \