install rmuser, addgroup, rmgroup in /usr/sbin
This commit is contained in:
parent
5b0a74089d
commit
901c028ed7
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=19832
@ -1,7 +1,7 @@
|
||||
# $Id$
|
||||
# $Id: Makefile,v 1.8 1996/11/04 17:21:08 wosch Exp $
|
||||
|
||||
SCRIPTS= adduser.perl #rmuser.perl addgroup.tcl rmgroup.sh
|
||||
MAN8= adduser.8 #rmuser.8 addgroup.8 rmgroup.8
|
||||
SCRIPTS= adduser.perl rmuser.perl addgroup.tcl rmgroup.sh
|
||||
MAN8= adduser.8 rmuser.8 addgroup.8 rmgroup.8
|
||||
|
||||
beforeinstall:
|
||||
.for script in ${SCRIPTS}
|
||||
|
@ -22,7 +22,7 @@
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id: adduser.8,v 1.11 1996/08/27 20:04:33 wosch Exp $
|
||||
.\" $Id: adduser.8,v 1.12 1996/08/28 17:54:13 adam Exp $
|
||||
|
||||
.Dd Jan, 9, 1995
|
||||
.Dt ADDUSER 8
|
||||
@ -235,7 +235,10 @@ logfile for adduser
|
||||
.Xr passwd 5 ,
|
||||
.Xr group 5 ,
|
||||
.Xr shells 5 ,
|
||||
.Xr addgroup 8 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr rmgroup 8 ,
|
||||
.Xr rmuser 8 ,
|
||||
.Xr vipw 8
|
||||
|
||||
.\" .Sh BUGS
|
||||
|
105
usr.sbin/adduser/rmuser.8
Normal file
105
usr.sbin/adduser/rmuser.8
Normal file
@ -0,0 +1,105 @@
|
||||
.\" Copyright 1995, 1996
|
||||
.\" Guy Helmer, Madison, South Dakota 57042. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer as
|
||||
.\" the first lines of this file unmodified.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. The name of the author may not be used to endorse or promote products
|
||||
.\" derived from this software without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY GUY HELMER ``AS IS'' AND ANY EXPRESS OR
|
||||
.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
.\" IN NO EVENT SHALL GUY HELMER BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id: rmuser.8,v 1.2 1996/08/11 13:03:24 wosch Exp $
|
||||
.\"
|
||||
.Dd July 16, 1996
|
||||
.Dt RMUSER 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm rmuser
|
||||
.Nd remove users from the system
|
||||
.Sh SYNOPSIS
|
||||
.Nm rmuser
|
||||
.Op Ar username
|
||||
.Sh DESCRIPTION
|
||||
The utility
|
||||
.Nm rmuser
|
||||
removes a user's
|
||||
.Xr crontab 1
|
||||
entry (if any) and any
|
||||
.Xr at 1
|
||||
jobs belonging to the user,
|
||||
then removes a user from the system's local password file, removes
|
||||
the user's home directory if it is owned by the user, and removes
|
||||
the user's incoming mail file if it exists. The username is removed
|
||||
from any groups to which it belongs in the file
|
||||
.Pa /etc/group .
|
||||
If a group becomes empty and the group name is the same as the username,
|
||||
the group is removed (this complements
|
||||
.Xr adduser 8 's
|
||||
per-user unique groups).
|
||||
.Pp
|
||||
.Nm rmuser
|
||||
politely refuses to remove users whose uid is 0 (typically root), since
|
||||
it seemed like a good idea at the time
|
||||
.Nm rmuser
|
||||
was written.
|
||||
.Pp
|
||||
.Nm rmuser
|
||||
shows the selected user's password file entry and asks for confirmation
|
||||
that you wish to remove the user. If the user's home directory is owned
|
||||
by the user (and not by any other user),
|
||||
.Nm rmuser
|
||||
asks whether you wish to remove the user's home directory and everything
|
||||
below.
|
||||
.Pp
|
||||
Available options:
|
||||
.Pp
|
||||
.Bl -tag -width username
|
||||
.It Ar \&username
|
||||
Identifies the user to be removed; if not present,
|
||||
.Nm rmuser
|
||||
interactively asks for the user to be removed.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/master.passwd -compact
|
||||
.It Pa /etc/master.passwd
|
||||
.It Pa /etc/passwd
|
||||
.It Pa /etc/group
|
||||
.It Pa /etc/spwd.db
|
||||
.It Pa /etc/pwd.db
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr at 1 ,
|
||||
.Xr chpass 1 ,
|
||||
.Xr crontab 1 ,
|
||||
.Xr finger 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr group 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr adduser 8 ,
|
||||
.Xr addgroup 8 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr rmgroup 8 ,
|
||||
.Xr vipw 8
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
command appeared in
|
||||
.Fx 2.1.5 .
|
||||
|
||||
.\" .Sh AUTHOR
|
||||
.\" Guy Helmer, Madison, South Dakota
|
462
usr.sbin/adduser/rmuser.perl
Normal file
462
usr.sbin/adduser/rmuser.perl
Normal file
@ -0,0 +1,462 @@
|
||||
#!/usr/bin/perl
|
||||
# -*- perl -*-
|
||||
# Copyright 1995, 1996 Guy Helmer, Madison, South Dakota 57042.
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer as
|
||||
# the first lines of this file unmodified.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY GUY HELMER ``AS IS'' AND ANY EXPRESS OR
|
||||
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
# IN NO EVENT SHALL GUY HELMER BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# rmuser - Perl script to remove users
|
||||
#
|
||||
# Guy Helmer <ghelmer@alpha.dsu.edu>, 07/17/96
|
||||
#
|
||||
# $Id: removeuser.perl,v 1.2 1996/08/11 13:03:25 wosch Exp $
|
||||
|
||||
sub LOCK_SH {0x01;}
|
||||
sub LOCK_EX {0x02;}
|
||||
sub LOCK_NB {0x04;}
|
||||
sub LOCK_UN {0x08;}
|
||||
sub F_SETFD {2;}
|
||||
|
||||
$ENV{"PATH"} = "/bin:/sbin:/usr/bin:/usr/sbin";
|
||||
umask(022);
|
||||
$whoami = $0;
|
||||
$passwd_file = "/etc/master.passwd";
|
||||
$new_passwd_file = "${passwd_file}.new.$$";
|
||||
$group_file = "/etc/group";
|
||||
$new_group_file = "${group_file}.new.$$";
|
||||
$mail_dir = "/var/mail";
|
||||
$crontab_dir = "/var/cron/tabs";
|
||||
$atjob_dir = "/var/at/jobs";
|
||||
|
||||
#$debug = 1;
|
||||
|
||||
sub cleanup {
|
||||
local($sig) = @_;
|
||||
|
||||
print STDERR "Caught signal SIG$sig -- cleaning up.\n";
|
||||
&unlockpw;
|
||||
if (-e $new_passwd_file) {
|
||||
unlink $new_passwd_file;
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
|
||||
sub lockpw {
|
||||
# Open the password file for reading
|
||||
if (!open(MASTER_PW, "$passwd_file")) {
|
||||
print STDERR "${whoami}: Error: Couldn't open ${passwd_file}: $!\n";
|
||||
exit(1);
|
||||
}
|
||||
# Set the close-on-exec flag just in case
|
||||
fcntl(MASTER_PW, &F_SETFD, 1);
|
||||
# Apply an advisory lock the password file
|
||||
if (!flock(MASTER_PW, &LOCK_EX|&LOCK_NB)) {
|
||||
print STDERR "Couldn't lock ${passwd_file}: $!\n";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
sub unlockpw {
|
||||
flock(MASTER_PW, &LOCK_UN);
|
||||
}
|
||||
|
||||
$SIG{'INT'} = 'cleanup';
|
||||
$SIG{'QUIT'} = 'cleanup';
|
||||
$SIG{'HUP'} = 'cleanup';
|
||||
$SIG{'TERM'} = 'cleanup';
|
||||
|
||||
if ($#ARGV > 0) {
|
||||
print STDERR "usage: ${whoami} [username]\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ($< != 0) {
|
||||
print STDERR "${whoami}: Error: you must be root to use ${whoami}\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
&lockpw;
|
||||
|
||||
if ($#ARGV == 0) {
|
||||
# Username was given as a parameter
|
||||
$login_name = pop(@ARGV);
|
||||
} else {
|
||||
# Get the user name from the user
|
||||
$login_name = &get_login_name;
|
||||
}
|
||||
|
||||
if (($pw_ent = &check_login_name($login_name)) eq '0') {
|
||||
print STDERR "${whoami}: Error: User ${login_name} not in password database\n";
|
||||
&unlockpw;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
($name, $password, $uid, $gid, $class, $change, $expire, $gecos, $home_dir,
|
||||
$shell) = split(/:/, $pw_ent);
|
||||
|
||||
if ($uid == 0) {
|
||||
print "${whoami}: Sorry, I'd rather not remove a user with a uid of 0.\n";
|
||||
&unlockpw;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
print "Matching password entry:\n\n$pw_ent\n\n";
|
||||
|
||||
$ans = &get_yn("Is this the entry you wish to remove? ");
|
||||
|
||||
if ($ans eq 'N') {
|
||||
print "User ${login_name} not removed.\n";
|
||||
&unlockpw;
|
||||
exit 0;
|
||||
}
|
||||
|
||||
#
|
||||
# Get owner of user's home directory; don't remove home dir if not
|
||||
# owned by $login_name
|
||||
|
||||
$remove_directory = 1;
|
||||
|
||||
if (-l $home_dir) {
|
||||
$real_home_dir = &resolvelink($home_dir);
|
||||
} else {
|
||||
$real_home_dir = $home_dir;
|
||||
}
|
||||
|
||||
#
|
||||
# If home_dir is a symlink and points to something that isn't a directory,
|
||||
# or if home_dir is not a symlink and is not a directory, don't remove
|
||||
# home_dir -- seems like a good thing to do, but probably isn't necessary...
|
||||
if (((-l $home_dir) && ((-e $real_home_dir) && !(-d $real_home_dir))) ||
|
||||
(!(-l $home_dir) && !(-d $home_dir))) {
|
||||
print STDERR "${whoami}: Home ${home_dir} is not a directory, so it won't be removed\n";
|
||||
$remove_directory = 0;
|
||||
}
|
||||
|
||||
if (length($real_home_dir) && -d $real_home_dir) {
|
||||
$dir_owner = (stat($real_home_dir))[4]; # UID
|
||||
if ($dir_owner != $uid) {
|
||||
print STDERR "${whoami}: Home dir ${real_home_dir} is not owned by ${login_name} (uid ${dir_owner})\n";
|
||||
$remove_directory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ($remove_directory) {
|
||||
$ans = &get_yn("Remove user's home directory ($home_dir)? ");
|
||||
if ($ans eq 'N') {
|
||||
$remove_directory = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#exit 0 if $debug;
|
||||
|
||||
#
|
||||
# Remove the user's crontab, if there is one
|
||||
# (probably needs to be done before password databases are updated)
|
||||
|
||||
if (-e "$crontab_dir/$login_name") {
|
||||
print STDERR "Removing user's crontab:";
|
||||
system('/usr/bin/crontab', '-u', $login_name, '-r');
|
||||
print STDERR " done.\n";
|
||||
}
|
||||
|
||||
#
|
||||
# Remove the user's at jobs, if any
|
||||
# (probably also needs to be done before password databases are updated)
|
||||
|
||||
&remove_at_jobs($login_name, $uid);
|
||||
|
||||
#
|
||||
# Copy master password file to new file less removed user's entry
|
||||
|
||||
&update_passwd_file;
|
||||
|
||||
#
|
||||
# Remove the user from all groups in /etc/group
|
||||
|
||||
&update_group_file($login_name);
|
||||
|
||||
#
|
||||
# Remove the user's home directory
|
||||
|
||||
if ($remove_directory) {
|
||||
print STDERR "Removing user's home directory ($home_dir):";
|
||||
&remove_dir($home_dir);
|
||||
print STDERR " done.\n";
|
||||
}
|
||||
|
||||
#
|
||||
# Remove the user's incoming mail file
|
||||
|
||||
if (-e "$mail_dir/$login_name" || -l "$mail_dir/$login_name") {
|
||||
print STDERR "Removing user's incoming mail file ($mail_dir/$login_name):";
|
||||
unlink "$mail_dir/$login_name" ||
|
||||
print STDERR "\n${whoami}: warning: unlink on $mail_dir/$login_name failed ($!) - continuing\n";
|
||||
print STDERR " done.\n";
|
||||
}
|
||||
|
||||
#
|
||||
# All done!
|
||||
|
||||
exit 0;
|
||||
|
||||
sub get_login_name {
|
||||
#
|
||||
# Get new user's name
|
||||
local($done, $login_name);
|
||||
|
||||
for ($done = 0; ! $done; ) {
|
||||
print "Enter login name for user to remove: ";
|
||||
$login_name = <>;
|
||||
chop $login_name;
|
||||
if (!($login_name =~ /[A-Za-z0-9_]/)) {
|
||||
print STDERR "Sorry, login name must contain alphanumeric characters only.\n";
|
||||
} elsif (length($login_name) > 8 || length($login_name) == 0) {
|
||||
print STDERR "Sorry, login name must be eight characters or less.\n";
|
||||
} else {
|
||||
$done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
print "User name is ${login_name}\n" if $debug;
|
||||
return($login_name);
|
||||
}
|
||||
|
||||
sub check_login_name {
|
||||
#
|
||||
# Check to see whether login name is in password file
|
||||
local($login_name) = @_;
|
||||
local($Mname, $Mpassword, $Muid, $Mgid, $Mclass, $Mchange, $Mexpire,
|
||||
$Mgecos, $Mhome_dir, $Mshell);
|
||||
local($i);
|
||||
|
||||
seek(MASTER_PW, 0, 0);
|
||||
while ($i = <MASTER_PW>) {
|
||||
chop $i;
|
||||
($Mname, $Mpassword, $Muid, $Mgid, $Mclass, $Mchange, $Mexpire,
|
||||
$Mgecos, $Mhome_dir, $Mshell) = split(/:/, $i);
|
||||
if ($Mname eq $login_name) {
|
||||
seek(MASTER_PW, 0, 0);
|
||||
return($i); # User is in password database
|
||||
}
|
||||
}
|
||||
seek(MASTER_PW, 0, 0);
|
||||
|
||||
return '0'; # User wasn't found
|
||||
}
|
||||
|
||||
sub get_yn {
|
||||
#
|
||||
# Get a yes or no answer; return 'Y' or 'N'
|
||||
local($prompt) = @_;
|
||||
local($done, $ans);
|
||||
|
||||
for ($done = 0; ! $done; ) {
|
||||
print $prompt;
|
||||
$ans = <>;
|
||||
chop $ans;
|
||||
$ans =~ tr/a-z/A-Z/;
|
||||
if (!($ans =~ /^[YN]/)) {
|
||||
print STDERR "Please answer (y)es or (n)o.\n";
|
||||
} else {
|
||||
$done = 1;
|
||||
}
|
||||
}
|
||||
|
||||
return(substr($ans, 0, 1));
|
||||
}
|
||||
|
||||
sub update_passwd_file {
|
||||
local($skipped, $i);
|
||||
|
||||
print STDERR "Updating password file,";
|
||||
seek(MASTER_PW, 0, 0);
|
||||
open(NEW_PW, ">$new_passwd_file") ||
|
||||
die "\n${whoami}: Error: Couldn't open file ${new_passwd_file}:\n $!\n";
|
||||
chmod(0600, $new_passwd_file) ||
|
||||
print STDERR "\n${whoami}: warning: couldn't set mode of $new_passwd_file to 0600 ($!)\n\tcontinuing, but please check mode of /etc/master.passwd!\n";
|
||||
$skipped = 0;
|
||||
while ($i = <MASTER_PW>) {
|
||||
if ($i =~ /\n$/) {
|
||||
chop $i;
|
||||
}
|
||||
if ($i ne $pw_ent) {
|
||||
print NEW_PW "$i\n";
|
||||
} else {
|
||||
print STDERR "Dropped entry for $login_name\n" if $debug;
|
||||
$skipped = 1;
|
||||
}
|
||||
}
|
||||
close(NEW_PW);
|
||||
seek(MASTER_PW, 0, 0);
|
||||
|
||||
if ($skipped == 0) {
|
||||
print STDERR "\n${whoami}: Whoops! Didn't find ${login_name}'s entry second time around!\n";
|
||||
unlink($new_passwd_file) ||
|
||||
print STDERR "\n${whoami}: warning: couldn't unlink $new_passwd_file ($!)\n\tPlease investigate, as this file should not be left in the filesystem\n";
|
||||
&unlockpw;
|
||||
exit 1;
|
||||
}
|
||||
|
||||
#
|
||||
# Run pwd_mkdb to install the updated password files and databases
|
||||
|
||||
print STDERR " updating databases,";
|
||||
system('/usr/sbin/pwd_mkdb', '-p', ${new_passwd_file});
|
||||
print STDERR " done.\n";
|
||||
|
||||
close(MASTER_PW); # Not useful anymore
|
||||
}
|
||||
|
||||
sub update_group_file {
|
||||
local($login_name) = @_;
|
||||
|
||||
local($i, $j, $grmember_list, $new_grent);
|
||||
local($grname, $grpass, $grgid, $grmember_list, @grmembers);
|
||||
|
||||
print STDERR "Updating group file:";
|
||||
open(GROUP, $group_file) ||
|
||||
die "\n${whoami}: Error: couldn't open ${group_file}: $!\n";
|
||||
if (!flock(GROUP, &LOCK_EX|&LOCK_NB)) {
|
||||
print STDERR "\n${whoami}: Error: couldn't lock ${group_file}: $!\n";
|
||||
exit 1;
|
||||
}
|
||||
local($group_perms, $group_uid, $group_gid) =
|
||||
(stat(GROUP))[2, 4, 5]; # File Mode, uid, gid
|
||||
open(NEW_GROUP, ">$new_group_file") ||
|
||||
die "\n${whoami}: Error: couldn't open ${new_group_file}: $!\n";
|
||||
chmod($group_perms, $new_group_file) ||
|
||||
printf STDERR "\n${whoami}: warning: could not set permissions of new group file to %o ($!)\n\tContinuing, but please check permissions of $group_file!\n", $group_perms;
|
||||
chown($group_uid, $group_gid, $new_group_file) ||
|
||||
print STDERR "\n${whoami}: warning: could not set owner/group of new group file to ${group_uid}/${group_gid} ($!)\n\rContinuing, but please check ownership of $group_file!\n";
|
||||
while ($i = <GROUP>) {
|
||||
if (!($i =~ /$login_name/)) {
|
||||
# Line doesn't contain any references to the user, so just add it
|
||||
# to the new file
|
||||
print NEW_GROUP $i;
|
||||
} else {
|
||||
#
|
||||
# Remove the user from the group
|
||||
if ($i =~ /\n$/) {
|
||||
chop $i;
|
||||
}
|
||||
($grname, $grpass, $grgid, $grmember_list) = split(/:/, $i);
|
||||
@grmembers = split(/,/, $grmember_list);
|
||||
undef @new_grmembers;
|
||||
local(@new_grmembers);
|
||||
foreach $j (@grmembers) {
|
||||
if ($j ne $login_name) {
|
||||
push(new_grmembers, $j);
|
||||
} elsif ($debug) {
|
||||
print STDERR "Removing $login_name from group $grname\n";
|
||||
}
|
||||
}
|
||||
if ($grname eq $login_name && $#new_grmembers == -1) {
|
||||
# Remove a user's personal group if empty
|
||||
print STDERR "Removing group $grname -- personal group is empty\n";
|
||||
} else {
|
||||
$grmember_list = join(',', @new_grmembers);
|
||||
$new_grent = join(':', $grname, $grpass, $grgid, $grmember_list);
|
||||
print NEW_GROUP "$new_grent\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
close(NEW_GROUP);
|
||||
rename($new_group_file, $group_file) || # Replace old group file with new
|
||||
die "\n${whoami}: error: couldn't rename $new_group_file to $group_file ($!)\n";
|
||||
close(GROUP); # File handle is worthless now
|
||||
print STDERR " done.\n";
|
||||
}
|
||||
|
||||
sub remove_dir {
|
||||
# Remove the user's home directory
|
||||
local($dir) = @_;
|
||||
local($linkdir);
|
||||
|
||||
if (-l $dir) {
|
||||
$linkdir = &resolvelink($dir);
|
||||
# Remove the symbolic link
|
||||
unlink($dir) ||
|
||||
warn "${whoami}: Warning: could not unlink symlink $dir: $!\n";
|
||||
if (!(-e $linkdir)) {
|
||||
#
|
||||
# Dangling symlink - just return now
|
||||
return;
|
||||
}
|
||||
# Set dir to be the resolved pathname
|
||||
$dir = $linkdir;
|
||||
}
|
||||
if (!(-d $dir)) {
|
||||
print STDERR "${whoami}: Warning: $dir is not a directory\n";
|
||||
unlink($dir) || warn "${whoami}: Warning: could not unlink $dir: $!\n";
|
||||
return;
|
||||
}
|
||||
system('/bin/rm', '-rf', $dir);
|
||||
}
|
||||
|
||||
sub remove_at_jobs {
|
||||
local($login_name, $uid) = @_;
|
||||
local($i, $owner, $found);
|
||||
|
||||
$found = 0;
|
||||
opendir(ATDIR, $atjob_dir) || return;
|
||||
while ($i = readdir(ATDIR)) {
|
||||
next if $i eq '.';
|
||||
next if $i eq '..';
|
||||
next if $i eq '.lockfile';
|
||||
|
||||
$owner = (stat("$atjob_dir/$i"))[4]; # UID
|
||||
if ($uid == $owner) {
|
||||
if (!$found) {
|
||||
print STDERR "Removing user's at jobs:";
|
||||
$found = 1;
|
||||
}
|
||||
# Use atrm to remove the job
|
||||
print STDERR " $i";
|
||||
system('/usr/bin/atrm', $i);
|
||||
}
|
||||
}
|
||||
closedir(ATDIR);
|
||||
if ($found) {
|
||||
print STDERR " done.\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub resolvelink {
|
||||
local($path) = @_;
|
||||
local($l);
|
||||
|
||||
while (-l $path && -e $path) {
|
||||
if (!defined($l = readlink($path))) {
|
||||
die "${whoami}: readlink on $path failed (but it should have worked!): $!\n";
|
||||
}
|
||||
if ($l =~ /^\//) {
|
||||
# Absolute link
|
||||
$path = $l;
|
||||
} else {
|
||||
# Relative link
|
||||
$path =~ s/\/[^\/]+\/?$/\/$l/; # Replace last component of path
|
||||
}
|
||||
}
|
||||
return $path;
|
||||
}
|
Loading…
Reference in New Issue
Block a user