diff options
Diffstat (limited to 'sys-apps/shadow/files/shadow-19990827-redhat.patch')
-rw-r--r-- | sys-apps/shadow/files/shadow-19990827-redhat.patch | 865 |
1 files changed, 865 insertions, 0 deletions
diff --git a/sys-apps/shadow/files/shadow-19990827-redhat.patch b/sys-apps/shadow/files/shadow-19990827-redhat.patch new file mode 100644 index 000000000000..75e332db2fd8 --- /dev/null +++ b/sys-apps/shadow/files/shadow-19990827-redhat.patch @@ -0,0 +1,865 @@ +--- shadow-19990827/man/shadowconfig.8.redhat Sat Sep 12 11:38:24 1998 ++++ shadow-19990827/man/shadowconfig.8 Wed Sep 22 15:56:41 1999 +@@ -19,6 +19,3 @@ + Turning shadow passwords on when they are already on, or off when they + are already off, is harmless. + +-Read +-.I /usr/doc/passwd/README.debian.gz +-for a brief introduction to shadow passwords and related features. +--- shadow-19990827/man/useradd.8.redhat Sun Mar 7 14:14:47 1999 ++++ shadow-19990827/man/useradd.8 Wed Sep 22 15:56:41 1999 +@@ -51,7 +51,7 @@ + .IR group [,...]] + .br + .RB [ -m " [" -k +-.IR skeleton_dir ]] ++.IR skeleton_dir ] " |" " " -M ] + .RB [ -p + .IR passwd ] + .br +@@ -60,6 +60,8 @@ + .RB [ -u + .IR uid " [" + .BR -o ]] ++.RB [ -n ] ++.RB [ -r ] + .I login + .TP 8 + .B useradd +@@ -79,6 +81,8 @@ + The new user account will be entered into the system files as needed, + the home directory will be created, and initial files copied, depending + on the command line options. ++The version provided with Red Hat Linux will create a group for each ++user added to the system, unless \fB-n\fR option is given. + The options which apply to the \fBuseradd\fR command are + .\" .IP "\fB-A {\fImethod\fR|\fBDEFAULT\fR},..." + .\" The value of the user's authentication method. +@@ -128,6 +132,21 @@ + option. + The default is to not create the directory and to not copy any + files. ++.IP \fB-M\fR ++The user 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-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-r\fR ++This flag is used to create a system account. That is, an user with an ++UID lower than value of UID_MIN defined in \fI/etc/login.defs\fR. 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-p \fIpasswd\fR" + The encrypted password, as returned by \fBcrypt\fR(3). + The default is to disable the account. +@@ -170,19 +189,24 @@ + .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 convention. + .SH CAVEATS + You may not add a user to an NIS group. + This must be performed on the NIS server. + .SH FILES +-/etc/passwd \- user account information ++\fB/etc/passwd\fR \- user account information ++.br ++\fB/etc/shadow\fR \- secure user account information + .br +-/etc/shadow \- secure user account information ++\fB/etc/group\fR \- group information + .br +-/etc/group \- group information ++\fB/etc/default/useradd\fR \- default information + .br +-/etc/default/useradd \- default information ++\fB/etc/login.defs\fR \- system-wide settings + .br +-/etc/skel \- directory containing default files ++\fB/etc/skel\fR \- directory containing default files + .SH SEE ALSO + .BR chfn (1), + .BR chsh (1), +--- shadow-19990827/man/groupadd.8.redhat Mon Dec 28 15:35:05 1998 ++++ shadow-19990827/man/groupadd.8 Wed Sep 22 15:56:41 1999 +@@ -32,7 +32,7 @@ + groupadd \- Create a new group + .SH SYNOPSIS + .B groupadd +-[\fB-g\fI gid \fR[\fB-o\fR]] ++[\fB-g\fI gid \fR[\fB-o\fR]] [\fB-r\fR] [\fB-f\fR] + .I group + .SH DESCRIPTION + The \fBgroupadd\fR command +@@ -44,9 +44,29 @@ + 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 99 and ++The default is to use the smallest ID value greater than 500 and + greater than every other group. +-Values between 0 and 99 are typically reserved for system accounts. ++Values between 0 and 499 are typically reserved for \fIsystem accounts\fR. ++.IP \fB-r\fR ++This flag instructs \fBgroupadd\fR to add a \fIsystem ++account\fR. First available \fIgid\fR lower than 499 will be ++automatically selected unless \fB-g\fR option is given also on the ++command line. ++.br ++This is an option added by Red Hat Software. ++.IP \fB-f\fR ++This is \fIforce\fR flag. This will stop \fBgroupadd\fR exit with ++error when the group about to be added already exists on the ++system. If that is the case, the group won't be altered (or added ++again, for that matter). ++.br ++This option also modifies the way \fB-g\fR option works. When you ++request a \fIgid\fR that it is not unique and you don't give \fB-o\fR ++option too, the group creation will fall back to the standard behavior ++(adding a group as neither \fB-g\fR or \fB-o\fR options were ++specified). ++.br ++This is an option added by Red Hat Software. + .SH FILES + /etc/group \- group account information + .br +--- shadow-19990827/src/useradd.c.redhat Mon Jun 7 12:40:45 1999 ++++ shadow-19990827/src/useradd.c Wed Sep 22 15:56:41 1999 +@@ -61,7 +61,7 @@ + #define USER_DEFAULTS_FILE "/etc/default/useradd" + #define NEW_USER_FILE "/etc/default/nuaddXXXXXX" + #endif +- ++ + /* + * Needed for MkLinux DR1/2/2.1 - J. + */ +@@ -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 = "/dev/null"; + static const char *def_template = SKEL_DIR; + #ifdef SHADOWPWD + static long def_inactive = -1; +@@ -87,7 +87,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 = ""; +@@ -115,10 +115,13 @@ + sflg = 0, /* shell program for new account */ + cflg = 0, /* comment (GECOS) field for new account */ + mflg = 0, /* create user's home directory if it doesn't exist */ +- kflg = 0, /* specify a directory to fill new user directory */ ++ Mflg = 0, /* do NOT create user's home directory no matter what */ ++ kflg = 0, /* specify a directory to fill new user directory */ + fflg = 0, /* days until account with expired password is locked */ + eflg = 0, /* days since 1970-01-01 when account is locked */ +- Dflg = 0; /* set/show new user default values */ ++ Dflg = 0, /* set/show new user default values */ ++ nflg = 0, /* do not add a group for this user */ ++ rflg = 0; /* create a system account */ + + #ifdef AUTH_METHODS + static int Aflg = 0; /* specify authentication method for user */ +@@ -181,19 +184,19 @@ + #define E_HOMEDIR 12 /* can't create home directory */ + + #ifdef SVR4 +-#define DGROUP "defgroup=" +-#define HOME "defparent=" +-#define SHELL "defshell=" +-#define INACT "definact=" +-#define EXPIRE "defexpire=" +-#define SKEL "defskel=" ++#define DGROUP "defgroup=" ++#define HOME "defparent=" ++#define SHELL "defshell=" ++#define INACT "definact=" ++#define EXPIRE "defexpire=" ++#define SKEL "defskel=" + #else +-#define DGROUP "GROUP=" +-#define HOME "HOME=" +-#define SHELL "SHELL=" +-#define INACT "INACTIVE=" +-#define EXPIRE "EXPIRE=" +-#define SKEL "SKEL=" ++#define DGROUP "GROUP=" ++#define HOME "HOME=" ++#define SHELL "SHELL=" ++#define INACT "INACTIVE=" ++#define EXPIRE "EXPIRE=" ++#define SKEL "SKEL=" + #endif + + /* local function prototypes */ +@@ -711,7 +714,7 @@ + #ifdef AUTH_METHODS + fprintf(stderr, _("[-A program] ")); + #endif +- fprintf(stderr, _("[-p passwd] name\n")); ++ fprintf(stderr, _("[-p passwd] [-n] [-r] name\n")); + + fprintf(stderr, _(" %s\t-D [-g group] [-b base] [-s shell]\n"), + Prog); +@@ -807,31 +810,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 +@@ -969,8 +948,13 @@ + const struct passwd *pwd; + uid_t uid_min, uid_max; + +- uid_min = getdef_num("UID_MIN", 100); +- uid_max = getdef_num("UID_MAX", 60000); ++ if (!rflg) { ++ uid_min = getdef_num("UID_MIN", 500); ++ uid_max = getdef_num("UID_MAX", 60000); ++ } else { ++ uid_min = 1; ++ uid_max = 499; ++ } + + /* + * Start with some UID value if the user didn't provide us with +@@ -1036,6 +1020,88 @@ + } + } + ++/* ++ * 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 = 499; ++ } ++ ++ /* ++ * 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 /* RH Linux 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); ++ } ++ } ++} ++ + #ifdef AUTH_METHODS + /* + * convert_auth - convert the argument list to a authentication list +@@ -1126,9 +1192,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 +@@ -1252,12 +1318,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; +@@ -1302,6 +1362,15 @@ + user_id = get_number(optarg); + uflg++; + break; ++ case 'n': ++ nflg++; ++ break; ++ case 'r': ++ rflg++; ++ break; ++ case 'M': ++ Mflg++; ++ break; + default: + usage(); + } +@@ -1312,9 +1381,12 @@ + * Certain options are only valid in combination with others. + * Check it here so that they can be specified in any order. + */ +- if ((oflg && !uflg) || (kflg && !mflg)) ++ if (kflg && !mflg) + usage(); + ++ if (mflg && Mflg) /* the admin is not decided .. create or not ? */ ++ usage(); ++ + /* + * Either -D or username is required. Defaults can be set with -D + * for the -b, -e, -f, -g, -s options only. +@@ -1435,6 +1507,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*/ + } + + +@@ -1483,9 +1580,6 @@ + struct spwd spent; + #endif + +- if (! oflg) +- find_new_uid (); +- + #ifdef AUTH_METHODS + if (Aflg) { + convert_auth(user_auth, auth_arg); +@@ -1643,6 +1737,118 @@ + } + } + ++/* 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); ++ (const char *) (grent->gr_name) = 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); ++ (const char *)(sgent->sg_name) = 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++; ++} ++ + /* + * main - useradd command + */ +@@ -1688,6 +1894,14 @@ + + process_flags(argc, argv); + ++ 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. +@@ -1706,8 +1920,12 @@ + */ + + if (getpwnam(user_name)) { ++ if (!oflg) { + fprintf(stderr, _("%s: user %s exists\n"), Prog, user_name); + exit(E_NAME_IN_USE); ++ } else { ++ exit(E_SUCCESS); ++ } + } + + /* +@@ -1717,28 +1935,33 @@ + + 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 */ ++ if (! uflg) ++ 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); +- } ++ } /* Stupid warning removed for the innocent's protection */ ++ /* ++ * 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 beging with --gafton ++ */ + + close_files (); + exit(E_SUCCESS); +--- shadow-19990827/src/groupadd.c.redhat Mon Jun 7 12:40:45 1999 ++++ shadow-19990827/src/groupadd.c Wed Sep 22 15:56:41 1999 +@@ -72,6 +72,10 @@ + 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 (RedHat) */ ++ ++/* For adding "system" accounts */ ++#define MIN_GID 10 + + #ifdef NDBM + extern int gr_dbm_mode; +@@ -103,7 +107,7 @@ + static void + usage(void) + { +- fprintf(stderr, _("usage: groupadd [-g gid [-o]] group\n")); ++ fprintf(stderr, _("usage: groupadd [-g gid [-o]] [-r] [-f] group\n")); + exit(E_USAGE); + } + +@@ -228,8 +232,13 @@ + const struct group *grp; + gid_t gid_min, gid_max; + +- gid_min = getdef_num("GID_MIN", 100); +- gid_max = getdef_num("GID_MAX", 60000); ++ if (!rflg) { ++ gid_min = getdef_num("GID_MIN", 500); ++ gid_max = getdef_num("GID_MAX", 60000); ++ } else { ++ gid_min = MIN_GID; ++ gid_max = getdef_num("GID_MIN", 499); ++ } + + /* + * Start with some GID value if the user didn't provide us with +@@ -339,7 +348,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++; +@@ -384,7 +393,13 @@ + */ + fflg++; + break; +- default: ++ case 'r': ++ /* ++ * create a system group ++ */ ++ rflg++; ++ break; ++ default: + usage(); + } + } +--- shadow-19990827/src/userdel.c.redhat Mon Jun 7 12:40:45 1999 ++++ shadow-19990827/src/userdel.c Wed Sep 22 15:59:40 1999 +@@ -59,7 +59,9 @@ + + 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; +@@ -248,6 +250,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 + * +@@ -512,7 +608,8 @@ + + fprintf(stderr, _("%s: user %s is currently logged in\n"), + Prog, name); +- exit(E_USER_BUSY); ++ if (!fflg) ++ exit(E_USER_BUSY); + } + } + +@@ -647,6 +744,7 @@ + main(int argc, char **argv) + { + struct passwd *pwd; ++ struct group *gr; + int arg; + int errors = 0; + +@@ -736,6 +834,9 @@ + #endif + user_id = pwd->pw_uid; + user_home = xstrdup(pwd->pw_dir); ++ user_gid = pwd->pw_gid; ++ gr = getgrgid(pwd->pw_gid); ++ if (gr) user_group = xstrdup(gr->gr_name); + + /* + * Check to make certain the user isn't logged in. +@@ -792,6 +893,9 @@ + } + } + #endif ++ ++ /* remove user's group if appropriate */ ++ remove_group (); + + if (rflg) { + if (remove_tree(user_home) || rmdir(user_home)) { |