Report forwarded to debian-bugs-dist@lists.debian.org, Guy Maor <maor@debian.org>:
Bug#43527; Package adduser.   debian-bugs-dist@lists.debian.orgGuy Maor  Subject: Bug#43527: "adduser" does not check for qmail "~alias/.qmail-newuser" alias Reply-To: "I. Forbes" , 43527@bugs.debian.org Resent-From: "I. Forbes" Resent-To: debian-bugs-dist@lists.debian.org Resent-CC: Guy Maor Resent-Date: Thu, 26 Aug 1999 09:03:07 GMT Resent-Message-ID: Resent-Sender: iwj@debian.org X-Debian-PR-Message: report 43527 X-Debian-PR-Package: adduser X-Debian-PR-Keywords: X-Loop: owner@bugs.debian.org Received: via spool by bugs@bugs.debian.org id=B.93565792522877 (code B ref -1); Thu, 26 Aug 1999 09:03:07 GMT From: "I. Forbes" To: submit@bugs.debian.org Date: Thu, 26 Aug 1999 10:54:16 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Priority: normal X-mailer: Pegasus Mail for Win32 (v3.01d) Package: adduser Version: 3.8 The "qmail" MTA (see www.qmail.org) is now available on debian via the package "qmail-src". This MTA does a few unconventional things, one of them is an alternate method of handling e- mail "alias" names. (Latest versions also honour the accepted /etc/aliases file). There is a user "alias" defined on the system. If a file named: ~alias/.qmail-newuser is present, the contents of that file are treated as a ".qmail" file, (which is a variation of sendmail's .forward file). Mail addressed to "newuser" will then be delivered according to the instructions contained in that file. This is well and good for qmail - it is all a bit different but it works very well. The trouble is that if the file ~alias/.qmail-newuser exists, it is not a good idea to go and create a new user called "newuser" as unpredictable things will happen to his mail. My "adduser" script has been patched to complain if you try and do this. I have attached it for your information and possible inclusion in future released of adduser. Search for "qmail" for a quick look at what has changed. The qmail mechanism is complex. It can react to ~alias/.qmail-newuser-default or ~alias/.qmail-new-user My patches were put together by a student who helped me (Craig Bates craig@zsd.co.za), I am not sure they will work for all of these possibilities. Thanks Ian Forbes #!/usr/bin/perl -w # # adduser 3.8 # # adduser: a utility to add users to the system # addgroup: a utility to add groups to the system # Copyright (C) 1997 Guy Maor # Copyright (C) 1995 Ted Hajek # Ian A. Murdock # General scheme of the program adapted by the original debian 'adduser' # program by Ian A. Murdock . # # This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # #################### # the program can be called as: # # adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID] # [--disabled-password] [--gecos GECOS] user # add a normal user to the system # example: adduser fred # $action = "adduser" # # adduser --group [--gid ID] group # addgroup [--gid ID] group # add a system group # example: addgroup --quiet www-data # $action = "addgroup" # # adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP # | --gid ID] [--disabled-password] [--gecos GECOS] user # add a system user. Create a like-named, like-id'd group with # --group, add to an existing group with --ingroup or --gid. Add # to "nogroup" with neither. # example: adduser --system --home /home/gopher-data --group gopher # $action = "addsysuser" # # adduser user group # add the existing user to an existing group. # $action = "addusertogroup" # # all commands take the following options: # --quiet don't give progress information on STDOUT # --force-badname disable checking of names for funny characters # --help usage message # --version version number and copyright # --conf FILE use FILE instead of /etc/adduser.conf ############ # Modified by Craig Bates - 29-01-99 to check qmail aliases. $verbose = 1; # should we be verbose? $allow_badname = 0; # should we allow bad names? $ask_passwd = 1; # ask for a passwd? $defaults = "/etc/adduser.conf"; $nogroup_id = getgrnam("nogroup") || 65534; $0 =~ s+.*/++; $config{"qmail_alias_dir"} = "/var/qmail/alias/"; $config{"dshell"} = "/bin/bash"; $config{"first_system_uid"} = 100; $config{"last_system_uid"} = 999; $config{"first_uid"} = 1000; $config{"last_uid"} = 29999; $config{"dhome"} = "/home"; $config{"skel"} = "/etc/skel"; $config{"usergroups"} = "yes"; $config{"users_gid"} = "100"; $config{"grouphomes"} = "no"; $config{"letterhomes"} = "no"; $config{"quotauser"} = ""; $action = $0 eq "addgroup" ? "addgroup" : "adduser"; while ($arg = shift(@ARGV)) { die "$0: No options allowed after names.\n" if ($names[0] && $arg =~ /^--/); if ($arg eq "--quiet") { $verbose = 0; } elsif ($arg eq "--force-badname") { $allow_badname = 1; } elsif ($arg eq "--help") { &usage(); exit 0; } elsif ($arg eq "--version") { &version(); exit 0; } elsif ($arg eq "--system") { $action = "addsysuser"; } elsif ($arg eq "--group") { $found_group_opt = 1; } elsif ($arg eq "--ingroup") { die "$0: --ingroup requires an argument.\n" if (!($ingroup_name = shift(@ARGV))); } elsif ($arg eq "--home") { die "$0: --home requires an argument.\n" if (!($special_home = shift(@ARGV))); print "$0: Warning: The home dir you specified already exists.\n" if (-d $special_home && $verbose); die "$0: The home dir must be an absolute path.\n" if ($special_home !~ m+^/+ ); } elsif ($arg eq "--gecos") { $new_gecos = shift(@ARGV); } elsif ($arg eq "--disabled-password") { $ask_passwd = 0; } elsif ($arg eq "--uid") { die "$0: --uid requires a numeric argument.\n" if (!($new_uid = shift(@ARGV)) || $new_uid !~ /^\d+$/); } elsif ($arg eq "--gid") { die "$0: --gid requires a numeric argument.\n" if (!($new_gid = shift(@ARGV)) || $new_gid !~ /^\d+$/); } elsif ($arg eq "--conf") { die "$0: --conf requires an argument.\n" if (!($defaults = shift(@ARGV))); die "$0: `$defaults' doesn't exist.\n" if (! -f $defaults); } elsif ($arg eq "--debug") { $debugging = 1; } elsif ($arg =~ /^--/) { # bad argument! die "$0: Unknown argument `$arg'.\n"; } else { # it's a username push (@names, $arg); } } die "$0: Only root may add a user or group to the system.\n" if ($> != 0); die "$0: I need a name to add.\n" if (@names == 0); die "$0: No more than two names.\n" if (@names > 2); if (@names == 2) { # must be addusertogroup die "$0: Specify only one name in this mode.\n" if ($action eq "addsysuser" || $found_group_opt); $action = "addusertogroup"; $existing_user = shift (@names); $existing_group = shift (@names); } else { $new_name = shift (@names); } if ($found_group_opt) { if ($action eq "addsysuser") { $make_group_also = 1; } else { $action = "addgroup"; } } die "$0: --group, --ingroup, and --gid options are mutually exclusive.\n" if ($action ne "addgroup" && defined($found_group_opt) +defined($ingroup_name) +defined($new_gid) > 1); ##### # OK, we've processed the arguments. $action equals one of the following, # and the appropriate variables have been set: # # $action = "adduser" # $new_name - the name of the new user. # $ingroup_name | $new_gid - the group to add the user to # $special_home, $new_uid, $new_gecos - optional overrides # $action = "addgroup" # $new_name - the name of the new group # $new_gid - optional override # $action = "addsysuser" # $new_name - the name of the new user # $make_group_also | $ingroup_name | $new_gid | 0 - which group # $special_home, $new_uid, $new_gecos - optional overrides # $action = "addusertogroup" # $existing_user - the user to be added # $existing_group - the group to add her to ##### &read_config($defaults); &checkname($new_name) if $new_name; $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler'; ############## ## addgroup ## ############## if ($action eq "addgroup") { die "$0: The group `$new_name' already exists.\n" if (getgrnam($new_name)); die "$0: The GID `$new_gid' is already in use.\n" if (defined($new_gid) && getgrgid($new_gid)); if (!defined($new_gid)) { $new_gid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_gids); die "$0: No GID is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "Group `$new_name' not created.\n" if ($new_gid == -1); } print "Adding group $new_name ($new_gid)...\n" if $verbose; &systemcall('groupadd', '-g', $new_gid, $new_name); print "Done.\n" if $verbose; exit 0; } #################### ## addusertogroup ## #################### elsif ($action eq "addusertogroup") { die "$0: The user `$existing_user' doesn't exist.\n" if (!getpwnam($existing_user)); die "$0: The group `$existing_group' doesn't exist.\n" if (!getgrnam($existing_group)); if (&user_is_member($existing_user, $existing_group)) { print "The user `$existing_user' is already a member of ", "`$existing_group'.\n" if $verbose; exit 0; # not really an error } print "Adding user $existing_user to group $existing_group...\n" if $verbose; &systemcall('usermod', '-G', join(",", get_users_groups($existing_user), $existing_group), $existing_user); print "Done.\n" if $verbose; exit 0; } ################ ## addsysuser ## ################ elsif ($action eq "addsysuser") { $new_gid = $nogroup_id if (!$ingroup_name && !defined($new_gid) && !$make_group_also); &check_user_group(); print "Adding system user $new_name...\n" if $verbose; if (!defined($new_uid) && $make_group_also) { $new_uid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_uids, &get_current_gids); die "$0: No UID/GID pair is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); $new_gid = $new_uid; $ingroup_name = $new_name; } elsif (!defined($new_uid) && !$make_group_also) { $new_uid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_uids); die "$0: No UID is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } else { die "Internal error"; } } else { if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; } else { die "Internal error"; } } if ($make_group_also) { print "Adding new group $new_name ($new_gid).\n" if $verbose; $undogroup = $new_name; &systemcall('groupadd', '-g', $new_gid, $new_name); } print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n" if $verbose; $home_dir = $special_home || &homedir($new_name, $ingroup_name); $undouser = $new_name; &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s', '/bin/false', '-u', $new_uid, $new_name); &systemcall('chfn', '-f', $new_gecos, $new_name) if ($new_gecos); if (-d $home_dir) { print "Home directory $home_dir already exists.\n" if $verbose; } else { print "Creating home directory $home_dir.\n" if $verbose; $undohome = $home_dir; &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n"); chown($new_uid, $new_gid, $home_dir) || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n"); $dir_mode = $make_group_also ? 02755 : 0755; chmod ($dir_mode, $home_dir) || &cleanup("chmod $dir_mode $home_dir: $!\n"); } exit 0; } ############# ## adduser ## ############# elsif ($action eq "adduser") { if (!$ingroup_name && !defined($new_gid)) { if ($config{"usergroups"} eq "yes") { $make_group_also = 1; } else { $new_gid = $config{"users_gid"}; } } &check_user_group(); print "Adding user $new_name...\n" if $verbose; if (!defined($new_uid) && $make_group_also) { $new_uid = &first_avail_id($config{"first_uid"}, $config{"last_uid"}, &get_current_uids, &get_current_gids); die "$0: No UID/GID pair is available in the range ", "$config{\"first_uid\"} - $config{\"last_uid\"}\n", "(FIRST_UID - LAST_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); $new_gid = $new_uid; $ingroup_name = $new_name; } elsif (!defined($new_uid) && !$make_group_also) { $new_uid = &first_avail_id($config{"first_uid"}, $config{"last_uid"}, &get_current_uids); die "$0: No UID is available in the range ", "$config{\"first_uid\"} - $config{\"last_uid\"}\n", "(FIRST_UID - LAST_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } else { die "Internal error"; } } else { if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; } else { die "Internal error"; } } if ($make_group_also) { print "Adding new group $new_name ($new_gid).\n" if $verbose; $undogroup = $new_name; &systemcall('groupadd', '-g', $new_gid, $new_name); } print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n" if $verbose; $home_dir = $special_home || &homedir($new_name, $ingroup_name); $undouser = $new_name; &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s', $config{dshell}, '-u', $new_uid, $new_name); if (-d $home_dir) { print "Home directory $home_dir already exists. Not copying from", " $config{skel}\n" if $verbose; } else { print "Creating home directory $home_dir.\n" if $verbose; $undohome = $home_dir; &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n"); chown($new_uid, $new_gid, $home_dir) || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n"); $dir_mode = $make_group_also ? 02755 : 0755; chmod ($dir_mode, $home_dir) || &cleanup("chmod $dir_mode $home_dir: $!\n"); if ($config{"skel"}) { print "Copying files from $config{skel}\n" if $verbose; open(FIND, "cd $config{skel}; find . -print |") || &cleanup("fork for find: $!\n"); while () { chop; next if ($_ eq "."); ©_to_dir($config{"skel"}, $_, $home_dir, $new_uid, $new_gid, $make_group_also); } } } if ($ask_passwd) { &systemcall('passwd', $new_name); } if ($new_gecos) { &systemcall('chfn', '-f', $new_gecos, $new_name); } else { for (;;) { &systemcall('chfn', $new_name); print "Is the information correct? [y/n] "; chop ($answer=); last if ($answer =~ /^y/i); } } if ($config{"quotauser"}) { print "Setting quota from $config{quotauser}.\n"; &systemcall('edquota', '-p', $config{quotauser}, $new_name); } &systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid, $new_gid, $home_dir) if (-x "/usr/local/sbin/adduser.local"); exit 0; } # calculate home directory sub homedir { my $dir = $config{"dhome"}; $dir .= '/' . $_[1] if ($config{"grouphomes"} =~ /yes/i); $dir .= '/' . substr($_[0],0,1) if ($config{"letterhomes"} =~ /yes/i); $dir .= '/' . $_[0]; } # create a directory and all leading directories sub mktree { my($tree) = @_; my($done, @path); my $default_dir_mode = 0755; $tree =~ s:^/*(.*)/*$:$1:; # chop off leading & trailing slashes @path = split(/\//, $tree); $done = ""; while (@path) { $done .= '/' . shift(@path); -d $done || mkdir($done, $default_dir_mode) || return 0; } 1; } sub check_user_group() { die "$0: The user `$new_name' already exists.\n" if (getpwnam($new_name)); # qmail alias check added by CVB opendir(DIR, $config{"qmail_alias_dir"}); @file = readdir(DIR); closedir(DIR); foreach (@file) { if ($_ eq ".qmail-$new_name") { die "$new_name is a qmail alias\n"; } } ######### die "$0: The UID `$new_uid' already exists.\n" if (defined($new_uid) && getpwuid($new_uid)); if ($make_group_also) { die "$0: The group `$new_name' already exists.\n" if (getgrnam($new_name)); die "$0: The GID `$new_uid' already exists.\n" if (defined($new_uid) && getgrgid($new_uid)); } else { die "$0: The group `$ingroup_name' doesn't exist.\n" if ($ingroup_name && !getgrnam($ingroup_name)); die "$0: The GID `$new_gid' doesn't exist.\n" if (defined($new_gid) && !getgrgid($new_gid)); } } # copy files, directories, symlinks sub copy_to_dir { my($fromdir, $file, $todir, $newu, $newg, $sgiddir) = @_; if (-l "$fromdir/$file") { symlink(readlink("$fromdir/$file"), "$todir/$file") || &cleanup("symlink: $!\n"); } elsif (-f "$fromdir/$file") { open (FILE, "$fromdir/$file") || &cleanup("open $fromdir/$file: $!"); open (NEWFILE, ">$todir/$file") || &cleanup("open >$todir/$file: $!"); (print NEWFILE ) || &cleanup("print $todir/$file: $!"); close FILE; close(NEWFILE) || &cleanup("close $todir/$file "); } elsif (-d "$fromdir/$file") { mkdir("$todir/$file", 700) || &cleanup("mkdir: $!"); } else { &cleanup("Can't deal with $fromdir/$file. " ."Not a dir, file, or symlink.\n"); } chown($newu, $newg, "$todir/$file") || &cleanup("chown $newu:$newg $todir/$file: $!\n"); $perm = (stat("$fromdir/$file"))[2] & 07777; $perm |= 02000 if (-d "$fromdir/$file" && ($perm & 010) && $sgiddir); chmod($perm, "$todir/$file") || &cleanup("chmod $todir/$file: $!\n"); } # is name ok? sub checkname { my ($name) = @_; if ($allow_badname && $name !~ /^[A-Za-z_][-_A-Za-z0-9]*$/) { print STDERR "$0: To avoid problems, the username should consist of a letter or underscore followed by letters, digits, underscores, and dashes.\n"; exit 1; } elsif ($name !~ /^[a-z][a-z0-9]*$/) { if (!$allow_badname) { print STDERR "$0: Please enter a username consisting of a lower case letter followed by lower case letters and numbers. Use the `--force-badname' option to allow underscores, dashes, and uppercase.\n"; exit 1; } print "Allowing use of questionable username.\n" if ($verbose); } } # return the smallest X such that # $min <= X <= $max, and X is not an element of @ids # or -1 if no such X sub first_avail_id { my ($min, $max, @ids) = @_; @ids = sort {$a <=> $b} @ids; print "Selecting from $min $max (" . join(",",@ids) . ").\n" if $debugging; while ($min <= $max) { return $min if ($min < $ids[0] || @ids==0); shift @ids if ($min > $ids[0]); $min++ if ($min == $ids[0]); } -1; # nothing available } # return an array containing all the GIDs sub get_current_gids { my(@gids, $gid); setgrent; push @gids, $gid while defined($gid = (getgrent)[2]); endgrent; @gids; } # return an array containing all the UIDs sub get_current_uids { my(@uids, $uid); setpwent; push @uids, $uid while defined($uid = (getpwent)[2]); endpwent; @uids; } # return a user's groups sub get_users_groups { my($user) = @_; my($name,$members,@groups); setgrent; while (($name,$members) = (getgrent)[0,3]) { for (split(/ /, $members)) { if ($user eq $_) { push @groups, $name; last; } } } endgrent; @groups; } # user is member of group? sub user_is_member { my($user, $group) = @_; for (split(/ /, (getgrnam($group))[3])) { return 1 if ($user eq $_); } 0; } # parse the configuration file sub read_config { my ($conf_file) = @_; my ($var, $lcvar, $val); if (! -f $conf_file) { print "$0: $conf_file doesn't exist. Using defaults.\n" if $verbose; return; } open (CONF, $conf_file) || die "$0: $conf_file: $!\n"; while () { chomp; next if /^#/ || /^\s*$/; if ((($var, $val) = /^\s*(\S+)\s*=\s*(.*)/) != 2) { warn "$0: Couldn't parse $conf_file:$..\n"; next; } $lcvar = lc $var; if (!defined($config{$lcvar})) { warn "$0: Unknown variable `$var' at $conf_file:$..\n"; next; } $val =~ s/^"(.*)"$/$1/; $val =~ s/^'(.*)'$/$1/; $config{$lcvar} = $val; } close CONF || die "$!"; } sub systemcall { my $c = join(' ', @_); print "$c\n" if $debugging; system(@_) && &cleanup("$0: `$c' returned error code $?. Aborting.\n"); } sub cleanup { print "@{_}Cleaning up.\n"; if ($undohome) { print "Removing directory `$undohome'\n"; system('rm', '-rf', $undohome); } if ($undouser) { print "Removing user `$undouser'.\n"; system('userdel', $undouser); } if ($undogroup) { print "Removing group `$undogroup'.\n"; system('groupdel', $undogroup); } exit 1; } sub handler { my($sig) = @_; &cleanup("Caught a SIG$sig.\n"); } sub version { print "$0: add a user or group to the system. Version 3.8 Copyright (C) 1997 Guy Maor Copyright (C) 1995 Ian Murdock , Ted Hajek , This program is free software; you can redistribute 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, /usr/doc/copyright/GPL, for more details. "; } sub usage { print "adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID] [--disabled-password] [--gecos GECOS] user Add a normal user adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP | --gid ID] [--disabled-password] [--gecos GECOS] user Add a system user adduser --group [--gid ID] group addgroup [--gid ID] group Add a system group adduser user group Add an existing user to an existing group Global configuration is in the file $defaults. Other options are [--quiet] [--force-badname] [--help] [--version] [--conf FILE]. "; } --------------------------------------------------------------------- Ian Forbes ZSD http://www.zsd.co.za Office: +27 +21 683-1388 Fax: +27 +21 64-1106 Snail Mail: P.O. Box 46827, Glosderry, 7702, South Africa ---------------------------------------------------------------------   Acknowledgement sent to "I. Forbes" <iforbes@zsd.co.za>:
New bug report received and forwarded. Copy sent to Guy Maor <maor@debian.org>.   -t  From: owner@bugs.debian.org (Debian Bug Tracking System) To: "I. Forbes" Subject: Bug#43527: Acknowledgement ("adduser" does not check for qmail "~alias/.qmail-newuser" alias ) Message-ID: In-Reply-To: References: X-Debian-PR-Message: ack 43527 Thank you for the problem report you have sent regarding Debian. This is an automatically generated reply, to let you know your message has been received. It is being forwarded to the developers' mailing list for their attention; they will reply in due course. Your message has been sent to the package maintainer(s): Guy Maor If you wish to submit further information on your problem, please send it to 43527@bugs.debian.org (and *not* to bugs@bugs.debian.org). Please do not reply to the address at the top of this message, unless you wish to report a problem with the bug-tracking system. Ian Jackson (administrator, Debian bugs database)   Received: (at submit) by bugs.debian.org; 26 Aug 1999 08:58:45 +0000 Received: (qmail 22872 invoked from network); 26 Aug 1999 08:58:15 -0000 Received: from nimbus.zsd.co.za (qmailr@196.25.198.2) by master.debian.org with SMTP; 26 Aug 1999 08:58:15 -0000 Received: (qmail 16970 invoked from network); 26 Aug 1999 08:57:12 -0000 Received: from unknown (HELO discus) (192.168.1.7) by nimbus.zsd.co.za with SMTP; 26 Aug 1999 08:57:12 -0000 From: "I. Forbes" To: submit@bugs.debian.org Date: Thu, 26 Aug 1999 10:54:16 +0200 MIME-Version: 1.0 Content-type: text/plain; charset=US-ASCII Content-transfer-encoding: 7BIT Subject: "adduser" does not check for qmail "~alias/.qmail-newuser" alias Priority: normal X-mailer: Pegasus Mail for Win32 (v3.01d) Package: adduser Version: 3.8 The "qmail" MTA (see www.qmail.org) is now available on debian via the package "qmail-src". This MTA does a few unconventional things, one of them is an alternate method of handling e- mail "alias" names. (Latest versions also honour the accepted /etc/aliases file). There is a user "alias" defined on the system. If a file named: ~alias/.qmail-newuser is present, the contents of that file are treated as a ".qmail" file, (which is a variation of sendmail's .forward file). Mail addressed to "newuser" will then be delivered according to the instructions contained in that file. This is well and good for qmail - it is all a bit different but it works very well. The trouble is that if the file ~alias/.qmail-newuser exists, it is not a good idea to go and create a new user called "newuser" as unpredictable things will happen to his mail. My "adduser" script has been patched to complain if you try and do this. I have attached it for your information and possible inclusion in future released of adduser. Search for "qmail" for a quick look at what has changed. The qmail mechanism is complex. It can react to ~alias/.qmail-newuser-default or ~alias/.qmail-new-user My patches were put together by a student who helped me (Craig Bates craig@zsd.co.za), I am not sure they will work for all of these possibilities. Thanks Ian Forbes #!/usr/bin/perl -w # # adduser 3.8 # # adduser: a utility to add users to the system # addgroup: a utility to add groups to the system # Copyright (C) 1997 Guy Maor # Copyright (C) 1995 Ted Hajek # Ian A. Murdock # General scheme of the program adapted by the original debian 'adduser' # program by Ian A. Murdock . # # This program is free software; you can redistribute 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., 675 Mass Ave, Cambridge, MA 02139, USA. # # #################### # the program can be called as: # # adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID] # [--disabled-password] [--gecos GECOS] user # add a normal user to the system # example: adduser fred # $action = "adduser" # # adduser --group [--gid ID] group # addgroup [--gid ID] group # add a system group # example: addgroup --quiet www-data # $action = "addgroup" # # adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP # | --gid ID] [--disabled-password] [--gecos GECOS] user # add a system user. Create a like-named, like-id'd group with # --group, add to an existing group with --ingroup or --gid. Add # to "nogroup" with neither. # example: adduser --system --home /home/gopher-data --group gopher # $action = "addsysuser" # # adduser user group # add the existing user to an existing group. # $action = "addusertogroup" # # all commands take the following options: # --quiet don't give progress information on STDOUT # --force-badname disable checking of names for funny characters # --help usage message # --version version number and copyright # --conf FILE use FILE instead of /etc/adduser.conf ############ # Modified by Craig Bates - 29-01-99 to check qmail aliases. $verbose = 1; # should we be verbose? $allow_badname = 0; # should we allow bad names? $ask_passwd = 1; # ask for a passwd? $defaults = "/etc/adduser.conf"; $nogroup_id = getgrnam("nogroup") || 65534; $0 =~ s+.*/++; $config{"qmail_alias_dir"} = "/var/qmail/alias/"; $config{"dshell"} = "/bin/bash"; $config{"first_system_uid"} = 100; $config{"last_system_uid"} = 999; $config{"first_uid"} = 1000; $config{"last_uid"} = 29999; $config{"dhome"} = "/home"; $config{"skel"} = "/etc/skel"; $config{"usergroups"} = "yes"; $config{"users_gid"} = "100"; $config{"grouphomes"} = "no"; $config{"letterhomes"} = "no"; $config{"quotauser"} = ""; $action = $0 eq "addgroup" ? "addgroup" : "adduser"; while ($arg = shift(@ARGV)) { die "$0: No options allowed after names.\n" if ($names[0] && $arg =~ /^--/); if ($arg eq "--quiet") { $verbose = 0; } elsif ($arg eq "--force-badname") { $allow_badname = 1; } elsif ($arg eq "--help") { &usage(); exit 0; } elsif ($arg eq "--version") { &version(); exit 0; } elsif ($arg eq "--system") { $action = "addsysuser"; } elsif ($arg eq "--group") { $found_group_opt = 1; } elsif ($arg eq "--ingroup") { die "$0: --ingroup requires an argument.\n" if (!($ingroup_name = shift(@ARGV))); } elsif ($arg eq "--home") { die "$0: --home requires an argument.\n" if (!($special_home = shift(@ARGV))); print "$0: Warning: The home dir you specified already exists.\n" if (-d $special_home && $verbose); die "$0: The home dir must be an absolute path.\n" if ($special_home !~ m+^/+ ); } elsif ($arg eq "--gecos") { $new_gecos = shift(@ARGV); } elsif ($arg eq "--disabled-password") { $ask_passwd = 0; } elsif ($arg eq "--uid") { die "$0: --uid requires a numeric argument.\n" if (!($new_uid = shift(@ARGV)) || $new_uid !~ /^\d+$/); } elsif ($arg eq "--gid") { die "$0: --gid requires a numeric argument.\n" if (!($new_gid = shift(@ARGV)) || $new_gid !~ /^\d+$/); } elsif ($arg eq "--conf") { die "$0: --conf requires an argument.\n" if (!($defaults = shift(@ARGV))); die "$0: `$defaults' doesn't exist.\n" if (! -f $defaults); } elsif ($arg eq "--debug") { $debugging = 1; } elsif ($arg =~ /^--/) { # bad argument! die "$0: Unknown argument `$arg'.\n"; } else { # it's a username push (@names, $arg); } } die "$0: Only root may add a user or group to the system.\n" if ($> != 0); die "$0: I need a name to add.\n" if (@names == 0); die "$0: No more than two names.\n" if (@names > 2); if (@names == 2) { # must be addusertogroup die "$0: Specify only one name in this mode.\n" if ($action eq "addsysuser" || $found_group_opt); $action = "addusertogroup"; $existing_user = shift (@names); $existing_group = shift (@names); } else { $new_name = shift (@names); } if ($found_group_opt) { if ($action eq "addsysuser") { $make_group_also = 1; } else { $action = "addgroup"; } } die "$0: --group, --ingroup, and --gid options are mutually exclusive.\n" if ($action ne "addgroup" && defined($found_group_opt) +defined($ingroup_name) +defined($new_gid) > 1); ##### # OK, we've processed the arguments. $action equals one of the following, # and the appropriate variables have been set: # # $action = "adduser" # $new_name - the name of the new user. # $ingroup_name | $new_gid - the group to add the user to # $special_home, $new_uid, $new_gecos - optional overrides # $action = "addgroup" # $new_name - the name of the new group # $new_gid - optional override # $action = "addsysuser" # $new_name - the name of the new user # $make_group_also | $ingroup_name | $new_gid | 0 - which group # $special_home, $new_uid, $new_gecos - optional overrides # $action = "addusertogroup" # $existing_user - the user to be added # $existing_group - the group to add her to ##### &read_config($defaults); &checkname($new_name) if $new_name; $SIG{'INT'} = $SIG{'QUIT'} = $SIG{'HUP'} = 'handler'; ############## ## addgroup ## ############## if ($action eq "addgroup") { die "$0: The group `$new_name' already exists.\n" if (getgrnam($new_name)); die "$0: The GID `$new_gid' is already in use.\n" if (defined($new_gid) && getgrgid($new_gid)); if (!defined($new_gid)) { $new_gid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_gids); die "$0: No GID is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "Group `$new_name' not created.\n" if ($new_gid == -1); } print "Adding group $new_name ($new_gid)...\n" if $verbose; &systemcall('groupadd', '-g', $new_gid, $new_name); print "Done.\n" if $verbose; exit 0; } #################### ## addusertogroup ## #################### elsif ($action eq "addusertogroup") { die "$0: The user `$existing_user' doesn't exist.\n" if (!getpwnam($existing_user)); die "$0: The group `$existing_group' doesn't exist.\n" if (!getgrnam($existing_group)); if (&user_is_member($existing_user, $existing_group)) { print "The user `$existing_user' is already a member of ", "`$existing_group'.\n" if $verbose; exit 0; # not really an error } print "Adding user $existing_user to group $existing_group...\n" if $verbose; &systemcall('usermod', '-G', join(",", get_users_groups($existing_user), $existing_group), $existing_user); print "Done.\n" if $verbose; exit 0; } ################ ## addsysuser ## ################ elsif ($action eq "addsysuser") { $new_gid = $nogroup_id if (!$ingroup_name && !defined($new_gid) && !$make_group_also); &check_user_group(); print "Adding system user $new_name...\n" if $verbose; if (!defined($new_uid) && $make_group_also) { $new_uid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_uids, &get_current_gids); die "$0: No UID/GID pair is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); $new_gid = $new_uid; $ingroup_name = $new_name; } elsif (!defined($new_uid) && !$make_group_also) { $new_uid = &first_avail_id($config{"first_system_uid"}, $config{"last_system_uid"}, &get_current_uids); die "$0: No UID is available in the range ", "$config{\"first_system_uid\"} - $config{\"last_system_uid\"}\n", "(FIRST_SYS_UID - LAST_SYS_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } else { die "Internal error"; } } else { if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; } else { die "Internal error"; } } if ($make_group_also) { print "Adding new group $new_name ($new_gid).\n" if $verbose; $undogroup = $new_name; &systemcall('groupadd', '-g', $new_gid, $new_name); } print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n" if $verbose; $home_dir = $special_home || &homedir($new_name, $ingroup_name); $undouser = $new_name; &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s', '/bin/false', '-u', $new_uid, $new_name); &systemcall('chfn', '-f', $new_gecos, $new_name) if ($new_gecos); if (-d $home_dir) { print "Home directory $home_dir already exists.\n" if $verbose; } else { print "Creating home directory $home_dir.\n" if $verbose; $undohome = $home_dir; &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n"); chown($new_uid, $new_gid, $home_dir) || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n"); $dir_mode = $make_group_also ? 02755 : 0755; chmod ($dir_mode, $home_dir) || &cleanup("chmod $dir_mode $home_dir: $!\n"); } exit 0; } ############# ## adduser ## ############# elsif ($action eq "adduser") { if (!$ingroup_name && !defined($new_gid)) { if ($config{"usergroups"} eq "yes") { $make_group_also = 1; } else { $new_gid = $config{"users_gid"}; } } &check_user_group(); print "Adding user $new_name...\n" if $verbose; if (!defined($new_uid) && $make_group_also) { $new_uid = &first_avail_id($config{"first_uid"}, $config{"last_uid"}, &get_current_uids, &get_current_gids); die "$0: No UID/GID pair is available in the range ", "$config{\"first_uid\"} - $config{\"last_uid\"}\n", "(FIRST_UID - LAST_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); $new_gid = $new_uid; $ingroup_name = $new_name; } elsif (!defined($new_uid) && !$make_group_also) { $new_uid = &first_avail_id($config{"first_uid"}, $config{"last_uid"}, &get_current_uids); die "$0: No UID is available in the range ", "$config{\"first_uid\"} - $config{\"last_uid\"}\n", "(FIRST_UID - LAST_UID). ", "User `$new_name' not created.\n" if ($new_uid == -1); if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } else { die "Internal error"; } } else { if (defined($new_gid)) { $ingroup_name = getgrgid($new_gid); } elsif ($ingroup_name) { $new_gid = getgrnam($ingroup_name); } elsif ($make_group_also){ $new_gid=$new_uid; $ingroup_name=$new_name; } else { die "Internal error"; } } if ($make_group_also) { print "Adding new group $new_name ($new_gid).\n" if $verbose; $undogroup = $new_name; &systemcall('groupadd', '-g', $new_gid, $new_name); } print "Adding new user $new_name ($new_uid) with group $ingroup_name.\n" if $verbose; $home_dir = $special_home || &homedir($new_name, $ingroup_name); $undouser = $new_name; &systemcall('useradd', '-d', $home_dir, '-g', $ingroup_name, '-s', $config{dshell}, '-u', $new_uid, $new_name); if (-d $home_dir) { print "Home directory $home_dir already exists. Not copying from", " $config{skel}\n" if $verbose; } else { print "Creating home directory $home_dir.\n" if $verbose; $undohome = $home_dir; &mktree($home_dir) || &cleanup("Couldn't create $home_dir: $!.\n"); chown($new_uid, $new_gid, $home_dir) || &cleanup("chown $new_uid:$new_gid $home_dir: $!\n"); $dir_mode = $make_group_also ? 02755 : 0755; chmod ($dir_mode, $home_dir) || &cleanup("chmod $dir_mode $home_dir: $!\n"); if ($config{"skel"}) { print "Copying files from $config{skel}\n" if $verbose; open(FIND, "cd $config{skel}; find . -print |") || &cleanup("fork for find: $!\n"); while () { chop; next if ($_ eq "."); ©_to_dir($config{"skel"}, $_, $home_dir, $new_uid, $new_gid, $make_group_also); } } } if ($ask_passwd) { &systemcall('passwd', $new_name); } if ($new_gecos) { &systemcall('chfn', '-f', $new_gecos, $new_name); } else { for (;;) { &systemcall('chfn', $new_name); print "Is the information correct? [y/n] "; chop ($answer=); last if ($answer =~ /^y/i); } } if ($config{"quotauser"}) { print "Setting quota from $config{quotauser}.\n"; &systemcall('edquota', '-p', $config{quotauser}, $new_name); } &systemcall('/usr/local/sbin/adduser.local', $new_name, $new_uid, $new_gid, $home_dir) if (-x "/usr/local/sbin/adduser.local"); exit 0; } # calculate home directory sub homedir { my $dir = $config{"dhome"}; $dir .= '/' . $_[1] if ($config{"grouphomes"} =~ /yes/i); $dir .= '/' . substr($_[0],0,1) if ($config{"letterhomes"} =~ /yes/i); $dir .= '/' . $_[0]; } # create a directory and all leading directories sub mktree { my($tree) = @_; my($done, @path); my $default_dir_mode = 0755; $tree =~ s:^/*(.*)/*$:$1:; # chop off leading & trailing slashes @path = split(/\//, $tree); $done = ""; while (@path) { $done .= '/' . shift(@path); -d $done || mkdir($done, $default_dir_mode) || return 0; } 1; } sub check_user_group() { die "$0: The user `$new_name' already exists.\n" if (getpwnam($new_name)); # qmail alias check added by CVB opendir(DIR, $config{"qmail_alias_dir"}); @file = readdir(DIR); closedir(DIR); foreach (@file) { if ($_ eq ".qmail-$new_name") { die "$new_name is a qmail alias\n"; } } ######### die "$0: The UID `$new_uid' already exists.\n" if (defined($new_uid) && getpwuid($new_uid)); if ($make_group_also) { die "$0: The group `$new_name' already exists.\n" if (getgrnam($new_name)); die "$0: The GID `$new_uid' already exists.\n" if (defined($new_uid) && getgrgid($new_uid)); } else { die "$0: The group `$ingroup_name' doesn't exist.\n" if ($ingroup_name && !getgrnam($ingroup_name)); die "$0: The GID `$new_gid' doesn't exist.\n" if (defined($new_gid) && !getgrgid($new_gid)); } } # copy files, directories, symlinks sub copy_to_dir { my($fromdir, $file, $todir, $newu, $newg, $sgiddir) = @_; if (-l "$fromdir/$file") { symlink(readlink("$fromdir/$file"), "$todir/$file") || &cleanup("symlink: $!\n"); } elsif (-f "$fromdir/$file") { open (FILE, "$fromdir/$file") || &cleanup("open $fromdir/$file: $!"); open (NEWFILE, ">$todir/$file") || &cleanup("open >$todir/$file: $!"); (print NEWFILE ) || &cleanup("print $todir/$file: $!"); close FILE; close(NEWFILE) || &cleanup("close $todir/$file "); } elsif (-d "$fromdir/$file") { mkdir("$todir/$file", 700) || &cleanup("mkdir: $!"); } else { &cleanup("Can't deal with $fromdir/$file. " ."Not a dir, file, or symlink.\n"); } chown($newu, $newg, "$todir/$file") || &cleanup("chown $newu:$newg $todir/$file: $!\n"); $perm = (stat("$fromdir/$file"))[2] & 07777; $perm |= 02000 if (-d "$fromdir/$file" && ($perm & 010) && $sgiddir); chmod($perm, "$todir/$file") || &cleanup("chmod $todir/$file: $!\n"); } # is name ok? sub checkname { my ($name) = @_; if ($allow_badname && $name !~ /^[A-Za-z_][-_A-Za-z0-9]*$/) { print STDERR "$0: To avoid problems, the username should consist of a letter or underscore followed by letters, digits, underscores, and dashes.\n"; exit 1; } elsif ($name !~ /^[a-z][a-z0-9]*$/) { if (!$allow_badname) { print STDERR "$0: Please enter a username consisting of a lower case letter followed by lower case letters and numbers. Use the `--force-badname' option to allow underscores, dashes, and uppercase.\n"; exit 1; } print "Allowing use of questionable username.\n" if ($verbose); } } # return the smallest X such that # $min <= X <= $max, and X is not an element of @ids # or -1 if no such X sub first_avail_id { my ($min, $max, @ids) = @_; @ids = sort {$a <=> $b} @ids; print "Selecting from $min $max (" . join(",",@ids) . ").\n" if $debugging; while ($min <= $max) { return $min if ($min < $ids[0] || @ids==0); shift @ids if ($min > $ids[0]); $min++ if ($min == $ids[0]); } -1; # nothing available } # return an array containing all the GIDs sub get_current_gids { my(@gids, $gid); setgrent; push @gids, $gid while defined($gid = (getgrent)[2]); endgrent; @gids; } # return an array containing all the UIDs sub get_current_uids { my(@uids, $uid); setpwent; push @uids, $uid while defined($uid = (getpwent)[2]); endpwent; @uids; } # return a user's groups sub get_users_groups { my($user) = @_; my($name,$members,@groups); setgrent; while (($name,$members) = (getgrent)[0,3]) { for (split(/ /, $members)) { if ($user eq $_) { push @groups, $name; last; } } } endgrent; @groups; } # user is member of group? sub user_is_member { my($user, $group) = @_; for (split(/ /, (getgrnam($group))[3])) { return 1 if ($user eq $_); } 0; } # parse the configuration file sub read_config { my ($conf_file) = @_; my ($var, $lcvar, $val); if (! -f $conf_file) { print "$0: $conf_file doesn't exist. Using defaults.\n" if $verbose; return; } open (CONF, $conf_file) || die "$0: $conf_file: $!\n"; while () { chomp; next if /^#/ || /^\s*$/; if ((($var, $val) = /^\s*(\S+)\s*=\s*(.*)/) != 2) { warn "$0: Couldn't parse $conf_file:$..\n"; next; } $lcvar = lc $var; if (!defined($config{$lcvar})) { warn "$0: Unknown variable `$var' at $conf_file:$..\n"; next; } $val =~ s/^"(.*)"$/$1/; $val =~ s/^'(.*)'$/$1/; $config{$lcvar} = $val; } close CONF || die "$!"; } sub systemcall { my $c = join(' ', @_); print "$c\n" if $debugging; system(@_) && &cleanup("$0: `$c' returned error code $?. Aborting.\n"); } sub cleanup { print "@{_}Cleaning up.\n"; if ($undohome) { print "Removing directory `$undohome'\n"; system('rm', '-rf', $undohome); } if ($undouser) { print "Removing user `$undouser'.\n"; system('userdel', $undouser); } if ($undogroup) { print "Removing group `$undogroup'.\n"; system('groupdel', $undogroup); } exit 1; } sub handler { my($sig) = @_; &cleanup("Caught a SIG$sig.\n"); } sub version { print "$0: add a user or group to the system. Version 3.8 Copyright (C) 1997 Guy Maor Copyright (C) 1995 Ian Murdock , Ted Hajek , This program is free software; you can redistribute 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, /usr/doc/copyright/GPL, for more details. "; } sub usage { print "adduser [--home DIR] [--uid ID] [--ingroup GROUP | --gid ID] [--disabled-password] [--gecos GECOS] user Add a normal user adduser --system [--home DIR] [--uid ID] [--group | --ingroup GROUP | --gid ID] [--disabled-password] [--gecos GECOS] user Add a system user adduser --group [--gid ID] group addgroup [--gid ID] group Add a system group adduser user group Add an existing user to an existing group Global configuration is in the file $defaults. Other options are [--quiet] [--force-badname] [--help] [--version] [--conf FILE]. "; } --------------------------------------------------------------------- Ian Forbes ZSD http://www.zsd.co.za Office: +27 +21 683-1388 Fax: +27 +21 64-1106 Snail Mail: P.O. Box 46827, Glosderry, 7702, South Africa ---------------------------------------------------------------------   Severity set to `wishlist'. Request was from Roland Bauerschmidt <rb@debian.org> to control@bugs.debian.org.   Received: (at control) by bugs.debian.org; 1 Jul 2000 21:31:11 +0000 From roland@hbg.schule.bremen.de Sat Jul 01 16:31:11 2000 Return-path: Received: from (www.hbg.schule.bremen.de) [195.37.106.41] by master.debian.org with esmtp (Exim 3.12 2 (Debian)) id 138Ur1-00052L-00; Sat, 01 Jul 2000 16:31:11 -0500 Received: by www.hbg.schule.bremen.de (Postfix, from userid 1000) id 79B382F61D; Sat, 1 Jul 2000 23:31:08 +0200 (CEST) Date: Sat, 1 Jul 2000 23:31:08 +0200 From: Roland Bauerschmidt To: control@bugs.debian.org Message-ID: <20000701233108.A7920@hbg.schule.bremen.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2i Sender: roland@hbg.schule.bremen.de Delivered-To: control@bugs.debian.org severity 43527 wishlist thanks as qmail is even not in the distribution I consider this as a wishlist bug. Roland -- * Roland Bauerschmidt * http://www.copyleft.de/~roland/ * * Debian GNU / Linux -- the choice of a gnu generation *   Severity set to `wishlist'. Request was from Roland Bauerschmidt <rb@debian.org> to control@bugs.debian.org.   Received: (at control) by bugs.debian.org; 1 Jul 2000 21:31:11 +0000 From roland@hbg.schule.bremen.de Sat Jul 01 16:31:11 2000 Return-path: Received: from (www.hbg.schule.bremen.de) [195.37.106.41] by master.debian.org with esmtp (Exim 3.12 2 (Debian)) id 138Ur1-00052L-00; Sat, 01 Jul 2000 16:31:11 -0500 Received: by www.hbg.schule.bremen.de (Postfix, from userid 1000) id 79B382F61D; Sat, 1 Jul 2000 23:31:08 +0200 (CEST) Date: Sat, 1 Jul 2000 23:31:08 +0200 From: Roland Bauerschmidt To: control@bugs.debian.org Message-ID: <20000701233108.A7920@hbg.schule.bremen.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2i Sender: roland@hbg.schule.bremen.de Delivered-To: control@bugs.debian.org severity 43527 wishlist thanks as qmail is even not in the distribution I consider this as a wishlist bug. Roland -- * Roland Bauerschmidt * http://www.copyleft.de/~roland/ * * Debian GNU / Linux -- the choice of a gnu generation *   Tags added: wontfix Request was from Roland Bauerschmidt <roland@bauerschmidt.eu.org> to control@bugs.debian.org.   Received: (at control) by bugs.debian.org; 26 Feb 2001 01:42:27 +0000 From roland@minnesota.bauerschmidt.eu.org Sun Feb 25 19:42:27 2001 Return-path: Received: from ultra.hbci.com [::ffff:206.230.105.5] by master.debian.org with esmtp (Exim 3.12 1 (Debian)) id 14XCgF-0006iQ-00; Sun, 25 Feb 2001 19:42:27 -0600 Received: from localhost (postfix@[64.211.114.35]) by ultra.hbci.com (Pro-8.9.3/8.9.3) with ESMTP id TAA02827 for ; Sun, 25 Feb 2001 19:39:18 -0600 (CST) Received: by localhost (Postfix, from userid 1000) id E842A46824; Sun, 25 Feb 2001 19:40:35 -0600 (CST) Date: Sun, 25 Feb 2001 19:40:35 -0600 From: Roland Bauerschmidt To: control@bugs.debian.org Subject: adduser Message-ID: <20010225194035.A2200@minnesota.bauerschmidt.eu.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.3.15i Delivered-To: control@bugs.debian.org tag 43527 wontfix -- Roland Bauerschmidt