Annotation of loncom/lchtmldir, revision 1.2

1.1       foxr        1: #!/usr/bin/perl
                      2: 
                      3: # The Learning Online Network with CAPA
                      4: #
                      5: # Copyright Michigan State University Board of Trustees
                      6: #
                      7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
                      8: #
                      9: # LON-CAPA is free software; you can redistribute it and/or modify
                     10: # it under the terms of the GNU General Public License as published by
                     11: # the Free Software Foundation; either version 2 of the License, or
                     12: # (at your option) any later version.
                     13: #
                     14: # LON-CAPA is distributed in the hope that it will be useful,
                     15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     17: # GNU General Public License for more details.
                     18: #
                     19: # You should have received a copy of the GNU General Public License
                     20: # along with LON-CAPA; if not, write to the Free Software
                     21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
                     22: #
                     23: # /home/httpd/html/adm/gpl.txt
                     24: #
                     25: # http://www.lon-capa.org/
                     26: #
                     27: #  lchtmldir - LONC-CAPA setuid script to:
                     28: #              o If necessary, add a public_html directory 
                     29: #                to the specified user home directory.
                     30: #              o Set the permissions according to the authentication type.
                     31: #
                     32: #  Motivations:
                     33: #     Originally, account creation would create a public_html
                     34: #     directory for unix authorized people only.  It is possible to have
                     35: #     Kerberos, internal and locally authorized 'users' which may be authors
                     36: #     and hence need a properly owned an protected public_html directory
                     37: #     to serve as their construction space.
                     38: #
                     39: #  Author:
                     40: #    Ron Fox
                     41: #    NSCL
                     42: #    Michigan State University8
                     43: #    East Lansing, MI 48824-1321
                     44: 
                     45: #   General flow of control:
                     46: #   1. Validate process state (must be run as www).
                     47: #   2. Validate parameters:  Need two parameters:
                     48: #         o Homedir  - Home diretory of user 
                     49: #         o Username - Name of the user.
                     50: #         o AuthMode - Authentication mode, can be:
                     51: #                      - unix
                     52: #                      - internal
                     53: #                      - krb4
                     54: #                      - localauth
                     55: #  3. Untaint the usename and home directory
                     56: #
                     57: #  4. As root if necessary, create $Homedir/public_html
                     58: #  5. Set ownership/permissions according to authentication mode (AuthMode)
                     59: #       - unix - ~owner:www/2775
                     60: #       - krb4 - ~owner:www/2775
                     61: #       - internal - www:www/2775
                     62: #       - local    - www:www/2775
                     63: #
                     64: 
                     65: #
                     66: #   Take a few precautions to be sure that we're not vulnerable to trojan
                     67: #   horses and other fine issues:
                     68: #
                     69: use strict; 
                     70: 
                     71: $ENV{'PATH'} = '/bin:/usr/bin:/usr/local/sbin:/home/httpd/perl';
                     72: delete @ENV{qw{IFS CDPATH ENV BASH_ENV}};
                     73: 
                     74: my $DEBUG = 0;                         # .nonzero -> Debug printing enabled.
                     75: 
                     76: 
                     77: # If the UID of the running process is not www exit with error.
                     78: 
                     79: if ($DEBUG) {
                     80:     print("Checking uid...\n");
                     81: }
                     82: my $wwwid = getpwnam('www');
                     83: &DisableRoot;
                     84: if($wwwid != $>) {
                     85:     if ($DEBUG) {
                     86: 	print("User ID incorrect.  This program must be run as user 'www'\n");
                     87:     }
                     88:     exit 1;			# Exit with error status.
                     89: }
                     90: 
                     91: # There must be three 'command line' parameters.  The first
                     92: # is the home directory of the user.
                     93: # The second is the name of the user.  This is only referenced
                     94: # in code branches dealing with unix mode authentication.
                     95: # The last is the authentication mode which must be one of unix, internal
                     96: # krb4 or localauth.
                     97: #   If there is an error in the argument count or countents, we exit with an
                     98: # error.
                     99: 
                    100: if ($DEBUG) {
                    101:     print("Checking parameters: \n");
                    102: }
                    103: if(@ARGV != 3) {
                    104:     if($DEBUG) {
                    105: 	print("Error: lchtmldir need 3 parameters \n");
                    106:     }
                    107:     exit 2;
                    108: }
                    109: my ($dir,$username,$authentication) = @ARGV;
                    110: 
                    111: if($DEBUG) {
                    112:     print ("Directory = $dir \n");
                    113:     print ("User      = $username \n");
                    114:     print ("Authmode  = $authentication \n");
                    115: 
                    116: }
                    117: 
1.2     ! foxr      118: if( $authentication ne "unix:"     &&
        !           119:     $authentication ne "internal:" &&
        !           120:     $authentication ne "krb4:"     &&
        !           121:     $authentication ne "localauth:") {
1.1       foxr      122:     if($DEBUG) {
                    123: 	print("Invalid authentication parameter: ".$authentication."\n");
                    124: 	print("Should be one of: unix, internal, krb4, localauth\n");
                    125:     }
                    126:     exit 3;
                    127: }
                    128: 
                    129: # Untaint the username.
                    130: 
                    131: my $match = $username =~ /^(\w+)$/;
                    132: my $patt  = $1;
                    133:  
                    134: if($DEBUG) {
                    135:    print("Username word match flag = ".$match."\n");
                    136:     print("Match value = ".$patt."\n");
                    137: }
                    138: 
                    139: my $safeuser = $patt;
                    140: if($DEBUG) {
                    141:     print("Save username = $safeuser \n");
                    142: }
                    143: if(($username ne $safeuser) or ($safeuser!~/^[A-za-z]/)) {
                    144:     if($DEBUG) {
                    145: 	print("User name $username had illegal characters\n");
                    146:     }
                    147:     exit 4;
                    148: }
                    149: 
                    150: #untaint the base directory require that the dir contain only 
                    151: # alphas, / numbers or underscores, and end in /$safeuser
                    152: 
                    153: $dir =~ /(^([\w\/]+))/;
                    154: 
                    155: my $dirtry1 = $1;
                    156: 
                    157: $dir =~ /$\/$safeuser/;
                    158: my $dirtry2 = $1;
                    159: 
                    160: if(($dirtry1 ne $dir) or ($dirtry2 ne $dir)) {
                    161:     if ($DEBUG) {
                    162: 	print("Directory $dir is not a valid home for $safeuser\n");
                    163:     }
                    164:     exit 5;
                    165: }
                    166: 
                    167: 
                    168: # As root, create the directory.
                    169: 
                    170: my $fulldir = $dirtry1."/public_html";
                    171: if($DEBUG) {
                    172:     print("Full directory path is: $fulldir \n");
                    173: }
                    174: if(!( -e $dirtry1)) {
                    175:     if($DEBUG) {
                    176: 	print("User's home directory $dirtry1 does not exist\n");
                    177:     }
                    178:     exit 6;
                    179: }
                    180: &EnableRoot;
                    181: 
                    182: &System("/bin/mkdir $fulldir")   unless (-e $fulldir);
                    183:     unless(-e $fulldir."/index.html") {
                    184: 	open OUT,">".$fulldir."/index.html";
                    185: 	print OUT<<END;
                    186: 	<html>
                    187: 	<head>
                    188: 	<title>$safeuser</title>
                    189:         </head>
                    190:         <body>
                    191:         <h1>$safeuser</h1>
                    192:           <p>
                    193:             Learning Online Network
                    194:           </p>
                    195:           <p>
                    196:             This area provides for:
                    197:           </p>
                    198:           <ul>
                    199:              <li>resource construction</li>
                    200:              <li>resource publication</li>
                    201:              <li>record-keeping</li>
                    202:           </ul>
                    203:         </body>
                    204:        </html>
                    205: END
                    206:     close OUT;
                    207:     }
                    208: &System("/bin/chmod  02775  $fulldir");
                    209: &System("/bin/chmod  0775  $fulldir"."/index.html");
                    210: 
                    211: 
                    212: # Based on the authentiation mode, set the ownership of the directory.
                    213: 
1.2     ! foxr      214: if($authentication eq "unix:") {	# Unix mode authentication...
1.1       foxr      215:     
                    216:    
                    217:     &System("/bin/chown -R   $username".":".$username." ".$fulldir);
                    218:     &JoinGroup($username);
                    219: 
                    220: 
                    221: }
1.2     ! foxr      222: elsif ($authentication eq "internal:") { # Internal authentication.
1.1       foxr      223: 
                    224:     &System("/bin/chown -R www:www  $fulldir");
                    225: }
1.2     ! foxr      226: elsif ($authentication eq "krb4:") { # Kerberos version 4 authentication
        !           227:     &System("/bin/chown -R $username".':'.$username." ".$fulldir);
1.1       foxr      228:     &JoinGroup($username);
                    229: }
1.2     ! foxr      230: elsif ($authentication eq "localauth:") { # Local authentiation
1.1       foxr      231:     &System("/bin/chown -R  $username".':'.$username."  $fulldir");
                    232: }
                    233: else {
                    234:     if($DEBUG) {
                    235: 	print("Authentication not legal".$authentication);
                    236:     }
                    237:     &DisableRoot;
                    238:     exit 5;
                    239: 
                    240: }
                    241: &DisableRoot;
                    242: 
                    243: exit 0;
                    244: 
                    245: #----------------------------------------------------------------------
                    246: #
                    247: #  Local utility procedures.
                    248: #  These include:
                    249: #     EnableRoot - Start running as root.
                    250: #     DisableRoot- Stop running as root.
                    251: #     JoinGroup  - Join www to the specified group.
                    252: 
                    253: # Turn on as root:
                    254: 
                    255: sub EnableRoot {
                    256:     if ($wwwid==$>) {
                    257: 	($<,$>)=($>,$<);
                    258: 	($(,$))=($),$();
                    259:     }
                    260:     else {
                    261: 	# root capability is already enabled
                    262:     }
                    263:     if($DEBUG) {
                    264: 	print("Enable Root - id =  $> \n");
                    265:     }
                    266:     return $>;  
                    267: }
                    268: 
                    269: sub DisableRoot {
                    270:     if ($wwwid==$<) {
                    271: 	($<,$>)=($>,$<);
                    272: 	($(,$))=($),$();
                    273:     }
                    274:     else {
                    275: 	# root capability is already disabled
                    276:     }
                    277:     if($DEBUG) {
                    278: 	print("Disable root: id = ".$>."\n");
                    279:     }
                    280: }
                    281: 
                    282: sub JoinGroup {
                    283:     my $usergroup = shift;
                    284: 
                    285:     my $groups = `/usr/bin/groups www`;
                    286:     chomp $groups; $groups=~s/^\S+\s+\:\s+//;
                    287:     my @grouplist=split(/\s+/,$groups);
                    288:     my @ugrouplist=grep {!/www|$usergroup/} @grouplist;
                    289:     my $gl=join(',',(@ugrouplist,$usergroup));
                    290:     if (&System('/usr/sbin/usermod','-G',$gl,'www')) {
                    291: 	if($DEBUG) {
                    292: 	    print "Error. Could not make www a member of the group ".
                    293: 		"\"$usergroup\".\n";
                    294: 	}
                    295: 	exit 6;
                    296:     }
                    297:     
                    298: }
                    299: 
                    300: 
                    301: 
                    302: sub System {
                    303:     my $command = shift;
                    304:     if($DEBUG) {
                    305: 	print("system: $command \n");
                    306:     }
                    307:     system($command);
                    308: }
                    309: 
                    310: 
                    311: 
                    312: 

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