Subject: bin/13874: useradd/usermod don't know about login-class [patch]
To: None <gnats-bugs@gnats.netbsd.org>
From: Hubert Feyrer <hubert@feyrer.de>
List: netbsd-bugs
Date: 09/05/2001 20:51:45
>Number:         13874
>Category:       bin
>Synopsis:       useradd/usermod don't know about login-class [patch]
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    agc
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Wed Sep 05 11:47:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Hubert Feyrer
>Release:        NetBSD 1.5.2
>Organization:
bla!
>Environment:
	
System: NetBSD miyu 1.5.2 NetBSD 1.5.2 (MIYU) #12: Fri Aug 17 21:35:53 MEST 2001 feyrer@miyu:/usr/cvs/src-1.5/sys/arch/i386/compile/MIYU i386


>Description:
	Someone complained on IRC (EFnet) that NetBSD's useradd and
	usermod doesn't support setting the login class as "pw usermod"
	and "pw useradd" does on FreeBSD. 

>How-To-Repeat:
	usermod -L guests guest
>Fix:
	The patch below adds these options:

	miyu# ./obj.i386/user mod -L foo lc
	miyu# ./obj.i386/user info lc
	...
	class   foo
	miyu# ./obj.i386/user add -D -L test
	miyu# ./obj.i386/user add -D
	...
	class           test
	miyu# ./obj.i386/user add lc2
	miyu# ./obj.i386/user info lc2
	...
	class   test

	This patch was developed against latest netbsd-1-5 branch
	sources, and it applies also against -current sources.
	(So much for pulling this up ;-)


Index: user.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/user/user.8,v
retrieving revision 1.5.4.1
diff -u -r1.5.4.1 user.8
--- user.8	2000/10/20 20:00:32	1.5.4.1
+++ user.8	2001/09/05 18:46:28
@@ -31,7 +31,7 @@
 .\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\"
-.Dd November 30, 1999
+.Dd September 5, 2001
 .Dt USER 8
 .Os NetBSD
 .Sh NAME
@@ -45,6 +45,7 @@
 .Op Fl e Ar expiry-time
 .Op Fl f Ar inactive-secs
 .Op Fl g Ar gid/name/=uid
+.Op Fl L Ar login-class
 .Op Fl r Ar low..high
 .Nm ""
 .Cm add
@@ -57,6 +58,7 @@
 .Op Fl f Ar inactive-secs
 .Op Fl g Ar gid/name/=uid
 .Op Fl k Ar skel-dir
+.Op Fl L Ar login-class
 .Op Fl p Ar password
 .Op Fl r Ar low..high
 .Op Fl s Ar shell
@@ -83,6 +85,7 @@
 .Op Fl e Ar expiry-time
 .Op Fl f Ar inactive-secs
 .Op Fl g Ar gid/name/=uid
+.Op Fl L Ar login-class
 .Op Fl l Ar new-login
 .Op Fl p Ar password
 .Op Fl s Ar shell
Index: user.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/user/user.c,v
retrieving revision 1.20.4.8
diff -u -r1.20.4.8 user.c
--- user.c	2001/02/26 18:01:17	1.20.4.8
+++ user.c	2001/09/05 18:46:29
@@ -82,6 +82,7 @@
 	char		*u_expire;		/* when password will expire */
 	int		u_inactive;		/* inactive */
 	char		*u_skeldir;		/* directory for startup files */
+	char		*u_class;		/* login class */
 	unsigned	u_rsize;		/* size of range array */
 	unsigned	u_rc;			/* # of ranges */
 	range_t		*u_rv;			/* the ranges */
@@ -102,7 +103,8 @@
 	F_SECGROUP	= 0x0100,
 	F_SHELL 	= 0x0200,
 	F_UID		= 0x0400,
-	F_USERNAME	= 0x0800
+	F_USERNAME	= 0x0800,
+	F_CLASS		= 0x1000
 };
 
 #define CONFFILE	"/etc/usermgmt.conf"
@@ -143,6 +145,10 @@
 #define DEF_EXPIRE	NULL
 #endif
 
+#ifndef DEF_CLASS
+#define DEF_CLASS	""
+#endif
+
 #ifndef WAITSECS
 #define WAITSECS	10
 #endif
@@ -695,7 +701,9 @@
 	FILE	*fp;
 	int	ret;
 	int	fd;
+#ifdef EXTENSIONS
 	int	i;
+#endif
 
 	(void) snprintf(template, sizeof(template), "%s.XXXXXX", CONFFILE);
 	if ((fd = mkstemp(template)) < 0) {
@@ -711,6 +719,9 @@
 	    fprintf(fp, "base_dir\t%s\n", up->u_basedir) <= 0 ||
 	    fprintf(fp, "skel_dir\t%s\n", up->u_skeldir) <= 0 ||
 	    fprintf(fp, "shell\t\t%s\n", up->u_shell) <= 0 ||
+#ifdef EXTENSIONS
+	    fprintf(fp, "class\t\t%s\n", up->u_class) <= 0 ||
+#endif
 	    fprintf(fp, "inactive\t%d\n", up->u_inactive) <= 0 ||
 	    fprintf(fp, "expire\t\t%s\n", (up->u_expire == NULL) ?  UNSET_EXPIRY : up->u_expire) <= 0 ||
 	    fprintf(fp, "preserve\t%s\n", (up->u_preserve == 0) ? "false" : "true") <= 0) {
@@ -748,6 +759,9 @@
 	memsave(&up->u_skeldir, DEF_SKELDIR, strlen(DEF_SKELDIR));
 	memsave(&up->u_shell, DEF_SHELL, strlen(DEF_SHELL));
 	memsave(&up->u_comment, DEF_COMMENT, strlen(DEF_COMMENT));
+#ifdef EXTENSIONS
+	memsave(&up->u_class, DEF_CLASS, strlen(DEF_CLASS));
+#endif
 	up->u_rsize = 16;
 	NEWARRAY(range_t, up->u_rv, up->u_rsize, exit(1));
 	up->u_inactive = DEF_INACTIVE;
@@ -776,6 +790,12 @@
 				for (cp = s + 5 ; *cp && isspace(*cp) ; cp++) {
 				}
 				memsave(&up->u_shell, cp, strlen(cp));
+#ifdef EXTENSIONS
+			} else if (strncmp(s, "class", 5) == 0) {
+				for (cp = s + 5 ; *cp && isspace(*cp) ; cp++) {
+				}
+				memsave(&up->u_class, cp, strlen(cp));
+#endif
 			} else if (strncmp(s, "inactive", 8) == 0) {
 				for (cp = s + 8 ; *cp && isspace(*cp) ; cp++) {
 				}
@@ -950,11 +970,16 @@
 				up->u_password, password);
 		}
 	}
-	cc = snprintf(buf, sizeof(buf), "%s:%s:%d:%d::%d:%ld:%s:%s:%s\n",
+	cc = snprintf(buf, sizeof(buf), "%s:%s:%d:%d:%s:%d:%ld:%s:%s:%s\n",
 			login,
 			password,
 			up->u_uid,
 			gid,
+#ifdef EXTENSIONS
+			up->u_class,
+#else
+			"",
+#endif
 			up->u_inactive,
 			(long) expire,
 			up->u_comment,
@@ -1106,6 +1131,10 @@
 			pwp->pw_dir = up->u_home;
 		if (up->u_flags & F_SHELL)
 			pwp->pw_shell = up->u_shell;
+#ifdef EXTENSIONS
+		if (up->u_flags & F_CLASS)
+			pwp->pw_class = up->u_class;
+#endif
 	}
 	loginc = strlen(login);
 	while ((line = fgetln(master, &len)) != NULL) {
@@ -1116,11 +1145,18 @@
 		colonc = (size_t)(colon - line);
 		if (strncmp(login, line, loginc) == 0 && loginc == colonc) {
 			if (up != NULL) {
-				len = (int)asprintf(&buf, "%s:%s:%d:%d::%ld:%ld:%s:%s:%s\n",
+				len = (int)asprintf(&buf, "%s:%s:%d:%d:"
+#ifdef EXTENSIONS
+									 "%s" 
+#endif
+									      ":%ld:%ld:%s:%s:%s\n",
 					newlogin,
 					pwp->pw_passwd,
 					pwp->pw_uid,
 					pwp->pw_gid,
+#ifdef EXTENSIONS
+					pwp->pw_class,
+#endif
 					(long)pwp->pw_change,
 					(long)pwp->pw_expire,
 					pwp->pw_gecos,
@@ -1207,7 +1243,7 @@
 	if (strcmp(prog, "useradd") == 0) {
 		(void) fprintf(stderr, "Usage: %s -D [-b basedir] [-e expiry] "
 		    "[-f inactive] [-g group]\n\t[-r lowuid..highuid] "
-		    "[-s shell]\n", prog);
+		    "[-s shell] [-L class]\n", prog);
 		(void) fprintf(stderr, "Usage: %s [-G group] [-b basedir] "
 		    "[-c comment] [-d homedir] [-e expiry]\n\t[-f inactive] "
 		    "[-g group] [-k skeletondir] [-m] [-o] [-p password]\n"
@@ -1217,7 +1253,7 @@
 		(void) fprintf(stderr, "Usage: %s [-G group] [-c comment] "
 		    "[-d homedir] [-e expire] [-f inactive]\n\t[-g group] "
 		    "[-l newname] [-m] [-o] [-p password] [-s shell] [-u uid]\n"
-		    "\t[-v] user\n", prog);
+		    "\t[-L class] [-v] user\n", prog);
 	} else if (strcmp(prog, "userdel") == 0) {
 		(void) fprintf(stderr, "Usage: %s -D [-p preserve]\n", prog);
 		(void) fprintf(stderr,
@@ -1247,7 +1283,7 @@
 }
 
 #ifdef EXTENSIONS
-#define ADD_OPT_EXTENSIONS	"p:r:v"
+#define ADD_OPT_EXTENSIONS	"p:r:vL:"
 #else
 #define ADD_OPT_EXTENSIONS	
 #endif
@@ -1259,7 +1295,9 @@
 	int	defaultfield;
 	int	bigD;
 	int	c;
+#ifdef EXTENSIONS
 	int	i;
+#endif
 
 	(void) memset(&u, 0, sizeof(u));
 	read_defaults(&u);
@@ -1307,6 +1345,12 @@
 		case 'k':
 			memsave(&u.u_skeldir, optarg, strlen(optarg));
 			break;
+#ifdef EXTENSIONS
+		case 'L':
+			defaultfield = 1;
+			memsave(&u.u_class, optarg, strlen(optarg));
+			break;
+#endif
 		case 'm':
 			u.u_flags |= F_MKDIR;
 			break;
@@ -1350,6 +1394,9 @@
 		(void) printf("base_dir\t%s\n", u.u_basedir);
 		(void) printf("skel_dir\t%s\n", u.u_skeldir);
 		(void) printf("shell\t\t%s\n", u.u_shell);
+#ifdef EXTENSIONS
+		(void) printf("class\t\t%s\n", u.u_class);
+#endif
 		(void) printf("inactive\t%d\n", u.u_inactive);
 		(void) printf("expire\t\t%s\n", (u.u_expire == NULL) ? UNSET_EXPIRY : u.u_expire);
 #ifdef EXTENSIONS
@@ -1367,7 +1414,7 @@
 }
 
 #ifdef EXTENSIONS
-#define MOD_OPT_EXTENSIONS	"p:v"
+#define MOD_OPT_EXTENSIONS	"p:vL:"
 #else
 #define MOD_OPT_EXTENSIONS	
 #endif
@@ -1422,6 +1469,12 @@
 			have_new_user = 1;
 			u.u_flags |= F_USERNAME;
 			break;
+#ifdef EXTENSIONS
+		case 'L':
+			memsave(&u.u_class, optarg, strlen(optarg));
+			u.u_flags |= F_CLASS;
+			break;
+#endif
 		case 'm':
 			u.u_flags |= F_MKDIR;
 			break;
@@ -1749,7 +1802,9 @@
 		(void) printf("groups\t%s %s\n", grp->gr_name, buf);
 	}
 	(void) printf("change\t%s", pwp->pw_change ? ctime(&pwp->pw_change) : "NEVER\n");
+#ifdef EXTENSIONS
 	(void) printf("class\t%s\n", pwp->pw_class);
+#endif
 	(void) printf("gecos\t%s\n", pwp->pw_gecos);
 	(void) printf("dir\t%s\n", pwp->pw_dir);
 	(void) printf("shell\t%s\n", pwp->pw_shell);
Index: useradd.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/user/useradd.8,v
retrieving revision 1.5.4.1
diff -u -r1.5.4.1 useradd.8
--- useradd.8	2000/10/20 20:00:33	1.5.4.1
+++ useradd.8	2001/09/05 18:46:29
@@ -31,7 +31,7 @@
 .\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\"
-.Dd November 30, 1999
+.Dd Septemper 5, 2001
 .Dt USERADD 8
 .Os NetBSD
 .Sh NAME
@@ -45,6 +45,7 @@
 .Op Fl f Ar inactive-secs
 .Oo
 .Fl g Ar gid | name | Li =uid Oc
+.Op Fl L Ar login-class
 .Oo
 .Op Fl k Ar skel-dir
 .Fl r Ar low Ns Li .. Ns Ar high
@@ -61,6 +62,7 @@
 .Oo
 .Fl g Ar gid | name | Li =uid Oc
 .Op Fl k Ar skel-dir
+.Op Fl L Ar login-class
 .Op Fl p Ar password
 .Oo
 .Fl r Ar low Ns Li .. Ns Ar high
@@ -123,16 +125,20 @@
 sets the default group for any user added using the
 .Nm
 command.
-.It Fl k skel-dir
+.It Fl k Ar skel-dir
 sets the skeleton directory in which to find files with
 which to populate new users' home directories.
+.It Fl L Ar login-class
+This option sets the login class for the user being created.  See
+.Xr login.conf 5
+for more information on user login classes.
 .It Xo
 .Fl r Ar low Ns Li .. Ns Ar high
 .Xc
 sets the low and high bounds of uid ranges for new users. A new user
 can only be created if there are uids which can be assigned from one
 of the free ranges.
-.It Fl s
+.It Fl s Ar shell
 sets the login shell for new users.
 .El
 .Pp
@@ -204,8 +210,26 @@
 .Ar skel_dir
 field in the
 .Pa /etc/usermgmt.conf
+file - it has the format:
+.br \" XXX skip empty line? - HF
+.Bd -ragged -offset indent -compact
+.Ic skel_dir
+.Ar path-to-skeleton-dir
+.Ed
+.It Fl L Ar login-class
+This option sets the login class for the user being created.  See
+.Xr login.conf 5
+for more information on user login classes. Thie value can be preset
+for all users by using the
+.Ar class
+field in the
+.Pa /etc/usermgmt.conf
 file - it has the format:
-.Ar skel_dir <path-to-skeleton-dir> .
+.br \" XXX skip empty line? - HF
+.Bd -ragged -offset indent -compact
+.Ic class
+.Ar login-class
+.Ed
 .It Fl m
 create a new home directory for the new user.
 .It Fl o
@@ -253,6 +277,7 @@
 .Bl -tag -width /etc/usermgmt.conf -compact
 .It Pa /etc/usermgmt.conf
 .It Pa /etc/skel/*
+.It Pa /etc/login.conf
 .El
 .Sh SEE ALSO
 .Xr chpass 1 ,
@@ -260,7 +285,8 @@
 .Xr group 5 ,
 .Xr user 8 ,
 .Xr userdel 8 ,
-.Xr usermod 8
+.Xr usermod 8 ,
+.Xr login.conf 5
 .Sh HISTORY
 The
 .Nm
Index: usermod.8
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/user/usermod.8,v
retrieving revision 1.4.4.3
diff -u -r1.4.4.3 usermod.8
--- usermod.8	2001/02/26 15:16:09	1.4.4.3
+++ usermod.8	2001/09/05 18:46:29
@@ -31,7 +31,7 @@
 .\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
 .\"
-.Dd November 30, 1999
+.Dd September 5, 2001
 .Dt USERMOD 8
 .Os NetBSD
 .Sh NAME
@@ -48,6 +48,7 @@
 .Oo
 .Fl g Ar gid | name | Li =uid
 .Oc
+.Op Fl L Ar login-class
 .Op Fl l Ar new-login
 .Op Fl p Ar password
 .Op Fl s Ar shell
@@ -111,13 +112,27 @@
 by using the
 .Ar gid
 field in the
-.Pa /usr/share/adduser/defaults
+.Pa /etc/usermgmt.conf
 file - it has the format:
 .br \" XXX Shouldn't be necessary -- mdoc bug? --bjh21
 .Bd -ragged -offset indent -compact
 .Ic group
 .Ar gid | name | Li =uid
 .Ed
+.It Fl L Ar login-class
+This option sets the login class for the user being created.  See
+.Xr login.conf 5
+for more information on user login classes. Thie value can be preset
+for all users by using the
+.Ar class
+field in the
+.Pa /etc/usermgmt.conf
+file - it has the format:
+.br \" XXX skip empty line? - HF
+.Bd -ragged -offset indent -compact
+.Ic class
+.Ar login-class
+.Ed
 .It Fl l Ar new-user
 gives the new user name.
 It must consist of alphanumeric characters, or the characters
@@ -158,7 +173,7 @@
 by using the
 .Ar shell
 field in the
-.Pa /usr/share/adduser/defaults
+.Pa /etc/usermgmt.conf
 file - it has the format:
 .D1 Ic shell Ar login-shell
 .It Fl u Ar uid
>Release-Note:
>Audit-Trail:
>Unformatted: