File:
[LON-CAPA] /
loncom /
lcnfsoff
Revision
1.1:
download - view:
text,
annotated -
select for diffs
Thu Nov 2 22:29:39 2000 UTC (23 years, 11 months ago) by
harris41
Branches:
MAIN
CVS tags:
version_0_6_2,
version_0_6,
version_0_5_1,
version_0_5,
version_0_4,
stable_2002_spring,
stable_2002_july,
stable_2002_april,
stable_2001_fall,
STABLE,
HEAD
these setuid scripts work now
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>