Wolfram Schneider <wosch@cs.tu-berlin.de>:
o manpage o save configuration in /etc/adduser.conf o send message file (/etc/adduser.message) Submitted by: woschcs.tu-berlin.de
This commit is contained in:
parent
5a856815bb
commit
0cf90bc747
@ -1,26 +1,163 @@
|
||||
.Dd January 3, 1994
|
||||
.Dt ADDUSER 8
|
||||
.Os FreeBSD
|
||||
.\"
|
||||
.\" (c) Copyright 1995 Wolfram Schneider. 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.
|
||||
.\" 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. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by Wolfram Schneider
|
||||
.\" 4. 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 THE AUTHOR ``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 THE AUTHOR 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.
|
||||
.\"
|
||||
.\" /usr/sbin/adduser - add new user(s)
|
||||
.\"
|
||||
.\" Bugs: sure (my english!)
|
||||
.\" Email: Wolfram Schneider <wosch@cs.tu-berlin.de>
|
||||
.\"
|
||||
.\" $Id: adduser.8,v 1.4 1995/01/08 17:40:20 w Exp w $
|
||||
.\"
|
||||
|
||||
.Dd Jan, 9, 1995
|
||||
.Dt ADDUSER 8
|
||||
.Os FreeBSD 2.1
|
||||
.Sh NAME
|
||||
.Nm adduser
|
||||
|
||||
.Sh SYNOPSIS
|
||||
.Nm
|
||||
.Nd command for adding new users
|
||||
|
||||
.Sh DESCRIPTION
|
||||
.Nm Adduser
|
||||
is a simple program for adding new users. Adduser check
|
||||
passwd, group and shell database. It create passwd/group entry,
|
||||
HOME-directory, dotfiles and send new user a welcome message.
|
||||
|
||||
.Sh RESTRICTION
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Sy username
|
||||
Login name. Only lowercase characters or digits.
|
||||
.It Sy fullname
|
||||
Firstname an surname.
|
||||
.Ql Pa \:
|
||||
not allowed.
|
||||
.It Sy shell
|
||||
Only valid shells from shell database.
|
||||
.It Sy uid
|
||||
Automatic generated.
|
||||
.It Sy gid
|
||||
Automatic generated. Gid and uid are equal (if possible). Groupname
|
||||
is the same as username.
|
||||
.El
|
||||
|
||||
.Sh CONFIGURATION
|
||||
.Bl -tag -width Ds -compact
|
||||
.It Sy 1.
|
||||
Read intern variables.
|
||||
.It Sy 2.
|
||||
Read config file (/etc/adduser.conf)
|
||||
.It Sy 3.
|
||||
Parse command line options
|
||||
.El
|
||||
|
||||
.Sh OPTIONS
|
||||
.Bl -tag -width Ds
|
||||
.It Fl help
|
||||
Print options and exit.
|
||||
.It Fl silent
|
||||
Few warnings, question, bugreports.
|
||||
.It Fl verbose
|
||||
Many warning, question. Recommended for noivice users.
|
||||
.It Fl debug
|
||||
Debuging.
|
||||
.It Fl noconfig
|
||||
Do not read config file.
|
||||
.It Fl home Ar partition
|
||||
Default home partition where all users located.
|
||||
.It Fl shell Ar shell
|
||||
Default shell for new users.
|
||||
.It Fl dotdir Ar directory
|
||||
Copy files from .Ar directory into the HOME-directory of new users.
|
||||
.Ql Pa dot.foo
|
||||
files renamed to
|
||||
.Ql Pa .foo
|
||||
Don't copy files if
|
||||
.Ar directory
|
||||
equal with
|
||||
.Ar no
|
||||
.It Fl message Ar file
|
||||
Send new users a welcome message.
|
||||
Don't send message if
|
||||
.Ar file
|
||||
equal with
|
||||
.Ar no
|
||||
.It Fl create_conf
|
||||
Create new config and message file and exit.
|
||||
|
||||
.Sh FORMATS
|
||||
.Bl -tag -width Ds -compact
|
||||
.Ql Pa #
|
||||
is a commemt.
|
||||
|
||||
.P
|
||||
.It Sy config file
|
||||
.Nm Adduser
|
||||
is a perl script for adding users to the system. Still awaiting
|
||||
a man page entry for it but for now you can probably get away with just
|
||||
typing
|
||||
.Nm adduser
|
||||
and filling in the blanks.
|
||||
read and write this file.
|
||||
See /etc/adduser.conf for more details.
|
||||
.It Sy message file
|
||||
Eval variables in this file. See /etc/adduser.message for more
|
||||
details.
|
||||
.El
|
||||
|
||||
.Sh FILES
|
||||
Beats me. Wolfram? Man page please! :-)
|
||||
.Bl -tag -width /etc/master.passwdxx -compact
|
||||
.It Pa /etc/master.passwd
|
||||
user database
|
||||
.It Pa /etc/group
|
||||
group database
|
||||
.It Pa /etc/shells
|
||||
shell database
|
||||
.It Pa /etc/adduser.conf
|
||||
config file for adduser
|
||||
.It Pa /etc/adduser.message
|
||||
message file for adduser
|
||||
.It Pa /usr/share/skel
|
||||
skeletal login directory
|
||||
.It Pa /var/log/adduser
|
||||
logfile for adduser
|
||||
.El
|
||||
|
||||
.Sh SEE ALSO
|
||||
.Xr pwd_mkdb 8
|
||||
.Xr perl 1
|
||||
.Xr chpass 1 ,
|
||||
.Xr finger 1 ,
|
||||
.Xr passwd 1 ,
|
||||
.Xr aliases 5 ,
|
||||
.Xr passwd 5 ,
|
||||
.Xr group 5 ,
|
||||
.Xr shells 5 ,
|
||||
.Xr pwd_mkdb 8 ,
|
||||
.Xr vipw 8
|
||||
|
||||
.\" .Sh BUGS
|
||||
|
||||
.Sh HISTORY
|
||||
The adduser command first appeared in FreeBSD 2.0C (12-94) by Gary Clark, II.
|
||||
This newer version was submitted by Wolfram Schneider.
|
||||
The
|
||||
.Nm
|
||||
command appeared in FreeBSD 2.1
|
||||
|
||||
.\" .Sh AUTHOR
|
||||
.\" Wolfram Schneider, Berlin
|
||||
|
@ -12,7 +12,7 @@
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgement:
|
||||
# This product includes software developed by Wolfram Schneider
|
||||
# This product includes software developed by Wolfram Schneider
|
||||
# 4. The name of the author may not be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission
|
||||
#
|
||||
@ -32,33 +32,45 @@
|
||||
# Bugs: sure (my english!)
|
||||
# Email: Wolfram Schneider <wosch@cs.tu-berlin.de>
|
||||
#
|
||||
# $Id: adduser,v 1.17 1995/01/02 00:08:43 w Exp w $
|
||||
# $Id: adduser,v 1.40 1995/01/08 17:40:09 w Exp w $
|
||||
#
|
||||
|
||||
# read variables
|
||||
sub variables {
|
||||
$verbose = 1;
|
||||
$batch = 0; # batch mode
|
||||
$defaultpasswd = 0;
|
||||
$dotdir = "/usr/share/skel";
|
||||
|
||||
if (1) {
|
||||
$home = "/home";
|
||||
$shells = "/etc/shells";
|
||||
$passwd = "/etc/master.passwd";
|
||||
$verbose = 1; # verbose = [0-2]
|
||||
$defaultpasswd = "no"; # use password for new users
|
||||
$dotdir = "/usr/share/skel"; # copy dotfiles from this dir
|
||||
$send_message = "/etc/adduser.message"; # send message to new user
|
||||
$config = "/etc/adduser.conf"; # config file for adduser
|
||||
$config_read = 1; # read config file
|
||||
$logfile = "/var/log/adduser"; # logfile
|
||||
$home = "/home"; # default HOME
|
||||
$etc_shells = "/etc/shells";
|
||||
$etc_passwd = "/etc/master.passwd";
|
||||
$group = "/etc/group";
|
||||
$pwd_mkdb = "pwd_mkdb -p";
|
||||
} else {
|
||||
$pwd_mkdb = "pwd_mkdb -p"; # program for building passwd database
|
||||
|
||||
if ($test) {
|
||||
$home = "/home/w/tmp/adduser/home";
|
||||
$shells = "./shells";
|
||||
$passwd = "./master.passwd";
|
||||
$etc_shells = "./shells";
|
||||
$etc_passwd = "./master.passwd";
|
||||
$group = "./group";
|
||||
$pwd_mkdb = "pwd_mkdb -p -d .";
|
||||
$config = "adduser.conf";
|
||||
$send_message = "./adduser.message";
|
||||
$logfile = "./log.adduser";
|
||||
}
|
||||
|
||||
$ENV{'PATH'} = "/sbin:/bin:/usr/sbin:/usr/bin";
|
||||
# List of directories where shells located
|
||||
@path = ('/bin', '/usr/bin', '/usr/local/bin');
|
||||
# common shells, first element has higher priority
|
||||
@shellpref = ('bash', 'tcsh', 'ksh', 'csh', 'sh');
|
||||
|
||||
$defaultshell = 'bash'; # defaultshell if not empty
|
||||
|
||||
$uid_start = 1000; # new users get this uid
|
||||
$uid_end = 32000;
|
||||
$uid_end = 32000; # max. uid
|
||||
|
||||
# global variables
|
||||
$username = ''; # $username{username} = uid
|
||||
@ -66,15 +78,16 @@ sub variables {
|
||||
$pwgid = ''; # $pwgid{pwgid} = username; gid from passwd db
|
||||
$groupname =''; # $groupname{groupname} = gid
|
||||
$gid = ''; # $gid{gid} = groupname; gid form group db
|
||||
$defaultshell = '';
|
||||
@passwd_backup = '';
|
||||
@message_buffer = '';
|
||||
@user_variable_list = ''; # user variables in /etc/adduser.conf
|
||||
$do_not_delete = '## DO NOT DELETE THIS LINE!';
|
||||
}
|
||||
|
||||
# read shell database
|
||||
# See also: shells(5)
|
||||
# read shell databasem, see also: shells(5)
|
||||
sub shells_read {
|
||||
local($s, @dummy);
|
||||
open(S, $shells) || die "$shells:$!\n";
|
||||
open(S, $etc_shells) || die "$shells:$!\n";
|
||||
while(<S>) {
|
||||
if (/^[ \t]*\//) {
|
||||
($s, @dummy) = split;
|
||||
@ -90,83 +103,128 @@ sub shells_read {
|
||||
# add new/local shells
|
||||
sub shells_add {
|
||||
local($e,$dir,@list);
|
||||
|
||||
foreach $e (@shellpref) {
|
||||
if (!$shell{$e}) {
|
||||
foreach $dir (@path) {
|
||||
if (-x "$dir/$e") {
|
||||
push(@list, "$dir/$e") if
|
||||
&confirm_yn("Found shell: $dir/$e. Add to $shells?", "yes");
|
||||
if ($verbose) {
|
||||
if (&confirm_yn("Found shell: $dir/$e. Add to $etc_shells?", "yes")) {
|
||||
push(@list, "$dir/$e");
|
||||
push(@shellpref, "$dir/$e");
|
||||
$shell{&basename("$dir/$e")} = "$dir/$e";
|
||||
$changes++;
|
||||
}
|
||||
} else {
|
||||
print "Found unused shell: $dir/$e\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($#list >= 0) {
|
||||
foreach $e (@list) {
|
||||
$shell{&basename($e)} = $e;
|
||||
#print "$e\n";
|
||||
}
|
||||
&append_file($shells, @list);
|
||||
}
|
||||
&append_file($etc_shells, @list) if $#list >= 0;
|
||||
}
|
||||
|
||||
# choise your favourite shell
|
||||
sub shells_pref {
|
||||
# choise your favourite shell an return the shell
|
||||
sub shell_default {
|
||||
local($e,$i,$s);
|
||||
local($sh) = $defaultshell;
|
||||
|
||||
$i = 0;
|
||||
while($i < $#shellpref) {
|
||||
last if $shell{$shellpref[$i]};
|
||||
$i++;
|
||||
# $defaultshell is empty, looking for another shell
|
||||
if (!$sh || !$shell{$sh}) {
|
||||
$i = 0;
|
||||
while($i < $#shellpref) {
|
||||
last if $shell{$shellpref[$i]};
|
||||
$i++;
|
||||
}
|
||||
$sh = $shellpref[$i];
|
||||
|
||||
if (!$sh || !$shell{$sh}) {
|
||||
warn "No valid shell found in $etc_shells.\n";
|
||||
$sh = '';
|
||||
}
|
||||
}
|
||||
if ($verbose) {
|
||||
$s = &confirm_list("Enter your default shell:", 0,
|
||||
$sh, sort(keys %shell));
|
||||
print "Your default shell is: $s -> $shell{$s}\n";
|
||||
$changes++ if $s ne $sh;
|
||||
return $s;
|
||||
} else {
|
||||
return $sh;
|
||||
}
|
||||
$s = &confirm_list("Enter Your default shell:", 0,
|
||||
$shellpref[$i], sort(keys %shell));
|
||||
print "Your default shell is: $s -> $shell{$s}\n" if $verbose;
|
||||
$defaultshell = $s;
|
||||
}
|
||||
|
||||
# return default home partition
|
||||
# return default home partition, create base directory if nesseccary
|
||||
sub home_partition {
|
||||
local($h);
|
||||
$oldverbose = $verbose if !defined $oldverbose;
|
||||
|
||||
$h = &confirm_list("Enter Your default HOME partition:", 1, $home, "");
|
||||
if (-e "$h") {
|
||||
if ($verbose) {
|
||||
$h = &confirm_list("Enter your default HOME partition:", 1, $home, "");
|
||||
} else {
|
||||
$h = $home;
|
||||
}
|
||||
|
||||
if ($h !~ "^/") {
|
||||
warn "Please use absolute path for home: ``$h''.\n";
|
||||
$verbose++;
|
||||
$h =~ s|^[^/]+||;
|
||||
$home = $h;
|
||||
return &home_partition;
|
||||
}
|
||||
|
||||
if (-e $h) {
|
||||
if (!(-d _ || -l $h)) {
|
||||
warn "$h exist, but is it not a directory or symlink!\n";
|
||||
$verbose++;
|
||||
return &home_partition;
|
||||
}
|
||||
if (! -w _) {
|
||||
warn "$h is not writable!\n";
|
||||
$verbose++;
|
||||
return &home_partition;
|
||||
}
|
||||
} else {
|
||||
$verbose++;
|
||||
return &home_partition unless &mkdirhier($h);
|
||||
}
|
||||
|
||||
$home = $h;
|
||||
|
||||
$verbose = $oldverbose;
|
||||
undef $oldverbose;
|
||||
$changes++ if $h ne $home;
|
||||
return $h;
|
||||
}
|
||||
|
||||
# check for valid passwddb
|
||||
sub passwd_check {
|
||||
print "Check $passwd\n" if $verbose > 0;
|
||||
system("$pwd_mkdb $passwd");
|
||||
die "\nInvalid $passwd - cannot add any users!\n" if $?;
|
||||
print "Check $etc_passwd\n" if $verbose > 0;
|
||||
system("$pwd_mkdb $etc_passwd");
|
||||
die "\nInvalid $etc_passwd - cannot add any users!\n" if $?;
|
||||
}
|
||||
|
||||
# read /etc/passwd
|
||||
sub passwd_read {
|
||||
local($un, $pw, $ui, $gi);
|
||||
local($un, $pw, $ui, $gi, $sh, %shlist);
|
||||
|
||||
open(P, "$passwd") || die "$passwd: $!\n";
|
||||
print "Check $group\n" if $verbose;
|
||||
foreach $sh (keys %shell) {
|
||||
$shlist{$shell{$sh}} = $sh; #print "$sh $shell{$sh}\n";
|
||||
}
|
||||
|
||||
open(P, "$etc_passwd") || die "$passwd: $!\n";
|
||||
while(<P>) {
|
||||
chop;
|
||||
push(@passwd_backup, $_);
|
||||
($un, $pw, $ui, $gi) = (split(/:/, $_))[0..3];
|
||||
($un, $pw, $ui, $gi, $sh) = (split(/:/, $_))[0..3,9];
|
||||
print "$un already exist with uid: $username{$un}!\n"
|
||||
if $username{$un};
|
||||
$username{$un} = $ui;
|
||||
print "User $un: uid $ui exist twice: $uid{$ui}\n"
|
||||
if $uid{$ui} && $verbose;
|
||||
if $uid{$ui} && $verbose && $ui; # don't warn for uid 0
|
||||
print "User $un: illegal shell: ``$sh''\n"
|
||||
if ((!$shlist{$sh} && $sh) &&
|
||||
($un !~ /^(bin|uucp|falcon|nobody)$/));
|
||||
$uid{$ui} = $un;
|
||||
$pwgid{$gi} = $un;
|
||||
}
|
||||
@ -197,31 +255,35 @@ sub group_check {
|
||||
foreach $e (keys %pwgid) {
|
||||
if (!$gid{$e}) {
|
||||
$user = $pwgid{$e};
|
||||
warn "Gid $e is defined in $passwd for user ``$user''\n";
|
||||
warn "but not in $group!\n";
|
||||
warn "User ``$user'' has gid $e but a group with this " .
|
||||
"gid does not exist.\n";
|
||||
#warn "Gid $e is defined in $etc_passwd for user ``$user''\n";
|
||||
#warn "but not in $group!\n";
|
||||
if ($groupname{$user}) {
|
||||
warn <<EOF;
|
||||
I'm confused! Maybe the gids ($e <-> $groupname{$user}) for user ``$user''
|
||||
in $passwd & $group are wrong.
|
||||
See $passwd ``$user:*:$username{$user}:$e''
|
||||
See $group ``$user:*:$groupname{$user}''
|
||||
Maybe the gids ($e <-> $groupname{$user}) for user+group ``$user'' are wrong.
|
||||
EOF
|
||||
} else {
|
||||
push(@list, "$user:*:$e:$user")
|
||||
if (&confirm_yn("Add group``$user'' gid $e to $group?", "y"));
|
||||
if $verbose &&
|
||||
&confirm_yn("Add group``$user'' gid $e to $group?", "y");
|
||||
}
|
||||
}
|
||||
}
|
||||
&append_file($group, @list) if $#list >= 0;
|
||||
}
|
||||
|
||||
#
|
||||
# main loop for creating new users
|
||||
#
|
||||
sub new_users {
|
||||
local(@userlist) = @_;
|
||||
local($name);
|
||||
local($defaultname) = "a-z0-9";
|
||||
|
||||
print "\nOk, let's go.\n";
|
||||
print "Don't worry about mistakes. I ask You later for " .
|
||||
print "\n" if $verbose;
|
||||
print "Ok, let's go.\n" .
|
||||
"Don't worry about mistakes. I ask you later for " .
|
||||
"correct input.\n" if $verbose;
|
||||
|
||||
while(1) {
|
||||
@ -246,10 +308,10 @@ sub new_users {
|
||||
print <<EOF;
|
||||
|
||||
Name: $name
|
||||
Passwd: none, is empty
|
||||
Passwd: no, is empty
|
||||
Fullname: $fullname
|
||||
Uid: $u_id
|
||||
Gid: $g_id
|
||||
Gid: $g_id ($name)
|
||||
HOME: $home/$name
|
||||
Shell: $sh
|
||||
EOF
|
||||
@ -257,11 +319,11 @@ EOF
|
||||
local($new_entry) =
|
||||
"$name::$u_id:$g_id::0:0:$fullname:$home/$name:$sh";
|
||||
|
||||
&append_file($passwd, $new_entry);
|
||||
&append_file($etc_passwd, $new_entry);
|
||||
|
||||
system("$pwd_mkdb $passwd");
|
||||
system("$pwd_mkdb $etc_passwd");
|
||||
if ($?) {
|
||||
local($crash) = "$passwd.crash$$";
|
||||
local($crash) = "$etc_passwd.crash$$";
|
||||
warn "$pwd_mkdb failed, try to restore ...\n";
|
||||
|
||||
open(R, "> $crash") || die "Sorry, give up\n";
|
||||
@ -272,7 +334,7 @@ EOF
|
||||
|
||||
system("$pwd_mkdb $crash");
|
||||
die "Sorry, give up\n" if $?;
|
||||
die "Successfully restore $passwd. Exit.\n";
|
||||
die "Successfully restore $etc_passwd. Exit.\n";
|
||||
}
|
||||
# Add new group
|
||||
&append_file($group, "$name:*:$g_id:$name")
|
||||
@ -287,32 +349,64 @@ EOF
|
||||
$gid{$g_id} = $name;
|
||||
|
||||
print "Added user ``$name''\n";
|
||||
|
||||
if ($send_message && $send_message ne "no") {
|
||||
local($m) = &confirm_list("Send message to ``$name'' and:",
|
||||
1, "no", ("second_mail_address", "no"));
|
||||
if ($verbose) {
|
||||
print "send message to: ``$name''";
|
||||
if ($m eq "no") { print "\n" }
|
||||
else { print " and ``$m''\n"}
|
||||
}
|
||||
$m = "" if $m eq "no";
|
||||
local($e);
|
||||
if (!open(M, "| mail -s Welcome $name $m")) {
|
||||
warn "Cannot send mail to: $name $m!\n";
|
||||
} else {
|
||||
foreach $e (@message_buffer) {
|
||||
print M eval "\"$e\"";
|
||||
}
|
||||
close M;
|
||||
}
|
||||
}
|
||||
|
||||
local($a) = &confirm_yn("Change password", $defaultpasswd);
|
||||
if (($a && $defaultpasswd) || (!$a && !$defaultpasswd)) {
|
||||
local($empty_password) = "";
|
||||
if (($a && $defaultpasswd ne "no" && $defaultpasswd) ||
|
||||
(!$a && $defaultpasswd eq "no")) {
|
||||
while(1) {
|
||||
system("passwd $name");
|
||||
last unless $?;
|
||||
if (!$?) { $empty_password = "*"; last }
|
||||
last unless
|
||||
&confirm_yn("Passwd $name failed. Try again?", "yes");
|
||||
}
|
||||
}
|
||||
&home_create($name);
|
||||
}
|
||||
if (&confirm_yn("Continue with next user?", "yes")) {
|
||||
&new_users;
|
||||
&adduser_log("$name:$empty_password:$u_id:$g_id($name):$fullname");
|
||||
&home_create($name);
|
||||
}
|
||||
if (&confirm_yn("Continue with next user?", "yes")) {
|
||||
print "\n" if !$verbose;
|
||||
&new_users;
|
||||
} else {
|
||||
print "Good by.\n" if $verbose;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
sub password_pref {
|
||||
$defaultpasswd = !&confirm_yn("Use empty passwords", "yes");
|
||||
# ask for password usage
|
||||
sub password_default {
|
||||
local($p) = $defaultpasswd;
|
||||
if ($verbose) {
|
||||
$p = &confirm_yn("Use passwords", $defaultpasswd);
|
||||
$changes++ unless $p;
|
||||
}
|
||||
return "yes" if (($defaultpasswd eq "yes" && $p) ||
|
||||
($defaultpasswd eq "no" && !$p));
|
||||
return "no"; # otherwise
|
||||
}
|
||||
|
||||
# misc
|
||||
sub check_root {
|
||||
die "You are not root!\n" if $<;
|
||||
die "You are not root!\n" if $< && !$test;
|
||||
}
|
||||
|
||||
sub usage {
|
||||
@ -324,13 +418,35 @@ OPTIONS:
|
||||
-help this help
|
||||
-silent opposite of verbose
|
||||
-verbose verbose
|
||||
-debug verbose verbose
|
||||
-noconfig don't read config-file
|
||||
-home home default HOME partition [$home]
|
||||
-shell shell default SHELL
|
||||
-dotdir dir copy files from dir, default $dotdir
|
||||
-shell shell default SHELL [$defaultshell]
|
||||
-dotdir dir copy files from dir, default [$dotdir]
|
||||
-message file send message to new users [$send_message]
|
||||
-create_conf create configuration/message file and exit
|
||||
USAGE
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# print banner
|
||||
sub copyright {
|
||||
print <<EOF;
|
||||
(c) Copyright 1995 Wolfram Schneider <wosch@cs.tu-berlin.de>
|
||||
EOF
|
||||
}
|
||||
|
||||
# hints
|
||||
sub hints {
|
||||
if ($verbose) {
|
||||
print "Use option ``-silent'' if you don't want see " .
|
||||
"some warnings & questions.\n\n";
|
||||
} else {
|
||||
print "Use option ``-verbose'' if you want see more warnings & " .
|
||||
"questions \nor try to repair bugs.\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
sub parse_arguments {
|
||||
local(@argv) = @_;
|
||||
@ -338,14 +454,19 @@ sub parse_arguments {
|
||||
while ($_ = $argv[0], /^-/) {
|
||||
shift @argv;
|
||||
last if /^--$/;
|
||||
if (/^--?(debug|verbose)$/) { $verbose = 1 }
|
||||
elsif (/^--?(silent|guru|wizard)$/) { $verbose = 0 }
|
||||
elsif (/^--?(verbose)$/) { $verbose = 1 }
|
||||
if (/^--?(verbose)$/) { $verbose = 1 }
|
||||
elsif (/^--?(silent|guru|wizard|quit)$/) { $verbose = 0 }
|
||||
elsif (/^--?(debug)$/) { $verbose = 2 }
|
||||
elsif (/^--?(h|help|\?)$/) { &usage }
|
||||
elsif (/^--?(home)$/) { $home = $argv[0]; shift @argv }
|
||||
elsif (/^--?(shell)$/) { $shell = $argv[0]; shift @argv }
|
||||
elsif (/^--?(shell)$/) { $defaultshell = $argv[0];
|
||||
shift @argv }
|
||||
elsif (/^--?(dotdir)$/) { $dotdir = $argv[0]; shift @argv }
|
||||
elsif (/^--?(batch)$/) { $batch = 1; }
|
||||
elsif (/^--?(message)$/) { $send_message = $argv[0]; shift @argv;
|
||||
$sendmessage = 1; }
|
||||
# see &config_read
|
||||
elsif (/^--?(create_conf)$/) { &create_conf; }
|
||||
elsif (/^--?(noconfig)$/) { $config_read = 0; }
|
||||
else { &usage }
|
||||
}
|
||||
#&usage if $#argv < 0;
|
||||
@ -357,19 +478,68 @@ sub basename {
|
||||
return $name;
|
||||
}
|
||||
|
||||
#
|
||||
sub dirname {
|
||||
local($name) = @_;
|
||||
$name =~ s|[/]+$||; # delete any / at end
|
||||
$name =~ s|[^/]+$||;
|
||||
$name = "/" unless $name; # dirname of / is /
|
||||
return $name;
|
||||
}
|
||||
|
||||
# return 1 if $file is a readable file or link
|
||||
sub filetest {
|
||||
local($file, $verb) = @_;
|
||||
|
||||
if (-e $file) {
|
||||
if (-f $file || -l $file) {
|
||||
return 1 if -r _;
|
||||
warn "$file unreadable\n" if $verb;
|
||||
} else {
|
||||
warn "$file is not a plain file or link\n" if $verb;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
# create configuration files and exit
|
||||
sub create_conf {
|
||||
$create_conf = 1;
|
||||
&message_create($send_message);
|
||||
&config_write(1);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
# log for new user in /var/log/adduser
|
||||
sub adduser_log {
|
||||
local($string) = @_;
|
||||
local($e);
|
||||
|
||||
return 1 if $logfile eq "no";
|
||||
|
||||
local($sec, $min, $hour, $mday, $mon, $year) = localtime;
|
||||
$mon++;
|
||||
|
||||
foreach $e ('sec', 'min', 'hour', 'mday', 'mon', 'year') {
|
||||
# '7' -> '07'
|
||||
eval "\$$e = 0 . \$$e" if (eval "\$$e" < 10);
|
||||
}
|
||||
|
||||
&append_file($logfile, "$year/$mon/$mday $hour:$min:$sec $string");
|
||||
}
|
||||
|
||||
# create HOME directory, copy dotfiles from $dotdir to $HOME
|
||||
sub home_create {
|
||||
local($name) = @_;
|
||||
local(@list);
|
||||
local($e,$from, $to);
|
||||
|
||||
print "Create HOME directory\n";
|
||||
print "Create HOME directory\n" if $verbose;
|
||||
if(!mkdir("$home/$name", 0755)) {
|
||||
warn "Cannot create HOME directory for $name: $!\n";
|
||||
warn "Cannot create HOME directory for user ``$home/$name'': $!\n";
|
||||
return 0;
|
||||
}
|
||||
push(@list, "$home/$name");
|
||||
if ($dotdir) {
|
||||
if ($dotdir && $dotdir ne "no") {
|
||||
opendir(D, "$dotdir") || warn "$dotdir: $!\n";
|
||||
foreach $from (readdir(D)) {
|
||||
if ($from !~ /^(\.|\.\.)$/) {
|
||||
@ -382,8 +552,8 @@ sub home_create {
|
||||
}
|
||||
closedir D;
|
||||
}
|
||||
#warn "Chown: $name, $name, @list\n";
|
||||
#chown in perl does not work
|
||||
#warn "Chown: $name, $name, @list\n";
|
||||
#chown in perl does not work
|
||||
system("chown $name:$name @list") || warn "$!\n" && return 0;
|
||||
return 1;
|
||||
}
|
||||
@ -423,10 +593,14 @@ sub mkdirhier {
|
||||
# If !$allow accept only elements from @list.
|
||||
sub confirm_list {
|
||||
local($message, $allow, $confirm, @list) = @_;
|
||||
local($read, $c);
|
||||
local($read, $c, $print);
|
||||
|
||||
$print = "$message " if $message;
|
||||
$print .= "@list ";
|
||||
print "$print";
|
||||
print "\n " if length($print) > 50;
|
||||
print "[$confirm]: ";
|
||||
|
||||
print "$message " if $message;
|
||||
print "@list [$confirm]: ";
|
||||
chop($read = <STDIN>);
|
||||
$read =~ s/^[ \t]*//;
|
||||
$read =~ s/[ \t\n]*$//;
|
||||
@ -441,7 +615,9 @@ sub confirm_list {
|
||||
}
|
||||
|
||||
# YES or NO question
|
||||
# $confirm => 'y' or 'n'. Return true if answer 'y' (or 'n')
|
||||
# return 1 if &confirm("message", "yes") and answer is yes
|
||||
# or if &confirm("message", "no") an answer is no
|
||||
# otherwise 0
|
||||
sub confirm_yn {
|
||||
local($message, $confirm) = @_;
|
||||
local($yes) = "^(yes|YES|y|Y)$";
|
||||
@ -472,12 +648,116 @@ sub confirm_yn {
|
||||
}
|
||||
|
||||
# test if $dotdir exist
|
||||
sub dotdir_check {
|
||||
return 1 if -e $dotdir && -r _ && (-d _ || -l $dotdir);
|
||||
warn "Directory: $dotdir does not exist or unreadable. " .
|
||||
"Cannot copy dotfiles!\n";
|
||||
$dotdir = '';
|
||||
return 0;
|
||||
sub dotdir_default {
|
||||
#$dotdir = "no" unless $dotdir;
|
||||
local($dir) = $dotdir;
|
||||
local($oldverbose) = $verbose;
|
||||
|
||||
if ($dir !~ "^/") {
|
||||
warn "Please use absulote path for dotdir: ``$dir''\n";
|
||||
$dir = "no";
|
||||
$verbose++ unless $verbose;
|
||||
}
|
||||
while($verbose) {
|
||||
$dir = &confirm_list("Copy dotfiles from:", 1,
|
||||
$dir, ("no", $dir));
|
||||
last if $dir eq "no";
|
||||
last if (-e $dir && -r _ && (-d _ || -l $dir));
|
||||
last if !&confirm_yn("Dotdir ``$dir'' is not a dir. Try again", "yes");
|
||||
}
|
||||
unless (-e $dir && -r _ && (-d _ || -l $dir)) {
|
||||
warn "Directory: $dir does not exist or unreadable.\n"
|
||||
if $dir ne "no";
|
||||
warn "Do not copy dotfiles.\n";
|
||||
$dir = "no";
|
||||
}
|
||||
$changes++ if $dir ne $dotdir;
|
||||
$verbose = $oldverbose;
|
||||
return $dir;
|
||||
}
|
||||
|
||||
# ask for messages to new users
|
||||
sub message_default {
|
||||
local($file) = $send_message;
|
||||
local(@d);
|
||||
|
||||
push(@d, $file);
|
||||
push(@d, "no") if $file ne "no";
|
||||
if (!&filetest($file, 1) && $file ne "no") {
|
||||
if (! -e $file &&
|
||||
&confirm_yn("Create message file ``$file''?", "yes")) {
|
||||
&message_create($file);
|
||||
} else {
|
||||
$file = "no";
|
||||
}
|
||||
}
|
||||
|
||||
while($verbose) {
|
||||
$file = &confirm_list("Send message from file: ", 1,
|
||||
$file, @d);
|
||||
last if $file eq "no";
|
||||
if (&filetest($file, 1)) {
|
||||
last;
|
||||
} else {
|
||||
&message_create($file) if ! -e $file &&
|
||||
&confirm_yn("Create ``$file''?", "yes");
|
||||
last if &filetest($file, 0);
|
||||
last if !&confirm_yn(
|
||||
"File ``$file'' does not exist, try again?", "yes");
|
||||
}
|
||||
}
|
||||
if ($file eq "no" || !&filetest($file, 0)) {
|
||||
warn "Do not send message\n" if $verbose;
|
||||
$file = "no";
|
||||
} else {
|
||||
&message_read($file);
|
||||
}
|
||||
|
||||
$changes++ if $file ne $send_message;
|
||||
return $file;
|
||||
}
|
||||
|
||||
# create message file
|
||||
sub message_create {
|
||||
local($file) = @_;
|
||||
local($dir) = &dirname($file);
|
||||
|
||||
if (! -d $dir) {
|
||||
return 0 unless &mkdirhier($dir);
|
||||
}
|
||||
if (!open(M, "> $file")) {
|
||||
warn "Messagefile ``$file'': $!\n"; return 0;
|
||||
}
|
||||
print M <<EOF;
|
||||
#
|
||||
# Message file for adduser(8)
|
||||
# comment: ``#''
|
||||
# defaultvariables: \$name, \$fullname
|
||||
# other variables: see /etc/adduser.conf after
|
||||
# line ``$do_not_delete''
|
||||
#
|
||||
|
||||
\$fullname,
|
||||
|
||||
your account ``\$name'' was created. Have fun!
|
||||
|
||||
See also chpass(1), finger(1), passwd(1)
|
||||
EOF
|
||||
close M;
|
||||
return 1;
|
||||
}
|
||||
|
||||
# read message file into buffer
|
||||
sub message_read {
|
||||
local($file) = @_;
|
||||
@message_buffer = '';
|
||||
|
||||
if (!open(R, "$file")) {
|
||||
warn "File ``$file'':$!\n"; return 0;
|
||||
}
|
||||
while(<R>) {
|
||||
push(@message_buffer, $_) unless /^[ \t]*#/;
|
||||
}
|
||||
}
|
||||
|
||||
# write @list to $file with file-locking
|
||||
@ -523,6 +803,7 @@ sub next_id {
|
||||
return ($uid_start, $gid_start);
|
||||
}
|
||||
|
||||
# cp(1)
|
||||
sub cp {
|
||||
local($from, $to, $tilde) = @_;
|
||||
|
||||
@ -552,25 +833,164 @@ sub cp {
|
||||
return 1;
|
||||
}
|
||||
|
||||
# read config file
|
||||
sub config_read {
|
||||
local($opt) = @_;
|
||||
local($ev); # evaluate variable or list
|
||||
local($user_flag) = 0;
|
||||
|
||||
return 1 if $opt =~ /-(noconfig|create_conf)/; # don't read config file
|
||||
|
||||
if ($config_read && -f $config) {
|
||||
if(!open(C, "$config")) {
|
||||
warn "$config: $!\n"; return 0;
|
||||
}
|
||||
print "Read config file: $config" if $verbose > 1;
|
||||
while(<C>) {
|
||||
chop;
|
||||
/^$do_not_delete/ && $user_flag++;
|
||||
if (/^[ \t]*[a-zA-Z_-]+[ \t]*=/) {
|
||||
# prepare for evaluating
|
||||
s/#.*$//;
|
||||
s/^[ \t]+//;
|
||||
s/[ \t;]+$//;
|
||||
s/[ \t]*=[ \t]*/=/;
|
||||
s/=(.*)/="$1"/ unless /=['"(]/;
|
||||
|
||||
print "$_\n" if $verbose > 1;
|
||||
if (/=\(/) { # perl list
|
||||
$ev = "\@";
|
||||
} else { # perl variable
|
||||
$ev = "\$";
|
||||
}
|
||||
eval "$ev$_" || warn "Ignore garbage: $ev $_\n";
|
||||
push(@user_variable_list, "$_\n") if $user_flag;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# write config file
|
||||
sub config_write {
|
||||
local($silent) = @_;
|
||||
|
||||
if (($changes || ! -e $config || !$config_read) || $silent) {
|
||||
if (!$silent) {
|
||||
if (-e $config) {
|
||||
return 1 if
|
||||
&confirm_yn("\nWrite your changes to $config?", "no");
|
||||
} else {
|
||||
return 1 unless
|
||||
&confirm_yn("\nWrite your configuration to $config?", "yes");
|
||||
}
|
||||
}
|
||||
|
||||
local($dir) = &dirname($config);
|
||||
if (! -d $dir && !&mkdirhier($dir)) {
|
||||
warn "Cannot save your configuration\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(!open(C, "> $config")) {
|
||||
warn "$config: $!\n"; return 0;
|
||||
}
|
||||
# prepare some variables
|
||||
$send_message = "no" unless $send_message;
|
||||
$defaultpasswd = "no" unless $defaultpasswd;
|
||||
local($shpref) = "'" . join("', '", @shellpref) . "'";
|
||||
local($shpath) = "'" . join("', '", @path) . "'";
|
||||
local($user_var) = join('', @user_variable_list);
|
||||
|
||||
print C <<EOF;
|
||||
#
|
||||
# $config - automatic generated by adduser(8)
|
||||
#
|
||||
# Note: adduser read *and* write this file.
|
||||
# You may change values, but don't add new things befor the
|
||||
# line ``## DO NOT DELETE THIS LINE!''
|
||||
#
|
||||
|
||||
# verbose = [0-2]
|
||||
verbose = $verbose
|
||||
|
||||
# use password for new users
|
||||
# defaultpasswd = yes | no
|
||||
defaultpasswd = $defaultpasswd
|
||||
|
||||
# copy dotfiles from this dir ("/usr/share/skel" or "no")
|
||||
dotdir = "$dotdir"
|
||||
|
||||
# send this file to new user ("/etc/adduser.message" or "no")
|
||||
send_message = "$send_message"
|
||||
|
||||
# config file for adduser ("/etc/adduser.conf")
|
||||
config = "$config"
|
||||
|
||||
# logfile ("/var/log/adduser" or "no")
|
||||
logfile = "$logfile"
|
||||
|
||||
# default HOME directory ("/home")
|
||||
home = "$home"
|
||||
|
||||
# List of directories where shells located
|
||||
# path = ('/bin', '/usr/bin', '/usr/local/bin')
|
||||
path = ($shpath)
|
||||
|
||||
# common shell list, first element has higher priority
|
||||
# shellpref = ('bash', 'tcsh', 'ksh', 'csh', 'sh')
|
||||
shellpref = ($shpref)
|
||||
|
||||
# defaultshell if not empty ("bash")
|
||||
defaultshell = "$defaultshell"
|
||||
|
||||
# new users get this uid (1000)
|
||||
uid_start = 1000
|
||||
|
||||
$do_not_delete
|
||||
## your own variables, see /etc/adduser.message
|
||||
## Warning: this may be a security hole!
|
||||
$user_var
|
||||
|
||||
# end
|
||||
EOF
|
||||
close C;
|
||||
}
|
||||
}
|
||||
|
||||
################
|
||||
# main
|
||||
#
|
||||
&check_root; # You must be root to run this script!
|
||||
$test = 0; # test mode, only for development
|
||||
|
||||
# init
|
||||
#&usage if $ARGV[0] =~ /^--?(help|h|\?)$/; # help if you are not root
|
||||
&check_root; # you must be root to run this script!
|
||||
&variables; # initialize variables
|
||||
&config_read(@ARGV); # read variables form config-file
|
||||
&parse_arguments(@ARGV); # parse arguments
|
||||
|
||||
#
|
||||
©right;
|
||||
&hints;
|
||||
|
||||
# check
|
||||
$changes = 0;
|
||||
&passwd_check; # check for valid passwdb
|
||||
&shells_read; # read /etc/shells
|
||||
&passwd_read; # read /etc/master.passwd
|
||||
&group_read; # read /etc/group
|
||||
&group_check; # check for incon*
|
||||
&dotdir_check; # check $dotdir
|
||||
print "\n";
|
||||
&home_partition; # find HOME partition
|
||||
&shells_read; # read /etc/shells
|
||||
&shells_add; # maybe add some new shells
|
||||
&shells_pref; # enter default shell
|
||||
&password_pref; # maybe use password
|
||||
|
||||
# some questions
|
||||
&shells_add; # maybe add some new shells
|
||||
$defaultshell = &shell_default; # enter default shell
|
||||
$home = &home_partition; # find HOME partition
|
||||
$dotdir = &dotdir_default; # check $dotdir
|
||||
$send_message = &message_default; # send message to new user
|
||||
$defaultpasswd = &password_default; # maybe use password
|
||||
&config_write(0); # write variables in file
|
||||
|
||||
# main loop for creating new users
|
||||
&new_users; # add new users
|
||||
|
||||
#end
|
||||
|
Loading…
x
Reference in New Issue
Block a user