Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No data (ldapserch result is empty) while entry-Based ACIs is defined with "deny" permition #84

Open
posledov opened this issue Aug 2, 2019 · 7 comments

Comments

@posledov
Copy link

posledov commented Aug 2, 2019

Software version

OS:

  • Debian GNU/Linux 9

Java:

  • openjdk version "1.8.0_222"
  • OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1~deb9u1-b10)
  • OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)

OpenDJ:

  • 4.4.2
  • 4.4.3

Base DN data

dn: dc=example
objectClass: domain
objectClass: top
dc: example

dn: ou=People,dc=example
objectClass: organizationalUnit
objectClass: top
ou: People

dn: uid=user.1,ou=People,dc=example
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
cn: Aaren Atp
sn: Atp
uid: user.1
userPassword: password

dn: ou=Services,dc=example
objectClass: organizationalUnit
objectClass: top
ou: Services
aci: (version 3.0; acl "Test ACI"; deny (all) userdn="ldap:///uid=user.1,ou=
 People,dc=example";)

dn: uid=service.1,ou=Services,dc=example
objectClass: top
objectClass: account
objectClass: simpleSecurityObject
uid: service.1
userPassword: password

Global ACI

they are default/untouched

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "cn=Directory Manager" \
 --bindPassword "DMpassword" \
 --baseDN "cn=Access Control Handler,cn=config" \
 "(&)" ds-cfg-global-aci
 
dn: cn=Access Control Handler,cn=config
ds-cfg-global-aci: (extop="1.3.6.1.4.1.26027.1.6.1 || 1.3.6.1.4.1.26027.1.6.3 || 1.3.6.1.4.1.4203.1.11.1 || 1.3.6.1.4.1.1466.20037 || 1.3.6.1.4.1.4203.1.11.3") (version 3.0; acl "Anonymous extended operation access"; allow(read) userdn="ldap:///anyone";)
ds-cfg-global-aci: (target="ldap:///")(targetscope="base")(targetattr="objectClass||namingContexts||supportedAuthPasswordSchemes||supportedControl||supportedExtension||supportedFeatures||supportedLDAPVersion||supportedSASLMechanisms||supportedTLSCiphers||supportedTLSProtocols||vendorName||vendorVersion")(version 3.0; acl "User-Visible Root DSE Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";)
ds-cfg-global-aci: (target="ldap:///cn=schema")(targetscope="base")(targetattr="objectClass||attributeTypes||dITContentRules||dITStructureRules||ldapSyntaxes||matchingRules||matchingRuleUse||nameForms||objectClasses")(version 3.0; acl "User-Visible Schema Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";)
ds-cfg-global-aci: (targetattr!="userPassword||authPassword||debugsearchindex||changes||changeNumber||changeType||changeTime||targetDN||newRDN||newSuperior||deleteOldRDN")(version 3.0; acl "Anonymous read access"; allow (read,search,compare) userdn="ldap:///anyone";)
ds-cfg-global-aci: (targetattr="audio||authPassword||description||displayName||givenName||homePhone||homePostalAddress||initials||jpegPhoto||labeledURI||mobile||pager||postalAddress||postalCode||preferredLanguage||telephoneNumber||userPassword")(version 3.0; acl "Self entry modification"; allow (write) userdn="ldap:///self";)
ds-cfg-global-aci: (targetattr="createTimestamp||creatorsName||modifiersName||modifyTimestamp||entryDN||entryUUID||subschemaSubentry||etag||governingStructureRule||structuralObjectClass||hasSubordinates||numSubordinates||isMemberOf")(version 3.0; acl "User-Visible Operational Attributes"; allow (read,search,compare) userdn="ldap:///anyone";)
ds-cfg-global-aci: (targetattr="userPassword||authPassword")(version 3.0; acl "Self entry read"; allow (read,search,compare) userdn="ldap:///self";)
ds-cfg-global-aci: (targetcontrol="1.3.6.1.1.12 || 1.3.6.1.1.13.1 || 1.3.6.1.1.13.2 || 1.2.840.113556.1.4.319 || 1.2.826.0.1.3344810.2.3 || 2.16.840.1.113730.3.4.18 || 2.16.840.1.113730.3.4.9 || 1.2.840.113556.1.4.473 || 1.3.6.1.4.1.42.2.27.9.5.9") (version 3.0; acl "Authenticated users control access"; allow(read) userdn="ldap:///all";)
ds-cfg-global-aci: (targetcontrol="2.16.840.1.113730.3.4.2 || 2.16.840.1.113730.3.4.17 || 2.16.840.1.113730.3.4.19 || 1.3.6.1.4.1.4203.1.10.2 || 1.3.6.1.4.1.42.2.27.8.5.1 || 2.16.840.1.113730.3.4.16 || 1.2.840.113556.1.4.1413 || 1.3.6.1.4.1.36733.2.1.5.1") (version 3.0; acl "Anonymous control access"; allow(read) userdn="ldap:///anyone";)

/opt/opendj/bin $

getEffectiveRightsAuthzid

dn:uid=user.1,ou=People,dc=example

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "cn=Directory Manager" \
 --bindPassword "DMpassword" \
 --baseDN "ou=Services,dc=example" \
 --control effectiverights \
 --getEffectiveRightsAuthzid "dn:uid=user.1,ou=People,dc=example" \
 "(&)" aclRights
 
dn: ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0

dn: uid=service.1,ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0

/opt/opendj/bin $

uid=service.1,ou=Services,dc=example

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "cn=Directory Manager" \
 --bindPassword "DMpassword" \
 --baseDN "ou=Services,dc=example" \
 --control effectiverights \
 --getEffectiveRightsAuthzid "dn:uid=service.1,ou=Services,dc=example" \
 "(&)" aclRights

dn: ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0

dn: uid=service.1,ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

/opt/opendj/bin $

ldapsearch

uid=user.1,ou=People,dc=example (correct behavior)

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "uid=user.1,ou=People,dc=example" \
 --bindPassword "password" \
 --baseDN "ou=Services,dc=example" "(&)"

/opt/opendj/bin $

uid=service.1,ou=Services,dc=example (incorrect behavior)

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "uid=service.1,ou=Services,dc=example" \
 --bindPassword "password" \
 --baseDN "ou=Services,dc=example" "(&)"

/opt/opendj/bin $

Expected behavior

uid=service.1,ou=Services,dc=example

/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "uid=service.1,ou=Services,dc=example" \
 --bindPassword "password" \
 --baseDN "ou=Services,dc=example" "(&)"

dn: ou=Services,dc=example
objectClass: organizationalUnit
objectClass: top
ou: Services

dn: uid=service.1,ou=Services,dc=example
objectClass: account
objectClass: simpleSecurityObject
objectClass: top
uid: service.1
userPassword: {SSHA}3y3Mfl/AesocwfJGUpXU2hK+st+hHYzhu9TbYg==

/opt/opendj/bin $

Logs

/opt/opendj/data/logs/access

[02/авг/2019:12:45:27 +0300] BIND REQ conn=30 op=0 msgID=1 version=3 type=SIMPLE dn="uid=service.1,ou=Services,dc=example" 
[02/авг/2019:12:45:27 +0300] BIND RES conn=30 op=0 msgID=1 result=0 authDN="uid=service.1,ou=Services,dc=example" etime=2 
[02/авг/2019:12:45:27 +0300] SEARCH REQ conn=30 op=1 msgID=2 base="ou=Services,dc=example" scope=sub filter="(&)" attrs="ALL" 
[02/авг/2019:12:45:27 +0300] SEARCH RES conn=30 op=1 msgID=2 result=0 nentries=0 etime=2 
[02/авг/2019:12:45:27 +0300] DISCONNECT conn=30 reason="Client Disconnect" 

/opt/opendj/data/logs/ldap-access.audit.json

{
  "eventName":"DJ-LDAP",
  "client":{
    "ip":"192.168.121.3",
    "port":49508
  },
  "server":{
    "ip":"192.168.13.137",
    "port":389
  },
  "request":{
    "protocol":"LDAP",
    "operation":"BIND",
    "connId":30,
    "msgId":1,
    "version":"3",
    "authType":"Simple",
    "dn":"uid=service.1,ou=Services,dc=example"
  },
  "transactionId":"0",
  "response":{
    "status":"SUCCESSFUL",
    "statusCode":"0",
    "elapsedTime":2,
    "elapsedTimeUnits":"MILLISECONDS"
  },
  "userId":"uid=service.1,ou=Services,dc=example",
  "timestamp":"2019-08-02T09:45:27.324Z",
  "_id":"7dd98aeb-227b-477f-93d2-52e0debd33d5-1509"
}
{
  "eventName":"DJ-LDAP",
  "client":{
    "ip":"192.168.121.3",
    "port":49508
  },
  "server":{
    "ip":"192.168.13.137",
    "port":389
  },
  "request":{
    "protocol":"LDAP",
    "operation":"SEARCH",
    "connId":30,
    "msgId":2,
    "dn":"ou=Services,dc=example",
    "scope":"sub",
    "filter":"(&)",
    "attrs":[
      "ALL"
    ]
  },
  "transactionId":"0",
  "response":{
    "status":"SUCCESSFUL",
    "statusCode":"0",
    "elapsedTime":2,
    "elapsedTimeUnits":"MILLISECONDS",
    "nentries":0
  },
  "timestamp":"2019-08-02T09:45:27.397Z",
  "_id":"7dd98aeb-227b-477f-93d2-52e0debd33d5-1511"
}
{
  "eventName":"DJ-LDAP",
  "client":{
    "ip":"192.168.121.3",
    "port":49508
  },
  "server":{
    "ip":"192.168.13.137",
    "port":389
  },
  "request":{
    "protocol":"LDAP",
    "operation":"DISCONNECT",
    "connId":30
  },
  "transactionId":"0",
  "response":{
    "status":"SUCCESSFUL",
    "statusCode":"0",
    "elapsedTime":0,
    "elapsedTimeUnits":"MILLISECONDS",
    "reason":"Client Disconnect"
  },
  "timestamp":"2019-08-02T09:45:27.423Z",
  "_id":"7dd98aeb-227b-477f-93d2-52e0debd33d5-1513"
}
@posledov
Copy link
Author

Am I the only one bothered by this problem? 😞

@yavis73
Copy link

yavis73 commented Sep 24, 2019

hi,
I configured and tested the settings you suggested, but it works fine.

  Add one more aci and try it to succeed

dn: ou = Services, dc = example
objectClass: organizationalUnit
objectClass: top
ou: Services
aci: (version 3.0; acl "Test ACI"; deny (all) userdn = "ldap: ///uid=user.1,ou=People,dc=example";)
aci: (version 3.0; acl "Test ACI2"; allow (search, read) userdn = "ldap: /// anyone";)

@posledov
Copy link
Author

@yavis73 first of all thank you for reply!

Add one more aci and try it to succeed

You are right... But why?..

  1. Whether access is allowed or denied depends on whether an ACI's bind rule is evaluated to be true.

  2. Use subjects to restrict whether the ACI applies depending on who connected, and when, where, and how they connected.

Why single ACI
aci: (version 3.0; acl "Test ACI"; deny (all) userdn="ldap:///uid=user.1,ou=People,dc=example";)
blocks access for all but not for user.1 only?
(Without this rule access is allowed for all)

Why subject userdn="ldap:///uid=user.1,ou=People,dc=example" for deny action is completely ignored?

Can anyone explain me, please?

@yavis73
Copy link

yavis73 commented Oct 1, 2019

hi,
I understood your question is that user1's access rights are denied, but there is no specification of service1's access rights, so service1 must be accessible.

It seems to be asking why service1 is not accessible.

Is that right?
=---------------------------------------------
If no permission policy(ACI)is specified for a particular entry, whether it is allow policy or deny policy, the global access policy is applied by default.

If any ACIs is set for a particular entry, it will take precedence over the global ACIs.
All permissions except those set permissions are denied.

Try searching for another node that you do not have permission set for.
If so, you may understand this problem.

@posledov
Copy link
Author

posledov commented Oct 1, 2019

hello, @yavis73

user1's access rights are denied, but there is no specification of service1's access rights

you are absolutely right!

If no permission policy(ACI)is specified for a particular entry, whether it is allow policy or deny policy, the global access policy is applied by default.

Base DN data

dn: dc=example
objectClass: domain
objectClass: top
dc: example

dn: ou=People,dc=example
objectClass: organizationalUnit
objectClass: top
ou: People

dn: uid=user.1,ou=People,dc=example
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
objectClass: top
cn: Aaren Atp
sn: Atp
uid: user.1
userPassword: password

dn: ou=Services,dc=example
objectClass: organizationalUnit
objectClass: top
ou: Services
aci: (version 3.0; acl "Test ACI"; deny (all) userdn="ldap:///uid=user.1,ou=
 People,dc=example";)

dn: uid=service.1,ou=Services,dc=example
objectClass: top
objectClass: account
objectClass: simpleSecurityObject
uid: service.1
userPassword: password

As you can see, there are no other ACI except aci: (version 3.0; acl "Test ACI"; deny (all) userdn="ldap:///uid=user.1,ou=People,dc=example";), and this instruction should prohibit access for uid=user.1,ou=People,dc=example ONLY, but not for other!

Moreover...

getEffectiveRightsAuthzid

dn:uid=user.1,ou=People,dc=example
/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "cn=Directory Manager" \
 --bindPassword "DMpassword" \
 --baseDN "ou=Services,dc=example" \
 --control effectiverights \
 --getEffectiveRightsAuthzid "dn:uid=user.1,ou=People,dc=example" \
 "(&)" aclRights
 
dn: ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0

dn: uid=service.1,ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0

/opt/opendj/bin $

aclRights;entryLevel: add:0,delete:0,-->read:0<--,write:0,proxy:0uid=user.1,ou=People,dc=example shouldn't read

uid=service.1,ou=Services,dc=example
/opt/opendj/bin $ ./ldapsearch \
 --hostname 192.168.13.137 \
 --bindDN "cn=Directory Manager" \
 --bindPassword "DMpassword" \
 --baseDN "ou=Services,dc=example" \
 --control effectiverights \
 --getEffectiveRightsAuthzid "dn:uid=service.1,ou=Services,dc=example" \
 "(&)" aclRights

dn: ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0

dn: uid=service.1,ou=Services,dc=example
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

/opt/opendj/bin $

aclRights;entryLevel: add:0,delete:0,-->read:1<--,write:0,proxy:0uid=service.1,ou=Services,dc=example should read

But in fact, no one can access.

I'm pretty sure it's a bug...

@yavis73
Copy link

yavis73 commented Oct 1, 2019

Oh, I see.

First, the aclRights query result and the actual operation result are different.

Algorithms for looking up aclRights information and permission checking algorithms for actual entry search permission are different.

It should be fix by someone.

@posledov
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants