}
switch ( *bv.bv_val ) {
+ case 'x':
+ /* **** NOTE: draft-ietf-ldapext-aci-model-0.3.txt does not
+ * define any equivalent to the AUTH right, so I've just used
+ * 'x' for now.
+ */
+ ACL_PRIV_SET(mask, ACL_PRIV_AUTH);
+ break;
+ case 'd':
+ /* **** NOTE: draft-ietf-ldapext-aci-model-0.3.txt defines
+ * the right 'd' to mean "delete"; we hijack it to mean
+ * "disclose" for consistency wuith the rest of slapd.
+ */
+ ACL_PRIV_SET(mask, ACL_PRIV_DISCLOSE);
+ break;
case 'c':
ACL_PRIV_SET(mask, ACL_PRIV_COMPARE);
break;
case 'w':
ACL_PRIV_SET(mask, ACL_PRIV_WRITE);
break;
- case 'x':
- /* **** NOTE: draft-ietf-ldapext-aci-model-0.3.txt does not
- * define any equivalent to the AUTH right, so I've just used
- * 'x' for now.
- */
- ACL_PRIV_SET(mask, ACL_PRIV_AUTH);
- break;
default:
break;
}
const char *text;
int rc;
- /* format of string is "group/objectClassValue/groupAttrName" */
+ /* format of string is "{group|role}/objectClassValue/groupAttrName" */
if ( acl_get_part( subj, 0, '/', &subjdn ) < 0 ) {
return 0;
}
slap_access_t *deny,
slap_aci_scope_t asserted_scope )
{
- struct berval bv, scope, perms, type, sdn;
+ struct berval bv,
+ scope,
+ perms,
+ type,
+ opts,
+ sdn;
int rc;
sdn.bv_val = type.bv_val + type.bv_len + STRLENOF( "#" );
sdn.bv_len = aci->bv_len - ( sdn.bv_val - aci->bv_val );
+ /* get the type options, if any */
+ if ( acl_get_part( &type, 1, '/', &opts ) > 0 ) {
+ opts.bv_len = type.bv_len - ( opts.bv_val - type.bv_val );
+ type.bv_len = opts.bv_val - type.bv_val - 1;
+
+ } else {
+ BER_BVZERO( &opts );
+ }
+
if ( ber_bvcmp( &aci_bv[ ACI_BV_ACCESS_ID ], &type ) == 0 ) {
return dn_match( &op->o_ndn, &sdn );
return rc;
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_GROUP ], &type ) == 0 ) {
- if ( aci_group_member( &sdn, &aci_bv[ ACI_BV_GROUP_CLASS ],
- &aci_bv[ ACI_BV_GROUP_ATTR ], op, e, nmatch, matches ) )
+ struct berval oc,
+ at;
+
+ if ( BER_BVISNULL( &opts ) ) {
+ oc = aci_bv[ ACI_BV_GROUP_CLASS ];
+ at = aci_bv[ ACI_BV_GROUP_ATTR ];
+
+ } else {
+ if ( acl_get_part( &opts, 0, '/', &oc ) < 0 ) {
+ assert( 0 );
+ }
+
+ if ( acl_get_part( &opts, 1, '/', &at ) < 0 ) {
+ at = aci_bv[ ACI_BV_GROUP_ATTR ];
+ }
+ }
+
+ if ( aci_group_member( &sdn, &oc, &at, op, e, nmatch, matches ) )
{
return 1;
}
} else if ( ber_bvcmp( &aci_bv[ ACI_BV_ROLE ], &type ) == 0 ) {
- if ( aci_group_member( &sdn, &aci_bv[ ACI_BV_ROLE_CLASS ],
- &aci_bv[ ACI_BV_ROLE_ATTR ], op, e, nmatch, matches ) )
+ struct berval oc,
+ at;
+
+ if ( BER_BVISNULL( &opts ) ) {
+ oc = aci_bv[ ACI_BV_ROLE_CLASS ];
+ at = aci_bv[ ACI_BV_ROLE_ATTR ];
+
+ } else {
+ if ( acl_get_part( &opts, 0, '/', &oc ) < 0 ) {
+ assert( 0 );
+ }
+
+ if ( acl_get_part( &opts, 1, '/', &at ) < 0 ) {
+ at = aci_bv[ ACI_BV_ROLE_ATTR ];
+ }
+ }
+
+ if ( aci_group_member( &sdn, &oc, &at, op, e, nmatch, matches ) )
{
return 1;
}
if ( acl_match_set( &sdn, op, e, 1 ) ) {
return 1;
}
+
+ } else {
+ /* it passed normalization! */
+ assert( 0 );
}
return 0;
* umbrella, because sets share some helpers with ACIs.
*/
static int
-dynacl_aci_parse( const char *fname, int lineno, slap_style_t sty, const char *right, void **privp )
+dynacl_aci_parse(
+ const char *fname,
+ int lineno,
+ const char *opts,
+ slap_style_t sty,
+ const char *right,
+ void **privp )
{
AttributeDescription *ad = NULL;
const char *text = NULL;
for ( i = 0; i < perms->bv_len; ) {
switch ( perms->bv_val[ i ] ) {
+ case 'x':
+ case 'd':
case 'c':
case 's':
case 'r':
case 'w':
- case 'x':
break;
default:
subject = BER_BVNULL,
nsubject = BER_BVNULL;
int idx,
- rc,
+ rc = LDAP_SUCCESS,
freesubject = 0,
freetype = 0;
char *ptr;
- ( ocbv.bv_val - type.bv_val );
}
- if ( oc_bvfind( &ocbv ) == NULL ) {
+ oc = oc_bvfind( &ocbv );
+ if ( oc == NULL ) {
rc = LDAP_INVALID_SYNTAX;
goto cleanup;
}