Hello
I have the following setup:
ldap0 is the LDAP master ldap1 and ldap2 are replicas using syncrepl.
- Users can use simple authentication on the 3 servers. - ldap0 holds a bunch of ACL to handle modifications - ldap1 and ldap2 have minimal ACL and are there just for reading - Mutual authentication between master and replicas is done by TLS certificates.
Now I'd like the replicas to follow updatedn referrals on behalf of the client. That way clients could ask ldap1 and ldap2 to perform modifications, and that would just work. As I understand, this is done through slapo-chain.
The modification has to be done on behalf of the user that authenticated on the replica (else my ACL will block). I don't want to give replicas an universal write access to the master, because that will mean I'll have to duplicate the ACL between the master and the replicas. For performance and maintainability sake, I want to avoid that.
In an ideal world, I'd like replicas to connect to the master using their certificates, and the master would trust the user identity, as it was authenticated on the replica. Is there an example of how this should be done?
I had a look to the test suite, and it does not help very much, as I'm not familiar enough with the authz stuff to grasp enough of how it is supposed to work.
I tried this on the replica, as global option:
overlay chain chain-uri ldaps://ldap0 chain-idassert-bind bindmethod=sasl saslmech=EXTERNAL mode=self
But the modification operation is done using the identity from the replica TLS certificate (which fails) and not from the initial user.
Any hint?
Emmanuel Dreyfus wrote:
But the modification operation is done using the identity from the replica TLS certificate (which fails) and not from the initial user.
Owing to a "feature" in idassert code, an authcId or a binddn must be present for the proxyAuthz control to be successfully added to the chained request.
If you use mechs like EXTERNAL, it's going to be empty, resulting in the behavior you observed. Please try adding whatever to authcId or binddn (for example binddn="cn=chain") and report. You may file an ITS for this, if you like. I'm fixing it anyway.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: pierangelo.masarati@sys-net.it ---------------------------------------
Pierangelo Masarati ando@sys-net.it wrote:
But the modification operation is done using the identity from the replica TLS certificate (which fails) and not from the initial user.
Owing to a "feature" in idassert code, an authcId or a binddn must be present for the proxyAuthz control to be successfully added to the chained request.
If you use mechs like EXTERNAL, it's going to be empty, resulting in the behavior you observed. Please try adding whatever to authcId or binddn (for example binddn="cn=chain") and report.
It does alter the behavior: now I get this on the master Sep 9 23:41:10 ldap0 slapd[5365]: conn=170 op=1 RESULT tag=103 err=47 text=not authorized to assume identity
And the BIND operation still shows the TLS certificate DN for both authzid and authcid: the binddn or authcid I provide does not appear.
Do I miss some directive on the master to allow the proxy authorization?
Emmanuel Dreyfus wrote:
It does alter the behavior: now I get this on the master Sep 9 23:41:10 ldap0 slapd[5365]: conn=170 op=1 RESULT tag=103 err=47 text=not authorized to assume identity
And the BIND operation still shows the TLS certificate DN for both authzid and authcid: the binddn or authcid I provide does not appear.
That's expected: it is only needed by an internal check that decides whether to proxyAuthz or not. I've fixed this in HEAD/re24/re23, if you could try it... it's a trivial patch from back-ldap/bind.c you can pull from the CVS.
Do I miss some directive on the master to allow the proxy authorization?
Yes. You should map the identity of the certificate DN onto some existing identity on the producer using the authz-regexp directive, and then add to that identity an authzTo rule that allows it to authorize as anyone (or as those that are authorized to exploit this feature).
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: pierangelo.masarati@sys-net.it ---------------------------------------
Pierangelo Masarati ando@sys-net.it wrote:
And the BIND operation still shows the TLS certificate DN for both authzid and authcid: the binddn or authcid I provide does not appear.
That's expected: it is only needed by an internal check that decides whether to proxyAuthz or not. I've fixed this in HEAD/re24/re23, if you could try it... it's a trivial patch from back-ldap/bind.c you can pull from the CVS.
That patch fix the problem alone, or I also need authz-regexp? For OpenLDAP 2.3.38, I just need bind.c 1.85.2.36-1.85.2.37, right? No other file is to be changed?
Do I miss some directive on the master to allow the proxy authorization?
Yes. You should map the identity of the certificate DN onto some existing identity on the producer using the authz-regexp directive, and then add to that identity an authzTo rule that allows it to authorize as anyone (or as those that are authorized to exploit this feature).
Something like this? (I have never used that statements before) authz-regexp cn=ldap1.example.net uid=ldap1,ou=pseudousers,dc=example,dc=net authzTo dn.exact="uid=ldap1,ou=pseudousers,dc=example,dc=net"
Do I need authz-policy?
Emmanuel Dreyfus wrote:
That patch fix the problem alone, or I also need authz-regexp?
The two things are orthogonal:
- if you want the identity slapo-chain binds as to be allowed to authorize others, even if those do not exist in the database, you'll need to populate this identity's authzTo.
- In order to do this, that identity must exist in the database.
- So, if the DN resulting from a SASL bind does not exist in the database, you'll have to map it to an existing one using authz-regexp.
So your identity is actually undergoing two transformations:
1) cert DN -> existing DN, for the sole purpose of granting existing DN some permissions it needs to authorize other users; this is done by the authz-regexp directive alone
2) existing DN -> authorized DN via proxyAuthz, to actually perform the operation with the asserted identity; this transformation requires existing DN to be allowed to authorize as authorized DN, so requires an appropriate combination of the authz-policy parameters and of th authzTo attribute in the existing DN's entry.
Hope it's clear now.
For OpenLDAP 2.3.38, I just need bind.c 1.85.2.36-1.85.2.37, right? No other file is to be changed?
Yes. This patch only fixes a malformed internal test which required the authcId or the binddn to be present for proxyAuthz use in identity assertion, even though there are SASL mechs (like EXTERNAL) that do not make use of authcID. This patch lets things work without the need to set an otherwise unused authcId parameter in the idassert configuration.
Do I miss some directive on the master to allow the proxy authorization?
Yes. You should map the identity of the certificate DN onto some existing identity on the producer using the authz-regexp directive, and then add to that identity an authzTo rule that allows it to authorize as anyone (or as those that are authorized to exploit this feature).
Something like this? (I have never used that statements before) authz-regexp cn=ldap1.example.net uid=ldap1,ou=pseudousers,dc=example,dc=net
authzTo dn.exact="uid=ldap1,ou=pseudousers,dc=example,dc=net"
Yes for the authz-regexp, No for the authzTo. For example, if the DN in the consumer's cert is "cn=cert", and you want it to be mapped to "cn=consumer", so that it can only authorize users whose DN is of the form "uid=foobar,ou=writers", you need to:
- add
authz-policy to authz-regexp "^cn=cert$" "cn=consumer"
Then you need to modify the "cn=consumer" entry as follows:
dn: cn=consumer changetype: modify add: authzTo authzTo: dn.regex:^uid=[^,]+,ou=writers$
See http://www.openldap.org/faq/data/cache/1254.html for details on the syntax of authzTo.
Now you need to carefully protect the authzTo attribute, otherwise, for example, those who can modify it for self would be able to authorize as the rootdn. Something like
access to attrs=authzTo by * auth
Do I need authz-policy?
Yes, see above.
I'd appreciate if you could turn this, in due course, and as soon as detail shake down, into a FAQ entry. I think the subject belongs to chaining, which could go into the description of slapo-chain. Explicit reference to replication could be added.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: pierangelo.masarati@sys-net.it ---------------------------------------
On Mon, Sep 10, 2007 at 08:35:20AM +0200, Pierangelo Masarati wrote:
I'd appreciate if you could turn this, in due course, and as soon as detail shake down, into a FAQ entry. I think the subject belongs to chaining, which could go into the description of slapo-chain. Explicit reference to replication could be added.
Yes, I need to document my whole setup, which has been an incredible pain to get working (slapo-chain being just the last issue). That will probably makes a few FAQ entries...
Pierangelo Masarati ando@sys-net.it wrote:
I'd appreciate if you could turn this, in due course, and as soon as detail shake down, into a FAQ entry.
Done: http://www.openldap.org/faq/data/cache/1434.html
Pierangelo Masarati ando@sys-net.it wrote:
Yes. You should map the identity of the certificate DN onto some existing identity on the producer using the authz-regexp directive, and then add to that identity an authzTo rule that allows it to authorize as anyone (or as those that are authorized to exploit this feature).
I got it working. Here is what I have, I'd be glad if you could confirm me that I did not introduce security holes:
On the replica: overlay chain chain-uri ldaps://ldap0.example.net chain-idassert-bind bindmethod=sasl saslmech=EXTERNAL binddn="cn=bugworkaround" mode=self chain-idassert-authzFrom "*" chain-return-error TRUE
On the master: authz-policy to authz-regexp cn=ldap1.example.net cn=ldap1.example.net,ou=pseudo-user,dc=example,dc=net authz-regexp cn=ldap2.example.net cn=ldap2.example.net,ou=pseudo-user,dc=example,dc=net
access to attrs=authzTo by * read stop
In the DIT: dn: ou=pseudo-user,dc=example,dc=net objectClass: organizationalUnit ou: pseudo-user
dn: cn=ldap1.example.net,ou=pseudo-user,dc=example,dc=net objectClass: organizationalRole cn: ldap1.example.net ou: pseudo-user authzTo: *
dn: cn=ldap2.example.net,ou=pseudo-user,dc=example,dc=net objectClass: organizationalRole cn: ldap2.example.net ou: pseudo-user authzTo: *
Emmanuel Dreyfus wrote:
Pierangelo Masarati ando@sys-net.it wrote:
Yes. You should map the identity of the certificate DN onto some existing identity on the producer using the authz-regexp directive, and then add to that identity an authzTo rule that allows it to authorize as anyone (or as those that are authorized to exploit this feature).
I got it working. Here is what I have, I'd be glad if you could confirm me that I did not introduce security holes:
On the replica: overlay chain chain-uri ldaps://ldap0.example.net chain-idassert-bind bindmethod=sasl saslmech=EXTERNAL binddn="cn=bugworkaround" mode=self chain-idassert-authzFrom "*" chain-return-error TRUE
On the master: authz-policy to authz-regexp cn=ldap1.example.net cn=ldap1.example.net,ou=pseudo-user,dc=example,dc=net authz-regexp cn=ldap2.example.net cn=ldap2.example.net,ou=pseudo-user,dc=example,dc=net
access to attrs=authzTo by * read stop
In the DIT: dn: ou=pseudo-user,dc=example,dc=net objectClass: organizationalUnit ou: pseudo-user
dn: cn=ldap1.example.net,ou=pseudo-user,dc=example,dc=net objectClass: organizationalRole cn: ldap1.example.net ou: pseudo-user authzTo: *
dn: cn=ldap2.example.net,ou=pseudo-user,dc=example,dc=net objectClass: organizationalRole cn: ldap2.example.net ou: pseudo-user authzTo: *
Correct. See my previous message.
p.
Ing. Pierangelo Masarati OpenLDAP Core Team
SysNet s.r.l. via Dossi, 8 - 27100 Pavia - ITALIA http://www.sys-net.it --------------------------------------- Office: +39 02 23998309 Mobile: +39 333 4963172 Email: pierangelo.masarati@sys-net.it ---------------------------------------
openldap-software@openldap.org