From: Jos Backus To: djb-qmailbeta@koobera.math.uic.edu Subject: mkpoppass/chkpoppass Date: Mon, 05 Aug 1996 09:58:13 +0200 Hi Dan, all, Not sure whether this is useful to anybody, but I thought I'd make a contribution of sorts. chkpoppass can be used instead of checkpassword. #!/usr/local/bin/perl # mkpoppass -- pop passwd file maintenance hack # 30 july 1996 # jos@oce.nl $mailhome = "/var/qmail/mailhome"; $passwdfile = "$mailhome/poppasswd"; sub makenewpasswd { my $passwd = shift; srand(time ^ $$); @saltchars=('a'..'z','A'..'Z',0..9,'.','/'); $salt =$saltchars[int(rand($#saltchars+1))]; $salt.=$saltchars[int(rand($#saltchars+1))]; $cpw=crypt($passwd,$salt); $cpw=crypt($passwd,$cpw); } { last unless $ARGV[0] =~ /^-/; $_ = shift; $check++, redo if /-c/; $delete++, redo if /-d/; $quiet++, redo if /-q/; $edit++, redo if /-e/; $passwdfile = shift, redo if /-f/; die "bad flag: $_"; } $view = @ARGV == 0; $new_user = shift; $new_passwd = shift; if ($edit) { $editcmd = $ENV{"EDITOR"} || "vi"; $editcmd .= " -c /$new_user" if $new_user; $editcmd .= " $passwdfile"; system $editcmd; exit $?; } if (!$view&&!$check) { if (!$new_passwd) { print "Password for $new_user: "; chop($new_passwd=); } } $found = 0; open PASSWD,$passwdfile or die; while () { if (/\s*#/ or /^\s*$/) { # keep comments/empty lines push @lines, $_; next; } chomp; ($user,$passwd) = split /\s*:\s*/; if ($user eq $new_user) { $found = 1; if ($delete) { $writefile = 1; next; } if ($check) { last; } else { $writefile = 1; $passwd = makenewpasswd $new_passwd; } } push @lines,"$user:$passwd\n"; } close PASSWD; if ($view) { for (@lines) { print; } exit 0; } if ($check) { if ($found) { $c = crypt($new_passwd,$passwd); #print "$user: old '$passwd', new '$c'\n" if !$quiet; $ok = ($passwd eq $c); print $ok ? "ok" : "error","\n"; exit !$ok; } else { die "user $new_user not in passwd file!\n"; } } if (!$found) { # new user $user = $new_user; $passwd = makenewpasswd $new_passwd; push @lines,"$user:$passwd\n"; $writefile = 1; } if ($writefile) { rename $passwdfile,"$passwdfile.bak" if -f $passwdfile; open PASSWD,">$passwdfile" or die "Can't write $passwdfile: $!\n"; for (@lines) { print PASSWD; } close PASSWD; print "Wrote ",scalar @lines," lines to $passwdfile\n" if !$quiet; } #!/usr/local/bin/perl # chkpoppass -- check pop password, setup and call qmail-pop3d if OK # 30 july 1996 # jos@oce.nl $mailhome = "/var/qmail/mailhome"; $poppasswdfile = "$mailhome/poppasswd"; $shell = '/bin/sh'; $user_program = shift || die "need a program to run!\n"; open X,"<&=3" or exit 111; $_ = ; ($user,$passwd) = /^(.*)\0(.*)\0/; close X; $found=$user&&$passwd; sub poppasswd { my ($sent_user,$sent_passwd) = @_; local($user,$passwd); $found = 0; open PASSWD,$poppasswdfile or exit 111; while () { next if /\s*#/ or /^\s*$/; chomp; ($user,$passwd) = split /\s*:\s*/; next if $user ne $sent_user; if ($passwd eq crypt($sent_passwd,$passwd)) { $found = 1; last; } } close PASSWD; return $found; } sub etcpasswd { my ($sent_user,$sent_passwd) = (@_); local($user,$passwd); ($user,$passwd,$uid,$gid,$quota,$comment,$gecos,$dir,$shell) = getpwnam($sent_user); $found = ($user and $passwd eq crypt($sent_passwd,$passwd)); return $found; } if ($found) { if (poppasswd $user,$passwd) { $home="$mailhome/$user"; $found=1; } elsif (etcpasswd $user,$passwd) { $home="$dir"; $found=1;} } if ($found) { $ENV{"SHELL"} = $shell; $ENV{"USER"} = $user; $ENV{"HOME"} = $home; chdir $ENV{"HOME"} or exit 111; exec $user_program, @ARGV; } exit 2; Groetjes, Jos -- Jos Backus _/ _/_/_/ R-IS/SNB _/ _/ _/ Oce-Nederland B.V. _/ _/_/_/ Venlo, The Netherlands _/ _/ _/ _/ jos@oce.nl _/_/ _/_/_/ #include .