I've found a situation similar to what I believe inspired "disclose" ACLs, in which giving out the return value of LDAP_SIZELIMIT_EXCEEDED is telling clients something that I don't want them to know (i.e. "keep digging.") I'd like to just throw away the code and change it to LDAP_SUCCESS. Can anybody think of a way to do this (slapo-retcode comes to mind, but I can't see how it would work on these very non-dynamic entries) or should I just write an eight line overlay?
Is this something that enough people want that there should be, say, a "silent" option to the limits directive?
Aaron Richton wrote:
I've found a situation similar to what I believe inspired "disclose" ACLs, in which giving out the return value of LDAP_SIZELIMIT_EXCEEDED is telling clients something that I don't want them to know (i.e. "keep digging.") I'd like to just throw away the code and change it to LDAP_SUCCESS. Can anybody think of a way to do this (slapo-retcode comes to mind, but I can't see how it would work on these very non-dynamic entries) or should I just write an eight line overlay?
Is this something that enough people want that there should be, say, a "silent" option to the limits directive?
This seems like a pointless option. If I do a search for (cn>=a) and get 500 entries returned, and another search for (cn>=b) and still get 500 entries returned, then it's obvious there are more entries out there even if you mask the result code. The "disclose" feature of ACLs is a real security measure, because it prevents you from seeing that which you could not see by any means. What you're proposing here is not; the information you're hiding can still be discovered by other legitimate mechanisms. It is easily circumvented and it's contrary to the specification of the Directory System models.
Hmm, maybe drawing a parallel to an ACL was a bad idea (although this behavior does sound similar to "disclose" to me because I want to not expose the truth to some unprivileged clients). The clients I want to keep in the dark are due to their code path, not because the information is something that I want to keep from them for privacy/security per se.
We have entries along the lines of:
uid=person1,o=Org1,c=US uid=person2,o=Org1,c=US uid=person2,o=Org2,c=US uid=person3,o=Org2,c=US
This is totally valid in our (feel free to call it warped) view of the world. person2 is indeed the same physical person, but they only intersect on "uid" from the directory perspective. Very notably, person2@Org1 and person2@Org2 have different userPassword attributes.
I'm sure this all sounds slightly ridiculous, but it actually works quite well. It makes things particularly easy for administrators of systems in either Org1 or Org2. The exception is on queries that span Org*. We've seen two basic client behaviors with off-the-shelf software:
1. Search, and use the first candidate entry that's returned. Our users hae been trained that "Org1" is the most important and they should use that password/expect those attributes on systems that span units.
2. Search, and error out since multiple candidates are returned.
I don't necessarily think there's anything wrong with (2), but it causes my example "person2" to not get access. What I'd like is to mimic (1). I've been patching client software to that behavior, but it seems that there's a lot of (2) out there. So I'm looking for something server-side to fix this "permanently". If I set a sizelimit of 1, then only
uid=person2,o=Org1,c=US
will be returned on a '(uid=person2)' query. The problem is that the return code is not LDAP_SUCCESS, so I error out on that issue. If I mask the exceeded result, then the (2) clients will be blissfully ignorant that person2 spans multiple entries, and grant access under the Org1 candidate dn (which is what I want).
On Thu, 8 Mar 2007, Howard Chu wrote:
Aaron Richton wrote:
I've found a situation similar to what I believe inspired "disclose" ACLs, in which giving out the return value of LDAP_SIZELIMIT_EXCEEDED is telling clients something that I don't want them to know (i.e. "keep digging.") I'd like to just throw away the code and change it to LDAP_SUCCESS. Can anybody think of a way to do this (slapo-retcode comes to mind, but I can't see how it would work on these very non-dynamic entries) or should I just write an eight line overlay?
Is this something that enough people want that there should be, say, a "silent" option to the limits directive?
This seems like a pointless option. If I do a search for (cn>=a) and get 500 entries returned, and another search for (cn>=b) and still get 500 entries returned, then it's obvious there are more entries out there even if you mask the result code. The "disclose" feature of ACLs is a real security measure, because it prevents you from seeing that which you could not see by any means. What you're proposing here is not; the information you're hiding can still be discovered by other legitimate mechanisms. It is easily circumvented and it's contrary to the specification of the Directory System models.
-- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc Chief Architect, OpenLDAP http://www.openldap.org/project/
First off - what you do in the privacy of your own network is your business, go ahead and write the 8 line overlay if that's what you want.
But realize that the design you have here is an epic security breach waiting to happen. The purpose of authentication is to unambiguously identify the client of a service. (And in the case of mutual authentication, the provider of the service as well.) When you do not enforce a 1-to-1 mapping of users to login IDs and credentials, you don't have "authentication" - you just have a guess. I.e., all of your client software in group (1) below is broken, by definition.
Presumably one reason for giving person2 two separate entries is to give them two separate roles, two separate classes of authorization. You might entrust someone with the person2/org2 username and password to accomplish one set of tasks; if the software accepts that password but then looks up and uses the person2/org1 privileges instead, you're in trouble and most of the time you won't even detect when something bad happens until you read about it in the press.
Aaron Richton wrote:
Hmm, maybe drawing a parallel to an ACL was a bad idea (although this behavior does sound similar to "disclose" to me because I want to not expose the truth to some unprivileged clients). The clients I want to keep in the dark are due to their code path, not because the information is something that I want to keep from them for privacy/security per se.
We have entries along the lines of:
uid=person1,o=Org1,c=US uid=person2,o=Org1,c=US uid=person2,o=Org2,c=US uid=person3,o=Org2,c=US
This is totally valid in our (feel free to call it warped) view of the world. person2 is indeed the same physical person, but they only intersect on "uid" from the directory perspective. Very notably, person2@Org1 and person2@Org2 have different userPassword attributes.
I'm sure this all sounds slightly ridiculous, but it actually works quite well. It makes things particularly easy for administrators of systems in either Org1 or Org2. The exception is on queries that span Org*. We've seen two basic client behaviors with off-the-shelf software:
- Search, and use the first candidate entry that's returned. Our users
hae been trained that "Org1" is the most important and they should use that password/expect those attributes on systems that span units.
- Search, and error out since multiple candidates are returned.
I don't necessarily think there's anything wrong with (2), but it causes my example "person2" to not get access. What I'd like is to mimic (1). I've been patching client software to that behavior, but it seems that there's a lot of (2) out there. So I'm looking for something server-side to fix this "permanently". If I set a sizelimit of 1, then only
uid=person2,o=Org1,c=US
will be returned on a '(uid=person2)' query. The problem is that the return code is not LDAP_SUCCESS, so I error out on that issue. If I mask the exceeded result, then the (2) clients will be blissfully ignorant that person2 spans multiple entries, and grant access under the Org1 candidate dn (which is what I want).
On Thu, 8 Mar 2007, Howard Chu wrote:
Aaron Richton wrote:
I've found a situation similar to what I believe inspired "disclose" ACLs, in which giving out the return value of LDAP_SIZELIMIT_EXCEEDED is telling clients something that I don't want them to know (i.e. "keep digging.") I'd like to just throw away the code and change it to LDAP_SUCCESS. Can anybody think of a way to do this (slapo-retcode comes to mind, but I can't see how it would work on these very non-dynamic entries) or should I just write an eight line overlay?
Is this something that enough people want that there should be, say, a "silent" option to the limits directive?
This seems like a pointless option. If I do a search for (cn>=a) and get 500 entries returned, and another search for (cn>=b) and still get 500 entries returned, then it's obvious there are more entries out there even if you mask the result code. The "disclose" feature of ACLs is a real security measure, because it prevents you from seeing that which you could not see by any means. What you're proposing here is not; the information you're hiding can still be discovered by other legitimate mechanisms. It is easily circumvented and it's contrary to the specification of the Directory System models.
I'm not sure how I'm failing to achieve 1-to-1 mapping. There is zero rewriting involved in any of this. The client must search for and use an unambigious target DN for the bind request. This presupposes knowledge of (.*)Org1 or (.*)Org2 at authentication time. "person2,o=Org1" and "person2,o=Org2" are as unambigious as "x,o=Org1" and "y,o=Org1"--they just plain don't strcmp() identical. Client and server logs both reflect Org1 or Org2, access can be granted as appropriate, etc.
The fact that this doesn't trickle all the way down to the primary key being "uid=person2@Org1" doesn't mean that the client and server can't tell an absolute identity. If somebody writes a client that binds to one DN of person2/org2 and then reads the attributes of a different DN person2/org1, they're way beyond what I can help them with. (Although the masked sizelimit might work there too, because the brain dead client will only see person2/org1 in all cases :) Or I could ACL out reading org1 from the org2 identity.) What I'm guessing would be a more X.500 way of doing this -- only have person1@bigOrg and give org1Password and org2Password attributes -- would also be beyond my help if somebody decided to bind against org2Password and then read org1AccessLevel. Actually, I might be even worse off with that, because I can't think of any way to ACL out the org1 attributes from the org2 identity. I can only give rope in the directory; tying the knots is left for the client developers...
Anyway, the whole point of the dialogue here is to avoid needing a private overlay and to try and find something that at least tries to comply with the spirit of the standards, lets you have multiple identities that are easy to access (I'm sure there's some awesome idassert stuff out there, but I can't beat a TLS-encrypted userPassword for client compatibility), and if I do need to write something, might have a hope of being useful outside of my crazy world. "What you're doing is so insane that nobody else would want it" is perfectly acceptable, though.
On Thu, 8 Mar 2007, Howard Chu wrote:
First off - what you do in the privacy of your own network is your business, go ahead and write the 8 line overlay if that's what you want.
But realize that the design you have here is an epic security breach waiting to happen. The purpose of authentication is to unambiguously identify the client of a service. (And in the case of mutual authentication, the provider of the service as well.) When you do not enforce a 1-to-1 mapping of users to login IDs and credentials, you don't have "authentication" - you just have a guess. I.e., all of your client software in group (1) below is broken, by definition.
Presumably one reason for giving person2 two separate entries is to give them two separate roles, two separate classes of authorization. You might entrust someone with the person2/org2 username and password to accomplish one set of tasks; if the software accepts that password but then looks up and uses the person2/org1 privileges instead, you're in trouble and most of the time you won't even detect when something bad happens until you read about it in the press.
Aaron Richton wrote:
Hmm, maybe drawing a parallel to an ACL was a bad idea (although this behavior does sound similar to "disclose" to me because I want to not expose the truth to some unprivileged clients). The clients I want to keep in the dark are due to their code path, not because the information is something that I want to keep from them for privacy/security per se.
We have entries along the lines of:
uid=person1,o=Org1,c=US uid=person2,o=Org1,c=US uid=person2,o=Org2,c=US uid=person3,o=Org2,c=US
This is totally valid in our (feel free to call it warped) view of the world. person2 is indeed the same physical person, but they only intersect on "uid" from the directory perspective. Very notably, person2@Org1 and person2@Org2 have different userPassword attributes.
I'm sure this all sounds slightly ridiculous, but it actually works quite well. It makes things particularly easy for administrators of systems in either Org1 or Org2. The exception is on queries that span Org*. We've seen two basic client behaviors with off-the-shelf software:
- Search, and use the first candidate entry that's returned. Our users hae
been trained that "Org1" is the most important and they should use that password/expect those attributes on systems that span units.
- Search, and error out since multiple candidates are returned.
I don't necessarily think there's anything wrong with (2), but it causes my example "person2" to not get access. What I'd like is to mimic (1). I've been patching client software to that behavior, but it seems that there's a lot of (2) out there. So I'm looking for something server-side to fix this "permanently". If I set a sizelimit of 1, then only
uid=person2,o=Org1,c=US
will be returned on a '(uid=person2)' query. The problem is that the return code is not LDAP_SUCCESS, so I error out on that issue. If I mask the exceeded result, then the (2) clients will be blissfully ignorant that person2 spans multiple entries, and grant access under the Org1 candidate dn (which is what I want).
On Thu, 8 Mar 2007, Howard Chu wrote:
Aaron Richton wrote:
I've found a situation similar to what I believe inspired "disclose" ACLs, in which giving out the return value of LDAP_SIZELIMIT_EXCEEDED is telling clients something that I don't want them to know (i.e. "keep digging.") I'd like to just throw away the code and change it to LDAP_SUCCESS. Can anybody think of a way to do this (slapo-retcode comes to mind, but I can't see how it would work on these very non-dynamic entries) or should I just write an eight line overlay?
Is this something that enough people want that there should be, say, a "silent" option to the limits directive?
This seems like a pointless option. If I do a search for (cn>=a) and get 500 entries returned, and another search for (cn>=b) and still get 500 entries returned, then it's obvious there are more entries out there even if you mask the result code. The "disclose" feature of ACLs is a real security measure, because it prevents you from seeing that which you could not see by any means. What you're proposing here is not; the information you're hiding can still be discovered by other legitimate mechanisms. It is easily circumvented and it's contrary to the specification of the Directory System models.
-- -- Howard Chu Chief Architect, Symas Corp. http://www.symas.com Director, Highland Sun http://highlandsun.com/hyc Chief Architect, OpenLDAP http://www.openldap.org/project/
openldap-software@openldap.org