File:  [LON-CAPA] / loncom / lcuserdel
Revision 1.15: download - view: text, annotated - select for diffs
Mon Feb 3 18:03:52 2003 UTC (21 years, 3 months ago) by harris41
Branches: MAIN
CVS tags: version_2_5_X, version_2_5_2, version_2_5_1, version_2_5_0, version_2_4_X, version_2_4_99_0, version_2_4_2, version_2_4_1, version_2_4_0, version_2_3_X, version_2_3_99_0, version_2_3_2, version_2_3_1, version_2_3_0, version_2_2_X, version_2_2_99_1, version_2_2_99_0, version_2_2_2, version_2_2_1, version_2_2_0, version_2_1_X, version_2_1_99_3, version_2_1_99_2, version_2_1_99_1, version_2_1_99_0, version_2_1_3, version_2_1_2, version_2_1_1, version_2_1_0, version_2_0_X, version_2_0_99_1, version_2_0_2, version_2_0_1, version_2_0_0, version_1_99_3, version_1_99_2, version_1_99_1_tmcc, version_1_99_1, version_1_99_0_tmcc, version_1_99_0, version_1_3_X, version_1_3_3, version_1_3_2, version_1_3_1, version_1_3_0, version_1_2_X, version_1_2_99_1, version_1_2_99_0, version_1_2_1, version_1_2_0, version_1_1_X, version_1_1_99_5, version_1_1_99_4, version_1_1_99_3, version_1_1_99_2, version_1_1_99_1, version_1_1_99_0, version_1_1_3, version_1_1_2, version_1_1_1, version_1_1_0, version_1_0_99_3, version_1_0_99_2, version_1_0_99_1, version_1_0_99, version_1_0_3, version_1_0_2, version_1_0_1, version_1_0_0, version_0_99_5, version_0_99_4, version_0_99_3, version_0_99_2, version_0_99_1, version_0_99_0, conference_2003, HEAD
best wishes to all.

    1: #!/usr/bin/perl
    2: #
    3: # lcuserdel
    4: #
    5: 
    6: use strict;
    7: 
    8: # This script is a setuid script (chmod 6755) that should
    9: # be run by user 'www'.  It DOES NOT delete directories.
   10: # All it does is remove a user's entries from
   11: # /etc/passwd, /etc/groups, and /etc/smbpasswd.
   12: # It also disables user directory access by making the directory
   13: # to be owned by user=www (as opposed to the former "username").
   14: # This command only returns an error if it is
   15: # invoked incorrectly (by passing bad command-line arguments, etc).
   16: 
   17: # This script works under the same process control mechanism
   18: # as lcuseradd and lcpasswd, to make sure that only one of these
   19: # processes is running at any one time on the system.
   20: 
   21: # Standard input usage
   22: # First line is USERNAME
   23: 
   24: # Valid user names must consist of ascii
   25: # characters that are alphabetical characters
   26: # (A-Z,a-z), numeric (0-9), or the underscore
   27: # mark (_). (Essentially, the perl regex \w).
   28: 
   29: # Command-line arguments [USERNAME]
   30: # Yes, but be very careful here (don't pass shell commands)
   31: # and this is only supported to allow perl-system calls.
   32: 
   33: # Usage within code
   34: #
   35: # $exitcode=system("/home/httpd/perl/lcuserdel","NAME")/256;
   36: # print "uh-oh" if $exitcode;
   37: 
   38: # These are the exit codes.
   39: # ( (0,"ok"),
   40: #   (1,"User ID mismatch.  This program must be run as user 'www'"),
   41: #   (2,"Error. This program needs just 1 command-line argument (username).") )
   42: #   (3,"Error. Only one line should be entered into standard input."),
   43: #   (4,"Error. Too many other simultaneous password change requests being made."),
   44: #   (5,"Error. The user name specified has invalid characters.") )
   45: 
   46: # Security
   47: $ENV{'PATH'}=""; # Nullify path information.
   48: $ENV{'BASH_ENV'}=""; # Nullify shell environment information.
   49: 
   50: # Do not print error messages if there are command-line arguments
   51: my $noprint=0;
   52: if (@ARGV) {
   53:     $noprint=1;
   54: }
   55: 
   56: # Read in /etc/passwd, and make sure this process is running from user=www
   57: open (IN, "</etc/passwd");
   58: my @lines=<IN>;
   59: close IN;
   60: my $wwwid;
   61: for my $l (@lines) {
   62:     chop $l;
   63:     my @F=split(/\:/,$l);
   64:     if ($F[0] eq 'www') {$wwwid=$F[2];}
   65: }
   66: if ($wwwid!=$<) {
   67:     print("User ID mismatch.  This program must be run as user 'www'\n") unless $noprint;
   68:     exit 1;
   69: }
   70: &disable_root_capability;
   71: 
   72: # Handle case of another lcpasswd process
   73: unless (&try_to_lock("/tmp/lock_lcpasswd")) {
   74:     print "Error. Too many other simultaneous password change requests being made.\n" unless $noprint;
   75:     exit 4;
   76: }
   77: 
   78: # Gather input.  Should only be 1 value (user name).
   79: my @input;
   80: if (@ARGV==1) {
   81:     @input=@ARGV;
   82: }
   83: elsif (@ARGV) {
   84:     print("Error. This program needs just 1 command-line argument (username).\n") unless $noprint;
   85:     unlink('/tmp/lock_lcpasswd');
   86:     exit 2;
   87: }
   88: else {
   89:     @input=<>;
   90:     if (@input!=1) {
   91: 	print("Error. Only one line should be entered into standard input.\n") unless $noprint;
   92: 	unlink('/tmp/lock_lcpasswd');
   93: 	exit 3;
   94:     }
   95:     map {chop} @input;
   96: }
   97: 
   98: my ($username)=@input;
   99: $username=~/^(\w+)$/;
  100: my $safeusername=$1;
  101: if ($username ne $safeusername) {
  102:     print "Error. The user name specified has invalid characters.\n";
  103:     unlink('/tmp/lock_lcpasswd');
  104:     exit 5;
  105: }
  106: 
  107: &enable_root_capability;
  108: 
  109: # By using the system userdel command:
  110: # Remove entry from /etc/passwd if it exists
  111: # Remove entry from /etc/groups if it exists
  112: # I surround with groupdel command to make absolutely sure the group definition disappears.
  113: system('/usr/sbin/groupdel',$safeusername); # ignore error message
  114: system('/usr/sbin/userdel',$safeusername); # ignore error message
  115: system('/usr/sbin/groupdel',$safeusername); # ignore error message
  116: 
  117: # Remove entry from /etc/smbpasswd if it exists
  118: #  the safest way to do this is with smbpasswd -x
  119: #  as that's independent of location of the smbpasswd file.
  120: #
  121: if (-e '/usr/bin/smbpasswd') {
  122:   ($>,$<) = (0,0);		# fool smbpasswd to think this is not setuid.
  123:   system('/usr/bin/smbpasswd -x '.$safeusername);
  124:   $< = $wwwid;
  125: }
  126: 
  127: 
  128: # Change ownership on directory from username:username to www:www
  129: # This prevents subsequently added users from having access.
  130: 
  131: system('/bin/chown','-R','www:www',"/home/$safeusername");
  132: 
  133: &disable_root_capability;
  134: unlink("/tmp/lock_lcpasswd");
  135: exit 0;
  136: 
  137: # ----------------------------------------------------------- have setuid script run as root
  138: sub enable_root_capability {
  139:     if ($wwwid==$>) {
  140: 	($<,$>)=($>,$<);
  141: 	($(,$))=($),$();
  142:     }
  143:     else {
  144: 	# root capability is already enabled
  145:     }
  146:     return $>;
  147: }
  148: 
  149: # ----------------------------------------------------------- have setuid script run as www
  150: sub disable_root_capability {
  151:     if ($wwwid==$<) {
  152: 	($<,$>)=($>,$<);
  153: 	($(,$))=($),$();
  154:     }
  155:     else {
  156: 	# root capability is already disabled
  157:     }
  158: }
  159: 
  160: # ----------------------------------- make sure that another lcpasswd process isn't running
  161: sub try_to_lock {
  162:     my ($lockfile)=@_;
  163:     my $currentpid;
  164:     my $lastpid;
  165:     # Do not manipulate lock file as root
  166:     if ($>==0) {
  167: 	return 0;
  168:     }
  169:     # Try to generate lock file.
  170:     # Wait 3 seconds.  If same process id is in
  171:     # lock file, then assume lock file is stale, and
  172:     # go ahead.  If process id's fluctuate, try
  173:     # for a maximum of 10 times.
  174:     for (0..10) {
  175: 	if (-e $lockfile) {
  176: 	    open(LOCK,"<$lockfile");
  177: 	    $currentpid=<LOCK>;
  178: 	    close LOCK;
  179: 	    if ($currentpid==$lastpid) {
  180: 		last;
  181: 	    }
  182: 	    sleep 3;
  183: 	    $lastpid=$currentpid;
  184: 	}
  185: 	else {
  186: 	    last;
  187: 	}
  188: 	if ($_==10) {
  189: 	    return 0;
  190: 	}
  191:     }
  192:     open(LOCK,">$lockfile");
  193:     print LOCK $$;
  194:     close LOCK;
  195:     return 1;
  196: }
  197: 
  198: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.