Search code examples
regexlinuxsedsalt-projectrhel6

Salt-stack working with Pam.d


All systems running RHEL6 So, My end goal is to be able to have state controlled pam configuration(system-auth, and password-auth). That also doesn't interfere with changes that might need to happen on a local system to system basis.

Essentially I want to add lines to the pam config files for things like pam_cracklib without having to just overwrite the entire file with file.managed

example of current system-auth(not a full example, some items removed)

auth        required      pam_env.so
auth        sufficient    pam_unix.so  try_first_pass
auth        requisite     pam_succeed_if.so uid >= 100 quiet
auth        required      pam_deny.so

account     required      pam_unix.so broken_shadow
account     [default=bad success=ok user_unknown=ignore] pam_sss.so
account     required      pam_permit.so

password    sufficient    pam_unix.so sha512 shadow  try_first_pass use_authtok remember=24
password    required      pam_deny.so

An example problem:

I need the line:

password    requisite     pam_cracklib.so try_first_pass retry=3 dcredit=-1 minlen=12 ucredit=-1 ocredit=-1 lcredit=-1 difok=3

to appear, with those settings, above the password line of the pam_unix.so entry like so:

password    requisite     pam_cracklib.so try_first_pass retry=3 dcredit=-1 minlen=12 ucredit=-1 ocredit=-1 lcredit=-1 difok=3
password    sufficient    pam_unix.so sha512 shadow  try_first_pass use_authtok remember=24

In some cases, pam_cracklib may already exist, and I can simply use file.replace state to find the pattern for pam_cracklib and replace it with the good line. In other cases, pam_cracklib may need to be added, and as such the limitation with file.replace of appending or prepending causes problems.

Another example would be pam_faillock.so which needs to be inserted on very specific lines. IE before or after other pam modules of importance.

I've considered just biting the bullet and using file.managed to enforce a unified pam file to my systems, and then making exceptions as needed to keep the other things functional, but these feels a lot like painting myself into a corner.

Any suggestions on a method of dealing with specific item location placements, without enforcing an entire file? In sed I can can use ()'s along with the escape's \1, \2 to keep parts of a pattern, and combined with newlines and what not, I can look for a pattern and replace text above or below a line, and move on. But as far as I can tell that can't be done with file.replace. I suppose I could simply issue a sed command with cmd.run but then I have to be annoyed by the fact that it will run every time states are enforced.


Solution

    • I heard Auegas is supposed to address generic read-write access to various configuration files - Salt has its module. There is a PAM lense.
    • Another pointer is file.managed with marker_start and marker_end parameters. This approach works perfectly for simple configurations like hosts file where manually maintained part is separated from automatically enforced one.

    GENERAL NOTES

    It is fundamentally difficult problem to support syntax of various configuration files on the system for automatic modification. Templates fully overriding destination files provide generic approach with limitations you stated. The generic approach explodes in complexity if it is required to read the destination file and apply conditionally some modifications to the its original content.

    Think about automatically changing (manually written) source code while maintaining its readability and guaranteeing semantically correct runtime after that, do it for all top 10 programming languages.

    Even if general format is simple (e.g. text lines), there is still a problem to satisfy expectations of the software which consumes this configuration. Does the order of lines matter? Will duplicated lines be illegal? Should comments be preserved?