Annotation of loncom/lcuserdel, revision 1.4
1.1 harris41 1: #!/usr/bin/perl
2: #
3: # lcuserdel
4: #
5: # Scott Harrison
1.4 ! harris41 6: # SH: October 27, 2000
! 7: # SH: October 28, 2000
1.1 harris41 8:
9: use strict;
10:
1.2 harris41 11: # This script is a setuid script (chmod 6755) that should
1.1 harris41 12: # be run by user 'www'. It DOES NOT delete directories.
13: # All it does is remove a user's entries from
14: # /etc/passwd, /etc/groups, and /etc/smbpasswd.
15:
1.3 harris41 16: # This script works under the same process control mechanism
17: # as lcuseradd and lcpasswd, to make sure that only one of these
18: # processes is running at any one time on the system.
1.1 harris41 19:
20: # Standard input usage
21: # First line is USERNAME
22:
23: # Command-line arguments [USERNAME]
24: # Yes, but be very careful here (don't pass shell commands)
25: # and this is only supported to allow perl-system calls.
26:
1.2 harris41 27: # Usage within code
28: #
1.3 harris41 29: # $exitcode=system("/home/httpd/perl/lcuserdel","NAME")/256;
1.2 harris41 30: # print "uh-oh" if $exitcode;
31:
32: # These are the exit codes.
33:
1.1 harris41 34: # Security
35: $ENV{'PATH'}=""; # Nullify path information.
36: $ENV{'BASH_ENV'}=""; # Nullify shell environment information.
1.2 harris41 37:
38: # Do not print error messages if there are command-line arguments
39: my $noprint=0;
40: if (@ARGV) {
41: $noprint=1;
42: }
43:
1.3 harris41 44: # Read in /etc/passwd, and make sure this process is running from user=www
1.2 harris41 45: open (IN, "</etc/passwd");
46: my @lines=<IN>;
47: close IN;
48: my $wwwid;
49: for my $l (@lines) {
50: chop $l;
51: my @F=split(/\:/,$l);
52: if ($F[0] eq 'www') {$wwwid=$F[2];}
53: }
54: if ($wwwid!=$<) {
55: print("User ID mismatch. This program must be run as user 'www'\n") unless $noprint;
56: exit 1;
57: }
58: &disable_root_capability;
59:
1.3 harris41 60: # Handle case of another lcpasswd process
61: unless (&try_to_lock("/tmp/lock_lcpasswd")) {
62: print "Error. Too many other simultaneous password change requests being made.\n" unless $noprint;
63: exit 4;
64: }
65:
66: # Gather input. Should only be 1 value (user name).
1.2 harris41 67: my @input;
1.3 harris41 68: if (@ARGV==1) {
1.2 harris41 69: @input=@ARGV;
70: }
71: elsif (@ARGV) {
1.3 harris41 72: print("Error. This program needs just 1 command-line argument (username).\n") unless $noprint;
1.2 harris41 73: exit 2;
74: }
75: else {
76: @input=<>;
1.3 harris41 77: if (@input!=1) {
78: print("Error. Only one line should be entered into standard input.\n") unless $noprint;
1.2 harris41 79: exit 3;
80: }
81: map {chop} @input;
82: }
1.4 ! harris41 83:
! 84: my ($username)=@input;
! 85: $username=~/^(\w+)$/;
! 86: my $safeusername=$1;
! 87:
! 88: # By using the system userdel command:
! 89: # Remove entry from /etc/passwd if it exists
! 90: # Remove entry from /etc/groups if it exists
! 91: system('/usr/sbin/userdel',$safeusername);
! 92:
! 93: # Remove entry from /etc/smbpasswd if it exists
! 94:
! 95: # Move directory from /home/username to /home/username.1
! 96:
! 97: # Change ownership on directory from username:username to www:www
! 98: # This prevents subsequently added users from having access.
! 99:
1.3 harris41 100:
101: &disable_root_capability;
102: unlink("/tmp/lock_lcpasswd");
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: }
1.2 harris41 126: }
127:
1.3 harris41 128: # ----------------------------------- make sure that another lcpasswd 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: }
1.2 harris41 165:
1.1 harris41 166:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>