#!/usr/bin/perl use Getopt::Long qw(:config bundling_override); #use strict; #no strict 'refs'; umask(022); use vars qw( ); # # SYSTEM = "LDAP or compat" # $date = `/usr/bin/date "+%Y%m%d-%H:%M:%S"`; chomp($date); $basename = `/usr/bin/basename $0`; chomp($basename); $SUFFIX = "o=ORG,c=US"; $SOURCE = "/opt/usrmgt"; GetOptions( 'h|?' => \$help, 'v' => sub { $verbose = "-v" }, 'd' => \$debug, ) || usage(); usage() if $help; sub usage { print("usage: $basename [-v] [-h] [-d]\n"); cleanexit(9); } @files = ("/etc/passwd","/etc/group","/etc/security/passwd","/etc/security/user","/etc/security/group","/etc/security/limits"); foreach $file (@files) { system("/usr/bin/cp $file ${file}.$$"); $rc = $?; if ( $rc > 0 ) { cleanexit(1); } } $ITDS = "/opt/IBM/ldap/V6.3"; $ldaphost = "host1"; $ldapport = 20389; $ldapinst = "inst1"; $ldappwd = "rootdnpwd"; $baseauth = "-h $ldaphost -p $ldapport"; $sufbaseauth = "-h $ldaphost -p $ldapport -b $SUFFIX"; $rootauth = "$baseauth -D cn=rootdn -w ?"; $sufrootauth = "$sufbaseauth -D cn=rootdn -w ?"; %ldapattrs = initattr(); # translation table between AIX and LDAP Attributes $cmd = "$ITDS/bin/ldapsearch $sufbaseauth uid=root 2>/dev/null"; $ldaprootexist = `$cmd`; chomp($ldaprootexist); if ( not $ldaprootexist ) { # do NOT overwrite file base in case root is not defined print("ERROR: LDAP not configured with rootuser ...\n"); cleanexit(10); } getshadow(); setarrays(); # defining all attributes of security files and the %files array with relevant file types readldap(); $numldapusers = setbase(); $numusers = `/usr/bin/cat /etc/passwd | /usr/bin/wc -l`; chomp($numusers); $numusers += 0; $numaixusers = int($numusers/2) ; if ( $numldapusers < $numaixusers ) { print("ERROR: cannot write files ... too much is wrong\n"); usage(); } if ( $user{root}{tnumber} ne "root" ) { print("ERROR: cannot write files ... too much is wrong, root user not found ?\n"); usage(); } print("AIX: $numusers LDAP: $numldapusers COMP: $numaixusers\n"); ############################# # # updating /etc/passwd # ############################# $file = "/etc/passwd"; $newfile = "${file}.new"; system("/usr/bin/cp $file $newfile"); $rc = $?; if ( $rc > 0 ) { print("ERRORS occurred copying $file ... exiting\n"); cleanexit(12); } open(PWD,"> $newfile"); foreach $id (sort bysize keys (%passwd)) { #print("ID = $id NAME = $etcpasswd{$id}\n"); if ( $etcpasswd{$id} eq "default" ) { next; } print(PWD "$passwd{$id}\n"); } close(PWD); $rc = $?; if ( ! -z $newfile ) { if ( $rc eq 0 ) { print("INFO: Applying actual status of LDAP in $file ...\n"); rename("$newfile","$file") if ( not $debug ); } else { print("ERROR: cannot create $file ... exiting\n"); restoreexit(8); } } else { print("ERROR: $file cannot be created, since $newfile is empty ...\n"); exit 1; } ############################# # # updating /etc/group # ############################# $file = "/etc/group"; $newfile = "${file}.new"; system("/usr/bin/cp $file $newfile"); $rc = $?; if ( $rc > 0 ) { print("ERRORS occurred copying $file ... exiting\n"); restoreexit(12); } open(PWD,"> $newfile"); foreach $gid (sort bysize keys (%groupid)) { @row = (); foreach $tn (sort bysize keys (%{$gridmembers{$gid}})) { if ( $user{$tn}{tnumber} ) { push(@row, $tn); } } $members = join(",",@row); print(PWD "$groupid{$gid}:!:$gid:$members\n"); } close(PWD); $rc = $?; if ( ! -z $newfile ) { if ( $rc eq 0 ) { print("INFO: Applying actual status of LDAP in $file ...\n"); rename("$newfile","$file") if ( not $debug ); } else { print("ERROR: cannot create $file ... exiting\n"); restoreexit(8); } } else { print("ERROR: $file cannot be created, since $newfile is empty ...\n"); restoreexit(1); } ############################# # # updating /etc/security/user, /etc/security/passwd and /etc/security/limits # ############################# foreach $type (keys (%files)) { $file = $files{$type}; $newfile = "${file}.new"; system("/usr/bin/cp $file $newfile"); $rc = $?; if ( $rc > 0 ) { print("ERRORS occurred copying $file ... exiting\n"); restoreexit(12); } open(PWD,"> $newfile"); print(PWD "default:\n"); foreach $filekey (sort keys (%{$key{$type}})) { if ( exists $default{$filekey} ) { print(PWD "\t$filekey = $default{$filekey}\n") } } print(PWD "\n"); if ( $file !~ /group/ ) { $tn = "root"; print(PWD "$tn:\n") } foreach $filekey (sort keys (%{$key{$type}})) { if ( exists $user{$tn}{$filekey} ) { if ( $filekey eq "SYSTEM" ) { print(PWD "\t$filekey = \"$user{$tn}{$filekey}\"\n") } else { print(PWD "\t$filekey = $user{$tn}{$filekey}\n") } } } print(PWD "\n"); if ( $file !~ /group/ ) { foreach $id (sort bysize keys (%etcpasswd)) { $stanza = 0; $tn = $etcpasswd{$id}; next if ( $tn eq "root" || $tn eq "default" ); foreach $filekey (sort keys (%{$key{$type}})) { if ( not $stanza ) { print(PWD "$tn:\n"); $stanza = 1; } if ( exists $user{$tn}{$filekey} ) { if ( exists $default{$filekey} ) { if ( $user{$tn}{$filekey} ne $default{$filekey} ) { print(PWD "\t$filekey = $user{$tn}{$filekey}\n") } } else { print(PWD "\t$filekey = $user{$tn}{$filekey}\n") } } } print(PWD "\n"); } } else { foreach $gid (sort bysize keys (%groupid)) { $stanza = 0; $group = "$groupid{$gid}"; foreach $filekey (sort keys (%{$key{$type}})) { if ( not $stanza ) { print(PWD "$group:\n"); $stanza = 1; } if ( exists $user{$group}{$filekey} ) { print(PWD "\t$filekey = $user{$group}{$filekey}\n") } } print(PWD "\n"); } } close(PWD); $rc = $?; if ( ! -z $newfile ) { if ( $rc eq 0 ) { print("INFO: Applying actual status of LDAP in $file ...\n"); rename("$newfile","$file") if ( not $debug ); } else { print("ERROR: cannot create $file ... exiting\n"); restoreexit(8); } } else { print("ERROR: $file cannot be created, $newfile is empty ...\n"); restoreexit(1); } } cleanexit(0); sub readldap { my @ldap = (); my $stanza = 0; my $groupid = 0; my $ldapattr = undef; my $grattr = undef; my $gn = undef; my $value = undef; # READ GROUPS #cn=group1,ou=Groups,o=ORG,c=CH #cn=group1 #objectClass=aixauxgroup #objectClass=posixgroup #objectClass=top #gidnumber=12345 #memberuid=user1 $cmd = "$ITDS/bin/ldapsearch $sufrootauth objectclass=aixauxgroup"; print("Searching groups in LDAP: $cmd\n"); open(LDAP,"| $cmd > $SOURCE/logs/groups.ou 2>&1"); print(LDAP "$ldappwd\n"); close(LDAP); open(LDAP,"< $SOURCE/logs/groups.ou"); @ldap = <LDAP>; close(LDAP); chomp(@ldap); foreach $line (@ldap) { if ( $line =~ /ou=Groups/ ) { @row = split(",",$line); $gn = $row[0]; $gn =~ s/^cn=//; $stanza = 1; next; } if ( $stanza ) { # memberuid=uid=user1,ou=People,o=ORG,c=US $value = $line; @row = split("=",$value); $grattr = $row[0]; $value =~ s/^$grattr=//; if ( $value =~ /^uid=/ ) { $value =~ s/^uid=//; @row = split(",",$value); $value = $row[0]; } if ( $grattr eq "gidnumber" ) { $groupname{$gn} = $value; $groupid{$value} = $gn; $groupid = $value; } if ( $grattr eq "memberuid" ) { $groups{$value}{$gn} = 1; $gridmembers{$groupid}{$value} = 1; $grmembers{$gn}{$value} = 1; } } } # READ PEOPLE $cmd = "$ITDS/bin/ldapsearch $sufrootauth objectclass=aixauxaccount"; print("Searching People in LDAP: $cmd\n"); open(LDAP,"| $cmd > $SOURCE/logs/people.ou 2>&1"); print(LDAP "$ldappwd\n"); close(LDAP); open(LDAP,"< $SOURCE/logs/people.ou"); @ldap = <LDAP>; close(LDAP); chomp(@ldap); $stanza = 0; foreach $line (@ldap) { if ( $line =~ /ou=People/ ) { @row = split(",",$line); $tn = $row[0]; $tn =~ s/^uid=//; $user{$tn}{tnumber} = $tn; $stanza = 1; next; } if ( $stanza ) { @row = split("=",$line); $ldapattr = $row[0]; # find out attribute name $line =~ s/^$ldapattr=//; if ( $ldapattrs{$ldapattr} ) { if ( $ldapattr eq "shadowlastchange" ) { $line = $line * $multiplier; } if ( $ldapattr eq "gecos" ) { @row = split(",",$line); $user{$tn}{name} = $row[0]; $user{$tn}{mail} = $row[1]; } if ( $ldapattr eq "userpassword" ) { $line =~ s/{crypt}//; } if ( $ldapattr eq "gidnumber" ) { $userldap{$tn}{pgrp} = $groupid{$line}; $groups{$tn}{$groupid{$line}} = 1; $gridmembers{$line}{$tn} = 1; $grmembers{$groupid{$line}}{$tn} = 1; @row = (); foreach $value (sort keys (%{$groups{$tn}})) { push(@row,$value); } $user{$tn}{groups} = join(",",@row); $user{$tn}{groups} = $userldap{$tn}{pgrp} if (( not exists $userldap{$tn}{groups} ) || ( not defined $userldap{$tn}{groups} )) ; } $aixattr = $ldapattrs{$ldapattr}; if ( $tn eq "default" ) { $default{$aixattr} = $line; } else { $user{$tn}{$aixattr} = $line; $limits{$tn}{$aixattr} = $line if ( $limitsattrs{$aixattr} ); } } } } } # END OF READLDAP sub setarrays { $key{user}{SYSTEM} = 1; $key{user}{account_locked} = 1; $key{user}{admgroups} = 1; $key{user}{admin} = 1; $key{user}{auth1} = 1; $key{user}{auth2} = 1; $key{user}{daemon} = 1; $key{user}{dictionlist} = 1; $key{user}{expires} = 1; $key{user}{histexpire} = 1; $key{user}{histsize} = 1; $key{user}{loginretries} = 1; $key{user}{logintimes} = 1; $key{user}{login} = 1; $key{user}{maxage} = 1; $key{user}{maxexpired} = 1; $key{user}{maxrepeats} = 1; $key{user}{minage} = 1; $key{user}{minalpha} = 1; $key{user}{mindiff} = 1; $key{user}{minlen} = 1; $key{user}{minother} = 1; $key{user}{pwdchecks} = 1; $key{user}{pwdwarntime} = 1; $key{user}{registry} = 1; $key{user}{rlogin} = 1; $key{user}{su} = 1; $key{user}{sugroups} = 1; $key{user}{tpath} = 1; $key{user}{ttys} = 1; $key{user}{umask} = 1; $key{passwd}{lastupdate} = 1; $key{passwd}{password} = 1; $key{passwd}{flags} = 1; $key{group}{admin} = 1; $key{group}{adms} = 1; $key{group}{registry} = 1; $key{limits}{cpu} = 1; $key{limits}{fsize} = 1; $key{limits}{data} = 1; $key{limits}{stack} = 1; $key{limits}{rss} = 1; $key{limits}{core} = 1; $key{limits}{nofiles} = 1; $key{limits}{cpu_hard} = 1; $key{limits}{fsize_hard} = 1; $key{limits}{data_hard} = 1; $key{limits}{stack_hard} = 1; $key{limits}{rss_hard} = 1; $key{limits}{core_hard} = 1; $key{limits}{nofiles_hard} = 1; $files{"user"} = "/etc/security/user"; $files{"passwd"} = "/etc/security/passwd"; $files{"group"} = "/etc/security/group"; $files{"limits"} = "/etc/security/limits"; } sub setbase { my $ldapusers = 0; foreach $tn (keys (%user)) { $ldapusers += 1; if ( $tn eq "default" ) { $default{SYSTEM} = "\"LDAP or compat\""; $default{registry} = "LDAP"; $default{auth1} = "NONE"; $default{auth2} = "NONE"; } # "$tn:!:$id:$gid:$ge:/u/$tn:$sh"; $pc = $user{$tn}{passwordchar}; $id = $user{$tn}{id}; $gid = $user{$tn}{pgrpid}; $ge = $user{$tn}{gecos}; $home = $user{$tn}{home}; $shell = $user{$tn}{shell}; $lu = $user{$tn}{lastupdate}; $pw = $user{$tn}{password}; $passwd{$id} = "$tn:$pc:$id:$gid:$ge:$home:$shell"; $etcpasswd{$id} = "$tn"; } return $ldapusers; } sub bysize { $a <=> $b } sub cleanexit { my $rc = $_[0]; foreach $file (@files) { unlink("${file}.$$"); } exit $rc; } sub restoreexit { my $rc = $_[0]; foreach $file (@files) { rename("${file}.$$","$file") if ( -f "${file}.$$" ); } exit $rc; } sub getshadow { open(ETC,"< /etc/security/ldap/2307aixuser.map"); @etc = <ETC>; close(ETC); chomp(@etc); foreach $line (@etc) { if ( $line =~ /^lastupdate/ ) { @row = split(" ",$line); if ( $row[-1] =~ /seconds/ ) { $multiplier = 1; } elsif ( $row[-1] =~ /days/ ) { $multiplier = 86400; } } } } sub initattr { my %ldapattrs = (); $ldapattrs{"admingroupadminlist"} = "adms"; $ldapattrs{"admingroupnames"} = "admgroups"; $ldapattrs{"authmethod1"} = "auth1"; $ldapattrs{"authmethod2"} = "auth2"; $ldapattrs{"coresizelimit"} = "core"; $ldapattrs{"coresizelimithard"} = "core_hard"; $ldapattrs{"cpusize"} = "cpu"; $ldapattrs{"cpusizehard"} = "cpu_hard"; $ldapattrs{"datasegsize"} = "data"; $ldapattrs{"datasegsizehard"} = "data_hard"; $ldapattrs{"filepermmask"} = "umask"; $ldapattrs{"filesizelimit"} = "fsize"; $ldapattrs{"filesizelimithard"} = "fsize_hard"; $ldapattrs{"gecos"} = "gecos"; $ldapattrs{"gidnumber"} = "pgrpid"; $ldapattrs{"groupswitchuserallowed"} = "sugroups"; $ldapattrs{"homedirectory"} = "home"; $ldapattrs{"hostlastlogin"} = "host_last_login"; $ldapattrs{"hostlastunsuccessfullogin"} = "host_last_unsuccessful_login"; $ldapattrs{"isaccountenabled"} = "account_locked"; $ldapattrs{"isadministrator"} = "admin"; $ldapattrs{"isdaemon"} = "daemon"; $ldapattrs{"isloginallowed"} = "login"; $ldapattrs{"isremoteaccessallowed"} = "rlogin"; $ldapattrs{"isswitchuserallowed"} = "su"; $ldapattrs{"ixtimelastlogin"} = "time_last_login"; $ldapattrs{"ixtimelastunsuccessfullogin"} = "time_last_unsuccessful_login"; $ldapattrs{"logintimes"} = "logintimes"; $ldapattrs{"loginshell"} = "shell"; $ldapattrs{"maxfailedlogins"} = "loginretries"; $ldapattrs{"nsroledn"} = "nsroledn"; $ldapattrs{"openfilelimit"} = "nofiles"; $ldapattrs{"openfilelimithard"} = "nofiles_hard"; $ldapattrs{"passwordchar"} = "passwordchar"; $ldapattrs{"passwordcheckmethods"} = "pwdchecks"; $ldapattrs{"passwordflags"} = "flags"; $ldapattrs{"passworddictfiles"} = "dictionlist"; $ldapattrs{"passwordhistexpire"} = "histexpire"; $ldapattrs{"passwordhistsize"} = "histsize"; $ldapattrs{"passwordmaxrepeatedchars"} = "maxrepeats"; $ldapattrs{"passwordminalphachars"} = "minalpha"; $ldapattrs{"passwordmindiffchars"} = "mindiff"; $ldapattrs{"passwordminlength"} = "minlen"; $ldapattrs{"passwordminotherchars"} = "minother"; $ldapattrs{"physicalmemlimit"} = "rss"; $ldapattrs{"physicalmemlimithard"} = "rss_hard"; $ldapattrs{"rolelist"} = "roles"; $ldapattrs{"shadowexpire"} = "maxexpired"; $ldapattrs{"shadowlastchange"} = "lastupdate"; $ldapattrs{"shadowmax"} = "maxage"; $ldapattrs{"shadowmin"} = "minage"; $ldapattrs{"shadowwarning"} = "pwdwarntime"; $ldapattrs{"stacksizelimit"} = "stack"; $ldapattrs{"stacksizelimithard"} = "stack_hard"; $ldapattrs{"terminalaccess"} = "ttys"; $ldapattrs{"terminallastlogin"} = "tty_last_login"; $ldapattrs{"terminallastunsuccessfullogin"} = "tty_last_unsuccessful_login"; $ldapattrs{"timeexpirelockout"} = "expires"; $ldapattrs{"trustedpathstatus"} = "tpath"; $ldapattrs{"uid"} = "tnumber"; $ldapattrs{"uidnumber"} = "id"; $ldapattrs{"unsuccessfullogincount"} = "unsuccessful_login_count"; $ldapattrs{"userpassword"} = "password"; return %ldapattrs; }