Custom LDAP ACLs

openldap

#1

Hello,

We want to grant to some our employees permissions for creating and removing users.

I found an useful article Custom LDAP ACLs that describes how to assign required permissions to certain users.

My question is how to grant permissions to certain group rather than specific users?
Is that possible?

In my humble opinion, this would allow to manage users with needed permissions easier than using command line tools and arguments.

Thanks in advance.


#2

Hey,

Be aware that granting other users the rights to create new users is basically the same as making them unrestricted domain administrators in the first place. The reason is simple: if you can create a new user, you can just as well create a new domain admin and do everything you want to. There’s no security benefit in trying to create a user group that “may only create other users”.

Kind regards,
mosu


#3

This isn’t true if you restrict the permission of creating accounts to non-administrative accounts. With LDAP ACLs it should be possible to restrict the write access to the administrative groups (the group membership is implemented by the group attribute “uniqueMember”). But I’m not an expert in LDAP ACLs.


#4

Hey,

while this is true for for supplementary groups, it isn’t true for the primary group which is stored as gidNumber in the user object.

Another problem you have to take care of is modifying existing users who already are domain admins. If you may modify them, you can easily change their passwords which wouldn’t require modifying the “domain admins” group at all. So you have to lock down access to those users, too, and you have to remember doing that for each new domain admin you yourself add.

There are a lot of moving parts that have to be locked down in order not to leave an escape hatch for privilege escalation. It’s frigging hard. Which basically equates that you will make a mistake, forget about a corner case or another, and therefore end up with a system that’s much more complex but not that much more secure.

Complexity is the pretty much the natural enemy of security.

m.


#5

This is true, but primary groups are also stored as uniqueMember in the group object, so you could check for it in the ACLs.

This is true. Of course the approach of having restricted admins has a lot of problems, but is principally doable.


#6

Hey,

my point wasn’t so much that it is impossible (of course it is possible, it’s only software after all, and Open Source to boot), but rather whether it’s practical and a good idea to attempt it.

m.


#7

Thank you all for your discussion. It is really helpful.

Proceeding from the aforesaid, I am interested in your opinion regarding the following idea:
How about if we integrate some 3rd party software (RunDeck) or maybe the custom-developed one, that would be granting access to itself only for members of specified LDAP groups, e.g. Support or the similar one, and could be used for creating/deleting LDAP user accounts that don’t belong to primary group ‘Domain Admins’?

I guess it can be formed as UCS App for avoiding sharing SSH credentials to 3rd party systems because, as far as I know, UCS does not have API, which could be used for remote management of users.

Would be this secure and convenient at the same time?

I really look forward to hear your thoughts about the idea.


#8

Hey,

I’ve implemented custom web-based frontends that offer a limited set of domain manipulation functions to a limited set of users multiple times. I usually divide those up into two components:

  1. The web frontend, usually a CGI script written in whichever scripting language I’m most comfortable with (Perl, Ruby for me).
  2. A backend script that receives a very limited set of parameters from the web frontend script and translates those into domain modification calls (either modifying the LDAP directory directly or by calling the udm command-line tool), again written whatever language you want to.

There’s a very good reason for using two components: security. All CGI scripts usually run as the user the web server runs as, which is www-data, a non-privileged user. In order to modify the LDAP you need some kind of elevated privileges (e.g. udm uses the machine account and needs access to /etc/machine.secret which is only readable by root). One could give www-data that access, but the huge drawback is that suddenly all CGI scripts, all PHP scripts etc. all have that access. And all too often arbitrary users can upload arbitrary PHP files to be interpreted by the web server (e.g. via /home/username/public_html which is then accessible as http://server.name/~username/…).

Hence the split. I usually allow the user www-data to execute the backend script with arbitrary parameters via sudo.

In order to be really secure, you must implement all verification in the backend script (and some in both the backend and the frontend script). For example, if you want to restrict access to that tool to members of the group user admins, you will have to implement that in both scripts. The frontend script should show some kind of login screen and error out if the credentials provided don’t belong to a user who is a member of said group.

However, those same credentials must be passed on to the backend script which has to check the same. If the backend script didn’t verify credentials and relied on the frontend script to do so, any other rogue PHP/CGI script could simply pretend to make that check and call the backend script in order to make changes the calling rogue script shouldn’t be allowed to trigger.

As a communication channel I usually use temporary files containing JSON. I only pass the name of the temporary file to the backend script — for simplicity reasons. JSON is easy to read and write (use existing libraries, don’t implement your own parser, of course), you don’t have to worry about command line parameters being visible in the process list or in any history files etc.

I can usually whip up something simple within a day. Depending on the scope of functionality this can take an arbitrary amount of time, of course.

What I like about implementing your own solution is that you’re much more aware of where the security boundaries are and what the consequences of violating them are. Your frontend usually offers a very small number of functions with a small number of parameters. Validating them in the backend is therefore straightforward and fast. For example: users created by your user admins must always be members of certain groups? Easy, don’t offer the choice of which groups to add to in the frontend in the first place and hardcode them in the backend. Or you want to allow certain groups? Great, hardcode that list in the backend and make sure the “additional groups” passed from the frontend are all members of said list.

Using a real programming/scripting language also allows you to express arbitrary constraints — unlike LDAP ACLs.

Another real benefit is that your frontend only offers those controls/attributes that may actually be changed or set by the user admins members. This is unlike the UMC which would always offer you the full “edit user” mask, no matter what LDAP ACLs allow and prohibit. It’s very confusing to figure out which parameters you may or may not change in the UMC because it seems to suggest you may change each and every of those.

Kind regards,
mosu


#9

Wow! Your answer is awesome! Thank you very much!
Seems you have described all points required for creating own solution. I appreciate that.

Maybe I would look like a brazen person, you have mentioned that you have experience with implementing of this sort of custom web-based solutions. Perhaps you could point me on the source code on GitHub, BitBucket or whatever for reviewing it and using as departure point of developing or, if you want and have some kind of opportunity, you may share one of your previous implementations.

Thanks in advance.


#10

Hey,

you’re very welcome.

Unfortunately those solutions were commissioned by our customers, and I cannot make those public. Sorry.

Kind regards,
mosu


#11

Hello,

Got it. This is quite understandable.

Thanks for response and clarification.