Annotation of loncom/lcnfsoff, revision 1.1

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

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