OpenIdentityPlatform / OpenDJ

OpenDJ is an LDAPv3 compliant directory service, which has been developed for the Java platform, providing a high performance, highly available, and secure store for the identities managed by your organization. Its easy installation process, combined with the power of the Java platform makes OpenDJ the simplest, fastest directory to deploy and manage.
https://www.openidentityplatform.org/opendj
Other
365 stars 100 forks source link

DOC REVIEW: Syntax error and comments on dsconfig-driven ACI interaction #400

Open JesseCoretta opened 1 week ago

JesseCoretta commented 1 week ago

OpenDJ Administration Guide - Version 4.8.0 (PDF)

Page 60, Example 5.2, Block 2

$ dsconfig \
  set-access-control-handler-prop \
  --remove global-aci:\(targetattr!=\"userPassword\|\|authPassword\|\|changes\|\
  \|changeNumber\|\|changeType\|\|changeTime\|\|targetDN\|\|newRDN\|\
  \|newSuperior\|\|deleteOldRDN\|\|targetEntryUUID\|\|changeInitiatorsName\|\
  \|changeLogCookie\|\|includedAttributes\"\)\(version\ 3.0\;\ acl\ \"Anonymous\
  \ read\ access\"\;\ allow\ \(read,search,compare\)\
  \ userdn=\"ldap:///anyone\"\;\)\
  --hostname opendj.example.com \
  --port 4444 \
  --bindDN cn=Directory\ Manager \
  --bindPassword password \
  --trustAll \
  --no-prompt

Since the "!" character (at "\(targetattr=!..."), does not reside within quotation, it needs to be ESCAPED as is done for "(", ")", "`" and "|`" characters, else you will suffer command interpretation errors following an unsuspecting copy/pasta:

An error occurred while parsing the command-line arguments: The provided
argument " " is not recognized

See "dsconfig --help" to get more usage help

set-access-control-handler-prop: command not found
--remove: command not found
|newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName|: command not found
bash:  userdn="ldap:///anyone";) : No such file or directory
--hostname: command not found
--port: command not found
--bindDN: command not found
--bindPassword: command not found
--trustAll: command not found
--no-prompt: command not found

Taking all of this into account, a near-identical command sequence which worked was:

$ dsconfig \
set-access-control-handler-prop \
--remove global-aci:\(targetattr\!=\"userPassword\|\|authPassword\|\|changes\|\
\|changeNumber\|\|changeType\|\|changeTime\|\|targetDN\|\|newRDN\|\
\|newSuperior\|\|deleteOldRDN\|\|targetEntryUUID\|\|changeInitiatorsName\|\
\|changeLogCookie\|\|includedAttributes\"\)\(version\ 3.0\;\ acl\ \"Anonymous\
\ read\ access\"\;\ allow\ \(read,search,compare\)\
\ userdn=\"ldap:///anyone\"\;\)\
--hostname\ opendj.example.com \
--port 4444 \
--bindDN cn=Directory\ Manager \
--bindPassword password \
--trustAll \
--no-prompt

But, note the escaped "--hostname\ opendj.example.com". This was necessary because:

An error occurred while parsing the command-line arguments: Argument "opendj.example.com" does not start with one or two dashes and unnamed trailing arguments are not allowed

But on a hunch, I removed the escape and used "=" for the key/value operator instead of SPACE, which resulted in no error. It seems that the subsequent flags (i.e.: --port) do not suffer from this issue.

So I devised a variation of the above:

/opt/opendj/bin/dsconfig \
set-access-control-handler-prop \
--remove global-aci:\(targetattr\!=\"userPassword\|\|authPassword\|\|changes\|\
\|changeNumber\|\|changeType\|\|changeTime\|\|targetDN\|\|newRDN\|\
\|newSuperior\|\|deleteOldRDN\|\|targetEntryUUID\|\|changeInitiatorsName\|\
\|changeLogCookie\|\|includedAttributes\"\)\(version\ 3.0\;\ acl\ \"Anonymous\
\ read\ access\"\;\ allow\ \(read,search,compare\)\
\ userdn=\"ldap:///anyone\"\;\)\
--hostname=opendj.example.com \
--port=4444 \
--bindDN=cn=Directory\ Manager \
--bindPassword=password \
--trustAll \
--no-prompt

... which includes the escaped "!" fix AND the use of "=" operators in consistent fashion.

I was going to move on at this point, but something stopped me.

At the risk of sounding nit picky, these escape sequences are rather aggressive in practice.

While I acknowledge they are necessary given the limitations of interpreters like Bash, they introduce a higher risk syntax error. In a crisis situation, this can be ESPECIALLY unfortunate.

Wondering if we should instead do this (which I tested for syntax):

$ dsconfig \
set-access-control-handler-prop \
--remove global-aci:'(targetattr!="userPassword||authPassword||changes||
changeNumber||changeType||changeTime||targetDN||newRDN||
newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||
changeLogCookie||includedAttributes")(version 3.0; acl "Anonymous
 read access"; allow (read,search,compare) userdn="ldap:///anyone";)' \
--hostname=opendj.example.com \
--port=4444 \
--bindDN=cn=Directory\ Manager \
--bindPassword=password \
--trustAll \
--no-prompt

The above modified rule uses single apostrophe quoting for the ACI value itself and does away with ACI-specific escapes.

It does have the drawback of making the newline escapes inconsistent between flags and the multi-lined ACI, although I've never heard of anyone complaining because they had to escape fewer characters than before. The spirit of the rule is unchanged, thus:

If the global-aci does not match the ACI exactly then the command fails to remove the value.

... should not apply here, but I recommend that this scenario be incorporated into unit tests, if applicable.

Be advised, my host does not have the above ACI, thus the following error was raised:

The value (targetattr!="userPassword||authPassword||changes||
changeNumber||changeType||changeTime||targetDN||newRDN||
newSuperior||deleteOldRDN||targetEntryUUID||changeInitiatorsName||
changeLogCookie||includedAttributes")(version 3.0; acl "Anonymous
read access"; allow (read,search,compare) userdn="ldap:///anyone";) for the
global-aci property does not exist

... which is the error that has appeared during all successful syntax-permutations of my test on this matter. I take this as a good omen, given that all of the ACI elements survived the alternative quoting method, and my login and network parameters were observed and honored as before.

Thanks! 😃

JesseCoretta commented 1 day ago

@maximthomas / @vharseko -- do you have any thoughts on this?

maximthomas commented 1 day ago

Hi @JesseCoretta, Yes, you are right, your version is much easier to read due to the lack of escaping! Thanks!