OpenLDAP
Up to top level
Build   Contrib   Development   Documentation   Historical   Incoming   Software Bugs   Software Enhancements   Web  

Logged in as guest

Viewing Incoming/7392
Full headers

From: daniel@pluta.biz
Subject: ACL a_dn.a_self is skipped in case of "acl_mask: to all values ..."
Compose comment
Download message
State:
0 replies:
1 followups: 1

Major security issue: yes  no

Notes:

Notification:


Date: Sat, 15 Sep 2012 21:43:59 +0000
From: daniel@pluta.biz
To: openldap-its@OpenLDAP.org
Subject: ACL a_dn.a_self is skipped in case of "acl_mask: to all values ..."
Full_Name: Daniel Pluta
Version: Linux
OS: OPENLDAP_REL_ENG_2_4
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (84.167.49.115)


Hi,

given this (simplyfied and thus quite strange looking) sample acl statement:

access to dn.one="dc=example,dc=org" attrs=@groupOfNames
  by dnattr=owner selfread
  by users write

the first by clause ("by dnattr=owner selfread") is only honored in case of an
access "to value", like for example:

#Operation 1 (log see below):
dn: cn=group,dc=example,dc=org
changetype: modify
delete: owner
owner: uid=user,dc=example,dc=org
-

but is skipped in case of an access "to all values", like for example:

#Operation 2 (log see below):
dn: cn=group,dc=example,dc=org
changetype: modify
delete: owner
-


In case (hopefully) this is not the intended behavior. The following
"comment-patch" could be the place to start further investigations.

Thanks a lot.


diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c
index 4b72342..89cb9ae 100644
--- a/servers/slapd/acl.c
+++ b/servers/slapd/acl.c
@@ -1170,7 +1170,14 @@ slap_acl_mask(
                                !is_at_syntax( desc->ad_type,
SLAPD_NAMEUID_SYNTAX )) continue;

                        /* check if the target is an attribute. */
-                       if ( val == NULL ) continue;
+                       if ( val == NULL ) {
+                               /* check all values whether a_dn.a_self is
contained */
+
+                               /* if a_dn.a_self is contained: implicitly set
val to a_dn.a_self */
+
+                               /* else: continue */
+                               continue;
+                       }

                        /* a DN must be present */
                        if ( BER_BVISEMPTY( &op->o_ndn ) ) {


Operation 1: log level 128 
==========================
5054ed13 => access_allowed: result not in cache (owner)
5054ed13 => access_allowed: delete access to "cn=group,dc=example,dc=org"
"owner" requested
5054ed13 => dn: [1] dc=example,dc=org
5054ed13 => dn: [2] dc=example,dc=org
5054ed13 => acl_get: [2] matched
5054ed13 => acl_get: [2] attr owner
5054ed13 => acl_mask: access to entry "cn=group,dc=example,dc=org", attr
"owner"
requested
5054ed13 => acl_mask: to value by "uid=user,dc=example,dc=org", (=0)
5054ed13 <= check a_dn_at: owner
5054ed13 <= acl_mask: [1] applying read(=rscxd) (stop)
5054ed13 <= acl_mask: [1] mask: read(=rscxd)
5054ed13 => slap_access_allowed: delete access denied by read(=rscxd)
5054ed13 => access_allowed: no more rules


Operation 2: log level 128 
==========================
5054ed29 => access_allowed: result not in cache (owner)
5054ed29 => access_allowed: delete access to "cn=group,dc=example,dc=org"
"owner" requested
5054ed29 => dn: [1] dc=example,dc=org
5054ed29 => dn: [2] dc=example,dc=org
5054ed29 => acl_get: [2] matched
5054ed29 => acl_get: [2] attr owner
5054ed29 => acl_mask: access to entry "cn=group,dc=example,dc=org", attr
"owner"
requested
5054ed29 => acl_mask: to all values by "uid=user,dc=example,dc=org", (=0)
5054ed29 <= check a_dn_pat: users
5054ed29 <= acl_mask: [2] applying write(=wrscxd) (stop)
5054ed29 <= acl_mask: [2] mask: write(=wrscxd)
5054ed29 => slap_access_allowed: delete access granted by write(=wrscxd)
5054ed29 => access_allowed: delete access granted by write(=wrscxd)
5054ed29 acl: internal mod entryCSN: modify access granted
5054ed29 acl: internal mod modifiersName: modify access granted
5054ed29 acl: internal mod modifyTimestamp: modify access granted



slapd.conf:
===========

include         /tmp/example/core.schema
include         /tmp/example/cosine.schema
include         /tmp/example/sociopath.schema

pidfile         /tmp/example/run/slapd.pid
argsfile        /tmp/example/run/slapd.args

access to dn.base="" by * read
access to dn.base="cn=Subschema" by * read
access to *
 by self write
 by * read

database                mdb
suffix                  "dc=example,dc=org"
rootdn                  "cn=Manager,dc=example,dc=org"
rootpw                  secret
directory               /tmp/example/data
index                   objectClass     eq

add_content_acl         on

access to dn.base="dc=example,dc=org" attrs=children
  by users write

#simplyfied, thus probably strange looking, but nevertheless valid:
access to dn.one="dc=example,dc=org" attrs=@groupOfNames
  by dnattr=owner selfread
  by users write

access to dn.one="dc=example,dc=org"
  by self read
  by users read
  by anonymous auth

Followup 1

Download message
Date: Sun, 16 Sep 2012 09:21:25 +0200
From: Daniel Pluta <daniel@pluta.biz>
To: openldap-its@openldap.org
Subject: Re: (ITS#7392) ACL a_dn.a_self is skipped in case of "acl_mask: to
 all values ..."
Hi,

applying the patch linked below both previously mentioned operations 
produce the following log

Operation 1: log level 128
==========================
505573f8 => access_allowed: delete access to 
"cn=group,dc=example,dc=org" "owner" requested
505573f8 => dn: [1] dc=example,dc=org
505573f8 => dn: [2] dc=example,dc=org
505573f8 => acl_get: [2] matched
505573f8 => acl_get: [2] attr owner
505573f8 => acl_mask: access to entry "cn=group,dc=example,dc=org", attr 
"owner" requested
505573f8 => acl_mask: to value by "uid=user,dc=example,dc=org", (=0)
505573f8 <= check a_dn_at: owner
505573f8 <= acl_mask: [1] applying read(=rscxd) (stop)
505573f8 <= acl_mask: [1] mask: read(=rscxd)
505573f8 => slap_access_allowed: delete access denied by read(=rscxd)
505573f8 => access_allowed: no more rules
505573f8 => access_allowed: result not in cache (owner)


Operation 2: log level 128
==========================
505573f8 => access_allowed: delete access to 
"cn=group,dc=example,dc=org" "owner" requested
505573f8 => dn: [1] dc=example,dc=org
505573f8 => dn: [2] dc=example,dc=org
505573f8 => acl_get: [2] matched
505573f8 => acl_get: [2] attr owner
505573f8 => acl_mask: access to entry "cn=group,dc=example,dc=org", attr 
"owner" requested
505573f8 => acl_mask: to all values by "uid=user,dc=example,dc=org", (=0)
505573f8 => acl_mask: to self, attr "owner"
505573f8 <= check a_dn_at: owner
505573f8 <= acl_mask: [1] applying read(=rscxd) (stop)
505573f8 <= acl_mask: [1] mask: read(=rscxd)
505573f8 => slap_access_allowed: delete access denied by read(=rscxd)
505573f8 => access_allowed: no more rules


ftp://ftp.openldap.org/incoming/Daniel-Pluta-120916.patch

DISCLAIMER: It's not heavyly tested. I don't know whether the patch 
causes negative sideeffects elsewhere.


Up to top level
Build   Contrib   Development   Documentation   Historical   Incoming   Software Bugs   Software Enhancements   Web  

Logged in as guest


The OpenLDAP Issue Tracking System uses a hacked version of JitterBug

______________
© Copyright 2013, OpenLDAP Foundation, info@OpenLDAP.org