Your message dated Wed, 22 Feb 2006 11:32:07 -0800
with message-id <[EMAIL PROTECTED]>
and subject line Bug#333706: fixed in shadow 1:4.0.14-7
has caused the attached Bug report to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what I am
talking about this indicates a serious mail system misconfiguration
somewhere.  Please contact me immediately.)

Debian bug tracking system administrator
(administrator, Debian Bugs database)

--- Begin Message ---
Package: passwd
Version: 1:4.0.12-6
Severity: wishlist
Tags: patch

The LSB specifies the existence of a useradd '-r' option,

http://www.linuxbase.org/spec//booksets/LSB-Core-generic/LSB-Core-generic/useradd.html

I have commented more on this issue at,

http://lists.debian.org/debian-lsb/2005/10/msg00010.html

Other distros have fixed this but none have pushed the fix upstream. I
have attached Fedora/RedHat's patch against 4.0.7 from the source rpm
at,

http://download.fedora.redhat.com/pub/fedora/linux/core/4/i386/os/SRPMS/shadow-utils-4.0.7-9.src.rpm

The patch does more than just add '-r', it adds '-M' (not in the LSB) and maybe 
other stuff.

I don't think Debian should make this change until upstream has accepted it. So 
consider this a wishlist bug to help get the change upstream so Debian can use 
it too.

-- System Information:
Debian Release: testing/unstable
  APT prefers unstable
  APT policy: (500, 'unstable')
Architecture: i386 (i686)
Shell:  /bin/sh linked to /bin/bash
Kernel: Linux 2.6.12-1-k7
Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968)

Versions of packages passwd depends on:
ii  libc6                         2.3.5-6    GNU C Library: Shared libraries an
ii  libpam-modules                0.76-23    Pluggable Authentication Modules f
ii  libpam0g                      0.76-23    Pluggable Authentication Modules l
ii  login                         1:4.0.3-39 system login tools

passwd recommends no packages.

-- debconf information excluded


Thanks,

-- 
Matt Taggart
[EMAIL PROTECTED]
--- shadow-4.0.7/man/groupadd.8.redhat  2004-11-04 04:06:31.000000000 +0100
+++ shadow-4.0.7/man/groupadd.8 2005-03-01 17:06:16.000000000 +0100
@@ -30,7 +30,7 @@
 groupadd \- Create a new group
 .SH SYNOPSIS
 .TP 6
-\fBgroupadd\fR [\fB-g\fI gid \fR[\fB-o\fR]] [\fB-f\fR] \fIgroup\fR
+\fBgroupadd\fR [\fB-g\fI gid \fR[\fB-o\fR]] [\fB-r\fR] [\fB-f\fR] \fIgroup\fR
 .SH DESCRIPTION
 The \fBgroupadd\fR command creates a new group account using the values
 specified on the command line and the default values from the system. The
@@ -41,11 +41,18 @@
 This option causes to just exit with success status if the specified
 group already exists. With \fB-g\fR, if specified gid already exists,
 other (unique) gid is chosen (i.e. \fB-g\fR is turned off).
+.IP \fB-r\fR
+This flag instructs \fBgroupadd\fR to add a system
+account.  The first available \fIgid\fR lower than 499 will be
+automatically selected unless the \fB-g\fR option is also given on the
+command line.
+.br
+This is an option added by Red Hat.
 .IP "\fB-g\fR \fIgid\fR"
 The numerical value of the group's ID. This value must be unique, unless the
 \fB-o\fR option is used. The value must be non-negative. The default is to
-use the smallest ID value greater than 999 and greater than every other
-group. Values between 0 and 999 are typically reserved for system accounts.
+use the smallest ID value greater than 500 and greater than every other
+group. Values between 0 and 499 are typically reserved for system accounts.
 .SH FILES
 \fI/etc/group\fR       \- group account information
 .br
--- shadow-4.0.7/man/useradd.8.redhat   2004-12-17 00:57:46.000000000 +0100
+++ shadow-4.0.7/man/useradd.8  2005-03-01 17:06:16.000000000 +0100
@@ -36,7 +36,7 @@
 .br
 [\fB-g\fR \fIinitial_group\fR] [\fB-G\fR \fIgroup\fR[,...]]
 .br
-[[\fB-M\fR] \fB-m\fR [\fB-k\fR \fIskeleton_dir\fR]] [\fB-o\fR] [\fB-p\fR 
\fIpasswd\fR]
+[\fB-m\fR [\fB-k\fR \fIskeleton_dir\fR] | \fB-M\fR] [\fB-n\fR] [\fB-o\fR] 
[\fB-p\fR \fIpasswd\fR] [\fB-r\fP]
 .br
 [\fB-s\fR \fIshell\fR] [\fB-u\fR \fIuid\fR] \fIlogin\fR
 .TP 8
@@ -51,7 +51,9 @@
 a new user account using the values specified on the command line and the
 default values from the system. Depending on command line options, the
 useradd command will update system files and may also create the new user's
-home directory and copy initial files.
+home directory and copy initial files. The version provided with Red Hat Linux 
+will create a group for each user added to the system, unless the \fB-n\fR 
+option is given.
 .SH OPTIONS
 The options which apply to the
 \fBuseradd\fR command are:
@@ -80,11 +82,8 @@
 \fB-g\fR option. The default is for the user to belong only to the initial
 group.
 .IP \fB-M\fR
-RedHat added the CREATE_HOME option in login.defs in their version of
-shadow-utils (which makes -m the default, with new -M option to turn it
-off). Unfortunately, this changes the way useradd works (it can be run by
-scripts expecting some standard behaviour), compared to other Unices and
-other Linux distributions, and also adds a lot of confusion.
+The user's home directory will not be created, even if the system
+wide settings from \fI/etc/login.defs\fR is to create home dirs.
 .IP \fB-m\fR
 The user's home directory will be created if it does not exist. The files
 contained in \fIskeleton_dir\fR will be copied to the home directory if the
@@ -93,11 +92,24 @@
 \fI/etc/skel\fR will be created in the user's home directory as well. The
 \fB-k\fR option is only valid in conjunction with the \fB-m\fR option. The
 default is to not create the directory and to not copy any files.
+.IP \fB-n\fR
+A group having the same name as the user being added to the system
+will be created by default. This option will turn off this Red Hat
+Linux specific behavior.
 .IP "\fB-o\fR"
 Allow create user with duplicate (non-unique) UID.
 .IP "\fB-p \fIpasswd\fR"
 The encrypted password, as returned by \fBcrypt\fR(3). The default is to
 disable the account.
+.IP \fB-r\fR
+This flag is used to create a system account. That is, a user with a
+UID lower than the value of UID_MIN defined in \fI/etc/login.defs\fR and
+whose password does not expire. Note
+that \fBuseradd\fR will not create a home directory for such an user,
+regardless of the default setting in \fI/etc/login.defs\fR.
+You have to specify \fB-m\fR option if you want a home directory
+for a system account to be created.
+This is an option added by Red Hat.
 .IP "\fB-s\fR \fIshell\fR"
 The name of the user's login shell. The default is to leave this field
 blank, which causes the system to select the default login shell.
@@ -131,6 +143,9 @@
 .SH NOTES
 The system administrator is responsible for placing the default user files
 in the \fI/etc/skel/\fR directory.
+.br
+This version of useradd was modified by Red Hat to suit Red Hat
+user/group conventions.
 .SH CAVEATS
 You may not add a user to an NIS group. This must be performed on the NIS
 server.
@@ -141,8 +156,12 @@
 .br
 \fI/etc/group\fR                       \- group information
 .br
+\fI/etc/gshadow\fR                     \- secure group information
+.br
 \fI/etc/default/useradd\fR     \- default information
 .br
+\fI/etc/login.defs\fR                  \- system-wide settings
+.br
 \fI/etc/skel/\fR                       \- directory containing default files
 .SH EXIT VALUES
 .TP 2
--- shadow-4.0.7/src/useradd.c.redhat   2005-01-18 00:02:41.000000000 +0100
+++ shadow-4.0.7/src/useradd.c  2005-03-02 10:56:37.379986857 +0100
@@ -75,7 +75,7 @@
 static gid_t def_group = 100;
 static const char *def_gname = "other";
 static const char *def_home = "/home";
-static const char *def_shell = "";
+static const char *def_shell = "/sbin/nologin";
 static const char *def_template = SKEL_DIR;
 static const char *def_create_mail_spool = "no";
 
@@ -89,7 +89,7 @@
 #define        VALID(s)        (strcspn (s, ":\n") == strlen (s))
 
 static const char *user_name = "";
-static const char *user_pass = "!";
+static const char *user_pass = "!!";
 static uid_t user_id;
 static gid_t user_gid;
 static const char *user_comment = "";
@@ -121,8 +121,10 @@
  Gflg = 0,                     /* secondary group set for new account */
  kflg = 0,                     /* specify a directory to fill new user 
directory */
  mflg = 0,                     /* create user's home directory if it doesn't 
exist */
- nflg = 0,                     /* create a group having the same name as the 
user */
+ Mflg = 0,                     /* do NOT create user's home directory no 
matter what */
+ nflg = 0,                     /* do NOT create a group having the same name 
as the user */
  oflg = 0,                     /* permit non-unique user ID to be specified 
with -u */
+ rflg = 0,                     /* create a system account */
  sflg = 0,                     /* shell program for new account */
  uflg = 0;                     /* specify user ID for new account */
 
@@ -725,7 +727,7 @@
 #ifdef SHADOWPWD
        fprintf (stderr, _("               [-f inactive] [-e expire]\n"));
 #endif
-       fprintf (stderr, _("               [-p passwd] name\n"));
+       fprintf (stderr, _("               [-p passwd] [-M] [-n] [-r] name\n"));
        fprintf (stderr,
                 _("       useradd -D [-g group] [-b base] [-s shell]\n"));
 #ifdef SHADOWPWD
@@ -782,11 +784,19 @@
        spent->sp_namp = (char *) user_name;
        spent->sp_pwdp = (char *) user_pass;
        spent->sp_lstchg = time ((time_t *) 0) / SCALE;
-       spent->sp_min = scale_age (getdef_num ("PASS_MIN_DAYS", -1));
-       spent->sp_max = scale_age (getdef_num ("PASS_MAX_DAYS", -1));
-       spent->sp_warn = scale_age (getdef_num ("PASS_WARN_AGE", -1));
-       spent->sp_inact = scale_age (def_inactive);
-       spent->sp_expire = scale_age (user_expire);
+        if (!rflg) {
+                spent->sp_min = scale_age (getdef_num ("PASS_MIN_DAYS", -1));
+                spent->sp_max = scale_age (getdef_num ("PASS_MAX_DAYS", -1));
+                spent->sp_warn = scale_age (getdef_num ("PASS_WARN_AGE", -1));
+                spent->sp_inact = scale_age (def_inactive);
+                spent->sp_expire = scale_age (user_expire);
+        } else {
+                spent->sp_min = scale_age(-1);
+                spent->sp_max = scale_age(-1);
+                spent->sp_warn = scale_age(-1);
+                spent->sp_inact = scale_age(-1);
+                spent->sp_expire = scale_age(-1);
+        }
        spent->sp_flag = -1;
 }
 #endif
@@ -808,33 +818,7 @@
        struct sgrp *nsgrp;
 #endif
 
-       /*
-        * Lock and open the group file. This will load all of the group
-        * entries.
-        */
-
-       if (!gr_lock ()) {
-               fprintf (stderr, _("%s: error locking group file\n"),
-                        Prog);
-               fail_exit (E_GRP_UPDATE);
-       }
-       if (!gr_open (O_RDWR)) {
-               fprintf (stderr, _("%s: error opening group file\n"),
-                        Prog);
-               fail_exit (E_GRP_UPDATE);
-       }
-#ifdef SHADOWGRP
-       if (is_shadow_grp && !sgr_lock ()) {
-               fprintf (stderr,
-                        _("%s: error locking shadow group file\n"), Prog);
-               fail_exit (E_GRP_UPDATE);
-       }
-       if (is_shadow_grp && !sgr_open (O_RDWR)) {
-               fprintf (stderr,
-                        _("%s: error opening shadow group file\n"), Prog);
-               fail_exit (E_GRP_UPDATE);
-       }
-#endif
+        /* Locking and opening of the group files moved to open_files() 
--gafton */
 
        /*
         * Scan through the entire group file looking for the groups that
@@ -973,8 +957,13 @@
        const struct passwd *pwd;
        uid_t uid_min, uid_max;
 
-       uid_min = getdef_unum ("UID_MIN", 100);
-       uid_max = getdef_unum ("UID_MAX", 60000);
+        if (!rflg) {
+                uid_min = getdef_unum ("UID_MIN", 500);
+                uid_max = getdef_unum ("UID_MAX", 60000);
+        } else {
+                uid_min = 1;
+                uid_max = getdef_unum ("UID_MIN", 500) - 1;
+        }
 
        /*
         * Start with some UID value if the user didn't provide us with
@@ -1002,7 +991,7 @@
                                 Prog, user_name);
                        exit (E_NAME_IN_USE);
                }
-               if (uflg && user_id == pwd->pw_uid) {
+               if (!oflg && uflg && user_id == pwd->pw_uid) {
                        fprintf (stderr, _("%s: uid %u is not unique\n"),
                                 Prog, (unsigned int) user_id);
                        exit (E_UID_IN_USE);
@@ -1041,6 +1030,86 @@
 }
 
 /*
+ * find_new_gid - find the next available GID
+ *
+ *     find_new_gid() locates the next highest unused GID in the group
+ *     file, or checks the given group ID against the existing ones for
+ *     uniqueness.
+ */
+
+static void
+find_new_gid()
+{
+       const struct group *grp;
+       gid_t gid_min, gid_max;
+
+       if (!rflg) {
+           gid_min = getdef_num("GID_MIN", 500);
+           gid_max = getdef_num("GID_MAX", 60000);
+       } else {
+           gid_min = 1;
+           gid_max = getdef_num("GID_MIN", 500) - 1;
+       }
+
+       /*
+        * Start with some GID value if the user didn't provide us with
+        * one already.
+        */
+       user_gid = gid_min;
+
+       /*
+        * Search the entire group file, either looking for this
+        * GID (if the user specified one with -g) or looking for the
+        * largest unused value.
+        */
+#ifdef NO_GETGRENT
+       gr_rewind();
+       while ((grp = gr_next()))
+#else
+       setgrent();
+       while ((grp = getgrent()))
+#endif
+           {
+               if (strcmp(user_name, grp->gr_name) == 0) {
+                   user_gid = grp->gr_gid;
+                   return;
+               }
+               if (grp->gr_gid >= user_gid) {
+                   if (grp->gr_gid > gid_max)
+                       continue;
+                   user_gid = grp->gr_gid + 1;
+               }
+       }
+#ifndef NO_GETGRENT /* glibc does have this, so ... */
+       /* A quick test gets here: if the UID is available
+        * as a GID, go ahead and use it */
+       if (!getgrgid(user_id)) {
+           user_gid = user_id;
+           return;
+       }
+#endif
+       if (user_gid == gid_max + 1) {
+               for (user_gid = gid_min; user_gid < gid_max; user_gid++) {
+#ifdef NO_GETGRENT
+                       gr_rewind();
+                       while ((grp = gr_next()) && grp->gr_gid != user_gid)
+                               ;
+                       if (!grp)
+                               break;
+#else
+                       if (!getgrgid(user_gid))
+                               break;
+#endif
+               }
+               if (user_gid == gid_max) {
+                       fprintf(stderr, "%s: can't get unique gid (run out of 
GIDs)\n",
+                               Prog);
+                       fail_exit(4);
+               }
+       }
+}
+
+/*
  * process_flags - perform command line argument setting
  *
  *     process_flags() interprets the command line arguments and sets
@@ -1056,9 +1125,9 @@
        char *cp;
 
 #ifdef SHADOWPWD
-#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:O:M"
+#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:O:Mnr"
 #else
-#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:O:M"
+#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:O:Mnr"
 #endif
        while ((arg = getopt (argc, argv, FLAGS)) != EOF) {
 #undef FLAGS
@@ -1176,12 +1245,6 @@
                case 'm':
                        mflg++;
                        break;
-               case 'M':
-                       /*
-                        * don't create home dir - this is the default,
-                        * ignored for RedHat/PLD adduser compatibility.
-                        */
-                       break;
                case 'o':
                        oflg++;
                        break;
@@ -1229,12 +1292,24 @@
                        user_id = get_uid (optarg);
                        uflg++;
                        break;
+                case 'n':
+                    nflg++;
+                    break;
+                case 'r':
+                    rflg++;
+                    break;
+                case 'M':
+                    Mflg++;
+                    break;
                default:
                        usage ();
                }
                anyflag++;
        }
 
+       if (mflg && Mflg) /* the admin is not decided .. create or not ? */
+               usage();
+
        /*
         * Certain options are only valid in combination with others.
         * Check it here so that they can be specified in any order.
@@ -1313,7 +1388,6 @@
                                 Prog);
                        fail_exit (E_GRP_UPDATE);
                }
-               gr_unlock ();
 #ifdef SHADOWGRP
                if (is_shadow_grp && !sgr_close ()) {
                        fprintf (stderr,
@@ -1322,15 +1396,8 @@
                                 Prog);
                        fail_exit (E_GRP_UPDATE);
                }
-               if (is_shadow_grp)
-                       sgr_unlock ();
 #endif
        }
-#ifdef SHADOWPWD
-       if (is_shadow_pwd)
-               spw_unlock ();
-#endif
-       pw_unlock ();
 }
 
 /*
@@ -1369,6 +1436,31 @@
                exit (E_PW_UPDATE);
        }
 #endif
+       /*
+        * Lock and open the group file.  This will load all of the group
+        * entries.
+        */
+
+       if (! gr_lock ()) {
+               fprintf(stderr, _("%s: error locking group file\n"), Prog);
+               fail_exit(E_GRP_UPDATE);
+       }
+       if (! gr_open (O_RDWR)) {
+               fprintf(stderr, _("%s: error opening group file\n"), Prog);
+               fail_exit(E_GRP_UPDATE);
+       }
+#ifdef SHADOWGRP
+       if (is_shadow_grp && ! sgr_lock ()) {
+               fprintf(stderr, _("%s: error locking shadow group file\n"),
+                       Prog);
+               fail_exit(E_GRP_UPDATE);
+       }
+       if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+               fprintf(stderr, _("%s: error opening shadow group file\n"),
+                       Prog);
+               fail_exit(E_GRP_UPDATE);
+       }
+#endif        /* SHADOWGRP*/
 }
 
 
@@ -1520,6 +1612,118 @@
                grp_update ();
 }
 
+/* a fake something */
+static char *empty_list = NULL;
+
+/*
+ * new_grent - initialize the values in a group file entry
+ *
+ *     new_grent() takes all of the values that have been entered and
+ *     fills in a (struct group) with them.
+ */
+
+static void
+new_grent(grent)
+       struct group *grent;
+{
+       bzero ((char *) grent, sizeof *grent);
+       grent->gr_name = (char *) user_name;
+       grent->gr_passwd = "x";
+       grent->gr_gid = user_gid;
+       grent->gr_mem = &empty_list;
+}
+
+#ifdef SHADOWGRP
+/*
+ * new_sgent - initialize the values in a shadow group file entry
+ *
+ *     new_sgent() takes all of the values that have been entered and
+ *     fills in a (struct sgrp) with them.
+ */
+
+static void
+new_sgent(sgent)
+       struct sgrp *sgent;
+{
+       bzero ((char *) sgent, sizeof *sgent);
+       sgent->sg_name = (char *) user_name;
+       sgent->sg_passwd = "!";
+       sgent->sg_adm = &empty_list;
+       sgent->sg_mem = &empty_list;
+}
+#endif /* SHADOWGRP */
+
+/*
+ * grp_update - add new group file entries
+ *
+ *     grp_update() writes the new records to the group files.
+ */
+
+static void grp_add()
+{
+       struct  group   grp;
+#ifdef SHADOWGRP
+       struct  sgrp    sgrp;
+#endif /* SHADOWGRP */
+
+       /*
+        * Create the initial entries for this new group.
+        */
+
+       new_grent (&grp);
+#ifdef SHADOWGRP
+       new_sgent (&sgrp);
+#endif /* SHADOWGRP */
+
+       /*
+        * Write out the new group file entry.
+        */
+       if (! gr_update (&grp)) {
+               fprintf (stderr, "%s: error adding new group entry\n", Prog);
+               fail_exit (10);
+       }
+#ifdef NDBM
+
+       /*
+        * Update the DBM group file with the new entry as well.
+        */
+
+       if (gr_dbm_present() && ! gr_dbm_update (&grp)) {
+               fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog);
+               fail_exit (10);
+       }
+       endgrent ();
+#endif /* NDBM */
+
+#ifdef SHADOWGRP
+
+       /*
+        * Write out the new shadow group entries as well.
+        */
+
+       if (is_shadow_grp && ! sgr_update (&sgrp)) {
+               fprintf (stderr, "%s: error adding new group entry\n", Prog);
+               fail_exit (10);
+       }
+#ifdef NDBM
+
+       /*
+        * Update the DBM group file with the new entry as well.
+        */
+
+       if (is_shadow_grp && sg_dbm_present() && ! sg_dbm_update (&sgrp)) {
+               fprintf (stderr, "%s: cannot add new dbm group entry\n", Prog);
+               fail_exit (10);
+       }
+       endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+       SYSLOG((LOG_INFO, "new group: name=%s, gid=%d\n",
+               user_name, user_gid));
+       /* we need to remeber we have to close the group file... */
+       do_grp_update++;
+}
+
 /*
  * create_home - create the user's home directory
  *
@@ -1693,6 +1897,14 @@
 #endif
 #endif
 
+       if (!rflg) /* for system accounts defaults are ignored and we
+                    * do not create a home dir -- gafton */
+           if (getdef_bool("CREATE_HOME"))
+               mflg = 1;
+
+       if (Mflg) /* absolutely sure that we do not create home dirs */
+           mflg = 0;
+
        /*
         * See if we are messing with the defaults file, or creating
         * a new user.
@@ -1722,7 +1934,7 @@
         * to that group, use useradd -g username username.
         * --bero
         */
-       if (!gflg) {
+       if ( !(nflg || gflg) ) {
                if (getgrnam (user_name)) {
                        fprintf (stderr,
                                 _
@@ -1744,29 +1956,36 @@
 
        open_files ();
 
+       /* first, seek for a valid uid to use for this user.
+        * We do this because later we can use the uid we found as
+        * gid too ... --gafton */
+       find_new_uid ();
+
+       /* do we have to add a group for that user? This is why we need to
+        * open the group files in the open_files() function  --gafton */
+       if (! (nflg || gflg)) {
+               find_new_gid();
+               grp_add();
+       }
+
        usr_update ();
 
        if (mflg) {
                create_home ();
                copy_tree (def_template, user_home, user_id, user_gid);
-       } else if (getdef_str ("CREATE_HOME")) {
-               /*
-                * RedHat added the CREATE_HOME option in login.defs in their
-                * version of shadow-utils (which makes -m the default, with
-                * new -M option to turn it off). Unfortunately, this
-                * changes the way useradd works (it can be run by scripts
-                * expecting some standard behaviour), compared to other
-                * Unices and other Linux distributions, and also adds a lot
-                * of confusion :-(.
-                * So we now recognize CREATE_HOME and give a warning here
-                * (better than "configuration error ... notify administrator"
-                * errors in every program that reads /etc/login.defs). -MM
-                */
-               fprintf (stderr,
-                        _
-                        ("%s: warning: CREATE_HOME not supported, please use 
-m instead.\n"),
-                        Prog);
        }
+       /* Warning removed to protect the innocent. */
+       /*
+        * The whole idea about breaking some stupid scripts by creating a new
+        * variable is crap - I could care less about the scripts. Historically
+        * adduser type programs have always created the home directories and
+        * I don't like the idea of providing a script when we can fix the
+        * binary itself. And if the scripts are using the right options to the
+        * useradd then they will not break. If not, they depend on unspecified
+        * behavior and they will break, but they were broken anyway to begin
+         * with --gafton
+         */
+
 
        create_mail ();
 
--- shadow-4.0.7/src/userdel.c.redhat   2005-01-18 00:12:05.000000000 +0100
+++ shadow-4.0.7/src/userdel.c  2005-03-01 17:06:16.000000000 +0100
@@ -60,7 +60,9 @@
 #define E_HOMEDIR      12      /* can't remove home directory */
 static char *user_name;
 static uid_t user_id;
+static gid_t user_gid;
 static char *user_home;
+static char *user_group;
 
 static char *Prog;
 static int fflg = 0, rflg = 0;
@@ -280,6 +282,100 @@
 #endif                         /* SHADOWGRP */
 }
 
+/* remove_group()
+ * remove the user's group unless it is not really a user-private group
+ */
+static void
+remove_group ()
+{
+       char    *glist_name;
+       struct  group   *gr;
+       struct  passwd  *pwd;
+#ifdef NDBM
+       struct  group   *ogrp;
+#endif
+
+       if (user_group == NULL || user_name == NULL)
+           return;
+
+       if (strcmp(user_name, user_group)) {
+           return;
+       }
+
+       glist_name = NULL;
+       gr = getgrnam(user_group);
+       if (gr)
+           glist_name = *(gr->gr_mem);
+       while (glist_name) {
+           while (glist_name && *glist_name) {
+               if (strncmp(glist_name, user_name, 16)) {
+                   return;
+               }
+               glist_name++;
+           }
+       }
+
+       setpwent();
+       while ((pwd = getpwent())) {
+           if (strcmp(pwd->pw_name, user_name) == 0)
+               continue;
+
+           if (pwd->pw_gid == user_gid) {
+               return;
+           }
+       }
+
+       /* now actually do the removal if we haven't already returned */
+
+       if (! gr_remove (user_group)) {
+           fprintf (stderr, "%s: error removing group entry\n", Prog);
+       }
+#ifdef NDBM
+
+       /*
+        * Update the DBM group file
+        */
+
+       if (gr_dbm_present()) {
+               if ((ogrp = getgrnam (user_group)) &&
+                               ! gr_dbm_remove (ogrp)) {
+                       fprintf (stderr, "%s: error removing group dbm entry\n",
+                               Prog);
+               }
+       }
+       endgrent ();
+#endif /* NDBM */
+
+#ifdef SHADOWGRP
+
+       /*
+        * Delete the shadow group entries as well.
+        */
+
+       if (is_shadow_grp && ! sgr_remove (user_group)) {
+               fprintf (stderr, "%s: error removing shadow group entry\n",
+                       Prog);
+       }
+#ifdef NDBM
+
+       /*
+        * Update the DBM shadow group file
+        */
+
+       if (is_shadow_grp && sg_dbm_present()) {
+               if (! sg_dbm_remove (user_group)) {
+                       fprintf (stderr,
+                               "%s: error removing shadow group dbm entry\n",
+                               Prog);
+               }
+       }
+       endsgent ();
+#endif /* NDBM */
+#endif /* SHADOWGRP */
+       SYSLOG((LOG_INFO, "remove group `%s'\n", user_group));
+       return;
+}
+
 /*
  * close_files - close all of the files that were opened
  *
@@ -483,7 +579,8 @@
                         _
                         ("%s: user %s is currently logged in\n"),
                         Prog, name);
-               exit (E_USER_BUSY);
+               if (!fflg)
+                       exit (E_USER_BUSY);
        }
 }
 
@@ -614,6 +711,7 @@
 int main (int argc, char **argv)
 {
        struct passwd *pwd;
+       struct group *grp;
        int arg;
        int errors = 0;
 
@@ -732,6 +830,10 @@
 #endif
        user_id = pwd->pw_uid;
        user_home = xstrdup (pwd->pw_dir);
+       user_gid = pwd->pw_gid;
+       grp = getgrgid(user_gid);
+       if (grp)
+               user_group = xstrdup(grp->gr_name);
        /*
         * Check to make certain the user isn't logged in.
         */
@@ -789,6 +891,9 @@
        }
 #endif
 
+       /* Remove the user's group if appropriate. */
+       remove_group();
+
        if (rflg) {
                if (remove_tree (user_home)
                    || rmdir (user_home)) {
--- shadow-4.0.7/src/groupadd.c.redhat  2005-01-18 00:02:41.000000000 +0100
+++ shadow-4.0.7/src/groupadd.c 2005-03-01 17:06:16.000000000 +0100
@@ -72,6 +72,8 @@
 static int oflg = 0;           /* permit non-unique group ID to be specified 
with -g */
 static int gflg = 0;           /* ID value for the new group */
 static int fflg = 0;           /* if group already exists, do nothing and 
exit(0) */
+static int rflg = 0;            /* for adding system accounts (Red Hat) */
+
 
 #ifdef NDBM
 extern int gr_dbm_mode;
@@ -99,7 +101,7 @@
 
 static void usage (void)
 {
-       fprintf (stderr, _("Usage: groupadd [-g gid [-o]] [-f] group\n"));
+       fprintf (stderr, _("usage: groupadd [-g gid [-o]] [-r] [-f] group\n"));
        exit (E_USAGE);
 }
 
@@ -225,8 +227,13 @@
        const struct group *grp;
        gid_t gid_min, gid_max;
 
-       gid_min = getdef_unum ("GID_MIN", 100);
-       gid_max = getdef_unum ("GID_MAX", 60000);
+       if (!rflg) {
+               gid_min = getdef_unum ("GID_MIN", 500);
+               gid_max = getdef_unum ("GID_MAX", 60000);
+       } else {
+               gid_min = 1;
+               gid_max = getdef_unum ("GID_MIN", 500) - 1;
+       }
 
        /*
         * Start with some GID value if the user didn't provide us with
@@ -334,7 +341,7 @@
        char *cp;
        int arg;
 
-       while ((arg = getopt (argc, argv, "og:O:f")) != EOF) {
+       while ((arg = getopt (argc, argv, "og:O:fr")) != EOF) {
                switch (arg) {
                case 'g':
                        gflg++;
@@ -375,11 +382,17 @@
                         * "force" - do nothing, just exit(0), if the
                         * specified group already exists. With -g, if
                         * specified gid already exists, choose another
-                        * (unique) gid (turn off -g). Based on the RedHat's
+                        * (unique) gid (turn off -g). Based on the Red Hat's
                         * patch from shadow-utils-970616-9.
                         */
                        fflg++;
                        break;
+               case 'r':
+                       /*
+                         * create a system group
+                         */
+                        rflg++;
+                        break;
                default:
                        usage ();
                }

--- End Message ---
--- Begin Message ---
Source: shadow
Source-Version: 1:4.0.14-7

We believe that the bug you reported is fixed in the latest version of
shadow, which is due to be installed in the Debian FTP archive:

login_4.0.14-7_i386.deb
  to pool/main/s/shadow/login_4.0.14-7_i386.deb
passwd_4.0.14-7_i386.deb
  to pool/main/s/shadow/passwd_4.0.14-7_i386.deb
shadow_4.0.14-7.diff.gz
  to pool/main/s/shadow/shadow_4.0.14-7.diff.gz
shadow_4.0.14-7.dsc
  to pool/main/s/shadow/shadow_4.0.14-7.dsc



A summary of the changes between this version and the previous one is
attached.

Thank you for reporting the bug, which will now be closed.  If you
have further comments please address them to [EMAIL PROTECTED],
and the maintainer will reopen the bug report if appropriate.

Debian distribution maintenance software
pp.
Christian Perrier <[EMAIL PROTECTED]> (supplier of updated shadow package)

(This message was generated automatically at their request; if you
believe that there is a problem with it please contact the archive
administrators by mailing [EMAIL PROTECTED])


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Format: 1.7
Date: Wed, 22 Feb 2006 06:58:47 +0100
Source: shadow
Binary: login passwd
Architecture: source i386
Version: 1:4.0.14-7
Distribution: unstable
Urgency: low
Maintainer: Shadow package maintainers <[EMAIL PROTECTED]>
Changed-By: Christian Perrier <[EMAIL PROTECTED]>
Description: 
 login      - system login tools
 passwd     - change and administer password and group data
Closes: 333706 352494 353813
Changes: 
 shadow (1:4.0.14-7) unstable; urgency=low
 .
   * The "Carré d'Aurillac" release (let's stay in Cantal)
   * Upstream bugs or fixes not already fixed in upstream releases or CVS:
     - 467_useradd_-r_LSB: add a "-r" option for adding system users
       for LSB compatibility. Closes: #333706
     - 493_selinux_no_proc:
       Only check selinux_check_passwd_access on SELinux enabled system.
       This fix issues in passwd, chage, chfn and chsh when /proc is not
       mounted. Closes: #352494
   * Debian packaging fixes:
     - Stop replacing manpages-it (login only, newusers is still conflicting on
       passwd) and manpages-hu as new releases removed the conflicting manpages
     - passwd.config:
       Better POSIX compliance and avoid failure if root password is set to '!'
       Thanks to Vagrant Cascadian for reporting and providing the patch
       Closes: #353813
Files: 
 d1d4047820f2db31820c47b06805a132 1030 admin required shadow_4.0.14-7.dsc
 7136007b057731da3634a5568271f5ab 177515 admin required shadow_4.0.14-7.diff.gz
 82b17d748b0b50f28a54b68c3fe03c1f 730374 admin required passwd_4.0.14-7_i386.deb
 45f159325898f156ca6dadcb22ec8bf4 653292 admin required login_4.0.14-7_i386.deb

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (GNU/Linux)

iD8DBQFD/Lis1OXtrMAUPS0RAidaAJ9AppWsN4t11uyrEAsncEUS1iPNCgCfYhH/
PqOdgsprj7mTX9bKo/qq88I=
=ocPE
-----END PGP SIGNATURE-----


--- End Message ---

Reply via email to