File:  [LON-CAPA] / loncom / lcuserdel
Revision 1.3: download - view: text, annotated - select for diffs
Sat Oct 28 18:25:47 2000 UTC (23 years, 6 months ago) by harris41
Branches: MAIN
CVS tags: HEAD
changing around the initiation of process locking (no longer locking
for just smbpasswd), adding comments, beginning to further implement lcuserdel.
still trying to capture error condition of unsuccessfully opening /etc/passwd
-Scott

    1: #!/usr/bin/perl
    2: #
    3: # lcuserdel
    4: #
    5: # Scott Harrison
    6: # October 27, 2000
    7: # October 28, 2000
    8: 
    9: use strict;
   10: 
   11: # This script is a setuid script (chmod 6755) that should
   12: # be run by user 'www'.  It DOES NOT delete directories.
   13: # All it does is remove a user's entries from
   14: # /etc/passwd, /etc/groups, and /etc/smbpasswd.
   15: 
   16: # This script works under the same process control mechanism
   17: # as lcuseradd and lcpasswd, to make sure that only one of these
   18: # processes is running at any one time on the system.
   19: 
   20: # Standard input usage
   21: # First line is USERNAME
   22: 
   23: # Command-line arguments [USERNAME]
   24: # Yes, but be very careful here (don't pass shell commands)
   25: # and this is only supported to allow perl-system calls.
   26: 
   27: # Usage within code
   28: #
   29: # $exitcode=system("/home/httpd/perl/lcuserdel","NAME")/256;
   30: # print "uh-oh" if $exitcode;
   31: 
   32: # These are the exit codes.
   33: 
   34: # Security
   35: $ENV{'PATH'}=""; # Nullify path information.
   36: $ENV{'BASH_ENV'}=""; # Nullify shell environment information.
   37: 
   38: # Do not print error messages if there are command-line arguments
   39: my $noprint=0;
   40: if (@ARGV) {
   41:     $noprint=1;
   42: }
   43: 
   44: # Read in /etc/passwd, and make sure this process is running from user=www
   45: open (IN, "</etc/passwd");
   46: my @lines=<IN>;
   47: close IN;
   48: my $wwwid;
   49: for my $l (@lines) {
   50:     chop $l;
   51:     my @F=split(/\:/,$l);
   52:     if ($F[0] eq 'www') {$wwwid=$F[2];}
   53: }
   54: if ($wwwid!=$<) {
   55:     print("User ID mismatch.  This program must be run as user 'www'\n") unless $noprint;
   56:     exit 1;
   57: }
   58: &disable_root_capability;
   59: 
   60: # Handle case of another lcpasswd process
   61: unless (&try_to_lock("/tmp/lock_lcpasswd")) {
   62:     print "Error. Too many other simultaneous password change requests being made.\n" unless $noprint;
   63:     exit 4;
   64: }
   65: 
   66: # Gather input.  Should only be 1 value (user name).
   67: my @input;
   68: if (@ARGV==1) {
   69:     @input=@ARGV;
   70: }
   71: elsif (@ARGV) {
   72:     print("Error. This program needs just 1 command-line argument (username).\n") unless $noprint;
   73:     exit 2;
   74: }
   75: else {
   76:     @input=<>;
   77:     if (@input!=1) {
   78: 	print("Error. Only one line should be entered into standard input.\n") unless $noprint;
   79: 	exit 3;
   80:     }
   81:     map {chop} @input;
   82: }
   83: 
   84: &disable_root_capability;
   85: unlink("/tmp/lock_lcpasswd");
   86: exit 0;
   87: 
   88: # ----------------------------------------------------------- have setuid script run as root
   89: sub enable_root_capability {
   90:     if ($wwwid==$>) {
   91: 	($<,$>)=($>,$<);
   92: 	($(,$))=($),$();
   93:     }
   94:     else {
   95: 	# root capability is already enabled
   96:     }
   97:     return $>;
   98: }
   99: 
  100: # ----------------------------------------------------------- have setuid script run as www
  101: sub disable_root_capability {
  102:     if ($wwwid==$<) {
  103: 	($<,$>)=($>,$<);
  104: 	($(,$))=($),$();
  105:     }
  106:     else {
  107: 	# root capability is already disabled
  108:     }
  109: }
  110: 
  111: # ----------------------------------- make sure that another lcpasswd process isn't running
  112: sub try_to_lock {
  113:     my ($lockfile)=@_;
  114:     my $currentpid;
  115:     my $lastpid;
  116:     # Do not manipulate lock file as root
  117:     if ($>==0) {
  118: 	return 0;
  119:     }
  120:     # Try to generate lock file.
  121:     # Wait 3 seconds.  If same process id is in
  122:     # lock file, then assume lock file is stale, and
  123:     # go ahead.  If process id's fluctuate, try
  124:     # for a maximum of 10 times.
  125:     for (0..10) {
  126: 	if (-e $lockfile) {
  127: 	    open(LOCK,"<$lockfile");
  128: 	    $currentpid=<LOCK>;
  129: 	    close LOCK;
  130: 	    if ($currentpid==$lastpid) {
  131: 		last;
  132: 	    }
  133: 	    sleep 3;
  134: 	    $lastpid=$currentpid;
  135: 	}
  136: 	else {
  137: 	    last;
  138: 	}
  139: 	if ($_==10) {
  140: 	    return 0;
  141: 	}
  142:     }
  143:     open(LOCK,">$lockfile");
  144:     print LOCK $$;
  145:     close LOCK;
  146:     return 1;
  147: }
  148: 
  149: 

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