--- loncom/lcpasswd 2001/11/15 18:34:57 1.13 +++ loncom/lcpasswd 2010/10/12 10:33:47 1.22 @@ -1,17 +1,13 @@ #!/usr/bin/perl - # The Learning Online Network with CAPA # # lcpasswd - LON-CAPA setuid script to synchronously change all # filesystem-related passwords (samba, unix, etc) # -# YEAR=2000 -# 10/27,10/28,10/29,10/30 Scott Harrison -# -# YEAR=2001 -# 10/22,10/23,11/13,11/15 Scott Harrison +# YEAR=2002 +# 02/19 Matthew Hall # -# $Id: lcpasswd,v 1.13 2001/11/15 18:34:57 harris41 Exp $ +# $Id: lcpasswd,v 1.22 2010/10/12 10:33:47 foxr Exp $ ### ############################################################################### @@ -44,7 +40,7 @@ use strict; # # Standard input usage # First line is USERNAME -# Second line is CURRENT PASSWORD +# Second line is NEW PASSWORD # Third line is NEW PASSWORD # # Valid passwords must consist of the @@ -92,17 +88,19 @@ delete @ENV{qw(IFS CDPATH ENV BASH_ENV)} # Do not print error messages my $noprint=1; +print "In lcpasswd" unless $noprint; + # ----------------------------- Make sure this process is running from user=www my $wwwid=getpwnam('www'); -&disable_root_capability; -if ($wwwid!=$>) { + +if ($wwwid!=$<) { print("User ID mismatch. This program must be run as user 'www'\n") unless $noprint; exit 1; } # ----------------------------------- Start running script with www permissions -&disable_root_capability; + # --------------------------- Handle case of another lcpasswd process (locking) unless (&try_to_lock('/tmp/lock_lcpasswd')) { @@ -120,7 +118,7 @@ if (@input!=3) { unlink('/tmp/lock_lcpasswd'); exit 3; } -map {chomp} @input; +foreach (@input) {chomp;} my ($username,$password1,$password2)=@input; $username=~/^(\w+)$/; @@ -131,8 +129,8 @@ if (($username ne $safeusername) or ($sa exit 9; } my $pbad=0; -map {if (($_<32)&&($_>126)){$pbad=1;}} (split(//,$password1)); -map {if (($_<32)&&($_>126)){$pbad=1;}} (split(//,$password2)); +foreach (split(//,$password1)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}} +foreach (split(//,$password2)) {if ((ord($_)<32)||(ord($_)>126)){$pbad=1;}} if ($pbad) { print "Error. A password entry had an invalid character.\n"; unlink('/tmp/lock_lcpasswd'); @@ -152,14 +150,18 @@ unless(getpwnam($safeusername)) { unlink('/tmp/lock_lcpasswd'); exit 5; } - &enable_root_capability; ($>,$<)=(0,0); + +print "Now $> , $< , -invoking pwchange with $safeusername $password1" + unless $noprint; open OUT,"|pwchange $safeusername"; print OUT $password1; print OUT "\n"; close OUT; -($>,$<)=(0,500); +($>,$<)=(0,$wwwid); + +print "pwchange done, back to uid $wwwid" unless $noprint; if ($?) { exit 8; @@ -170,45 +172,33 @@ if (-e '/usr/bin/smbpasswd') { ($>,$<)=(0,0); # fool smbpasswd here to think this is not a setuid # environment - unless (-e '/etc/smbpasswd') { - open (OUT,'>/etc/smbpasswd'); close OUT; - } - my $smbexist=0; - open (IN, '; - close IN; - for my $l (@lines) { - chop $l; - my @F=split(/\:/,$l); - if ($F[0] eq $username) {$smbexist=1;} - } - unless ($smbexist) { - open(OUT,'>>/etc/smbpasswd'); - print OUT join(':',($safeusername,$userid, - 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX:XXXXXXXXXXXXXX'. - 'XXXXXXXXXXXXXXXXXX','','/home/'.$safeusername, - '/bin/bash')) . "\n"; - close OUT; - } +# If the -a switch is put on the smbpasswd +# command line, either a new entry will be created or the old one +# will be used. +# Therefore the old strategy of looking for and adding a dummy entry is +# not needed... Finally, the smbpasswd file is in /etc/samba not +# /etc/smbpasswd as older versions of the script implied. - open(OUT,"|/usr/bin/smbpasswd -s $safeusername>/dev/null") or + print "Running smbpasswd" unless $noprint; + open(OUT,"|/usr/bin/smbpasswd -s -a $safeusername>/dev/null") or die('cannot run smbpasswd'); print OUT $password2; print OUT "\n"; print OUT $password2; print OUT "\n"; close OUT; $<=$wwwid; # unfool the program + print "smbpasswd done" unless $noprint; } -&disable_root_capability; + unlink('/tmp/lock_lcpasswd'); exit 0; # ---------------------------------------------- have setuid script run as root sub enable_root_capability { if ($wwwid==$>) { - ($<,$>)=($>,$<); - ($(,$))=($),$(); + ($<,$>)=($>,0); + ($(,$))=($),0); } else { # root capability is already enabled @@ -232,10 +222,7 @@ sub try_to_lock { my ($lockfile)=@_; my $currentpid; my $lastpid; - # Do not manipulate lock file as root - if ($>==0) { - return 0; - } + # Try to generate lock file. # Wait 3 seconds. If same process id is in # lock file, then assume lock file is stale, and