shadow/redhat/shadow-970616-rh.patch

1243 lines
30 KiB
Diff

--- shadow-970616/man/shadowconfig.8.rh Thu May 1 14:18:17 1997
+++ shadow-970616/man/shadowconfig.8 Fri Dec 12 15:36:29 1997
@@ -14,7 +14,3 @@
will print an error message and exit with a nonzero code if it finds
anything awry. If that happens, you should correct the error and run
it again.
-.PP
-Read
-.I /usr/doc/passwd/README.debian.gz
-for a brief introduction to shadow passwords and related features.
--- shadow-970616/man/useradd.8.rh Thu May 1 19:15:12 1997
+++ shadow-970616/man/useradd.8 Fri Dec 12 15:36:29 1997
@@ -50,13 +50,15 @@
.RB [ -G
.IR group [,...]]
.RB [ -m " [" -k
-.IR skeleton_dir ]]
+.IR skeleton_dir ] " |" " " -M ]
.RB [ -s
.IR shell ]
.br
.RB [ -u
.IR uid " ["
.BR -o ]]
+.RB [ -n ]
+.RB [ -r ]
.I login
.TP 8
.B useradd
@@ -81,6 +83,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-s \fIshell\fR"
The name of the user's login shell.
The default is to leave this field blank, which causes the system
@@ -168,19 +187,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-970616/man/groupadd.8.rh Thu May 1 19:15:06 1997
+++ shadow-970616/man/groupadd.8 Fri Dec 12 15:36:29 1997
@@ -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-970616/lib/getdef.c.rh Thu May 1 19:14:40 1997
+++ shadow-970616/lib/getdef.c Fri Dec 12 15:36:29 1997
@@ -61,6 +61,7 @@
#ifdef HAVE_LIBCRACK
{ "CRACKLIB_DICTPATH", NULL },
#endif
+ { "CREATE_HOME", NULL },
{ "DEFAULT_HOME", NULL },
{ "DIALUPS_CHECK_ENAB", NULL },
{ "ENVIRON_FILE", NULL },
@@ -171,7 +172,7 @@
if ((d = def_find(item)) == NULL || d->value == NULL)
return 0;
- return (strcmp(d->value, "yes") == 0);
+ return (strcasecmp(d->value, "yes") == 0);
}
--- shadow-970616/src/useradd.c.rh Sun Jun 1 01:25:40 1997
+++ shadow-970616/src/useradd.c Fri Dec 12 15:58:04 1997
@@ -60,7 +60,7 @@
#define USER_DEFAULTS_FILE "/etc/default/useradd"
#define NEW_USER_FILE "/etc/default/nuaddXXXXXX"
#endif
-
+
/*
* Needed for MkLinux DR1/2/2.1 - J.
*/
@@ -71,22 +71,22 @@
/*
* These defaults are used if there is no defaults file.
*/
-static gid_t def_group = 1;
+static gid_t def_group = 100;
static char *def_gname = "other";
static char *def_home = "/home";
-static char *def_shell = "";
+static char *def_shell = "/dev/null";
static char *def_template = SKEL_DIR;
#ifdef SHADOWPWD
static long def_inactive = -1;
static char *def_expire = "";
#endif
-static char def_file[] = USER_DEFAULTS_FILE;
+static char def_file[] = USER_DEFAULTS_FILE;
#define VALID(s) (strcspn (s, ":\n") == strlen (s))
static char *user_name = "";
-static char *user_pass = "!";
+static char *user_pass = "!!";
static uid_t user_id;
static gid_t user_gid;
static char *user_comment = "";
@@ -114,10 +114,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 */
@@ -168,6 +171,7 @@
* exit status values
*/
#define E_SUCCESS 0 /* success */
+#define E_LOCKING 1 /* locking error */
#define E_USAGE 2 /* bad command syntax */
#define E_BAD_ARG 3 /* invalid argument to option */
#define E_UID_IN_USE 4 /* uid already in use (and no -o) */
@@ -177,19 +181,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
/*
@@ -679,7 +683,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]"
#ifdef SHADOWPWD
@@ -771,153 +775,129 @@
static void
grp_update()
{
- const struct group *grp;
- struct group *ngrp;
+ const struct group *grp;
+ struct group *ngrp;
#ifdef SHADOWGRP
- const struct sgrp *sgrp;
- struct sgrp *nsgrp;
+ const struct sgrp *sgrp;
+ struct sgrp *nsgrp;
#endif
- /*
- * Lock and open the group file. This will load all of the group
- * entries.
- */
+ /*
+ * Scan through the entire group file looking for the groups that
+ * the user is a member of.
+ */
- if (! gr_lock ()) {
- fprintf (stderr, "%s: error locking group file\n", Prog);
- exit (1);
- }
- if (! gr_open (O_RDWR)) {
- fprintf (stderr, "%s: error opening group file\n", Prog);
- exit (1);
- }
-#ifdef SHADOWGRP
- if (is_shadow_grp && ! sgr_lock ()) {
- fprintf (stderr, "%s: error locking shadow group file\n", Prog);
- exit (1);
- }
- if (is_shadow_grp && ! sgr_open (O_RDWR)) {
- fprintf (stderr, "%s: error opening shadow group file\n", Prog);
- exit (1);
- }
-#endif
+ for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
/*
- * Scan through the entire group file looking for the groups that
- * the user is a member of.
+ * See if the user specified this group as one of their
+ * concurrent groups.
*/
- for (gr_rewind (), grp = gr_next ();grp;grp = gr_next ()) {
+ if (!is_on_list(user_groups, grp->gr_name))
+ continue;
- /*
- * See if the user specified this group as one of their
- * concurrent groups.
- */
-
- if (!is_on_list(user_groups, grp->gr_name))
- continue;
-
- /*
- * Make a copy - gr_update() will free() everything
- * from the old entry, and we need it later.
- */
+ /*
+ * Make a copy - gr_update() will free() everything
+ * from the old entry, and we need it later.
+ */
- ngrp = __gr_dup(grp);
- if (!ngrp) {
- exit(13); /* XXX */
- }
+ ngrp = __gr_dup(grp);
+ if (!ngrp) {
+ exit(13); /* XXX */
+ }
- /*
- * Add the username to the list of group members and
- * update the group entry to reflect the change.
- */
+ /*
+ * Add the username to the list of group members and
+ * update the group entry to reflect the change.
+ */
- ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
- if (! gr_update (ngrp)) {
- fprintf (stderr, "%s: error adding new group entry\n",
- Prog);
- fail_exit (1);
- }
+ ngrp->gr_mem = add_list (ngrp->gr_mem, user_name);
+ if (! gr_update (ngrp)) {
+ fprintf (stderr, "%s: error adding new group entry\n",
+ Prog);
+ fail_exit (1);
+ }
#ifdef NDBM
- /*
- * Update the DBM group file with the new entry as well.
- */
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
- if (! gr_dbm_update (ngrp)) {
- fprintf (stderr, "%s: cannot add new dbm group entry\n",
- Prog);
- fail_exit (1);
- } else
- gr_dbm_added++;
-#endif
- SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
- user_name, ngrp->gr_name));
- }
+ if (! gr_dbm_update (ngrp)) {
+ fprintf (stderr, "%s: cannot add new dbm group entry\n",
+ Prog);
+ fail_exit (1);
+ } else
+ gr_dbm_added++;
+#endif
+ SYSLOG((LOG_INFO, "add `%s' to group `%s'\n",
+ user_name, ngrp->gr_name));
+ }
#ifdef NDBM
- endgrent ();
+ endgrent ();
#endif
#ifdef SHADOWGRP
- if (!is_shadow_grp)
- return;
+ if (!is_shadow_grp)
+ return;
- /*
- * Scan through the entire shadow group file looking for the groups
- * that the user is a member of. The administrative list isn't
- * modified.
- */
+ /*
+ * Scan through the entire shadow group file looking for the groups
+ * that the user is a member of. The administrative list isn't
+ * modified.
+ */
- for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
+ for (sgr_rewind (), sgrp = sgr_next ();sgrp;sgrp = sgr_next ()) {
- /*
- * See if the user specified this group as one of their
- * concurrent groups.
- */
+ /*
+ * See if the user specified this group as one of their
+ * concurrent groups.
+ */
- if (!gr_locate(sgrp->sg_name))
- continue;
+ if (!gr_locate(sgrp->sg_name))
+ continue;
- if (!is_on_list(user_groups, sgrp->sg_name))
- continue;
+ if (!is_on_list(user_groups, sgrp->sg_name))
+ continue;
- /*
- * Make a copy - sgr_update() will free() everything
- * from the old entry, and we need it later.
- */
+ /*
+ * Make a copy - sgr_update() will free() everything
+ * from the old entry, and we need it later.
+ */
- nsgrp = __sgr_dup(sgrp);
- if (!nsgrp) {
- exit(13); /* XXX */
- }
+ nsgrp = __sgr_dup(sgrp);
+ if (!nsgrp) {
+ exit(13); /* XXX */
+ }
- /*
- * Add the username to the list of group members and
- * update the group entry to reflect the change.
- */
+ /*
+ * Add the username to the list of group members and
+ * update the group entry to reflect the change.
+ */
- nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
- if (! sgr_update (nsgrp)) {
- fprintf (stderr, "%s: error adding new group entry\n",
- Prog);
- fail_exit (1);
- }
+ nsgrp->sg_mem = add_list (nsgrp->sg_mem, user_name);
+ if (! sgr_update (nsgrp)) {
+ fprintf (stderr, "%s: error adding new group entry\n",
+ Prog);
+ fail_exit (1);
+ }
#ifdef NDBM
- /*
- * Update the DBM group file with the new entry as well.
- */
+ /*
+ * Update the DBM group file with the new entry as well.
+ */
- if (! sg_dbm_update (nsgrp)) {
- fprintf (stderr, "%s: cannot add new dbm group entry\n",
- Prog);
- fail_exit (1);
- } else
- sg_dbm_added++;
+ if (! sg_dbm_update (nsgrp)) {
+ fprintf (stderr, "%s: cannot add new dbm group entry\n",
+ Prog);
+ fail_exit (1);
+ } else
+ sg_dbm_added++;
#endif /* NDBM */
- SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
- user_name, nsgrp->sg_name));
- }
+ SYSLOG((LOG_INFO, "add `%s' to shadow group `%s'\n",
+ user_name, nsgrp->sg_name));
+ }
#ifdef NDBM
- endsgent ();
+ endsgent ();
#endif /* NDBM */
#endif /* SHADOWGRP */
}
@@ -936,8 +916,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
@@ -1003,6 +988,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
@@ -1099,9 +1166,9 @@
int arg;
#ifdef SHADOWPWD
-#define FLAGS "A:Du:og:G:d:s:c:mk:p:f:e:b:"
+#define FLAGS "A:Du:og:G:d:s:c:mMk:p:f:e:b:nr"
#else
-#define FLAGS "A:Du:og:G:d:s:c:mk:p:b:"
+#define FLAGS "A:Du:og:G:d:s:c:mMk:p:b:nr"
#endif
while ((arg = getopt(argc, argv, FLAGS)) != EOF) {
#undef FLAGS
@@ -1251,6 +1318,15 @@
user_id = get_number(optarg);
uflg++;
break;
+ case 'n':
+ nflg++;
+ break;
+ case 'r':
+ rflg++;
+ break;
+ case 'M':
+ Mflg++;
+ break;
default:
usage ();
}
@@ -1261,9 +1337,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.
@@ -1312,39 +1391,53 @@
static void
close_files()
{
- if (! pw_close ()) {
- fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
- fail_exit (1);
- }
+ if (! pw_close ()) {
+ fprintf (stderr, "%s: cannot rewrite password file\n", Prog);
+ fail_exit (1);
+ }
#ifdef SHADOWPWD
- if (is_shadow_pwd && ! spw_close ()) {
- fprintf (stderr, "%s: cannot rewrite shadow password file\n",
- Prog);
- fail_exit (1);
+ if (is_shadow_pwd && ! spw_close ()) {
+ fprintf (stderr, "%s: cannot rewrite shadow password file\n",
+ Prog);
+ fail_exit (1);
+ }
+#endif
+ if (do_grp_update) {
+ if (! gr_close ()) {
+ fprintf (stderr, "%s: cannot rewrite group file\n",
+ Prog);
+ fail_exit (1);
}
-#endif
- if (do_grp_update) {
- if (! gr_close ()) {
- fprintf (stderr, "%s: cannot rewrite group file\n",
- Prog);
- fail_exit (1);
- }
- (void) gr_unlock ();
+ (void) gr_unlock ();
#ifdef SHADOWGRP
- if (is_shadow_grp && ! sgr_close ()) {
- fprintf (stderr, "%s: cannot rewrite shadow group file\n",
- Prog);
- fail_exit (1);
- }
- if (is_shadow_grp)
- sgr_unlock ();
-#endif
+ if (is_shadow_grp && ! sgr_close ()) {
+ fprintf (stderr, "%s: cannot rewrite shadow group file\n",
+ Prog);
+ fail_exit (1);
}
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif
+ }
#ifdef SHADOWPWD
- if (is_shadow_pwd)
- spw_unlock ();
+ if (is_shadow_pwd)
+ spw_unlock ();
#endif
- (void) pw_unlock ();
+ (void) pw_unlock ();
+ if (! gr_close ()) {
+ fprintf (stderr, "%s: cannot rewrite group file\n", Prog);
+ fail_exit (10);
+ }
+ (void) gr_unlock ();
+#ifdef SHADOWGRP
+ if (is_shadow_grp && ! sgr_close ()) {
+ fprintf (stderr, "%s: cannot rewrite shadow group file\n",
+ Prog);
+ fail_exit (10);
+ }
+ if (is_shadow_grp)
+ sgr_unlock ();
+#endif /* SHADOWGRP */
}
/*
@@ -1353,27 +1446,47 @@
* open_files() opens the two password files.
*/
-static void
-open_files()
+static void open_files(void)
{
- if (!pw_lock_first()) {
- fprintf (stderr, "%s: unable to lock password file\n", Prog);
- exit (1);
- }
- if (! pw_open (O_RDWR)) {
- fprintf (stderr, "%s: unable to open password file\n", Prog);
- exit (1);
- }
+ if (!pw_lock_first()) {
+ fprintf (stderr, "%s: unable to lock password file\n", Prog);
+ exit (1);
+ }
+ if (! pw_open (O_RDWR)) {
+ fprintf (stderr, "%s: unable to open password file\n", Prog);
+ exit (1);
+ }
#ifdef SHADOWPWD
- if (is_shadow_pwd && ! spw_lock ()) {
- fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
- exit (1);
- }
- if (is_shadow_pwd && ! spw_open (O_RDWR)) {
- fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
- exit (1);
- }
-#endif
+ if (is_shadow_pwd && ! spw_lock ()) {
+ fprintf (stderr, "%s: cannot lock shadow password file\n", Prog);
+ exit (1);
+ }
+ if (is_shadow_pwd && ! spw_open (O_RDWR)) {
+ fprintf (stderr, "%s: cannot open shadow password file\n", Prog);
+ exit (1);
+ }
+#endif
+ if (! gr_lock ()) {
+ fprintf (stderr, "%s: unable to lock group file\n", Prog);
+ exit (E_LOCKING);
+ }
+ if (! gr_open (O_RDWR)) {
+ fprintf (stderr, "%s: unable to open group file\n", Prog);
+ fail_exit (10);
+ }
+#ifdef SHADOWGRP
+ if (is_shadow_grp && ! sgr_lock ()) {
+ fprintf (stderr, "%s: unable to lock shadow group file\n",
+ Prog);
+ fail_exit (E_LOCKING);
+ }
+ if (is_shadow_grp && ! sgr_open (O_RDWR)) {
+ fprintf (stderr, "%s: unable to open shadow group file\n",
+ Prog);
+ fail_exit (10);
+ }
+#endif /* SHADOWGRP*/
+
}
@@ -1424,9 +1537,6 @@
struct spwd spent;
#endif
- if (! oflg)
- find_new_uid ();
-
#ifdef AUTH_METHODS
if (Aflg) {
convert_auth(user_auth, auth_arg);
@@ -1582,6 +1692,117 @@
}
}
+/* 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 = 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 = 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));
+}
+
/*
* main - useradd command
*/
@@ -1591,76 +1812,100 @@
int argc;
char **argv;
{
- /*
- * Get my name so that I can use it to report errors.
- */
+ /*
+ * Get my name so that I can use it to report errors.
+ */
- Prog = Basename(argv[0]);
+ Prog = Basename(argv[0]);
- openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
+ openlog(Prog, LOG_PID|LOG_CONS|LOG_NOWAIT, LOG_AUTH);
#ifdef SHADOWPWD
- is_shadow_pwd = (access(SHADOW_FILE, 0) == 0);
+ is_shadow_pwd = (access(SHADOW_FILE, 0) == 0);
#endif
#ifdef SHADOWGRP
- is_shadow_grp = (access(SGROUP_FILE, 0) == 0);
+ is_shadow_grp = (access(SGROUP_FILE, 0) == 0);
#endif
- /*
- * The open routines for the NDBM files don't use read-write
- * as the mode, so we have to clue them in.
- */
+ /*
+ * The open routines for the NDBM files don't use read-write
+ * as the mode, so we have to clue them in.
+ */
#ifdef NDBM
- pw_dbm_mode = O_RDWR;
+ pw_dbm_mode = O_RDWR;
#ifdef SHADOWPWD
- sp_dbm_mode = O_RDWR;
+ sp_dbm_mode = O_RDWR;
#endif
- gr_dbm_mode = O_RDWR;
+ gr_dbm_mode = O_RDWR;
#ifdef SHADOWGRP
- sg_dbm_mode = O_RDWR;
+ sg_dbm_mode = O_RDWR;
#endif
#endif
- get_defaults();
+ get_defaults();
- process_flags(argc, argv);
+ process_flags(argc, argv);
- /*
- * See if we are messing with the defaults file, or creating
- * a new user.
- */
+ if (!rflg) /* for system accounts defaults are ignored
+ * == do not create */
+ if (getdef_bool("CREATE_HOME"))
+ mflg = 1;
- if (Dflg) {
- if (gflg || bflg || fflg || eflg || sflg)
- exit (set_defaults () ? 1:0);
+ 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.
+ */
- show_defaults ();
- exit (0);
- }
+ if (Dflg) {
+ if (gflg || bflg || fflg || eflg || sflg)
+ exit (set_defaults () ? 1:0);
- /*
- * Start with a quick check to see if the user exists.
- */
+ show_defaults ();
+ exit (0);
+ }
- if (getpwnam(user_name)) {
- fprintf(stderr, "%s: user %s exists\n", Prog, user_name);
- exit(E_NAME_IN_USE);
- }
+ /*
+ * Start with a quick check to see if the user exists.
+ */
- /*
- * Do the hard stuff - open the files, create the user entries,
- * create the home directory, then close and update the files.
- */
-
- open_files ();
+ 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);
+ }
+ }
- usr_update ();
+ /*
+ * Do the hard stuff - open the files, create the user entries,
+ * create the home directory, then close and update the files.
+ */
+
+ 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 ... --rh */
+ if (! uflg)
+ find_new_uid ();
+
+ /* do we have to add a group for that user ? */
+ if (! (nflg || gflg)) {
+ find_new_gid();
+ grp_add();
+ }
+
+ usr_update ();
+
+ if (mflg) {
+ create_home ();
+ copy_tree (def_template, user_home, user_id, user_gid);
+ }
+ close_files ();
- if (mflg) {
- create_home ();
- copy_tree (def_template, user_home, user_id, user_gid);
- }
- close_files ();
- exit(E_SUCCESS);
- /*NOTREACHED*/
+ exit(E_SUCCESS);
+ /*NOTREACHED*/
}
--- shadow-970616/src/groupadd.c.rh Thu May 1 19:07:11 1997
+++ shadow-970616/src/groupadd.c Fri Dec 12 15:36:29 1997
@@ -61,6 +61,11 @@
oflg = 0, /* permit non-unique group ID to be specified with -g */
gflg = 0; /* ID value for the new group */
+/* For adding "system" accounts */
+static int system_flag = 0;
+static int force_flag = 0;
+#define MIN_GID 10
+
#ifdef NDBM
extern int gr_dbm_mode;
extern int sg_dbm_mode;
@@ -75,7 +80,7 @@
static void
usage()
{
- fprintf (stderr, "usage: groupadd [-g gid [-o]] group\n");
+ fprintf (stderr, "usage: groupadd [-g gid [-o]] [-r] [-f] group\n");
exit (2);
}
@@ -202,8 +207,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 (!system_flag) {
+ 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
@@ -227,16 +237,34 @@
while ((grp = getgrent())) {
#endif
if (strcmp(group_name, grp->gr_name) == 0) {
+ if (!force_flag) {
fprintf(stderr, "%s: name %s is not unique\n",
Prog, group_name);
fail_exit(9);
+ } else {
+ fail_exit(0);
+ }
}
if (gflg && group_id == grp->gr_gid) {
+ if (!force_flag) {
fprintf(stderr, "%s: gid %ld is not unique\n",
Prog, (long) group_id);
fail_exit(4);
+ } else {
+ /* we invalidate the gflg and search again */
+ gflg = 0;
+ if (oflg)
+ oflg = 0;
+ /* now, start at the begining... */
+#ifdef NO_GETGRENT
+ gr_rewind();
+#else
+ setgrent();
+#endif
+ continue;
+ }
}
- if (! gflg && grp->gr_gid >= group_id) {
+ if (!gflg && grp->gr_gid >= group_id) {
if (grp->gr_gid > gid_max)
continue;
group_id = grp->gr_gid + 1;
@@ -298,42 +326,49 @@
process_flags(argc, argv)
int argc;
char **argv;
-{
- extern int optind;
- extern char *optarg;
- char *end;
- int arg;
+ {
+ extern int optind;
+ extern char *optarg;
+ char *end;
+ int arg;
- while ((arg = getopt (argc, argv, "og:")) != EOF) {
+ while ((arg = getopt (argc, argv, "og:rf")) != EOF) {
switch (arg) {
- case 'g':
- gflg++;
- if (! isdigit (optarg[0]))
- usage ();
-
- group_id = strtol (optarg, &end, 10);
- if (*end != '\0') {
- fprintf (stderr, "%s: invalid group %s\n",
- Prog, optarg);
- fail_exit (3);
- }
- break;
- case 'o':
- if (! gflg)
- usage ();
-
- oflg++;
- break;
- default:
- usage ();
+ case 'g':
+ gflg++;
+ if (! isdigit (optarg[0]))
+ usage ();
+
+ group_id = strtol (optarg, &end, 10);
+ if (*end != '\0') {
+ fprintf (stderr, "%s: invalid group %s\n",
+ Prog, optarg);
+ fail_exit (3);
+ }
+ break;
+ case 'o':
+ if (! gflg)
+ usage ();
+
+ oflg++;
+ break;
+ case 'r': /* "system" group */
+ system_flag++;
+ break;
+ case 'f': /* "force" - don't exit with error if group already exist */
+ force_flag++;
+ break;
+
+ default:
+ usage ();
}
- }
- if (optind != argc - 1)
+ }
+ if (optind != argc - 1)
usage ();
- group_name = argv[argc - 1];
- check_new_name ();
-}
+ group_name = argv[argc - 1];
+ check_new_name ();
+ }
/*
* close_files - close all of the files that were opened
@@ -448,8 +483,12 @@
*/
if (getgrnam(group_name)) {
+ if ( !force_flag) {
fprintf (stderr, "%s: group %s exists\n", Prog, group_name);
exit(9);
+ } else {
+ exit(0);
+ }
}
/*