File:  [LON-CAPA] / loncom / lcnfsoff
Revision 1.2: download - view: text, annotated - select for diffs
Mon Feb 3 18:03:52 2003 UTC (21 years, 1 month 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: use strict;
    4: 
    5: # This script is a setuid script (chmod 6755; chown root:root).
    6: # It disables nfs/portmap services for a specific user at
    7: # a specific ip address.
    8: 
    9: # Exit codes.  0=ok.  Higher than 0 means something went wrong.
   10: 
   11: # Usage within code
   12: #
   13: # $exitcode=system("/home/httpd/perl/lcnfsoff","NAME","IPADDRESS")/256;
   14: # print "uh-oh" if $exitcode;
   15: 
   16: # Security
   17: $ENV{'PATH'}=""; # Nullify path information.
   18: $ENV{'BASH_ENV'}=""; # Nullify shell environment information.
   19: 
   20: # Do not print error messages if there are command-line arguments
   21: my $noprint=0;
   22: if (@ARGV) {
   23:     $noprint=1;
   24: }
   25: 
   26: # Read in /etc/passwd, and make sure this process is running from user=www
   27: open (IN, "</etc/passwd");
   28: my @lines=<IN>;
   29: close IN;
   30: my $wwwid;
   31: for my $l (@lines) {
   32:     chop $l;
   33:     my @F=split(/\:/,$l);
   34:     if ($F[0] eq 'www') {$wwwid=$F[2];}
   35: }
   36: if ($wwwid!=$<) {
   37:     print("User ID mismatch.  This program must be run as user 'www'\n") unless $noprint;
   38:     exit 1;
   39: }
   40: &disable_root_capability;
   41: 
   42: # Handle case of another lcnfs process
   43: unless (&try_to_lock("/tmp/lock_lcnfs")) {
   44:     print "Error. Too many other simultaneous nfs change requests being made.\n" unless $noprint;
   45:     exit 4;
   46: }
   47: # Gather input.  Should be 2 values (user name, numeric ip address).
   48: my @input;
   49: if (@ARGV==3) {
   50:     @input=@ARGV;
   51: }
   52: elsif (@ARGV) {
   53:     print("Error. This program needs 2 command-line arguments (username, numeric ip address).\n") unless $noprint;
   54:     unlink('/tmp/lock_lcnfs');
   55:     exit 2;
   56: }
   57: else {
   58:     @input=<>;
   59:     if (@input!=2) {
   60: 	print("Error. Two lines should be entered into standard input.\n") unless $noprint;
   61: 	unlink('/tmp/lock_lcnfs');
   62: 	exit 3;
   63:     }
   64:     map {chop} @input;
   65: }
   66: 
   67: my ($username,$ipaddress)=@input;
   68: $username=~/^(\w+)$/;
   69: my $safeusername=$1;
   70: if ($username ne $safeusername) {
   71:     print "Error. The user name specified has invalid characters.\n";
   72:     unlink('/tmp/lock_lcnfs');
   73:     exit 9;
   74: }
   75: 
   76: $ipaddress=~/^([\w|\.]*)$/;
   77: my $safeipaddress=$1;
   78: if ($ipaddress ne $safeipaddress) {
   79:     print "Error. The IP address must be numeric and of the form ##.##.##.##.\n";
   80:     unlink('/tmp/lock_lcnfs');
   81:     exit 8;
   82: }
   83: 
   84: &enable_root_capability;
   85: # Remove entry from /etc/exports
   86: my $exports=`/bin/cat /etc/exports`;
   87: $exports=~s/\/home\/${safeusername}\s*${safeipaddress}.*?\n//g;
   88: # Resynchronize /etc/exports file
   89: open (OUT,">/etc/exports");
   90: print OUT $exports;
   91: close OUT;
   92: system('/usr/sbin/exportfs','-r');
   93: 
   94: # Remove entry from /etc/hosts.allow
   95: my $hostsallow=`/bin/cat /etc/hosts.allow`;
   96: $hostsallow=~s/\# $safeusername\nportmap: $safeipaddress\n//g;
   97: open (OUT,">/etc/hosts.allow");
   98: print OUT $hostsallow;
   99: close OUT;
  100: 
  101: &disable_root_capability;
  102: unlink('/tmp/lock_lcnfs');
  103: exit 0;
  104: 
  105: # ----------------------------------------------------------- have setuid script run as root
  106: sub enable_root_capability {
  107:     if ($wwwid==$>) {
  108: 	($<,$>)=($>,$<);
  109: 	($(,$))=($),$();
  110:     }
  111:     else {
  112: 	# root capability is already enabled
  113:     }
  114:     return $>;
  115: }
  116: 
  117: # ----------------------------------------------------------- have setuid script run as www
  118: sub disable_root_capability {
  119:     if ($wwwid==$<) {
  120: 	($<,$>)=($>,$<);
  121: 	($(,$))=($),$();
  122:     }
  123:     else {
  124: 	# root capability is already disabled
  125:     }
  126: }
  127: 
  128: # ----------------------------------- make sure that another lcnfs process isn't running
  129: sub try_to_lock {
  130:     my ($lockfile)=@_;
  131:     my $currentpid;
  132:     my $lastpid;
  133:     # Do not manipulate lock file as root
  134:     if ($>==0) {
  135: 	return 0;
  136:     }
  137:     # Try to generate lock file.
  138:     # Wait 3 seconds.  If same process id is in
  139:     # lock file, then assume lock file is stale, and
  140:     # go ahead.  If process id's fluctuate, try
  141:     # for a maximum of 10 times.
  142:     for (0..10) {
  143: 	if (-e $lockfile) {
  144: 	    open(LOCK,"<$lockfile");
  145: 	    $currentpid=<LOCK>;
  146: 	    close LOCK;
  147: 	    if ($currentpid==$lastpid) {
  148: 		last;
  149: 	    }
  150: 	    sleep 3;
  151: 	    $lastpid=$currentpid;
  152: 	}
  153: 	else {
  154: 	    last;
  155: 	}
  156: 	if ($_==10) {
  157: 	    return 0;
  158: 	}
  159:     }
  160:     open(LOCK,">$lockfile");
  161:     print LOCK $$;
  162:     close LOCK;
  163:     return 1;
  164: }
  165: 
  166: 

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