Forum: Cfengine Help Subject: Re: I think I have created a solution for keeping admin passwords in sync on AIX Author: raymondcox Link to topic: https://cfengine.com/forum/read.php?3,20974,20986#msg-20986
Thank you for the input, the code I had was definitely too complex. In the end I have created a solution that does not rely on edit_line, but instead uses the chpasswd command. By using the native AIX command I am able to clear the ADMCHG flag, and update the lastupdate field all in one operation. This method has the added bonus of not having to directly edit the passwd file. I was always a little uncomfortable with directly editing the passwd file on AIX. Here is what I have come up with: # # Used to update the file /etc/security/passwd on an AIX system by creating a file that mimics # the format of the /etc/shadow file in LINUX. # Dependancies: # # /fixes/scripts/cfpasswd # Perl script used for dumping the passwords of the admin users defined in the slist admin_users. # /fixes/scripts/cfpasswd: # #!/usr/bin/perl # # $_user = $ARGV[0]; # # ($account, $passwd, $uid, $gid, $quota, $comment, $gcos, $home, $shell) = getpwnam($_user); # print "$passwd"; # # # # Convert the entries in /etc/security/passwd on AIX from: # #tstusr1: # password = bNR2bnq./xYWM # lastupdate = 1299424296 # flags = ADMCHG # #tstusr2: # password = 7f23WTTmyCHg6 # lastupdate = 1299165612 # flags = ADMCHG # TO: # # #tstusr1:bNR2bnq./xYWM: #tstusr2:7f23WTTmyCHg6: #tstusr3:8fPb6gQQrBDGA: #tstusr4:Wdffu2kUDRM4I: bundle agent harvest_passwords { files: tssdev:: "/var/cfengine/cache/cfsec_shadow" handle => "mock_shadow_file", comment => "Generate a mock shadow file from /etc/security/passwd", edit_defaults => empty, create => "true", edit_line => insert; !tssdev:: "/var/cfengine/cache/cfsec_shadow" handle => "download_mock_shadow_file", comment => "Copy the mock shadow file from a central password server", perms => mog("0440","root","system"), copy_from => remote_cp("/var/cfengine/cache/cfsec_shadow", "${g.aixpassmaster}"), classes => if_repaired("gotnewlist"), ifvarclass => "aix"; methods: gotnewlist:: "update_admin_pass" usebundle => passlist; } bundle edit_line insert { vars: "admin_users" slist => { "rayco" }; "admin_pass[$(admin_users)]" string => execresult("/fixes/scripts/cfpasswd $(admin_users)","useshell"); insert_lines: "$(admin_users):$(admin_pass[$(admin_users)]):"; } ########################################################################## bundle agent passlist { vars: "mypasswd" int => readstringarray("mypasswd_array","/var/cfengine/cache/cfsec_shadow","#[^\n]*",":",200,10000); "shadow_users" slist => getindices("mypasswd_array"), policy => "overridable"; methods: "check_update" usebundle => check_update("$(mypasswd_array[$(shadow_users)][0])","$(mypasswd_array[$(shadow_users)][1])"); } ########################################################################## bundle agent check_update(user,password) { vars: "secpass" string => execresult("/fixes/scripts/cfpasswd $(user)","useshell"), policy => "overridable"; classes: "updatepass" not => strcmp("$(password)","$(secpass)"); commands: updatepass:: "/usr/bin/echo" args => "$(user):$(password) | /usr/bin/chpasswd -c -e -R compat", contain => standard; } So far it is working flawlessly, although I only have it applied to a few machines so far. _______________________________________________ Help-cfengine mailing list Help-cfengine@cfengine.org https://cfengine.org/mailman/listinfo/help-cfengine