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/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/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/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/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/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?


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:


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.


After working through some things in the Augeas IRC room, it appears that my issue was simply a syntax error. When using "augtool print" directly (without dropping into the augtool> prompt), paths must be quoted. Meaning,

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

Will not work, but:

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

Yields the correct results. Also, if you drop into the augtool prompt, the command works correctly, even without quotes:

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.