User's and managing expired passwords

603 views
Skip to first unread message

Kyle Mallory

unread,
Aug 27, 2009, 3:05:42 PM8/27/09
to Puppet Users
We have a policy that requires all user passwords to expire after 90
days. We also use puppet for managing all users on our machines. Our
hope was, when our passwords expire, we could update the puppet
manifest which would propogate to all our servers, thus updating all
our passwords.

The problem is, the User type (w/ manage_passwords enabled and ruby-
shadow installed) will only set the password in /etc/shadow, but it
doesn't manage any of the other shadow parameters, namely the
sp_lstchg parameter). As a result, after our 90-day period, all of
our passwords have updated, but the individual machines still think
that the passwords have expired, and refuses to let us log in.

This seems a bug in the User type, in that if the password changes
from the previous password, it should also reset the last-changed
field as well. Ideally, if the User type is supporting passwords, it
would be nice if there were properties to also specify the other
shadow parameters, such as min, max, warn, expire, etc.

I looked into the puppet provider code for User, but I couldn't make
sense of how to fix. Could someone point me to the right place so I
can try and change this behavior (or maybe someone from Reductive Labs
can fix it in an immediately upcoming update)?

Thanks,

Len Rugen

unread,
Aug 27, 2009, 9:24:34 PM8/27/09
to puppet...@googlegroups.com
Just thinking.... could the password change use notify of a "usermod -e new-yyyy-dd-mm" command? 

Trevor Vaughan

unread,
Aug 28, 2009, 8:22:36 AM8/28/09
to puppet...@googlegroups.com
Probably not.

In theory, this would actually update the date every time the 'user'
type successfully runs.

I ended up hacking together my own function that would do what I
wanted it to do.

Hoping to roll it back into the main user type someday....

Trevor

jcbollinger

unread,
Aug 28, 2009, 10:18:58 AM8/28/09
to Puppet Users


On Aug 27, 2:05 pm, Kyle Mallory <jesuswasir...@gmail.com> wrote:
> We have a policy that requires all user passwords to expire after 90
> days.  We also use puppet for managing all users on our machines.  Our
> hope was, when our passwords expire, we could update the puppet
> manifest which would propogate to all our servers, thus updating all
> our passwords.

It seems a bit strange to me that you are managing users' passwords
for them in the first place. It is usually users' responsibility to
manage their own passwords. If you really do want to manage passwords
centrally, however, then why do you need a password expiration policy
in the first place? Instead, just change the passwords on whatever
schedule you choose. The point of enforcing an expiration policy is
to protect against users failing to change their passwords, so it
gains you nothing if users are not responsible for managing their
passwords in the first place. Just turn it off.

It sounds like you may be trying to use Puppet to cobble together a
single sign-on infrastructure. If so, then I recommend that you
instead use real SSO tools such as directory service authentication
(i.e. LDAP, Active Directory), or even NIS authentication.

> The problem is, the User type (w/ manage_passwords enabled and ruby-
> shadow installed) will only set the password in /etc/shadow, but it
> doesn't manage any of the other shadow parameters, namely the
> sp_lstchg parameter).  As a result, after our 90-day period, all of
> our passwords have updated, but the individual machines still think
> that the passwords have expired, and refuses to let us log in.
>
> This seems a bug in the User type, in that if the password changes
> from the previous password, it should also reset the last-changed
> field as well.  Ideally, if the User type is supporting passwords, it
> would be nice if there were properties to also specify the other
> shadow parameters, such as min, max, warn, expire, etc.

I agree that puppet failing to update the last-changed shadow field
looks like a bug in the User type (more specifically, in one of its
Providers). I, too, had a look at the code, but it is not at all
obvious where the password update code is, or by what path it is
invoked. (Obgrumble: Puppet code is extremely difficult to follow.)


John

Kyle Mallory

unread,
Aug 28, 2009, 11:15:47 AM8/28/09
to Puppet Users
On Aug 28, 8:18 am, jcbollinger <John.Bollin...@stJude.org> wrote:
>
> It seems a bit strange to me that you are managing users' passwords
> for them in the first place.  It is usually users' responsibility to
> manage their own passwords.  If you really do want to manage passwords
> centrally, however, then why do you need a password expiration policy
> in the first place?  Instead, just change the passwords on whatever
> schedule you choose.  The point of enforcing an expiration policy is
> to protect against users failing to change their passwords, so it
> gains you nothing if users are not responsible for managing their
> passwords in the first place.  Just turn it off.

Actually, these the passwords for the 3 system administrators. We
have to have an expiration policy to meet our security guidelines. We
are not opposed to the policy of changing our passwords every 90 days,
but we don't want to have to log into 15 different machines every 90
days to change it. Change it once in puppet, and be done with it.
We've considered distributed authentication mechanisms, but We Three
Administrators [From Orient Are] the only users on the machines sans a
few rare exceptions, so the trouble to configure NIS or LDAP didn't
seem worthwhile.

Ultimately, Puppet should only update the last-changed field when the
password *actually* changes, thereby allowing the individual machines
to continue to support denied logins if the password has expired.

I think I made some minor progress, as it appears that the password
handing is actually done by 'lib/puppet/provider/user/
user_role_add.rb' (which makes so sense to me whatsoever), and despite
everything to the contrary, doesn't actually user ruby-libshadow, but
rather hand-writes the shadow file itself (which makes even less sense
to me!). I'm in the testing whether this actually does what I think
it does.

Adam Crews

unread,
Aug 28, 2009, 12:45:32 PM8/28/09
to puppet...@googlegroups.com

I took a different and more hacky approach.
I wrote a function that fetches the complete shadow line from the
shadow file then pushes that line to the clients.
So I get central password management (including aging rules), but each
puppet client can stand on it's own (in case nis, or ldap, or radius,
ect.. goes away). I enforce the password rules on my puppetmaster
(that only sysadmins can login to). When a password expires, you
change it on the puppetmaster, and it is pushed to all the clients.

If anyone is interested in my configs, let me know and I can clean
them up a bit and post them somewhere.

-Adam

jcbollinger

unread,
Aug 31, 2009, 9:46:37 AM8/31/09
to Puppet Users


On Aug 28, 10:15 am, Kyle Mallory <jesuswasir...@gmail.com> wrote:
[...]
> I think I made some minor progress, as it appears that the password
> handing is actually done by 'lib/puppet/provider/user/
> user_role_add.rb' (which makes so sense to me whatsoever), and despite
> everything to the contrary, doesn't actually user ruby-libshadow, but
> rather hand-writes the shadow file itself (which makes even less sense
> to me!).  I'm in the testing whether this actually does what I think
> it does.

Puppet's resource model involves having a common front end for each
resource type that defines the available parameters, properties, and
features, plus one or more "providers" for that type that interact
with specific host environments to evaluate and update resource
instances on those environments. user_role_add.rb is one of the
providers for the User type. It is the default for Solaris, so if
you're running on Solaris then that's probably what you're using, and
if not then not.

I agree that the password management in that provider is rather
strange. It is usual for the User providers to rely on the host OS's
utilities to do work (e.g. user_role_add uses useradd, usermod, etc.),
so it is odd that password management is an exception. Moreover, it
is surpassingly strange that having rejected OS utilities for this
job, the provider does not rely on the Ruby shadow password library.
The code even contains comments complaining about manipulating the
shadow file directly!

seph

unread,
Aug 31, 2009, 3:46:12 PM8/31/09
to puppet...@googlegroups.com
>> Actually, these the passwords for the 3 system administrators.  We
>> have to have an expiration policy to meet our security guidelines.

> I took a different and more hacky approach.


> I wrote a function that fetches the complete shadow line from the
> shadow file then pushes that line to the clients.
>

> If anyone is interested in my configs, let me know and I can clean
> them up a bit and post them somewhere.

I have the same problem, and was thinking about implementing the same
style solution. I'd love to see your scripts.

seph

James Turnbull

unread,
Aug 31, 2009, 4:54:37 PM8/31/09
to puppet...@googlegroups.com, Andrew Shafer
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

jcbollinger wrote:
> Puppet's resource model involves having a common front end for each
> resource type that defines the available parameters, properties, and
> features, plus one or more "providers" for that type that interact
> with specific host environments to evaluate and update resource
> instances on those environments. user_role_add.rb is one of the
> providers for the User type. It is the default for Solaris, so if
> you're running on Solaris then that's probably what you're using, and
> if not then not.

Okay - my memory of why sucks but Solaris uses the standard useradd
provider and some methods are overridden in the provider that adds roles
support - including the libshadow password management.

> I agree that the password management in that provider is rather
> strange. It is usual for the User providers to rely on the host OS's
> utilities to do work (e.g. user_role_add uses useradd, usermod, etc.),
> so it is odd that password management is an exception. Moreover, it
> is surpassingly strange that having rejected OS utilities for this
> job, the provider does not rely on the Ruby shadow password library.
> The code even contains comments complaining about manipulating the
> shadow file directly!

Possibly there may be a reason - see
http://projects.reductivelabs.com/issues/1680. Andrew may be able to
shed light on how/why libshadow didn't do whatever magic was needed.

Andrew?

Regards

James Turnbull

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJKnDiNAAoJECFa/lDkFHAy7egIALguEHqQwlJhAJKkUay2+iDy
jqjObwWD49lqStWPlKISqVgmDhpZ63U6lLPTiQ85DT2MZ+RIRlFI6ykrN++dplCx
EoEV0EV+58FqRWZlVVU1ZZrUnVzSBirFFBQUdbiJXOOmP1zwkXExex4lkuIISD2k
MtPtVuQ+dILsIKfLfMG9jnz9L0Yqehh3MrnICW3g0pQXtmN8u5RRf7h2SZHC/VcZ
H0Osue520T7a7KZ73Z6xg/RaFBbxpWfaApGaG0g5gxv267lsQmCFzb5Gs9ubE358
nCzEjbwIbNe6XLG3l6Lu7rKtZAgtfXTM36AhmyydUeQoNukiqwuXKAKgcbR6isg=
=9kL3
-----END PGP SIGNATURE-----

James Turnbull

unread,
Aug 31, 2009, 5:11:09 PM8/31/09
to puppet...@googlegroups.com
2009/8/28 Kyle Mallory <jesusw...@gmail.com>:

>
> The problem is, the User type (w/ manage_passwords enabled and ruby-
> shadow installed) will only set the password in /etc/shadow, but it
> doesn't manage any of the other shadow parameters, namely the
> sp_lstchg parameter).  As a result, after our 90-day period, all of
> our passwords have updated, but the individual machines still think
> that the passwords have expired, and refuses to let us log in.

It doesn't manage this because the type doesn't have any support for
an "expire" attribute.

> This seems a bug in the User type, in that if the password changes
> from the previous password, it should also reset the last-changed
> field as well.  Ideally, if the User type is supporting passwords, it
> would be nice if there were properties to also specify the other
> shadow parameters, such as min, max, warn, expire, etc.

Not a bug as such - the lack of a feature to do this. There is a
ticket for the feature at:

http://projects.reductivelabs.com/issues/2224

I had a play with it a while ago but got distracted and did other things.

> I looked into the puppet provider code for User, but I couldn't make
> sense of how to fix.  Could someone point me to the right place so I
> can try and change this behavior (or maybe someone from Reductive Labs
> can fix it in an immediately upcoming update)?

You need to add support in the type (see
http://github.com/reductivelabs/puppet/blob/b728b931e5914cfeaf3d072fb77870e9a8ecf6cd/lib/puppet/type/user.rb)
for an "expire" attribute and possibly add a feature (see the user.rb
type code) for password expiration support that can enabled in user
providers that support this functionality.

You then need to enable appropriate support in each provider, if that
platform allows password expiration support.

Regards

James Turnbull

--
Author of:
* Pro Linux Systems Administration (http://tinyurl.com/linuxadmin)
* Pulling Strings with Puppet (http://tinyurl.com/pupbook)
* Pro Nagios 2.0 (http://tinyurl.com/pronagios)
* Hardening Linux (http://tinyurl.com/hardeninglinux)

Andrew Shafer

unread,
Aug 31, 2009, 6:06:47 PM8/31/09
to puppet...@googlegroups.com
git blame

I am the culprit.

The only provider that does passwords this way is user_role_add on
Solaris. If you are not using Solaris, you are not running that code.

The rational at the time was, useradd/mod do not support the password
parameter on Solaris and libshadow for Ruby is an unmaintained
project, difficult to build and without upstream support as a package
on the platform.

I might be naive about something, as this project was essentially my
introduction to Solaris, but I had some input from others with more
experience on Solaris.

If someone can suggest 'OS utilities' that don't also introduce clumsy
dependencies, I'd be happy to help integrate the change.

Regards,
Andrew

jcbollinger

unread,
Sep 1, 2009, 9:41:01 AM9/1/09
to Puppet Users


On Aug 31, 4:11 pm, James Turnbull <ja...@lovedthanlost.net> wrote:
> 2009/8/28 Kyle Mallory <jesuswasir...@gmail.com>:
>
>
>
> > The problem is, the User type (w/ manage_passwords enabled and ruby-
> > shadow installed) will only set the password in /etc/shadow, but it
> > doesn't manage any of the other shadow parameters, namely the
> > sp_lstchg parameter).  As a result, after our 90-day period, all of
> > our passwords have updated, but the individual machines still think
> > that the passwords have expired, and refuses to let us log in.
>
> It doesn't manage this because the type doesn't have any support for
> an "expire" attribute.
>
> > This seems a bug in the User type, in that if the password changes
> > from the previous password, it should also reset the last-changed
> > field as well.  Ideally, if the User type is supporting passwords, it
> > would be nice if there were properties to also specify the other
> > shadow parameters, such as min, max, warn, expire, etc.
>
> Not a bug as such - the lack of a feature to do this.  There is a
> ticket for the feature at:
>
> http://projects.reductivelabs.com/issues/2224

Maybe I'm missing something, but I don't think ticket 2224 is about
quite the same thing. Kyle isn't asking to manage an expiration date
for the account. Rather, he's asserting that when Puppet changes the
user's password, it should update the field in the shadow file that
records when the password was last changed. I agree with him, and I
don't see why any new User property should be needed to control that.
I'm not going to argue about whether this should be regarded as a
missing feature or a bug.

jcbollinger

unread,
Sep 1, 2009, 9:45:04 AM9/1/09
to Puppet Users


On Aug 31, 5:06 pm, Andrew Shafer <and...@reductivelabs.com> wrote:
[...]
> The rational at the time was, useradd/mod do not support the password
> parameter on Solaris and libshadow for Ruby is an unmaintained
> project, difficult to build and without upstream support as a package
> on the platform.

Fair enough.

[...]
> If someone can suggest 'OS utilities' that don't also introduce clumsy
> dependencies, I'd be happy to help integrate the change.

Would not the 'passwd' program would be the canonical OS utility for
this purpose?

Kyle Mallory

unread,
Sep 1, 2009, 11:14:07 AM9/1/09
to Puppet Users


On Aug 31, 4:06 pm, Andrew Shafer <and...@reductivelabs.com> wrote:
> git blame
>
> I am the culprit.
>
> The only provider that does passwords this way is user_role_add on
> Solaris. If you are not using Solaris, you are not running that code.
>
> The rational at the time was, useradd/mod do not support the password
> parameter on Solaris and libshadow for Ruby is an unmaintained
> project, difficult to build and without upstream support as a package
> on the platform.
>
> I might be naive about something, as this project was essentially my
> introduction to Solaris, but I had some input from others with more
> experience on Solaris.
>
> If someone can suggest 'OS utilities' that don't also introduce clumsy
> dependencies, I'd be happy to help integrate the change.
>
> Regards,
> Andrew

Andrew,

Makes sense, thanks.

I'm still a little baffled by where the actual shadow file management
is happening for non-Solaris OS's (we use Debian primarily). I'm even
more baffled by the dependency requirement for ruby_shadow to manage
this (regardless of its unmaintained state), if it's not being used.
If the dependency is there, and it is actually being used in some
capacity, then I'm hoping it should be relatively straight forward to
add one or two lines to set the last_changed parameter when calling
the libshadow function. Can you point me in the right direction?

Thanks,
Reply all
Reply to author
Forward
0 new messages