Managing users and groups - Current best practice


#1

(resending. sent from the wrong address previously)

Hi all,

Seth suggested I hit up the list if I didn’t find anything in the
archives so I am.

What’s the current best practice for fully managing users and groups
in Chef (outside of ldap). My recipe works fine except for the
handling of deleted users. I really would like the full auditing of
the process and to have everything fully documented.
Seth suggested using knife ssh for the job but I’m really trying to
keep EVERYTHING in databags and cookbooks. By using an untraceable
manual process, I really lose that ability. While the user shouldn’t
be on the system anymore (or at least locked with SSH keys removed), I
still need to know that they were there at one point.

So my options are (as I see it):

  1. Use knife ssh
  2. Created a deleted users data bag where I move users when they are
    deleted. Then it’s just another section in my users recipe for that
    data bag.
  3. Move to LDAP
  4. ???

Any other option I’m missing?

Thanks

John E. Vincent


#2

If your list of users is comprehensive (users). Then find the
list of current users (current_users). users - current_users
is the new users. current_users - users is the users that
should be deleted (where ‘-’ is the set minus operator).

Seems like a general useful thing to diff things in Chef. I used
this algorithm to handle munin plugins.

You might need other logic to avoid deleting users installed by
packages (i.e. if you cannot maintain a comprehensive users
list), and it may well be that you need to explicitly indicate
which users to delete either via a data bag as you suggested, or
my having a status or action per user in the users data bag.
Unexpected users could then generate warnings/errors. If you
have create and modification timestmps (as in LDAP) you can
reduce the set of data you need to look at. LDAP also has a
cn=changelog which you could watch for suitable events.

Debian have a standard for uid ranges, not sure if this goes for
all distributions, but it would allow you to exclude from
consideration package created users.

/Allan

Allan Wind
Life Integrity, LLC
http://lifeintegrity.com


#3

On Wed, Nov 24, 2010 at 12:45 AM, Allan Wind
allan_wind@lifeintegrity.com wrote:

If your list of users is comprehensive (users). Then find the
list of current users (current_users). users - current_users
is the new users. current_users - users is the users that
should be deleted (where ‘-’ is the set minus operator).

Seems like a general useful thing to diff things in Chef. I used
this algorithm to handle munin plugins.

You might need other logic to avoid deleting users installed by
packages (i.e. if you cannot maintain a comprehensive users
list), and it may well be that you need to explicitly indicate
which users to delete either via a data bag as you suggested, or
my having a status or action per user in the users data bag.
Unexpected users could then generate warnings/errors. If you
have create and modification timestmps (as in LDAP) you can
reduce the set of data you need to look at. LDAP also has a
cn=changelog which you could watch for suitable events.

Debian have a standard for uid ranges, not sure if this goes for
all distributions, but it would allow you to exclude from
consideration package created users.

/Allan

Allan Wind
Life Integrity, LLC
http://lifeintegrity.com

So I wanted to share what I ended up doing. I tried a few different
methods using Set and what not. The set didn’t quite work the way I
wanted so for now I’m using Array#delete_if to compare the id of users
with deleted_users. This is not the most efficient but having just
found time to dive back into it today, I went with the quickest
solution:


#4

Hey John,

On Tue, Dec 7, 2010 at 11:14 AM, John E. Vincent (lusis)
lusis.org+chef-list@gmail.com wrote:

So I wanted to share what I ended up doing. I tried a few different
methods using Set and what not. The set didn’t quite work the way I
wanted so for now I’m using Array#delete_if to compare the id of users
with deleted_users. This is not the most efficient but having just
found time to dive back into it today, I went with the quickest
solution:

https://gist.github.com/732237

Here’s that avoids the inner loop (untested):

groups = search(:groups)
users = search(:users)
deleted_users = search(:deleted_users)

deleted_user_ids = deleted_users.inject({}) { |ids, u|

ids[u[‘id’]] = 1; ids }
# remove deleted users from the users array so we don’t recreate them
users.delete_if { |user| deleted_user_ids.has_key(user[‘id’]) }

  • seth