Diff for /loncom/Attic/lcuseradd between versions 1.2 and 1.19

version 1.2, 2000/10/29 22:07:20 version 1.19, 2002/02/14 22:09:14
Line 1 Line 1
 #!/usr/bin/perl  #!/usr/bin/perl
   
   # The Learning Online Network with CAPA
   #
   # lcuseradd - LON-CAPA setuid script to coordinate all actions
   #             with adding a user with filesystem privileges (e.g. author)
 #  #
 # lcuseradd  # YEAR=2000
   # 10/27,10/29,10/30 Scott Harrison
   # YEAR=2001
   # 10/21,11/13,11/15 Scott Harrison
 #  #
 # Scott Harrison  # $Id$
 # October 27, 2000  ###
   
   ###############################################################################
   ##                                                                           ##
   ## ORGANIZATION OF THIS PERL SCRIPT                                          ##
   ##                                                                           ##
   ## 1. Description of script                                                  ##
   ## 2. Invoking script (standard input)                                       ##
   ## 3. Example usage inside another piece of code                             ##
   ## 4. Description of functions                                               ##
   ## 5. Exit codes                                                             ##
   ## 6. Initializations                                                        ##
   ## 7. Make sure this process is running from user=www                        ##
   ## 8. Start running script with www permissions                              ##
   ## 9. Handle case of another lcpasswd process (locking)                      ##
   ## 10. Error-check input, need 3 values (user name, password 1, password 2)  ##
   ## 11. Start running script with root permissions                            ##
   ## 12. Add user and make www a member of the user-specific group             ##
   ## 13. Set password                                                          ##
   ## 14. Make final modifications to the user directory                        ##
   ## 15. Exit script (unlock)                                                  ##
   ##                                                                           ##
   ###############################################################################
   
 use strict;  use strict;
   
   # ------------------------------------------------------- Description of script
   #
 # This script is a setuid script that should  # This script is a setuid script that should
 # be run by user 'www'.  It creates a /home/USERNAME directory  # be run by user 'www'.  It creates a /home/USERNAME directory
 # as well as a /home/USERNAME/public_html directory.  # as well as a /home/USERNAME/public_html directory.
 # It adds user entries to  # It adds a user to the unix system.
 # /etc/passwd and /etc/groups.  
 # Passwords are set with lcpasswd.  # Passwords are set with lcpasswd.
 # www becomes a member of this user group.  # www becomes a member of this user group.
   
 # Standard input usage  # -------------- Invoking script (standard input versus command-line arguments)
   #
   # Standard input (STDIN) usage
 # First line is USERNAME  # First line is USERNAME
 # Second line is PASSWORD  # Second line is PASSWORD
   # Third line is PASSWORD
 # Command-line arguments [USERNAME] [PASSWORD]  #
   # Command-line arguments [USERNAME] [PASSWORD] [PASSWORD]
 # Yes, but be very careful here (don't pass shell commands)  # Yes, but be very careful here (don't pass shell commands)
 # and this is only supported to allow perl-system calls.  # and this is only supported to allow perl-system calls.
   #
   # Valid passwords must consist of the
   # ascii characters within the inclusive
   # range of 0x20 (32) to 0x7E (126).
   # These characters are:
   # SPACE and
   # !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNO
   # PQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
   #
   # Valid user names must consist of ascii
   # characters that are alphabetical characters
   # (A-Z,a-z), numeric (0-9), or the underscore
   # mark (_). (Essentially, the perl regex \w).
   # User names must begin with an alphabetical character
   # (A-Z,a-z).
   
   # ---------------------------------- Example usage inside another piece of code
   # Usage within code
   #
   # $exitcode=
   #      system("/home/httpd/perl/lcuseradd","NAME","PASSWORD1","PASSWORD2")/256;
   # print "uh-oh" if $exitcode;
   
   # ---------------------------------------------------- Description of functions
   # enable_root_capability() : have setuid script run as root
   # disable_root_capability() : have setuid script run as www
   # try_to_lock() : make sure that another lcpasswd process isn't running
   
   # ------------------------------------------------------------------ Exit codes
   # These are the exit codes.
   # ( (0,"ok"),
   # (1,"User ID mismatch.  This program must be run as user 'www'"),
   # (2,"Error. This program needs 3 command-line arguments (username, ".
   #    "password 1, password 2)."),
   # (3,"Error. Three lines should be entered into standard input."),
   # (4,"Error. Too many other simultaneous password change requests being ".
   #    "made."),
   # (5,"Error. User $username does not exist."),
   # (6,"Error. Could not make www a member of the group \"$safeusername\"."),
   # (7,"Error. Root was not successfully enabled.),
   # (8,"Error. Cannot set password."),
   # (9,"Error. The user name specified has invalid characters."),
   # (10,"Error. A password entry had an invalid character."),
   # (11,"Error. User already exists.),
   # (12,"Error. Something went wrong with the addition of user ".
   #     "\"$safeusername\"."),
   # (13,"Error. Password mismatch."),
   
   # ------------------------------------------------------------- Initializations
 # Security  # Security
 $ENV{'PATH'}=""; # Nullify path information.  $ENV{'PATH'}='/bin/:/usr/bin:/usr/local/sbin:/home/httpd/perl'; # Nullify path
 $ENV{'BASH_ENV'}=""; # Nullify shell environment information.                                                                  # information
   delete @ENV{qw(IFS CDPATH ENV BASH_ENV)}; # nullify potential taints
   
   # Do not print error messages.
   my $noprint=1;
   
   # ----------------------------- Make sure this process is running from user=www
   my $wwwid=getpwnam('www');
   &disable_root_capability;
   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")) {
       print "Error. Too many other simultaneous password change requests being ".
    "made.\n" unless $noprint;
       exit 4;
   }
   
   # ------- Error-check input, need 3 values (user name, password 1, password 2).
   my @input;
   if (@ARGV==3) {
       @input=@ARGV;
   }
   elsif (@ARGV) {
       print("Error. This program needs 3 command-line arguments (username, ".
     "password 1, password 2).\n") unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 2;
   }
   else {
       @input=<>;
       if (@input!=3) {
    print("Error. Three lines should be entered into standard input.\n")
       unless $noprint;
    unlink('/tmp/lock_lcpasswd');
    exit 3;
       }
       foreach (@input) {chomp;}
   }
   
   my ($username,$password1,$password2)=@input;
   $username=~/^(\w+)$/;
   my $safeusername=$1;
   if (($username ne $safeusername) or ($safeusername!~/^[A-Za-z]/)) {
       print "Error. The user name specified has invalid characters.\n"
    unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 9;
   }
   my $pbad=0;
   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');
       exit 10;
   }
   
   # -- Only add user if we can create a brand new home directory (/home/username)
   if (-e "/home/$safeusername") {
       print "Error. User already exists.\n" unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 11;
   }
   
   # -- Only add user if the two password arguments match.
   if ($password1 ne $password2) {
       print "Error. Password mismatch.\n" unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 13;
   }
   
 # Add user entry to /etc/passwd and /etc/groups.  # ---------------------------------- Start running script with root permissions
   &enable_root_capability;
   
   # ------------------- Add user and make www a member of the user-specific group
   # -- Add user
   if (system('/usr/sbin/useradd','-c','LON-CAPA user',$safeusername)) {
       print "Error.  Something went wrong with the addition of user ".
     "\"$safeusername\".\n" unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 12;
   }
   
   # Make www a member of that user group.
   my $groups=`/usr/bin/groups www` or exit(6);
   chomp $groups; $groups=~s/^\S+\s+\:\s+//;
   my @grouplist=split(/\s+/,$groups);
   my @ugrouplist=grep {!/www|$safeusername/} @grouplist;
   my $gl=join(',',(@ugrouplist,$safeusername));
   if (system('/usr/sbin/usermod','-G',$gl,'www')) {
       print "Error. Could not make www a member of the group ".
     "\"$safeusername\".\n" unless $noprint;
       unlink('/tmp/lock_lcpasswd');
       exit 6;
   }
   
   # ---------------------------------------------------------------- Set password
 # Set password with lcpasswd (which creates smbpasswd entry).  # Set password with lcpasswd (which creates smbpasswd entry).
   
 # www becomes member of this user group  unlink('/tmp/lock_lcpasswd');
   &disable_root_capability;
   ($>,$<)=($wwwid,$wwwid);
   open OUT,"|/home/httpd/perl/lcpasswd";
   print OUT $safeusername;
   print OUT "\n";
   print OUT $password1;
   print OUT "\n";
   print OUT $password1;
   print OUT "\n";
   close OUT;
   if ($?) {
       exit 8;
   }
   ($>,$<)=($wwwid,0);
   &enable_root_capability;
   
   # ------------------------------ Make final modifications to the user directory
   # -- Add a public_html file with a stand-in index.html file
   
   # system('/bin/chmod','-R','0660',"/home/$safeusername");
   system('/bin/chmod','0710',"/home/$safeusername");
   mkdir "/home/$safeusername/public_html",0755;
   system('/bin/chmod','02770',"/home/$safeusername/public_html");
   open OUT,">/home/$safeusername/public_html/index.html";
   print OUT<<END;
   <html>
   <head>
   <title>$safeusername</title>
   </head>
   <body>
   <h1>$safeusername</h1>
   <p>
   Learning Online Network
   </p>
   <p>
   This area provides for:
   </p>
   <ul>
   <li>resource construction</li>
   <li>resource publication</li>
   <li>record-keeping</li>
   </ul>
   </body>
   </html>
   END
   close OUT;
   system('/bin/chown','-R',"$safeusername:$safeusername","/home/$safeusername");
   
   # -------------------------------------------------------- Exit script
   &disable_root_capability;
   exit 0;
   
   # ---------------------------------------------- Have setuid script run as root
   sub enable_root_capability {
       if ($wwwid==$>) {
    ($<,$>)=($>,$<);
    ($(,$))=($),$();
       }
       else {
    # root capability is already enabled
       }
       return $>;
   }
   
   # ----------------------------------------------- Have setuid script run as www
   sub disable_root_capability {
       if ($wwwid==$<) {
    ($<,$>)=($>,$<);
    ($(,$))=($),$();
       }
       else {
    # root capability is already disabled
       }
   }
   
   # ----------------------- Make sure that another lcpasswd process isn't running
   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
       # go ahead.  If process id's fluctuate, try
       # for a maximum of 10 times.
       for (0..10) {
    if (-e $lockfile) {
       open(LOCK,"<$lockfile");
       $currentpid=<LOCK>;
       close LOCK;
       if ($currentpid==$lastpid) {
    last;
       }
       sleep 3;
       $lastpid=$currentpid;
    }
    else {
       last;
    }
    if ($_==10) {
       return 0;
    }
       }
       open(LOCK,">$lockfile");
       print LOCK $$;
       close LOCK;
       return 1;
   }
   
   =head1 NAME
   
   lcuseradd - LON-CAPA setuid script to coordinate all actions
               with adding a user with filesystem privileges (e.g. author)
   
   =head1 DESCRIPTION
   
   lcuseradd - LON-CAPA setuid script to coordinate all actions
               with adding a user with filesystem privileges (e.g. author)
   
   =head1 README
   
   lcuseradd - LON-CAPA setuid script to coordinate all actions
               with adding a user with filesystem privileges (e.g. author)
   
   =head1 PREREQUISITES
   
   =head1 COREQUISITES
   
   =pod OSNAMES
   
   linux
   
   =pod SCRIPT CATEGORIES
   
   LONCAPA/Administrative
   
   =cut

Removed from v.1.2  
changed lines
  Added in v.1.19


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.