File:  [LON-CAPA] / loncom / Attic / lchtmldir
Revision 1.3: download - view: text, annotated - select for diffs
Fri May 3 03:43:54 2002 UTC (22 years, 7 months ago) by foxr
Branches: MAIN
CVS tags: version_0_5_1, version_0_5, version_0_4, stable_2002_july, STABLE, HEAD
Forgot to propagate change for -p switch into mkdir.

#!/usr/bin/perl

# The Learning Online Network with CAPA
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#
#  lchtmldir - LONC-CAPA setuid script to:
#              o If necessary, add a public_html directory 
#                to the specified user home directory.
#              o Set the permissions according to the authentication type.
#
#  Motivations:
#     Originally, account creation would create a public_html
#     directory for unix authorized people only.  It is possible to have
#     Kerberos, internal and locally authorized 'users' which may be authors
#     and hence need a properly owned an protected public_html directory
#     to serve as their construction space.
#
#  Author:
#    Ron Fox
#    NSCL
#    Michigan State University8
#    East Lansing, MI 48824-1321

#   General flow of control:
#   1. Validate process state (must be run as www).
#   2. Validate parameters:  Need two parameters:
#         o Homedir  - Home diretory of user 
#         o Username - Name of the user.
#         o AuthMode - Authentication mode, can be:
#                      - unix
#                      - internal
#                      - krb4
#                      - localauth
#  3. Untaint the usename and home directory
#
#  4. As root if necessary, create $Homedir/public_html
#  5. Set ownership/permissions according to authentication mode (AuthMode)
#       - unix - ~owner:www/2775
#       - krb4 - ~owner:www/2775
#       - internal - www:www/2775
#       - local    - www:www/2775
#

#
#   Take a few precautions to be sure that we're not vulnerable to trojan
#   horses and other fine issues:
#
use strict; 

$ENV{'PATH'} = '/bin:/usr/bin:/usr/local/sbin:/home/httpd/perl';
delete @ENV{qw{IFS CDPATH ENV BASH_ENV}};

my $DEBUG = 0;                         # .nonzero -> Debug printing enabled.


# If the UID of the running process is not www exit with error.

if ($DEBUG) {
    print("Checking uid...\n");
}
my $wwwid = getpwnam('www');
&DisableRoot;
if($wwwid != $>) {
    if ($DEBUG) {
	print("User ID incorrect.  This program must be run as user 'www'\n");
    }
    exit 1;			# Exit with error status.
}

# There must be three 'command line' parameters.  The first
# is the home directory of the user.
# The second is the name of the user.  This is only referenced
# in code branches dealing with unix mode authentication.
# The last is the authentication mode which must be one of unix, internal
# krb4 or localauth.
#   If there is an error in the argument count or countents, we exit with an
# error.

if ($DEBUG) {
    print("Checking parameters: \n");
}
if(@ARGV != 3) {
    if($DEBUG) {
	print("Error: lchtmldir need 3 parameters \n");
    }
    exit 2;
}
my ($dir,$username,$authentication) = @ARGV;

if($DEBUG) {
    print ("Directory = $dir \n");
    print ("User      = $username \n");
    print ("Authmode  = $authentication \n");

}

if( $authentication ne "unix:"     &&
    $authentication ne "internal:" &&
    $authentication ne "krb4:"     &&
    $authentication ne "localauth:") {
    if($DEBUG) {
	print("Invalid authentication parameter: ".$authentication."\n");
	print("Should be one of: unix, internal, krb4, localauth\n");
    }
    exit 3;
}

# Untaint the username.

my $match = $username =~ /^(\w+)$/;
my $patt  = $1;
 
if($DEBUG) {
   print("Username word match flag = ".$match."\n");
    print("Match value = ".$patt."\n");
}

my $safeuser = $patt;
if($DEBUG) {
    print("Save username = $safeuser \n");
}
if(($username ne $safeuser) or ($safeuser!~/^[A-za-z]/)) {
    if($DEBUG) {
	print("User name $username had illegal characters\n");
    }
    exit 4;
}

#untaint the base directory require that the dir contain only 
# alphas, / numbers or underscores, and end in /$safeuser

$dir =~ /(^([\w\/]+))/;

my $dirtry1 = $1;

$dir =~ /$\/$safeuser/;
my $dirtry2 = $1;

if(($dirtry1 ne $dir) or ($dirtry2 ne $dir)) {
    if ($DEBUG) {
	print("Directory $dir is not a valid home for $safeuser\n");
    }
    exit 5;
}


# As root, create the directory.

my $fulldir = $dirtry1."/public_html";
if($DEBUG) {
    print("Full directory path is: $fulldir \n");
}
if(!( -e $dirtry1)) {
    if($DEBUG) {
	print("User's home directory $dirtry1 does not exist\n");
    }
    exit 6;
}
&EnableRoot;

&System("/bin/mkdir -p $fulldir")   unless (-e $fulldir);
    unless(-e $fulldir."/index.html") {
	open OUT,">".$fulldir."/index.html";
	print OUT<<END;
	<html>
	<head>
	<title>$safeuser</title>
        </head>
        <body>
        <h1>$safeuser</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/chmod  02775  $fulldir");
&System("/bin/chmod  0775  $fulldir"."/index.html");


# Based on the authentiation mode, set the ownership of the directory.

if($authentication eq "unix:") {	# Unix mode authentication...
    
   
    &System("/bin/chown -R   $username".":".$username." ".$fulldir);
    &JoinGroup($username);


}
elsif ($authentication eq "internal:") { # Internal authentication.

    &System("/bin/chown -R www:www  $fulldir");
}
elsif ($authentication eq "krb4:") { # Kerberos version 4 authentication
    &System("/bin/chown -R $username".':'.$username." ".$fulldir);
    &JoinGroup($username);
}
elsif ($authentication eq "localauth:") { # Local authentiation
    &System("/bin/chown -R  $username".':'.$username."  $fulldir");
}
else {
    if($DEBUG) {
	print("Authentication not legal".$authentication);
    }
    &DisableRoot;
    exit 5;

}
&DisableRoot;

exit 0;

#----------------------------------------------------------------------
#
#  Local utility procedures.
#  These include:
#     EnableRoot - Start running as root.
#     DisableRoot- Stop running as root.
#     JoinGroup  - Join www to the specified group.

# Turn on as root:

sub EnableRoot {
    if ($wwwid==$>) {
	($<,$>)=($>,$<);
	($(,$))=($),$();
    }
    else {
	# root capability is already enabled
    }
    if($DEBUG) {
	print("Enable Root - id =  $> \n");
    }
    return $>;  
}

sub DisableRoot {
    if ($wwwid==$<) {
	($<,$>)=($>,$<);
	($(,$))=($),$();
    }
    else {
	# root capability is already disabled
    }
    if($DEBUG) {
	print("Disable root: id = ".$>."\n");
    }
}

sub JoinGroup {
    my $usergroup = shift;

    my $groups = `/usr/bin/groups www`;
    chomp $groups; $groups=~s/^\S+\s+\:\s+//;
    my @grouplist=split(/\s+/,$groups);
    my @ugrouplist=grep {!/www|$usergroup/} @grouplist;
    my $gl=join(',',(@ugrouplist,$usergroup));
    if (&System('/usr/sbin/usermod','-G',$gl,'www')) {
	if($DEBUG) {
	    print "Error. Could not make www a member of the group ".
		"\"$usergroup\".\n";
	}
	exit 6;
    }
    
}



sub System {
    my $command = shift;
    if($DEBUG) {
	print("system: $command \n");
    }
    system($command);
}





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