home *** CD-ROM | disk | FTP | other *** search
- #!/usr/bin/perl -w
-
- #########################################################################
- # #
- # ADDUSER Local System Additions v4.6 #
- # Copyright (C) 1999-2004, John Zaitseff #
- # #
- #########################################################################
-
- # Author: John Zaitseff <J.Zaitseff@zap.org.au>
- # Date: 23rd September, 2004
- # Version: 4.6
-
- # This program, once installed as /usr/local/sbin/adduser.local, is auto-
- # matically called by the adduser(8) system program on a Debian system.
- # This script completes the creation of a user account in a system-
- # dependent way.
- #
- # This script is automatically called by adduser with arguments "username
- # uid gid homedir". See adduser(8) for more details. In addition, this
- # script may be called manually. In this case, the following syntax
- # applies:
- #
- # /usr/local/sbin/adduser.local [options] username [uid gid homedir]
- #
- # where the following options exist:
- #
- # --dry-run -n - Pretend to fulfil everything required, without
- # doing anything.
- # --quiet -q - Don't show extraneous information.
- # --verbose -v - Show information about what was done (default).
- # --help -h - Show a brief command-line summary.
- # --version -V - Show the version of the adduser.local script.
- # --conf <file> - Use configuration file <file> instead of the
- # default /etc/adduser.local.conf.
-
-
- # This program, including associated files, is free software. You may
- # distribute it and/or modify it under the terms of the GNU General Public
- # License as published by the Free Software Foundation; either Version 2
- # of the license, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful, but
- # WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- # General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License along
- # with this program; if not, write to the Free Software Foundation, Inc.,
- # 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-
-
- #########################################################################
- # Configuration parameters and default values
-
- use strict;
-
-
- (our $O = $0) =~ s,^.*/,,; # adduser.local script name (without path)
- our $version = '4.6'; # Script version
-
- our @adduser = ('/usr/sbin/adduser', '--quiet'); # adduser(8)
- our @chown = ('/bin/chown'); # chown(1)
- our @install = ('/usr/bin/install', '-p'); # install(1)
-
- our $procmounts = '/proc/mounts'; # List of current mounts
-
- our $s_false = 'false'; # False string value, in lower case
- our $s_true = 'true'; # True string value, in lower case
-
- # These default values are extensively documented in adduser.local.conf.
-
- our $d_conffile = '/etc/adduser.local.conf'; # Configuration file location
- our $d_skelother = '/etc/skel.other'; # Location of skeleton files
- our $d_dirmode = '2755'; # Octal mode for directories
- our $d_filemode = '0644'; # Octal mode for files
-
- our $d_user = ''; # Default service user name
- our $d_group = ''; # Default service group name
- our $d_addtogroup = $s_false; # Default for addtogroup variable
- our $d_homedir = ''; # Default home directory
- our $d_subdir = ''; # Default subdirectory
- our $d_althome = $s_false; # Default for use alternate home directory
- our $d_mounted = $s_false; # Default for checking if mounted
- our $d_mkdir = $s_false; # Default for creating directory
- our $d_chgrpdir = $s_false; # Default for chgrpdir variable
- our $d_mklink = $s_false; # Default for creating symbolic link
- our $d_linkname = ''; # Default for symbolic link name
- our $d_skelfile = ''; # Default for skeleton file
- our $d_chgrpskel = $s_false; # Default for chgrpskel variable
-
- # Various strings appearing in the configuration file. While they are
- # case insensitive in the configuration file, they must appear in lower
- # case here.
-
- our $s_skelother = 'skelother';
- our $s_dirmode = 'dirmode';
- our $s_filemode = 'filemode';
-
- our $s_service = 'service';
-
- our $s_user = 'user';
- our $s_group = 'group';
- our $s_addtogroup = 'addtogroup';
- our $s_homedir = 'homedir';
- our $s_subdir = 'subdir';
- our $s_althome = 'althome';
- our $s_mounted = 'mounted';
- our $s_mkdir = 'mkdir';
- our $s_chgrpdir = 'chgrpdir';
- our $s_mklink = 'mklink';
- our $s_linkname = 'linkname';
- our $s_skelfile = 'skelfile';
- our $s_chgrpskel = 'chgrpskel';
-
- our @s_false = ($s_false, 'f', 'no', 'n', '0');
- our @s_true = ($s_true, 't', 'yes', 'y', '1');
-
- # Strings internal to this program (as used by the %cv hash)
-
- our $s_svcuid = '.svcuid'; # Storage for UID of service's user name
- our $s_svcgid = '.svcgid'; # GID of service's user name or group name
- our $s_actualdir = '.actualdir'; # Actual dir: homedir + subdir + username
- our $s_actuallink = '.actuallink'; # Actual sym link: user homedir + linkname
- our $s_actualsrcf = '.actualsrcf'; # Actual source file: skelother + skelfile
- our $s_actualdstf = '.actualdstf'; # Actual dest file: actualdir + skelfile
-
- our $s_addtogroupB = '.addtogroupB'; # Boolean versions of variables
- our $s_althomeB = '.althomeB';
- our $s_mountedB = '.mountedB';
- our $s_mkdirB = '.mkdirB';
- our $s_chgrpdirB = '.chgrpdirB';
- our $s_mklinkB = '.mklinkB';
- our $s_chgrpskelB = '.chgrpskelB';
-
-
- #########################################################################
- # Initialise global variables
-
- our $conffile = $d_conffile; # Default configuration file
- our $verbose = 1; # Be verbose by default
- our $dryrun = 0; # NOT a dry run by default
-
- our @services = (); # No services to install by default
-
- # %cv is a hash for all configuration variables read in from the
- # configuration file. Global variables are represented by their strings,
- # eg, $cv{"skelother"}. Service-specific variables are represented by the
- # service string value, a comma, then their string, eg, $cv{"www","user"}.
- # The %cl hash plays a similar role, but contains the line number of the
- # configuration.
-
- our (%cv, %cl);
-
- $cv{$s_skelother} = $d_skelother; $cl{$s_skelother} = 0;
- $cv{$s_dirmode} = $d_dirmode; $cl{$s_dirmode} = 0;
- $cv{$s_filemode} = $d_filemode; $cl{$s_filemode} = 0;
-
- # For safety's sake, initialise the PATH environment variable
-
- $ENV{PATH} = '/usr/sbin:/usr/bin:/sbin:/bin';
-
- # Declare some global variables
-
- our $username; # Username for which adduser.local was called
- our $uid; # User's UID
- our $gid; # User's GID
- our $homedir; # User's home directory
-
-
- #########################################################################
- # Process command-line arguments
-
- while ($_ = $ARGV[0]) {
- last if (! /^-/);
- shift @ARGV;
- last if ($_ eq '--');
-
- # Split combined short-form options into single arguments
- if (/^-(\w{2,})/) {
- my @args = split //, $1;
-
- foreach my $arg (@args) {
- $arg = "-$arg";
- }
- unshift @ARGV, @args;
- next;
- }
-
- # Process command-line options
- if (($_ eq '--conf') || ($_ eq '-c')) { # --conf filename
- &chkparam($_);
- $conffile = shift @ARGV;
- }
-
- elsif (($_ eq '--dry-run') || ($_ eq '-n')) { # --dry-run
- $dryrun = 1;
- }
-
- elsif (($_ eq '--quiet') || ($_ eq '-q')) { # --quiet
- $verbose = 0;
- }
-
- elsif (($_ eq '--verbose') || ($_ eq '-v')) { # --verbose
- $verbose = 1;
- }
-
- elsif (($_ eq '--help') || ($_ eq '-h')) { # --help
- &showusage();
- exit(0);
- }
-
- elsif (($_ eq '--version') || ($_ eq '-V')) { # --version
- &showversion();
- exit(0);
- }
-
- else {
- &showcmdlerr("Unrecognised option: $_");
- }
- }
-
-
- #########################################################################
- # Process additional command-line parameters: username [uid gid homedir]
-
- if ($#ARGV < 0) { &showcmdlerr("Missing username parameter"); }
- if ($#ARGV > 3) { &showcmdlerr("Too many command-line parameters"); }
-
- # Include some sanity checking. These checks are not particularly
- # rigorous, as root can do anything anyway... It is meant to stop silly
- # mistakes, not to stop thinking. In any case, this script SHOULD only be
- # called from adduser(8)...
-
- die "$O: Only root can execute this program\n" if ($> != 0) && (! $dryrun);
-
- if ($#ARGV == 0) {
- # Only a single parameter: username
-
- $username = $ARGV[0];
-
- (my $t_name, my $t1, $uid, $gid, my $t2, my $t3, my $t4, $homedir)
- = getpwnam($username);
-
- die "$O: No such user: $username\n" if ! $t_name;
-
- } elsif ($#ARGV == 3) {
- # Four parameters: username uid gid homedir
-
- $username = $ARGV[0];
- $uid = $ARGV[1];
- $gid = $ARGV[2];
- $homedir = $ARGV[3];
-
- $homedir =~ s,/$,,; # Remove trailing '/' if present
- (my $t_name, my $t1, my $t_uid, my $t_gid) = getpwnam($username);
-
- die "$O: No such user: $username\n" if ! $t_name;
- die "$O: No such UID: $uid\n" if ! getpwuid($uid);
- die "$O: No such GID: $gid\n" if ! getgrgid($gid);
- die "$O: UID of user $username not the same as $uid\n" if $t_uid != $uid;
- die "$O: GID of user $username not the same as $gid\n" if $t_gid != $gid;
- die "$O: Directory $homedir does not exist\n" if ! -d $homedir;
-
- } else {
- &showcmdlerr("Missing uid, gid and/or homedir parameters");
- }
-
-
- #########################################################################
- # Process the configuration file
-
- if (! -r $conffile) {
- warn "$O: Cannot read configuration file $conffile:\n";
- warn "$O: $conffile: $!\n";
-
- exit(0);
- }
-
- print "Processing configuration file $conffile\n" if $verbose;
-
- open(CONFFILE, $conffile) || die "$O: $conffile: $!\n";
- while (<CONFFILE>) {
- my ($var, $svc, $val);
-
- chomp;
-
- # Skip comments and blank lines
- next if /^\s*#/ || /^\s*$/;
-
- # Try matching a global variable with or without quotes
- if ((($var, $val) = /^\s*(\w+)\s*=\s*(.*)/) == 2) {
-
- # Remove trailing spaces and surrounding quotes
- # (Technically, doing it this way is somewhat sloppy)
- $val =~ s/^(.*?)\s*$/$1/;
- $val =~ s/^\"(.*)\"/$1/;
- $val =~ s/^\'(.*)\'/$1/;
-
- my $lcvar = lc $var;
- my $lcval = lc $val;
-
- # Process the global variable
- if ($lcvar eq $s_service) {
-
- # Special global configuration variable "service"
- my $svc = $lcval;
-
- if (grep((lc $_) eq $svc, @services)) {
- warn "$O: Service \"$val\" redefined at $conffile:$.\n";
- next;
- }
-
- push @services, $val;
-
- # Set up default values
-
- $cv{$svc,$s_user} = $d_user;
- $cv{$svc,$s_group} = $d_group;
- $cv{$svc,$s_addtogroup} = $d_addtogroup;
- $cv{$svc,$s_homedir} = $d_homedir;
- $cv{$svc,$s_subdir} = $d_subdir;
- $cv{$svc,$s_althome} = $d_althome;
- $cv{$svc,$s_mounted} = $d_mounted;
- $cv{$svc,$s_mkdir} = $d_mkdir;
- $cv{$svc,$s_chgrpdir} = $d_chgrpdir;
- $cv{$svc,$s_mklink} = $d_mklink;
- $cv{$svc,$s_linkname} = $d_linkname;
- $cv{$svc,$s_skelfile} = $d_skelfile;
- $cv{$svc,$s_chgrpskel} = $d_chgrpskel;
-
- $cl{$svc,$s_user} = 0;
- $cl{$svc,$s_group} = 0;
- $cl{$svc,$s_addtogroup} = 0;
- $cl{$svc,$s_homedir} = 0;
- $cl{$svc,$s_subdir} = 0;
- $cl{$svc,$s_althome} = 0;
- $cl{$svc,$s_mounted} = 0;
- $cl{$svc,$s_mkdir} = 0;
- $cl{$svc,$s_chgrpdir} = 0;
- $cl{$svc,$s_mklink} = 0;
- $cl{$svc,$s_linkname} = 0;
- $cl{$svc,$s_skelfile} = 0;
- $cl{$svc,$s_chgrpskel} = 0;
- }
- else {
- # Ordinary global variable
-
- if (! defined($cv{$lcvar})) {
- warn "$O: Unknown global variable \"$var\" at $conffile:$.\n";
- next;
- }
-
- $cv{$lcvar} = $val;
- $cl{$lcvar} = $.;
- }
- }
-
- # Try matching a service variable with or without quotes
- elsif ((($var, $svc, $val) = /^\s*(\w+)\s*\[\s*(\w+)\s*\]\s*=\s*(.*)/) == 3) {
-
- # Remove trailing spaces and surrounding quotes
- $val =~ s/^(.*?)\s*$/$1/;
- $val =~ s/^\"(.*)\"/$1/;
- $val =~ s/^\'(.*)\'/$1/;
-
- my $lcvar = lc $var;
- my $lcsvc = lc $svc;
-
- if (! grep((lc $_) eq $lcsvc, @services)) {
- warn "$O: Undefined service \"$svc\" at $conffile:$.\n";
- next;
- }
- if (! defined($cv{$lcsvc,$lcvar})) {
- warn "$O: Unknown service variable \"$var\" at $conffile:$.\n";
- next;
- }
-
- $cv{$lcsvc,$lcvar} = $val;
- $cl{$lcsvc,$lcvar} = $.;
- }
-
- # Otherwise, it is an error in the configuration file
- else {
- warn "$O: Could not parse $conffile:$.\n";
- next;
- }
- }
-
- close(CONFFILE) || die "$O: $conffile: $!\n";
-
-
- #########################################################################
- # Global variables sanity checking
- {
- my $t;
-
- # Check "skelother"
-
- if (! -d $cv{$s_skelother}) {
- warn "$O: Directory $cv{$s_skelother} does not exist\n";
- }
-
- # Check "dirmode"
-
- $t = $cv{$s_dirmode};
- if (($t !~ /^[01234567]{1,4}$/) || (oct($t) == 0)) {
- warn "$O: Illegal value \"$t\" at $conffile:$cl{$s_dirmode}\n";
- warn "$O: Global variable \"$s_dirmode\" set to $d_dirmode\n";
- $cv{$s_dirmode} = $d_dirmode;
- }
-
- # Check "filemode"
-
- $t = $cv{$s_filemode};
- if (($t !~ /^[01234567]{1,4}$/) || (oct($t) == 0)) {
- warn "$O: Illegal value \"$t\" at $conffile:$cl{$s_filemode}\n";
- warn "$O: Global variable \"$s_filemode\" set to $d_filemode\n";
- $cv{$s_filemode} = $d_filemode;
- }
- }
-
-
- #########################################################################
- # Actually perform what is required, with appropriate error checking
-
- foreach my $service (@services) {
-
- my $svc = lc $service;
- my ($t_user, $t_group, $t_homedir);
-
- print "Processing service \"$service\"\n" if $verbose;
-
- # Check validity of all boolean variables and convert them to true bools
-
- # Note that the notation $hash{$idx1,$idx2} is exactly the same as the
- # expression $hash{$idx1 . $; . $idx2}. It is for this reason that
- # $svcc is defined.
-
- my $svcc = $svc . $;; # $svc concatenated with $; ($SUBSEP)
-
- &chkbool($svcc.$s_addtogroup, $svcc.$s_addtogroupB, $d_addtogroup, "$s_addtogroup\[$service\]");
- &chkbool($svcc.$s_althome, $svcc.$s_althomeB, $d_althome, "$s_althome\[$service\]");
- &chkbool($svcc.$s_mounted, $svcc.$s_mountedB, $d_mounted, "$s_mounted\[$service\]");
- &chkbool($svcc.$s_mkdir, $svcc.$s_mkdirB, $d_mkdir, "$s_mkdir\[$service\]");
- &chkbool($svcc.$s_chgrpdir, $svcc.$s_chgrpdirB, $d_chgrpdir, "$s_chgrpdir\[$service\]");
- &chkbool($svcc.$s_mklink, $svcc.$s_mklinkB, $d_mklink, "$s_mklink\[$service\]");
- &chkbool($svcc.$s_chgrpskel, $svcc.$s_chgrpskelB, $d_chgrpskel, "$s_chgrpskel\[$service\]");
-
- # Process the "user" configuration variable
-
- if ($cv{$svc,$s_user} ne '') {
- # Retrieve information about the specified service's user name
-
- (my $t_user, my $t1, $cv{$svc,$s_svcuid}, $cv{$svc,$s_svcgid},
- my $t2, my $t3, my $t4, my $t_homedir)
- = getpwnam $cv{$svc,$s_user};
-
- if (! $t_user) {
- warn "$O: Illegal user name \"$cv{$svc,$s_user}\" at $conffile:$cl{$svc,$s_user}\n";
- } else {
- $cv{$svc,$s_user} = $t_user;
- }
-
- # Only set home directory information if not specified by user
- if ($cv{$svc,$s_homedir} eq '') {
- if ($cv{$svc,$s_althomeB}) {
- $cv{$svc,$s_homedir} = $homedir; # From command line
- } else {
- $cv{$svc,$s_homedir} = $t_homedir; # From service's home
- }
- }
-
- # If the group parameter is not specified, get the appropriate info
- # from the user information
- if ($cv{$svc,$s_svcgid} && ($cv{$svc,$s_group} eq '')) {
- ($cv{$svc,$s_group}) = getgrgid $cv{$svc,$s_svcgid};
- }
- }
-
- # Process the "group" configuration variable
-
- if ($cv{$svc,$s_group} ne '') {
- # Retrieve info about the group. Yes, it may have been done
- # above, but specifying "group" can be done without specifying
- # "user". In addition, a different group can be specified from
- # that used by "user".
-
- ($t_group, my $t1, $cv{$svc,$s_svcgid}) = getgrnam $cv{$svc,$s_group};
-
- if (! $t_group) {
- warn "$O: Illegal group name \"$cv{$svc,$s_group}\" at $conffile:$cl{$svc,$s_group}\n";
-
- $cv{$svc,$s_addtogroup} = $s_false; $cv{$svc,$s_addtogroupB} = 0;
- $cv{$svc,$s_chgrpdir} = $s_false; $cv{$svc,$s_chgrpdirB} = 0;
- $cv{$svc,$s_chgrpskel} = $s_false; $cv{$svc,$s_chgrpskelB} = 0;
- }
- else {
- $cv{$svc,$s_group} = $t_group;
- }
- }
-
- # Process the "addtogroup" configuration variable
-
- if ($cv{$svc,$s_addtogroupB} && ($cv{$svc,$s_group} ne '')) {
-
- my $t = $cv{$svc,$s_group};
- (my $t_group, my $t1, my $t_gid, my $t_members) = getgrnam $t;
-
- # Check if the user is already a member of that group
-
- if (($t_gid == $gid) || grep($_ eq $username, split(' ', $t_members))) {
- print " User \"$username\" already in group \"$t\"\n"
- if $verbose;
- } else {
- print " Adding user \"$username\" to group \"$t\"\n"
- if $verbose;
- system(@adduser, $username, $t) if ! $dryrun;
- }
- }
-
- # Process the "mounted" configuration variable
-
- $cv{$svc,$s_homedir} =~ s,/$,,; # Remove trailing / on homedir
- $cv{$svc,$s_subdir} =~ s,^/,,; # Remove leading / on subdir
- $cv{$svc,$s_subdir} =~ s,/$,,; # Remove trailing / on subdir
-
- if (($cv{$svc,$s_homedir} ne '') && $cv{$svc,$s_mountedB}) {
- # Need to check for "mounted" before checking for the existence of
- # of the service's home directory.
-
- if (! -r $procmounts) {
- warn "$O: $procmounts: $!\n";
- } else {
- my ($t_dev, $t_mntpoint, $t_type, $t_options);
- my $ismounted = 0;
- my $t_dir = $cv{$svc,$s_homedir} . '/';
-
- # Open mounts table and process it
-
- open(MOUNTS, $procmounts) || die "$O: $procmounts: $!\n";
- while (<MOUNTS>) {
- chomp;
- ($t_dev, $t_mntpoint, $t_type, $t_options) = split;
- if ($t_mntpoint !~ m,/$,) { $t_mntpoint .= '/'; }
-
- # Check if the service's home directory is mounted
- # Skip "/" as that is always mounted
- if (($t_mntpoint ne '/') &&
- (substr($t_dir, 0, length($t_mntpoint))
- eq $t_mntpoint)) {
- $ismounted = 1;
- }
- }
- close(MOUNTS) || die "$O: $procmounts: $!\n";
-
- if (! $ismounted) {
- print " Directory $cv{$svc,$s_homedir} not mounted\n"
- if $verbose;
- $cv{$svc,$s_homedir} = '';
- }
- }
- }
-
- # Process the "homedir" and "subdir" configuration variables
-
- if ($cv{$svc,$s_homedir} ne '') {
- if (! -d $cv{$svc,$s_homedir}) {
- warn "$O: Directory $cv{$svc,$s_homedir} does not exist\n";
- $cv{$svc,$s_homedir} = '';
- }
- elsif (($cv{$svc,$s_subdir} ne '') && (! $cv{$svc,$s_althomeB})) {
- my $t = $cv{$svc,$s_homedir} . '/' . $cv{$svc,$s_subdir};
- if (! -d $t) {
- warn "$O: Directory $t does not exist\n";
- $cv{$svc,$s_subdir} = '';
- $cv{$svc,$s_homedir} = '';
- }
- }
- }
-
- # Calculate the actual directory to create (if necessary)
-
- if ($cv{$svc,$s_homedir} ne '') {
- $cv{$svc,$s_actualdir} = $cv{$svc,$s_homedir};
- if ($cv{$svc,$s_subdir} ne '') {
- $cv{$svc,$s_actualdir} .= '/' . $cv{$svc,$s_subdir};
- }
- if (! $cv{$svc,$s_althomeB}) {
- $cv{$svc,$s_actualdir} .= '/' . $username;
- }
- }
-
- # Process the "mkdir" and "chgrpdir" configuration variables
-
- if (($cv{$svc,$s_homedir} ne '') && $cv{$svc,$s_mkdirB}) {
- my $t = $cv{$svc,$s_actualdir};
-
- if (-d $t) {
- print " Directory $t already exists\n" if $verbose;
- } elsif (-e $t) {
- warn "$O: $t is not a directory\n";
- $cv{$svc,$s_homedir} = '';
- } else {
- print " Directory $t created\n" if $verbose;
- mkdir($t, oct($cv{$s_dirmode})) if ! $dryrun;
- # Note that this newly-created directory will inherit the
- # SGID (set group ID) bit from its parent directory. This
- # IS desired, hence, do NOT do a separate chmod()!
- if ($cv{$svc,$s_chgrpdirB}) {
- chown($uid, $cv{$svc,$s_svcgid}, $t) if ! $dryrun;
- } else {
- chown($uid, $gid, $t) if ! $dryrun;
- }
- }
- }
-
- # Process the "mklink" and "linkname" configuration variables
-
- if (($cv{$svc,$s_homedir} ne '') && $cv{$svc,$s_mklinkB}
- && (-d $cv{$svc,$s_actualdir})) {
-
- # Calculate the actual link name
-
- $cv{$svc,$s_linkname} =~ s,/$,,; # Remove trailing '/'
-
- if ($cv{$svc,$s_linkname} eq '') {
- $cv{$svc,$s_actuallink} = $homedir . '/' . $service;
- } else {
- $cv{$svc,$s_actuallink} = $homedir . '/' . $cv{$svc,$s_linkname};
- }
-
- # Create the symbolic link, if needed
-
- my $t = $cv{$svc,$s_actuallink};
- if (-l $t) {
- print " Symbolic link $t already exists\n"
- if $verbose;
- } elsif (-e $t) {
- warn "$O: $t is not a symbolic link\n";
- } else {
- print " Symbolic link $t created\n" if $verbose;
- symlink($cv{$svc,$s_actualdir}, $t) if ! $dryrun;
- if ($cv{$svc,$s_chgrpdirB}) {
- &lchown($uid, $cv{$svc,$s_svcgid}, $t) if ! $dryrun;
- } else {
- &lchown($uid, $gid, $t) if ! $dryrun;
- }
- # Note that chown can NOT be used on Linux versions 2.1.81
- # or later, as it changes the ownership of the TARGET of
- # the symbolic link.
- }
- }
-
- # Process the "skelfile" and "chgrpskel" configuration variables
-
- if (($cv{$svc,$s_homedir} ne '') && ($cv{$svc,$s_skelfile} ne '')
- && (-d $cv{$svc,$s_actualdir})) {
-
- my $t = $cv{$svc,$s_skelfile};
- $cv{$svc,$s_actualsrcf} = $cv{$s_skelother} . '/' . $t;
- $cv{$svc,$s_actualdstf} = $cv{$svc,$s_actualdir} . '/' . $t;
-
- if (-e $cv{$svc,$s_actualdstf}) {
- print " File $cv{$svc,$s_actualdstf} already exists\n"
- if $verbose;
- } elsif (! -r $cv{$svc,$s_actualsrcf}) {
- warn "$O: $cv{$svc,$s_actualsrcf}: $!\n";
- } else {
- print " File $cv{$svc,$s_actualdstf} created\n" if $verbose;
- if ($cv{$svc,$s_chgrpskelB}) {
- system(@install, '-m', $cv{$s_filemode}, '-o', $uid,
- '-g', $cv{$svc,$s_svcgid},
- $cv{$svc,$s_actualsrcf}, $cv{$svc,$s_actualdstf})
- if ! $dryrun;
- } else {
- system(@install, '-m', $cv{$s_filemode}, '-o', $uid, '-g',
- $gid, $cv{$svc,$s_actualsrcf}, $cv{$svc,$s_actualdstf})
- if ! $dryrun;
- }
- }
- }
- }
-
-
- #########################################################################
- # End of program
-
- exit(0);
-
-
- #########################################################################
- # Show an error message relating to the command-line and terminate
-
- sub showcmdlerr {
- if (@_) {
- foreach my $line (@_) {
- warn "$O: $line\n";
- }
- }
-
- die "\nUsage:\n" .
- " $0 [--dry-run] [--conf filename]\n" .
- " [--quiet] [--verbose] [--help] [--version] [-nqvhV]\n" .
- " username [uid gid homedir]\n";
- }
-
-
- #########################################################################
- # Check that the next argument is a valid parameter
-
- sub chkparam ($) {
- my $arg = $_[0];
- if (! $ARGV[0] || ($ARGV[0] =~ /^-/)) {
- &showcmdlerr("Missing argument for $arg");
- }
- }
-
-
- #########################################################################
- # Check that the configuration variable contains is a valid boolean value
-
- sub chkbool ($$$$) {
- my $var = $_[0]; # Hash key of variable to check
- my $new = $_[1]; # Hash key of new variable, a true boolean
- my $def = $_[2]; # Default value, in case of error
- my $pvar = $_[3]; # Config. variable name (for warnings)
-
- my $val = lc $cv{$var};
-
- if (grep($_ eq $val, @s_true)) {
- $cv{$new} = 1;
- } elsif (grep($_ eq $val, @s_false)) {
- $cv{$new} = 0;
- } else {
- warn "$O: Illegal value \"$cv{$var}\" at $conffile:$cl{$var}\n";
- warn "$O: Variable \"$pvar\" set to $def\n";
-
- $cv{$var} = $def;
- &chkbool($var, $new, $def, $pvar);
- }
- }
-
-
- #########################################################################
- # A chown() that works with symbolic links
-
- sub lchown {
- # The chown() function does NOT change the ownership of symbolic links
- # under Linux 2.1.81 or later. Hence, make an external call to the
- # chown(1) program. This program MUST support the "-h" parameter.
-
- my $t_uid = shift;
- my $t_gid = shift;
-
- system(@chown, '-h', "$t_uid:$t_gid", @_);
- }
-
-
- #########################################################################
- # Display usage information
-
- sub showusage () {
- print <<"DATAEND"
-
- $O v$version --- adduser(8) local system additions.
- Copyright (C) 1999-2004, John Zaitseff.
-
- This program, once installed as /usr/local/sbin/adduser.local, is auto-
- matically called by the adduser(8) system program on a Debian system.
- This script completes the creation of a user account in a system-
- dependent way.
-
- This script is automatically called by adduser with arguments \"username
- uid gid homedir\". See adduser(8) for more details. In addition, this
- script may be called manually. In this case, the following syntax
- applies:
-
- /usr/local/sbin/adduser.local [options] username [uid gid homedir]
-
- where the following options exist:
-
- --dry-run -n - Pretend to fulfil everything required, without
- doing anything.
- --quiet -q - Don\'t show extraneous information.
- --verbose -v - Show information about what was done (default).
- --help -h - Show a brief command-line summary.
- --version -V - Show the version of the adduser.local script.
- --conf <file> - Use configuration file <file> instead of the
- default $d_conffile.
-
- DATAEND
-
- }
-
-
- #########################################################################
- # Display program version information
-
- sub showversion () {
- print <<"DATAEND"
-
- $O v$version --- adduser(8) local system additions.
- Copyright (C) 1999-2004, John Zaitseff.
-
- This program, including associated files, is distributed under the GNU General
- Public License. See /usr/share/common-licenses/GPL for more information.
-
- DATAEND
-
- }
-