anlpasswd-3.0/0040755000107400004540000000000007333632661012410 5ustar rackowmcszanlpasswd-3.0/anlpasswd0100555000107400004540000005727507333631710014337 0ustar rackowmcsz#!/usr/local/bin/perl # # ANL passwd program # $Version = "Version 3.0"; # # Last modified: 2001-Jul-03 # ################################################## # Mayor changes: # - program is using libcrack library (by Alec Muffett) for dictionary lookups # - program is tested on the following architectures: # SunOS, Solaris, Irix-6, AIX-4, linux # - password changes in local file are not supported any more (only YP) # (this is due to differences in /etc/passwd structure on different # UNIX platforms) # ################################################# ############# # Configs $debug = 0; # 1 is on 0 is off # # Customizable items. # Change these to reflect your local environment # # Legal shells; This is a list of valid login shells # If you add any new valid shells, this variable should # be updated. The shells listed here _must_ exist on # all machines on your network that use YP; otherwise, # a user may not be able to log in to all of the machines. @legal_shells = ( '/usr/local/bin/tcsh', '/usr/local/bin/zsh', '/bin/csh', '/bin/sh' ); # location of dictionaries $dict = "/usr/local/etc/dict"; # location of ypstuff executable $ypstuffdir = "/usr/local/adm/bin/"; # End configs ############### use IPC::Open2; use Getopt::Std; # These two are standard PERL5 libs #use libcrack; # Use libcrack module use Crypt::Cracklib; # Use libcrack module # This one has to be installed on your system # Below used for the prompter $shell_prompt = join(' ', @legal_shells); # Security blankets. $ENV{'IFS'} = '' if $ENV{'IFS'}; $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/bin:/usr/ucb:/usr/bsd'; umask(022); chdir '/etc' || die "Can't find /etc.\n"; if ( ! -f "$ypstuffdir/ypstuff" ){ die "Can't find ", $ypstuffdir, "/ypstuff"; } # Uncustomizable items. $| = 1; # command buffering on STDOUT chop($host = `hostname`); ########################## ac #1 start # Get the name of the command the user typed in to call this # program (either "passwd" or "yppasswd") and chop off the # path. ($program = $0) =~ s/.*\/(\w*)/\1/; ########################## ac #1 end # So that messages speak truth about what is being changed. --mwh $what = "password"; # Define the usage statement --mwh 8-26-92 $usage = "Usage: $0 [-f] [-s] [-a] [-r] [name]\n"; $usage .= "\t-f change the gecos information field.\n"; $usage .= "\t-s change the login shell.\n"; $usage .= "\t-a change without resetting password aging. Unsupported.\n"; $usage .= "\t-r forgo the good password checks. Root only.\n"; $usage .= "\n$Version\n"; if ( ! getopts( "fsar") ) { die "$usage"; } # Only one option is permitted at a time, so... $total_opts = $opt_f + $opt_s + $opt_a + $opt_r; # total number of options if ( $total_opts > 1 ) { die "Use only one of -f, -s, -a, -r, at a time.\n$usage\n"; } # relax the password "goodness" checks? $relax = 0; if ( $opt_r ) { if ( $< != 0 ) { die "\nThe -r (relax) option is for root only.\n$usage"; } $relax = $opt_r; print "\nWarning: Not checking if new password is \"good\"!\n."; } # changing shells if ( $opt_s ) { $what = "shell"; } # password aging if ( $opt_a ) { die "\nThe aging option is not supported.\n$usage" } # Change the gecos field if ( $opt_f ) { $what = "gcos"; } # Whose password are we changing, anyway? # (We use getlogin in preference to getpwuid($<)[0] in case # different accounts are sharing uids.) ($me) = @ARGV; die "You can't change the password for $me.\n" if $me && $<; $me = getlogin unless $me; $me = (getpwuid($<))[0] unless $me; # Trap these signals $SIG{'INT'} = 'cleanup'; $SIG{'HUP'} = 'cleanup'; $SIG{'QUIT'} = 'cleanup'; $SIG{'PIPE'} = 'cleanup'; $SIG{'ALRM'} = 'cleanup'; # Get passwd entry and remember all logins ############################# # Program supports only password changes through YP # starting with version 2.4 ($login,$opasswd,$uid,$gid,$ogcos,$home,$shell) = &getyp($me); if ($login) { # YP entry exists print "Changing $what entry for $me on yp server\n"; } else { die "Error: no entry for $me in YP database\n"; } # get rid of wherever it was acquired chop( $shell ); die "You aren't you! ($< $uid $me $x $login)\n" if $< && $< != $uid; # Just being paranoid... $salt = substr($opasswd,0,2); # ###### # added to save the original gcos $gcos = $ogcos; ###### # # Canonicalize name. # $ogcos =~ s/,.*//; $mynames = $ogcos; $mynames =~ s/\W+/ /; $mynames =~ s/^ //; $mynames =~ s/ $//; $mynames =~ s/ . / /g; $mynames =~ s/ . / /g; $mynames =~ s/^. //; $mynames =~ s/ .$//; $mynames =~ s/ /|/; $mynames = '^$' if $mynames eq ''; #################################### ac #3 end # Finally we can begin. system 'stty', '-echo'; if ($<) { print "Old password: "; chop($pass0 = ); print "\n"; if (length($pass0) > 8) { $passa = $pass0; $pass0 = substr($passa,0,8); } # Note: we shouldn't use die while echo is off. # Now it deals with "no password" accounts # do myexit(1) unless $pass0; if ( ! $pass0 ) { &myexit(1) if $opasswd; } if (crypt($pass0,$salt) ne $opasswd) { print "Sorry.\n"; do myexit(1); } } system 'stty', 'echo'; # This will get changed if in fact we are changing the password $cryptpass = $opasswd; # OK, now we believe they know who they are, what are we doing? if ( $opt_s ) { &shell_game; } if ( $opt_f ) { &gecos_update; } if ( ! $opt_s && ! $opt_f ) { &get_new_pw; $cryptpass = &encrypt_passwd($login,$pass1); } ####### # ## $login the login name ## $pass0 the original passwd ## $pass1 the new passwd to be encrypted and installed ## $uid the old user id ## $gid the group id ## $gcos the gcos stuff to be installed ## $home the home file system ## $shell the shell the gets installed ######## # @pw = ("$login","$cryptpass","$uid","$gid","","",$gcos,"$home","$shell"); # chop($host = `ypwhich -m passwd`); if ( ! &open2(READ, WRITE, "$ypstuffdir/ypstuff $host")) { die "Open2 failed\n"; } print "Opening $ypstuffdir/ypstuff $host\n" if $debug; print "$pass0\n" if $debug; print WRITE "$pass0\n"; print WRITE join("\n", @pw, ""); print join("\n", @pw, "") if $debug; close(WRITE); $repl = ; close(READ); if ($repl =~ /^SUCCESS\s*$/) { print "Success\n"; die "\n Password entry updated on server.\n\n"; } elsif ($repl =~ /^ERROR:\s+(.*)\s*$/) { die "\nPassword update on server not possible at this time. Failure: $1\nTry again later.\n"; } else { print "Unknown reply <$repl>\n"; die "\nPassword update on server failed. Failure: unknown\nTry again later.\n"; } ############################################################### # # # This subroutine is the whole reason for this program. It # # checks for many different kinds of bad password. We don't # # tell people what kind of pattern they MUST have, because # # that would reduce the search space unnecessarily. # # # # goodenough() returns 1 if password passes muster, else 0. # # # ############################################################### sub goodenough{ return 1 if $relax; # Only root can bypass this. $pass = shift(@_); $mono = $pass !~ /^.+([A-Z].*[a-z]|[a-z].*[A-Z])/; $mono = 0 if $pass =~ /[^a-zA-Z0-9 ]/; $now = time; ($nsec,$nmin,$nhour,$nmday,$nmon,$nyear) = localtime($now); # Embedded null can spoof crypt routine. if ($pass =~ /\0/) { print "Please don't use the null character in your password.\n"; return 0; } if ($pass =~ /:/) { print "Please don't use the colon character in your password. Some vendors have\n"; print "a problem in changing passwds to something new when the old has a colon.\n"; return 0; } # Do a little checking on the passwd for regex characters like * --Gene $tstring = $pass; $tstring =~ s/[\\()*.|\$^+\[\]]/\\$&/g; $tstring =~ s/[\\()?.|\$^+\[\]]/\\$&/g; print "$tstring is the new string comprared to $pass\n" if $debug; # Same password they just had? # This needs modified also to handle accounts that started with # no password. Without a salt from opasswd, crypt returns null, # so don't test. --Mark Henderson 8-26-92 # if (crypt($pass,$salt) eq $opasswd) { if ((crypt($pass,$salt) eq $opasswd) && ($opasswd)) { print "Please use a different password than you just had.\n"; return 0; } # Password is a part of the gecos field? if( $gcos =~ /$tstring/i ) { print "Please don't use a part of your gcos entry.\n"; return 0; } # Password in .plan file? if(&checkfile("$home/.plan", $tstring)) { print "Please don't use a part of your .plan file!\n"; return 0; } # Password in .project file? if(&checkfile("$home/.project", $tstring)) { print "Please don't use a part of your .project file!\n"; return 0; } # Too much like the old password? if ($pass0 && length($pass0) == length($pass)) { $diff = 0; for ($i = length($pass)-1; $i >= 0; --$i) { ++$diff if substr($pass,$i,1) ne substr($pass0,$i,1); } if ($diff <= 2) { print "That's too close to your old password. Please try again.\n"; return 0; } } # Too short? Get progressively nastier. if (length($pass) < 6) { print "I SAID, " if $isaid++; print "Please use at least 6 characters.\n"; print "\nIf you persist I will log you out!\n\n" if $isaid == 3; print "\nI mean it!!\n\n" if $isaid == 4; print "\nThis is your last warning!!!\n\n" if $isaid == 5; if ($isaid == 6) { print "\nGoodbye!\n\n"; seek(STDIN,-100,0); # Induce indigestion in shell. exit 123; } return 0; } $isaid = 0; # run it through the pattern matcher.. if ( $pass =~/^[A-Z]*$/ ) { print "Only upper case strings are not allowed.\n"; return 0;} if ( $pass =~/^[a-z]*$/ ) { print "Only lower case letters can be easily cracked.\n"; return 0;} if ( $pass =~/^[a-zA-Z]*$/ ) { print "Only letters can be easily cracked.\n"; return 0;} if ( $pass =~/^\d+$/ ) { print "You need to have more than a random number\n"; return 0;} if ( $pass =~/^[a-z]*\d+$/ ) { print "Only lower case letters with a number can be easily cracked.\n"; return 0;} if ( $pass =~/^[A-Z]*\d+$/ ) { print "Only upper case letters with a number can be easily cracked.\n"; return 0;} if ( $pass =~/^\d+[a-z]*$/ ) { print "Numbers with lower case strings can be easily cracked.\n"; return 0;} if ( $pass =~/^\d+[A-Z]*$/ ) { print "Numbers with upper case strings can be easily cracked.\n"; return 0;} if ( $pass =~/^\d+[a-zA-Z]*$/ ) { print "Numbers with only letters can be easily cracked.\n"; return 0;} if ( $pass =~/^[a-zA-Z]*\d+$/ ) { print "Only letters followed a number can be easily cracked.\n"; return 0;} if ( $pass =~/^\d+[a-zA-Z]*\d+$/ ) { print "DOE prohibits use of numbers in the first and/or last location.\n"; return 0;} # Call cracklib routine -- Added by EMir(); $foo = fascist_check($pass, $dict); if ( $foo ne "ok" ) { print "$foo!\n"; return 0; } endif; if ($pass =~ /(ibm|dec|sun|at&t|nasa)/i) { print qq#A common substring such as "$1" makes your# . " password too easy to guess.\n"; return 0; } # Does it look like a date? if ($pass =~ m!^[-\d/]*$!) { if ($pass =~ m!^\d{3}-\d{2}-\d{4}$! || $pass =~ m!^\d\d\d\d\d\d\d\d\d$!) { print "Please don't use a Social Security Number!\n"; return 0; } if ($pass =~ m!^\d*/\d*/\d*$! || $pass =~ m!^\d*-\d*-\d*$! || $pass =~ m!$nyear$!) { print "Please don't use dates.\n"; return 0; } if ($pass =~ m!^\d\d\d-?\d\d\d\d$!) { print "Please don't use a phone number.\n"; return 0; } if ($pass =~ m!^\d{6,7}$!) { print "Please don't use a short number.\n"; return 0; } } # minor cleanup to get matched parens --gene if ($mo = ($pass =~ /^[ \d]*([a-zA-Z]{3,5})[ \d]*$/) && ($mo =~ /^(jan|feb|mar(ch)?|apr(il)?|may|june?|july?|aug|sept?|oct|nov|dec)$/i) ) { print "Please don't use dates.\n"; return 0; } # Login id? if ($pass =~ /$me/i) { print "Please don't use your login id.\n"; return 0; } # My own name? if ($pass =~ /$mynames/i) { print "Please don't use part of your name.\n"; return 0; } # My host name? if ($pass =~ /$host/i) { print "Please don't use your host name.\n"; return 0; } # License plate number? if ($pass =~ /^\d?[a-zA-Z][a-zA-Z][a-zA-Z]\d\d\d$/ || $pass =~ /^\d\d\d[a-zA-Z][a-zA-Z][a-zA-Z]$/) { print "Please don't use a license number.\n"; return 0; } # A function key? (This pattern checks Sun-style fn keys.) if ($pass =~ /^\033\[\d+/) { print "Please don't use a function key.\n"; return 0; } # A sequence of closely related ASCII characters? @ary = unpack('C*',$pass); $ok = 0; for ($i = 0; $i < $#ary; ++$i) { $diff = $ary[$i+1] - $ary[$i]; $ok = 1 if $diff > 1 || $diff < -1; } if (!$ok) { print "Please don't use sequences.\n"; return 0; } # A sequence of keyboard keys? ($foo = $pass) =~ y/A-Z/a-z/; $foo =~ y/qwertyuiop[]asdfghjkl;'zxcvbnm,.\//a-la-ka-j/; $foo =~ y/!@#\$%^&*()_+|~/abcdefghijklmn/; $foo =~ y/-1234567890=\\`/kabcdefghijlmn/; @ary = unpack('C*',$foo); $ok = 0; for ($i = 0; $i < $#ary; ++$i) { $diff = $ary[$i+1] - $ary[$i]; $ok = 1 if $diff > 1 || $diff < -1; } if (!$ok) { print "Please don't use consecutive keys.\n"; return 0; } # Repeated patterns: ababab, abcabc, abcdabcd if ( $pass =~ /^(..)\1\1/ || $pass =~ /^(...)\1/ || $pass =~ /^(....)\1/ ) { print "Please don't use repeated sequences of $1.\n"; return 0; } # Reversed patterns: abccba abcddcba if ( $pass =~ /^(.)(.)(.)\3\2\1/ || $pass =~ /^(.)(.)(.)(.)\4\3\2\1/ ) { print "Please don't use palindromic sequences of $1$2$3$4.\n"; return 0; } # Some other login name? if ($isalogin{$pass}) { print "Please don't use somebody's login id.\n"; return 0; } # A local host name? if (-f "/usr/hosts/$pass") { print "Please don't use a local host name.\n"; return 0; } # Reversed login id? $reverse = reverse $me; if ($pass =~ /$reverse/i) { print "Please don't use your login id spelled backwards.\n"; return 0; } 1; } sub cleanup { system 'stty', 'echo'; print "\n\nAborted.\n"; exit 1; } sub myexit { system 'stty', 'echo'; exit shift(@_); } 1; # getyp($user): Accepts a text string (the username) as its argument. # Searches the yp database for this name. # Returns a list of all the fields of the passwd entry, # or null if the entry does not exist. sub getyp { print "Inside getyp.\n" if $debug; local($user) = @_; print "Getting the user entry for $user.\n"; $match = `ypcat passwd | grep ${user}:`; @ypentry = split(/:/, `ypmatch $user passwd`) if($match); print "The returned entry is @ypentry.\n" if $debug; return @ypentry; } 1; sub get_new_pw { system 'stty', '-echo'; # Pick a password for (;;) { $goodenough = 0; until ($goodenough) { print "New password: "; chop($pass1 = ); print "\n"; do myexit(1) unless $pass1; print "(Checking for lousy passwords...)\n"; $goodenough = &goodenough($pass1); if ($goodenough eq 0) { print "Password is not acceptable, try again!\n"; } # If longer than 8 chars, check first 8 chars alone. if ($goodenough && length($pass1) > 8) { $pass8 = substr($pass1,0,8); print "(Rechecking first 8 characters...)\n"; unless ($goodenough = &goodenough($pass8)) { print "(Note that only the first 8 characters count.)\n"; } } }; print "Retype new passwd: "; chop($pass2 = ); print "\n"; last if ($pass1 eq $pass2); print "Password mismatch--try again.\n"; } system 'stty', 'echo'; } 1; sub shell_game { # we have the original shell in $shell # offer the options ( This takes care of what is legal ) $result = &im_prompt2("c", "Which shell would you like?", $shell_prompt, $shell, @legal_shells); if($shell eq $result){ print "\nLeaving shell unchanged.\n\n"; exit(0); } $shell = $result; #leave here so debugging statement doesn't lie - KMS $new_shell = $result; #so that it really changes in non-yp passwd file -KMS } 1; sub gecos_update { local($name, $where, $office, $home); local($ngcos, $nname, $nwhere, $noffice, $nhome, $ok); # we have the gcos field from $gcos print "Current gcos is: $gcos\n" if $debug; ($name, $where, $office, $home) = split (",", $gcos); $ok = "no"; while ( $ok eq 'no' ) { # print"NOTICE: To deter silly names, changes to gecos field are logged.\n\n"; $nname = &im_prompt2("x", "Please enter name:", "", $name); $nwhere = &im_prompt2("x", "Please enter Affiliation:", "", $where); $noffice = &im_prompt2("x", "Please enter Office phone:", "", $office); $nhome = &im_prompt2("x", "Please enter Home phone:", "", $home); print "\nName: $nname\nLocation: $nwhere\n"; print "Office phone: $noffice\nHome phone: $nhome\n"; $ok = &im_prompt2("i", "\nAre these values ok?", "Yes/no", "Yes", "yes","no" ); # safety check for ":" and 's in the password file. $ngcos = join(",", $nname, $nwhere, $noffice, $nhome); if ( $ngcos =~ /:/ || $ngcos =~ /\n/ ) { $ok = "no"; print "Invalid gcos entry! \":\" and are not allowed.\n"; } } # $subject = "$0: $me changing gecos field\n"; # $subject .= "Old: $gcos\n"; # $subject .= "New: $ngcos\n"; # `/usr/ucb/Mail -s "$subject" $accounts &`; $gcos = $ngcos; #so the debugging statement tells the truth -KMS $new_gcos = $ngcos; #so the new value gets written to passwd file -KMS } 1; ################################################################## # checkfile(file, string): Searches a file for any occurances # of the string specified. Matches are done in a case-insensitive # manner. # If an occurance exists, returns 1; otherwise, returns 0 sub checkfile { local($file, $string) = @_; local($line); if ( -f $file ) { open (FILE, "$file"); while ($line = ) { return 1 if( $line =~ /$string/i ); } } return 0; } # This perl subroutine will encrypt passwords # The use of the subroutine is: # $crypted = &encrypt_passwd( $plaintext, $salt ); # # --Mark Henderson # # Merged it with main anlpasswd program # -- EMir(); sub encrypt_passwd { local($user,$pass)=@_; local($nsalt,$week,$now,$pert1,$pert2); local(@salt_set)=('a'..'z','A'..'Z','0'..'9','.','/'); $now=time; ($pert1,$pert2) = unpack("C2",$user); $week = $now / (60*60*24*7) + $pert1 + $pert2; $nsalt = $salt_set[$week % 64] . $salt_set[$now %64]; return crypt($pass,$nsalt); } # This perl routine will take a prompt, a default response and a list of # possible responses and deal with the user interface, ( and the user! ), # by displaying the prompt, showing the default, and checking to be sure # that the response is one of the legal choices. # --Mark Henderson # # Additional "types" that could be added would be a phone type, # a social security type, a generic numeric pattern type... # The usage is the following: # x = don't care, a = alpha-only, n = numeric-only, i = ignore case # c = case sensitive, r = ranged by the low and high values # # $result = &prompt("x", "text prompt", "help prompt", "default" ); # # $result = &prompt("a", "text prompt", "help prompt", "default" ); # # $result = &prompt("n", "text prompt", "help prompt", "default" ); # # $result = &prompt("i", "text prompt", "help prompt", "default", # "legal_options-ignore-case-list"); # # $result = &prompt("c", "text prompt", "help prompt", "default", # "legal_options-case-sensitive-list"); # # $result = &prompt("r", "text prompt", "help prompt", "default", # "low", "high"); # # What, you might ask, is the difference between a "text prompt" and a # "help prompt"? Think about the case where the "legal_options" look # something like: "1-1000". Now consider what happens when you tell someone # that "0" is not between 1-1000 and that the possible choices are: :) # 1 2 3 4 5 ..... # This is what the "help prompt" is for. # It will work off of unique parts of "legal_options". sub im_prompt2 { local ($debug) = 0; # debugging local($mopt, $prompt, $prompt_options, $default, @things); local($repl, @match, $tmp, $match_options, $case, $low, $high); # Figure out just what we are doing here ($mopt) = @_; print "mopt is: $mopt\n" if $debug; # check the size of the match option, it should just have one char. die "Illegal call in im_prompt2 prompter." if ( length($mopt) > 1 ); WHAT: { # What sort of checking are we doing $type = 0; $legal = 0; $range = 0; if ( $mopt =~ /x/ || $mopt =~ /a/ || $mopt =~ /n/ ) { ($mopt, $prompt, $prompt_options, $default) = @_; $type = 1; last WHAT; } if ( $mopt =~ /c/ || $mopt =~ /i/ ) { ($mopt, $prompt, $prompt_options, $default, @things) = @_; $legal = 1; last WHAT; } if ( $mopt =~ /r/ ) { ($mopt, $prompt, $prompt_options, $default, $low, $high) = @_; $range = 1; last WHAT; } } $ok = 0; while (1) { # print out the prompt string in all it's gore print "$prompt "; if ( $prompt_options ne '' ) { print "($prompt_options) "; } print "[default $default] " if $default ne ''; $_ = scalar; chop; # nuke the s/^\s*//; # ignore leading white space s/\s*$//; # ignore trailing white space $_ = $default if $_ eq ''; if ($_ eq '') { print "Invalid option\n"; next; } print "Reply: '$_'\n" if $debug; $repl = $_; # Now here is where things get real interesting HOW: { if ( $type ) { &typeit; last HOW; } if ( $legal ) { &legalit; last HOW; } if ( $range ) { &rangeit; last HOW; } } if ( $ok ) { return $repl; } else { if ( $prompt_options ne '' ) { print "Options are:\n$prompt_options\n"; } } } sub rangeit { # this routine makes sure that the reply is within a given range if ( $low <= $repl && $repl <= $high ) { $ok = 1; } else { print "Invalid range value. "; } } sub legalit { # this routine checks to see if a repl is one of a set of "things" # it checks case based on c = case check, i = ignore case if ( $mopt eq "c" ) { @match = grep(/^$repl/, @things); # check w/case } else { @match = grep(/^$repl/i, @things); # check ignoring case } # this is to check for unique stings if they aren't at the beginning if ( @match == 0 ) { if ( $mopt eq "c" ) { @match = grep(/$repl/, @things); # check w/case } else { @match = grep(/$repl/i, @things); # check ignoring case } } print join(":", @match), "\n" if $debug; if (@match == 1) { $repl = $match[0]; $ok = 1; } elsif (@match == 0) { print "Invalid legal match. "; } else { foreach $tmp ( @match ) { print "testing $tmp for $repl.\n" if ($debug); $ok = 1 if ($tmp eq $repl); } if ( ! $ok ) { print "Ambiguous reply. "; } } } sub typeit { # this routine does checks based on the following: # x = no checks, a = alpha only, n = numeric only print "inside of typeit\n" if $debug; if ( $mopt eq "x" ) { $ok = 1; } if ( $mopt eq "a" ) { if ( $repl =~ /^[a-zA-Z]*$/ ) { $ok = 1; } else { print "Invalid type value. "; } } if ( $mopt eq "n" ) { if ( $repl =~/^[0-9]*$/ ) { $ok = 1; } else { print "Invalid numeric value. "; } } } } anlpasswd-3.0/c-routines/0040755000107400004570000000000007333613767014324 5ustar rackowsrcanlpasswd-3.0/c-routines/makefile0100644000107400004570000000070106562404353016007 0ustar rackowsrc# On gamma, add -Dsun # On anagram, add -Ddynix # For Solaris or SUNOS #CFLAGS = -g #LIBS = -lnsl -lrpcsvc # For Irix #CFLAGS = -cckr -Dsun -n32 #LIBS = -lrpcsvc # For Linux CFLAGS = -DLINUX LIBS = -lrpcsvc # For Aix #CFLAGS = -DAIX #LIBS = -lrpcsvc ##################### # End of config part# ##################### all: ypstuff clean: /bin/rm -f *.o suidwrap ypstuff ypstuff: ypstuff.o $(CC) $(CFLAGS) -o ypstuff ypstuff.o $(LIBS) anlpasswd-3.0/c-routines/ypstuff.c0100644000107400004570000000443706544211271016160 0ustar rackowsrc#include #include #include #ifndef LINUX #include #endif #include /* * Invoke the rpc call to argv[1]. Stdin should be, on separate lines, * the cleartext passwd, followed by the elements of the new passwd * struct. */ #define LINE_CLEAR 0 #define LINE_NAME 1 #define LINE_PASSWD 2 #define LINE_UID 3 #define LINE_GID 4 #define LINE_AGE 5 #define LINE_COMMENT 6 #define LINE_GECOS 7 #define LINE_DIR 8 #define LINE_SHELL 9 typedef char Line[100]; main(argc, argv) int argc; char **argv; { int rc, why; char *host, *s; Line lines[10]; int i; int ypport; struct yppasswd ypp; if (argc != 2) { printf("ERROR: args\n"); exit(1); } host = argv[1]; for (i = 0; i < 10; i++) { if (fgets(lines[i], sizeof(lines[i]), stdin) == NULL) { printf("ERROR: Short input\n"); exit(1); } if ((s = (char *) index(lines[i], '\n')) != NULL) *s = 0; } ypp.oldpass = lines[LINE_CLEAR]; ypp.newpw.pw_name = lines[LINE_NAME]; ypp.newpw.pw_passwd = lines[LINE_PASSWD]; ypp.newpw.pw_uid = atoi(lines[LINE_UID]); ypp.newpw.pw_gid = atoi(lines[LINE_GID]); #ifdef sun ypp.newpw.pw_age = lines[LINE_AGE]; #else #ifndef AIX #ifndef LINUX ypp.newpw.pw_quota = atoi(lines[LINE_AGE]); #endif #endif #endif #ifndef AIX #ifndef LINUX ypp.newpw.pw_comment = lines[LINE_COMMENT]; #endif #endif ypp.newpw.pw_gecos = lines[LINE_GECOS]; ypp.newpw.pw_dir = lines[LINE_DIR]; ypp.newpw.pw_shell = lines[LINE_SHELL]; if ((ypport = getrpcport(host, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP)) == 0) { printf("ERROR: %s is not running ypassswdd.\n", host); exit(1); } if (ypport >= IPPORT_RESERVED) { printf("ERROR: yppasswdd on %s not privleged.\n", host); exit(1); } rc = callrpc(host, YPPASSWDPROG, YPPASSWDVERS, YPPASSWDPROC_UPDATE, xdr_yppasswd, &ypp, xdr_int, &why); if (rc > 0) { #ifdef dynix printf("ERROR: callrpc failed: rc=%d Dynix won't decode\n", rc); #else printf("ERROR: callrpc failed: rc=%d %s\n", rc,clnt_sperrno(rc)); #endif exit(1); } if (why > 0) { printf("ERROR: callrpc failed: why=%d\n", why); exit(1); } printf("SUCCESS\n"); exit(0); } anlpasswd-3.0/Crypt-Cracklib-0.01.tar.gz0100644000107400004540000000571607333613630016725 0ustar rackowmcszJ_6Crypt-Cracklib-0.01.tarZ{sHϿ̧`r׼B 9ᖇpoBb%a{?u$vY^zz{z^y3 SV5ugܳLPU* v.vw{J P**Ϡ hiٲ l"*!ߑTx]lr/^KEJ1_zrڂDkR_\@![? K童RP' }Yx_jrd(_Q>UͪVI5NAЧvz|McV8-E+ͯ 6I,d{}x3BјC2 4%`wWs~cpx?4t ,I|ml0ճk;XgE c Sm%&3lb\8F@Y T 4Cm>k PuE[N8&[ZfʵMd/H&tuᣧ3Rv9CԫiZbtf IOj,̌ZrۉhDŽDf q`ոS!ɖM75떴O84Q(Z;C!I>o' -c~B _)˸aDFD COzǦvĂgˈaS7S,;R2 IW^$;X^Z$])8 v`(ϴMtJnuNx 8LTvJQ_ G]@)YE>ᔹfk0q{(Jpf}џ3Y?wqżvˈ ^!BTCN Z"qS(X30`Y׸@|\V6XhGUuY nX_"E3o8mnمT[,Jm+5!i\F W0J`$Z)\KU f"A,n-B}+4E b 굇Bo'em [#BP$uݰ8R׸e!3SNjp)5r'HWm. q+l"g'ALjH֩l)WSg^\.I**M;iW09OƒIk/:\&;ޜrlY96Vb NV 1cIO~ a53L;4ɱ< |kɳ $7j%b趬`cy6fPK!(8dg,h<zU[.kKHXpKkGY/4T*9ʲv ljm01S9"n-MYW8s]uG'+z:Aqz@JYqa-p`~ !HorG0 *O7wԁtq[V;<)艥r>*= ?}JK .Mxn-]=bQ*V'nEa:}*JK?:F#e--g:q 8")΅҇fgqW-08>p8x:Yn۹|ˇ2Z]>vy&s +{D|ZG" StDg)_mZ4Tz9IbgLАb/MJV7 HG\cx!Cn`4s,dWF3n`֥j+3H a %ozbc5 6CR(06. 3s(-۔~q?{R7N{e1Rn)36@ ׼ajo޲27ٺnh:Xq{]pa?:l|Z3^ُ<ޝt\m{nxo M{yۚ`?VݨSjMy%%{AhV?,kf5qC=P76Jl=Ρ@垄r?rOCnpo꾯U3AnO7q3m %6Nbz"`w?=LlIhe{'D; xU==c~oIUH$ˇ{bWqP? BYy7]2e+lZ'>87AHz!$^WoBj M/"'ΑJV< ȭE7^bspWzjPNJV^>f,s}&s7.hEcCJLf9MYdB{$$yZbU7W^RD>-8+`+9]i r8Q' ٤<{ ,M!i鰞2}Uj[idt\,&h0p=@> e=$b`.0],a ?r6HK_)3wQ /'e|ob6Q~BQAZl p=2G%a'Ob77~'ڷ:O$nGT vW'lgp1{s.·ɣ$]`qFn$BD]=b3/&("dnL4K^G qp}3h//uxe3͡  =2LF݆\]uva ٌsؖOb" M~pRS :L $Ǔh\] ƛ'صסo4R"!MC``Emg$>Á ᴂX=e4Z]\bu$yWdIьhVm{ a 6!Y/N\HRrJRz%-RxyY-p0J"Ӷ0~S/Q~,( +HǨsDG\*j?d@CՕ~0&t3f30}MCz]Yh#KWˆ[+{g4V&VN΋?1)OS谿ÏlY]ènd h/pX6A+|A0e)@1A ~"~%7p^@9#J;jig.wx5HZ%E-n^-q vx^$ C_ĉxbDT cQvS!Fgʛwx L͔>POz14:V&R c ۉBl|X Cb!喹aTXm=o iuE+Ŷ64<|fbC@sE$/1G+|Y9@;$ ZDք|az,'d䯵xDd2kz&l.w#X6܄CA³r-^PP_t,_: _gݜ N`RW[70^h睵9AX<¦B/E1+;V#Y[D I=mos}O޵5sz Ovo?2 '$RyH}-RPRߔ&J'A2 X}lWvq Hgl%SZlR&de~*i#Dݍ\wdmTHLnn.iż*\]/j*WUFY }d/G!mBj)& _pxT2KX.? QꃶT;I +9Ҕ0j))!+!E r^n2c,9>d-ޙgC|,2 {SJ*<u@Ѡhvk[ݖ1=Ԅ0D|-LS#X^ EVU`Np'NImc|sw:$ύ㳉!j|ʑf4KׅAlf7&~?8pG"Yu`4NVȓQ)풬CC)D(hHT ks {]nɉtb^ջS6X_M)q1 Bc x L]LrSUyPD'C0BJyvݯe%đMLȆ6uPQ |p9\͹vJrd0ky螪QAD@#b |}A=q"(l psIě[dRR]G "R,"C9&DoR²tz[_~B5W6:lLŏ)&nV̱ ĪfJZ#I^2dw`^U8><8my&` x+ޱ Q3i8`Wqq.ģYsٍ㗴ݶSݫ, -Tr`Rhj+$fS xv8HfL qA KoҘy_b$뤛7AF7"?ˮofy- ǧwZmJҐ8]ROI46/'eky. 1TMĖonG5%5Q[PjYjOnjZ `"$[Pߍ 6z`Cp7ٻh̀Ĝd=(MfS?V w'.)r)I{GܿV{~\zܤ62}awaՀ( y,B/OCb0**UfZ )l8M p@%+L[9<'eڡхi_&wu09;^cϽ\6?8 Xw#z.ӥY;$ϊ6YiArQS'aљM\ތǣaݳ~(}_92aZ+`&[eP-l$@"H| .-_%ܹOݒF#j .7)z`k}G%OUm4\wև|⼮AJ9KG}" Z-,Jr#εB,- Xz[ieo𿭿nu.zێ&KtvͲcS۩j?&ߩ>/bG<k0@GeI&t]r\ՇwCKHү^&~X1 VD ٺAQ@aD+>ҷz;uC:C2Y{;EumP)}DQ+ăΒQ9PU燳0,gw)fVS܂?u[p^FGLJYU}2#. @)f aR3Mo5B̒yNQ\"ѥ*Ctf]k\ԝ' -z(WS\)FWQ!&*,8h jdp8{vjp=:'/fo~k|sʰȷր|UHd>Jn>{)-SOD@}xi֟}S\]Nק× =걓\ȐuFO3s)оN,iAG3XO"p r MNξݐwTip=mh͋ (e8)K8>`gn4w@ wL9Iy{z1I4ZLk!|CnPs2ZFJjq. 6<`(tt'&dP ?įrty^XiJMgPZ=*O:}:l`YDv\MU4{}({[5>m9R P*G+:nۭA2ynuU:]﫺&Ht/ Aޥ+$US57+ ZQZ&Oip5w˃,%&+#u+?@`LwQL2ߢS't/J-E9Urn"N*/IWR&AA|}D;./ڗ7h_dD.jYL#BW:o4ĕ ˫2EffWw=F$4ISZ/s>%Y/+^adA%˜4*ZE(l·˺cCrۿGW)w闭^yy_D?q"B괶[M<%|;ȥr =|IcQ7>f&JIR3α9Xɛ[(j3qי`,jjDIUlʆ)ǕO%+o&mϙ5ufbɅx*Ze~1XGgh HgP Uޥך13rl♮4 nb'R:[slz,Mwu&F,xdRG2[`}7Mh,vIYu{\ h]",gX132MywxB]uINL02)vm{ި1jcL3TjE`D`:3`Ξ)j>yUI;ĶP@OC(b7Ii%BkhBgY( rA&~RٝβR?~wpY~:<5RWv>k-Z{7+٬&jv?_?SoR;ݓ#qxrtxШ !zkAY翛/ïeu};,!Vľw*0h6az.$ t^kj/Ot/P$*۸CI(Vؘ 4T#WHLtn 6rG0cXPKRKʛlt!FGuY ``[d3?cyPgZv-FS-{U\T׆2A#N[hRN;lC ͛ύ$@ ʰ6&hzc0YBH^ _a Qitly0SjYc_=vA!!V ^`(J >I?X#RGUfߧ;w zؤv+P٢Q}lW^ _IB΄$JxopnEE]y?E> Ygg)fƭpMWJc-\p5?a??2;Ol" ]Zڡv;T"Xe f&nnnbn?~wnǂRRqZe(b#Z,3;OTr q6$n>RHt&JDZϚXtN+=t3 i6ެHyӼH@ yɬ72c%yloFspM9c;y897j;on\"Q.5-ׯ[2wuܡQ[:m%4-jV_::EuQ'[PPǣ+Em[V# T\ Eqet CAYm5 q!;oګ6kK?"kâʞ#Q4:eE/Č^+($,ܮc5a`o+AӁy"Mj&ɲLԜ9[hkΕAX3'+"Js$r[ ePė;nRjkG_-bl,45~ĽcQG4!x稃jSycSy}_Tl'=UNVϬ\L#YDSAp}Oc(R<5& {!^ x`PD/vn!G𱢷TEp {HoЦ-ZQ(|#z5\FɃ*)zQ6~[},K bzs̖l1D :Ҵٴ^%6 ^F"?5|~lm7h!08TKy/yHIb gRE~CFD"͚hREtg"@971aNABHTo[xU%QJѺu5P99@_g swQr[q-+\_?+7=]GL'M ly,/)&~T[su x z>ԈqcrI9~~8pp|Mv;uK HQ(bDNYA1Z7$7PÇ1sS0~&0s8Y$S (2=TWJwfт)ε\3<6$" XTYὐ ҄jGcå?]G(PҖ:.PEv܀\zJAm 6GK>;9׸AbN=q^INT'Y4ԪT\EK '#|\]#ͥe,x $eG_|ufMfL!?H:C?Pgw9N+Fw#XNq;cC$FVBѹEwKLu@,4⊧^ɐVXTjןXRw>ۅQr3Q.]Ap(0}Jw,' o$ܐnْ8owPg4bIkqaRyyLa5}•d#2;ʚ87Y.u'K$$Ҧ'R9m]fϳO`f3((q# 0)!n{0tS` vNV\l|<;qڞ77vghS $v8~twXw~m}7:^ <$  Дn8D1.QxhAjCVq[(a|j&| `k;T,՞UjNf)ؚpX UDCne)elfѾ~J}듛=NX瞅W7G'ڻ&!= kBFM3/v ‡qmK%i9"B^ "OyGZ1سph0)H֬aSL,E 'S92upYݭHK]D4ojrv8 ëRO$Ƀ4SQ /;yd }3Mj"Zf(2Iֺ7(Si E9N d k6<7uIh~3Lo@%o1gא,i( BoMvL[8ƾ-X_8ߛ;hp2Vms 4$ҶTG] }zUBJy5%|D1jfm<~d@&DB/: 7TIؤukl@xE 3z=ڒjѴMb<>84w,ɸ_Ҝ EmS2hҾHnϷb N9xgg,`6oHO}׿%ҏt11U22ᎆ|.)ƆDTۙIfH!>=Obҷ21zifW3"N_ ot^ggJFӾЕ{E9b`-Db<|КQL-@/"*!yS/I{HZގ*%A+ۉX$g%*U|*L%۬R4&!CoĮ13gLo 6"F6NDňiXfYzt&qɰɗ19M K7K&ߒoIke л" U]p9؁Q.aSLHnYz2{)VqK[kR&Л@HHvKex8i߾ܚڗl9nIf L,Ԅ7)\U%12]*hr4c4j״cq=G BS'ICEbGde)K-4af'@@JWlRPM65m t[+!m[,dRܗ5" ?C]1e >7Ҋ&.#R 5tS2WfXEߟ_Eң5՘?S?UaͫEZta:+'k99_=@SQ4WQxEϦ0DKPx J/A%(dgixptW;?889;vX3scG׎Ln8 G;5e|PYx{'G;{uƲvw2{}rs YojǙ\'8y8`0~x]& yq&!k?5AQG%#F&[he{{; ("DG AF-R|-wz|fr!sx> 9>k*/+ y9Iend)mBE>ܤAG-<<} 2t^Ч^ԥE' uT!^!d6 (c1C4]Фq"@^m&6$4ETH;_<|rG`-&jUL 1_!l%6x!I;a|bpLCm{vu95 #^h]GÝ10g҇>oI.=;d5Ҙ4ñ?:bp0jA,Y7,$-<ۼ48  zڱ |糢,#nmvd3 Tp'rE){`afw@'KGQ}aQ;qst,ՎjQ)Ё:f )Ff ">wI;>3D\tD xUr., {jP\cJ*tI*\o}Ku۷jwκ_zGbzyTIR~th4T=1]-X=z){VQFVLɓ~/NnϿ˕ߢkl=I6 Y@P>|>.ŎՅp{îPD}PChiwK["ݎڧ[:7:>E=1bU1|Ӭ,qR9qLfٸK>8y?t/lƚ;\.$E*}J544q}}wO]2=}"w݄ qo?ߡg ,u]g>2j74(TBDmIVs [7mjZCݰ!'at&n^TR=ez@\YQjBJu ˛Az~oNYd^tRѐuvINːpȴWQ(zj=DҬ8<򉲕@}Ftj~M+".VfkwiD״")Z7ĭLLQ) rSV*ؼ_&"*rs}3@䞄9V2"Yb>ch>Jӧ ۡsH*4`6VMoTDiL*C?l3K0]߰N![?8jh~hv=kyl\(#؏g$n9hTΘg:͕\&&UWM`3DLH$^VȻ2UqIRXPWX|l"֗W87kG._ř!}oFŀ?:O0Vtٟ(*{ Uz:?٣#LMH+;ukH_"$_OIY7 R,9-匩Z2JvFMw2LW|GRNKaפ'VÊZqèLRI r/lf$8˰|;1*7{5-QKC~T,AyI߆΁oU6//D勖ј3/(R_y$L~*~ ׄ6}ɶ\t#Ivxy8 _f[zԯ]*o=@xn>֜\[n^haД\"Wȭvqf%6Ԩqo/5{%p\%Ẹ6335& D7)|: {³*}7=.ȰanO8I2u2c2h{#=0ƴ .Enzm01s9{mh#*V#0h5 嫳a ޕȍ87XvgDaȃ\CZхGaSc^aKW?&2p*ՖlNk{@ c{0{eąHB${ McXZ<(g>y$Xoʏ wN!¢5JnU s k(y3gzJfl|U(UJ"ΜEsn0#$S,9"$>}RvzW6'F#7=ቱs;h3" ,D4RD[>J'%aS};EA)&ME)l)L};D`SEJvK}SX77c!vh<%q_mg`kvo,㫓;gDy*9ov6E@zщk+<|yhbt!8U<~dJz<繃*E#M7`Ї߿7jlUf?Z^r{+M2F=Y;pk?&Blū|E/.}A B_|V][{n}\{n}Smѡ7/a--`942/;A0,`OĂ"č!h@Oaəli7޳1ny[]3z(h4uoh!u_gf\Ǒ+ D> FcI`yHOw"#kQ9؏~ _0W*k _3C8nry&f*!1t) tV2^rS,D/.VAThE ͚)?ST^5V1S_Zzx 7[(L/?ޢG[Y1홯qK6Y\]]-9 s*vyfsܨ)lEk;s&bnE^@,ӎƳxx-mG@ 5xn]](I‹q.*n D0TYZUabaJMxlW[_YVVcR^n6v͢!Ƒ? 4DFs-G""RIg&(mڲI;2ϵ0/C{Bxk̶*mcpayXn0Z>!oZy;JAD:)?z/붃}ʘk/.W5Gkݽ[T6*Xb_tR];6H-Νu!+˴/a+;>\v&K|sof\-d1ȍ: `4 PBR;:i.x} Aɨ_6/d늶' _ @B䏗.F^e^.#|{.Wf+T(M fT .sVEc$QyeϻznQ&ڦ> e9>HTZ]_Mqfduc8~08C, Cy(8|#?1[0iy Ide&7+ pW.3;/ݍK~Ӓk7.YQ% #kdzz9-5l [VT`л#ЋupOz".@Үh¿hWzT:Ǡ/fP[\P& uE|'5;N kM@@Ӟ1Y74Vj2V >i֚N;+ ІJj8Aٗ7F"It., <+,`5.YL"#`z/B\;` ]e`)/?l ΟGM̗͍feu!gW})y-ӿTY:ځEBkm{Aj:-3a@)\!Qo6], !r(A1Ed~;+a>;~dYœ5) K[[ay)Q j]AF=ۨUZϻT?,f(2 텠բZ]S<  tDJt܋PW!4[!Q!W'6+K;Go'k&G )mGSK/.PO+zŨL( yqH)4lz 02{eҙ T =i4NOjY|aQ0="=Vdf- :9).pHuȿ֩`⑹B'GwWY#1%Iኂ<ȻA2񚈮½]h 5Hqp(t5~ YxcXc{t(*("1f0 R?fc 0flpɾ } ]b7,sAlIub՝XJ|Kim˕I r`ؒ8 @wI_is%ǒ5L(rjz[DRrFfL"wߺU'M=ӊ_OB=0i,~SZ3lxt= l0).--*kei=KY&L E?$ `;4 1ҒESj?M~S2yG%V}Ďx P{}nT0C;r2!b9pq뜙vb?G+>wm:j dc<G1Ż^GW;;7WlFɘ96?7dnm,=imdQq6$*g&6INʑŦ+נ7E Mu"Y &:weffoʸZ(66K2<$ OK>%bRa-OAv*'!1@g@:z0 TX|Ј~@K((J{yDX,G%*Q }-|ZW OBd~?P!"RӀhZ7 B!et0ʸ ӭ7VH8ߟ ˛&;z1pݱa>w-3, YH0dp[]oD>;WRr WM96Iךx) K!\+Nlz# 663FՁf v ^@Od!8\*T#Ղ ;jx OUx֕aHU5[W-|rjՆO ~ ϳ7 79㜳)/zRͅOk&Y좠==1 O?oYγhM({3ӡNv v$*' 3wsIJˢpFȞDT?G/g]aeja4[ Mʝ&xܖ )|`9a\4ϥ [xy- _Ělt2{#YBe !1sIoB'ϳ)d|YSZ !*Rovcq?+vu"TAK ?GWJ!;n.-^|MbEA*oV///uiVNQ̑@d=O=Q-CnEHD+; dQdk'aUEU-$Ȗg?aZLX;l '8/0QrLkdlGh;d?oܫԑEVatZod 'h ~ċ-^򭇜٧_0X'^lP\̓=Y-_?E\&C7S{$m"oo(xx%^,Z/cd5̊f X/Z7L/?GW=w?l%bKoy},E&3ش!6z{Kbk 卌nӻY-v@B>#DH2bв@ut@n(;tŷ]%.Y"CVsNR^~ModS٨bc_q( kl+=|ػ  ka ,4ŸB.iɱC^jCQ{̺q5#l{6d8:#O,`R?+a8/V7Yt[0`Aq(bd`qBY$p2yjk]gD !Ap hN Z0>HקU2fLKI!4Hp%UXZ~#t$*ۍ2In#SR;GB"E}ٜ1~yE50FO: ! RDBWę|bȯxyÃq=_YیZX<ȟEĈ@ #%98Y^E2Ƨa U1  =Gw ȧZ/| Z鴂IMX7d,~  G  @X0XJ!4(: RXՐ߰ aH#272Ġ_0)FU-- ggl#5 q%0E1L;uz3.fpM(Ɵ`B@ qM7ć^UvdGY="Fx{WG;G?c2IA e(ρEY#03Y9"&錥Js%Ez;tpRwӡL -wŠHQ4ѱ>J tHf!#FҖ;E=s=q98?>|}s\?دD 3 h+ P 6 {"#@錂 Y)C wVUO!cW"4U!y1q`fX]>`ou&=}(PVS ./anlpasswd ypcat passwd | grep # again to see that it worked. MCS Systems Group Mathematics & Computer Science Division Argonne National Laboratory Argonne, Illinois Email: systems@mcs.anl.gov