Annotation of loncom/lcpasswd, revision 1.1

1.1     ! harris41    1: #!/usr/bin/perl
        !             2: 
        !             3: use strict;
        !             4: 
        !             5: # Scott Harrison
        !             6: # October 27, 2000
        !             7: 
        !             8: # This script is a setuid script that should
        !             9: # be run by user 'www'.
        !            10: 
        !            11: # Standard input usage
        !            12: # First line is USERNAME
        !            13: # Second line is CURRENT PASSWORD
        !            14: # Third line is NEW PASSWORD
        !            15: 
        !            16: # Security
        !            17: $ENV{'PATH'}=""; # Nullify path information.
        !            18: $ENV{'BASH_ENV'}=""; # Nullify shell environment information.
        !            19: 
        !            20: open (IN, "</etc/passwd");
        !            21: my @lines=<IN>;
        !            22: close IN;
        !            23: my $wwwid;
        !            24: for my $l (@lines) {
        !            25:     chop $l;
        !            26:     my @F=split(/\:/,$l);
        !            27:     if ($F[0] eq 'www') {$wwwid=$F[2];}
        !            28: }
        !            29: if ($wwwid!=$<) {
        !            30:     print("User ID mismatch.  This program must be run as user 'www'\n");
        !            31:     exit 0;
        !            32: }
        !            33: if (@ARGV) {
        !            34:     print("Error. This program does not accept command-line arguments.\n");
        !            35:     exit 0;
        !            36: }
        !            37: 
        !            38: # Gather input from standard input.  Should only be 3 lines.
        !            39: my @input=<>;
        !            40: if (@input!=3) {
        !            41:     print("Error. Three lines need to be entered into standard input.\n");
        !            42:     exit 0;
        !            43: }
        !            44: 
        !            45: # Handle case of another lcpasswd process
        !            46: unless (&try_to_lock("/tmp/lock_lcpasswd")) {
        !            47:     print "Error. Too many other simultaneous password change requests being made.\n";
        !            48:     exit 0;
        !            49: }
        !            50: 
        !            51: my ($username,$oldpwd,$newpwd)=map {chop; $_} @input;
        !            52: 
        !            53: # Grab the line corresponding to username
        !            54: my ($userid,$useroldcryptpwd);
        !            55: my @F; my @U;
        !            56: for my $l (@lines) {
        !            57:     @F=split(/\:/,$l);
        !            58:     if ($F[0] eq $username) {($userid,$useroldcryptpwd)=($F[2],$F[1]); @U=@F;}
        !            59: }
        !            60: 
        !            61: # Verify existence of user
        !            62: if (!defined($userid)) {
        !            63:     print "Error. User $username does not exist.\n";
        !            64:     exit 0;
        !            65: }
        !            66: 
        !            67: # Verify password entry
        !            68: if (crypt($oldpwd,$useroldcryptpwd) ne $useroldcryptpwd) {
        !            69:     print "Error. Invalid entry of current password.\n";
        !            70:     exit 0;
        !            71: }
        !            72: 
        !            73: # Construct new password entry
        !            74: my $newcryptpwd=crypt($newpwd,$newpwd);
        !            75: $U[1]=$newcryptpwd;
        !            76: my $userline=join(":",@U);
        !            77: print $newcryptpwd;
        !            78: print $userline;
        !            79: #my $rootid=&enable_root_capability;
        !            80: #if ($rootid!=0) {
        !            81: #    print "Error.  Root was not successfully enabled.\n";
        !            82: #    exit 0;
        !            83: #}
        !            84: # open SAMBAPASSWORDFILE, ">/etc/smbpasswd";
        !            85: 	($<,$>)=($>,$<);
        !            86: 	($(,$))=($),$();
        !            87: open PASSWORDFILE, "/tmp/passwd2" or die("Cannot open /etc/passwd!");
        !            88: for my $l (@lines) {
        !            89:     @F=split(/\:/,$l);
        !            90:     if ($F[0] eq $username) {print PASSWORDFILE "$userline\n";}
        !            91:     else {print PASSWORDFILE "$l\n";}
        !            92: }
        !            93: close PASSWORDFILE;
        !            94: # close SAMBAPASSWORDFILE;
        !            95: &disable_root_capability;
        !            96: unlink("/tmp/lock_lcpasswd");
        !            97: 
        !            98: sub enable_root_capability {
        !            99:     if ($wwwid==$<) {
        !           100: 	($<,$>)=($>,$<);
        !           101: 	($(,$))=($),$();
        !           102:     }
        !           103:     else {
        !           104: 	# root capability is already enabled
        !           105:     }
        !           106:     return $<;
        !           107: }
        !           108: 
        !           109: sub disable_root_capability {
        !           110:     if ($wwwid==$>) {
        !           111: 	($<,$>)=($>,$<);
        !           112: 	($(,$))=($),$();
        !           113:     }
        !           114:     else {
        !           115: 	# root capability is already disabled
        !           116:     }
        !           117: }
        !           118: 
        !           119: sub try_to_lock {
        !           120:     my ($lockfile)=@_;
        !           121:     my $currentpid;
        !           122:     my $lastpid;
        !           123:     for (0..10) {
        !           124: 	if (-e $lockfile) {
        !           125: 	    open(LOCK,"<$lockfile");
        !           126: 	    $currentpid=<LOCK>;
        !           127: 	    close LOCK;
        !           128: 	    if ($currentpid==$lastpid) {
        !           129: 		last;
        !           130: 	    }
        !           131: 	    sleep 3;
        !           132: 	    $lastpid=$currentpid;
        !           133: 	}
        !           134: 	else {
        !           135: 	    last;
        !           136: 	}
        !           137: 	if ($_==10) {
        !           138: 	    return 0;
        !           139: 	}
        !           140:     }
        !           141:     open(LOCK,">$lockfile");
        !           142:     print LOCK $$;
        !           143:     close LOCK;
        !           144:     return 1;
        !           145: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>