Index | Thread | Search

From:
David Leadbeater <dgl@dgl.cx>
Subject:
user(8) group line limit
To:
tech@openbsd.org
Date:
Thu, 12 Mar 2026 12:22:48 +1100

Download raw body.

Thread
The line length limit used for /etc/group in user(8) does not match what
group(5) documents. This results in a command like usermod -G group user
succeeding, but getgrent(2) no longer accepting the line, resulting in
all the users appearing to drop out of the group.


Index: user.c
===================================================================
RCS file: /cvs/src/usr.sbin/user/user.c,v
diff -u -p -r1.132 user.c
--- user.c	27 Feb 2025 01:32:55 -0000	1.132
+++ user.c	11 Mar 2026 23:59:52 -0000
@@ -166,6 +166,7 @@ enum {
 	MaxFileNameLen = PATH_MAX,
 	MaxUserNameLen = _PW_NAME_LEN,
 	MaxCommandLen = 2048,
+	MaxGroupLineLen = 1024, /* MAXLINELENGTH in getgrent. */
 	PasswordLength = _PASSWORD_LEN,
 	LowGid = DEF_LOWUID,
 	HighGid = DEF_HIGHUID
@@ -530,7 +531,7 @@ modify_gid(char *group, char *newent)
 					continue;
 				} else {
 					cc = strlcpy(buf, newent, sizeof(buf));
-					if (cc >= sizeof(buf)) {
+					if (cc >= sizeof(buf) || cc >= MaxGroupLineLen) {
 						warnx("group `%s' entry too long",
 						    newent);
 						fclose(from);
@@ -658,7 +659,7 @@ append_group(char *user, int ngroups, co
 				if (buf[strlen(buf) - 1] != ':')
 					strlcat(buf, ",", sizeof(buf));
 				cc = strlcat(buf, user, sizeof(buf)) + 1;
-				if (cc >= sizeof(buf)) {
+				if (cc >= sizeof(buf) || cc >= MaxGroupLineLen) {
 					warnx("Warning: group `%s' would "
 					    "become too long, not modifying",
 					    groups[i]);
@@ -2342,7 +2343,7 @@ groupmod(int argc, char **argv)
 		}
 	}
 	cc = strlcat(buf, "\n", sizeof(buf));
-	if (cc >= sizeof(buf))
+	if (cc >= sizeof(buf) || cc >= MaxGroupLineLen)
 		errx(EXIT_FAILURE, "group `%s' entry too long", grp->gr_name);
 
 	openlog("groupmod", LOG_PID, LOG_USER);