Ubuntu – Configuring PAM with Augeas

augeaspampuppetUbuntu

I am attempting to use Augeas to configure the files in my /etc/pam.d directory in a default Ubuntu 14.04 install. My goal is to find all nodes that have an argument of either 'nullok' or 'nullok_secure' and remove those arguments from the configuration. This will eventually be enforced by Puppet, but I am currently working out the configuration using augtool on a local machine.

From everything I have read, the following expressions SHOULD yield me the nodes with 'nullok and 'nullok_secure':

augtool print /files/etc/pam.d/*/*/argument[../argument = 'nullok']
augtool print /files/etc/pam.d/*/*/argument[../argument = 'nullok_secure']

Or, alternately:

augtool print /files/etc/pam.d/*/*/argument[. = 'nullok']
augtool print /files/etc/pam.d/*/*/argument[. = 'nullok_secure']

Unfortunately, these aren't getting me anywhere, and I can't, for the life of me, figure out why. This is the augtool print of the one files I know has the argument (with comments removed for briefness):

/files/etc/pam.d/common-auth
/files/etc/pam.d/common-auth/1
/files/etc/pam.d/common-auth/1/type = "auth"
/files/etc/pam.d/common-auth/1/control = "[success=2 default=ignore]"
/files/etc/pam.d/common-auth/1/module = "pam_unix.so"
/files/etc/pam.d/common-auth/1/argument = "nullok_secure"
/files/etc/pam.d/common-auth/2
/files/etc/pam.d/common-auth/2/type = "auth"
/files/etc/pam.d/common-auth/2/control = "[success=1 default=ignore]"
/files/etc/pam.d/common-auth/2/module = "pam_lsass.so"
/files/etc/pam.d/common-auth/2/argument = "try_first_pass"
/files/etc/pam.d/common-auth/3
/files/etc/pam.d/common-auth/3/type = "auth"
/files/etc/pam.d/common-auth/3/control = "requisite"
/files/etc/pam.d/common-auth/3/module = "pam_deny.so"
/files/etc/pam.d/common-auth/4
/files/etc/pam.d/common-auth/4/type = "auth"
/files/etc/pam.d/common-auth/4/control = "required"
/files/etc/pam.d/common-auth/4/module = "pam_permit.so"
/files/etc/pam.d/common-auth/5
/files/etc/pam.d/common-auth/5/type = "auth"
/files/etc/pam.d/common-auth/5/control = "optional"
/files/etc/pam.d/common-auth/5/module = "pam_cap.so"

What am I missing here? Shouldn't these commands give me the nodes I am looking for?

Best Answer

First, the two expressions you list are not stricly equivalent.

/files/etc/pam.d/*/*/argument[../argument = 'nullok']

selects argument nodes 2 levels under /files/etc/pam.d that have an argument sibling node (or themselves) with a value set to nullok, whereas

/files/etc/pam.d/*/*/argument[. = 'nullok']

selects argument nodes 2 levels under /files/etc/pam.d with a value set to nullok (but not their siblings, if any).

Now the problem you're having is that the argument nodes you're trying to match are actually 3 levels under /files/etc/pam.d, not 2, so you'd need another level of /*.

The easiest way to avoid counting levels would be match at any level, by using // instead:

/files/etc/pam.d//argument[.='nullok']

That said, I don't know what you plan on doing with it, but you might want to know that there is an Augeas-based Puppet provider to manage PAM entries, which might be much easier than reimplementing your own solution.