Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:


Hello,

I need a script that checks a password file or invalid users. I am on a Unix box and all the passwords are NIS. I just add them to a front end. But users come and go - but their passwords stay - and the list just get long.

I want to take each password - one by one - do a ypmatch on it - if it is in NIS - keep it - if not - delete it.

If possible if ypmatch comes back with a 'cracked' or 'expired' email the admin.

What I plan to do - check the list for lines beginning with "+" - do a system call with the first field (Unix ID) doing a ypmatch.

I am not sure how to interpret the out come though - is it there or not.

Anybody have suggestions on how to proceed - or aware of a library that would help with this?

i.e.
root:123456/xx.xxx:0:3::/home/root:/csh <---skip
johnny:XXXxxxXXXxxx:0:3:John Admin:/home/John:bin/csh <---skip
+dots::0:0:Support:/home/support:/bin/csh <--in NIS - keep
+user1::0:0:Hobbit Bilbo:/home/asia:/bin/csh <--in NIS - keep
+user2::0:0:Jim Bean:/home/asia:/bin/csh <--not in NIS remove
+user3::0:0:Bill Gates:/home/asia:/bin/csh <--in NIS - keep
It will write the new password file - but without user2

Thanks,
V

Replies are listed 'Best First'.
Re: Password file and NIS check?
by tbo (Scribe) on Sep 09, 2002 at 20:13 UTC
    If you want to access the NIS map, you can do something like that :
    use strict; use GDBM_File; my $nis_domain="your_domain"; #location of nis files my $passwd_byuid="/var/yp/".$nis_domain."/passwd.byuid"; my %nis;# informations from nis map my @delete; # users not in the nis map mu @user_info; # informations from /etc/passwd ## get the users from /etc/passwd ### open (fd, '/etc/passwd') or die "can't access /etc/passwd"; my @CONTENTS = <fd>; close (fd); tie (%nis,'GDBM_File',$passwd_byname,0,0) or die "Can't access NIS pas +swd.byname"; foreach $line (@CONTENTS) { @user_info=split (/:/,$line); if (substr($user_info[0],0,1) eq "+") { $user_info[0]=~ s/\+//; if (!$nis{'$user_info[0]'}) { push @delete,$user_info[0]; } } } untie (%nis);
    You will have in @delete the users to be deleted.
Re: Password file and NIS check?
by krisahoch (Deacon) on Sep 09, 2002 at 18:09 UTC

    Anono-monk,

    What is your criteria for skipping an entry? You have root, and johnny marked as skip, but you didnt give a reason that it should be skipped.

    Otherwise, here is a theoretical solution


    First, open your /etc/passwd file, and read it to an array
    open (fd, '/etc/passwd') or die $!; my @CONTENTS = <fd>; close (fd);
    Now that that is done, get each entry except for root, and compare it to the NIS one
    sub ypMatchit {#This does the most work # I don't know if you want to add root and johnny # to your new file or not. If you do want them to # be added, then change the next trwo undef's you # see to be '0'; return undef if ($_ && 'root'); return undef if ((<i>rules for skipping johnny are enforced</i>)); my $Final = ypmatch($_); #add any other processing you want to do here return 0 if ($Final = (SUCCESS)); return undef; } my @FINAL = (); foreach my $CurrentEntry ( @CONTENTS ) { push @FINAL, $CurrentEntry if( defined(ypMatchit($CurrentEntry))); }

    Now write the final thing out to a file
    open (FD, '/etc/newPasswd') or die $!; foreach (@FINAL) { print FD $_; } close (FD);

    This is all theory by the way, but I think it is a good start (I did somthing similiar several months ago, and this methodology worked.

    HTH - Kristofer

Re: Password file and NIS check?
by Zaxo (Archbishop) on Sep 09, 2002 at 19:05 UTC

    See getpwent and friends for reading the local user data. Watch out for system users like nobody and daemon.

    After Compline,
    Zaxo

      I don't think it works : getpwent will read the local files AND the nis map. (I've already had this problem with getgrent).