tags 334351 + patch pending
thanks

I believe the attached patch solve the issue, but dropping the use of
NGROUPS_MAX, and instead count the number of groups before allocating
the memory needed from the heap.

Please test it and let me know if it solve your problem.  Unless you
tell me it failed to work, I'll upload a new version with this bug
fixed in a few days.

Index: plan-1.9/src/netplan.h
===================================================================
RCS file: /home/pere/src/plan/plan-1.9/src/netplan.h,v
retrieving revision 1.1.1.2
diff -u -3 -p -r1.1.1.2 netplan.h
--- plan-1.9/src/netplan.h	9 Jan 2005 11:21:54 -0000	1.1.1.2
+++ plan-1.9/src/netplan.h	23 Dec 2005 23:13:48 -0000
@@ -56,7 +56,8 @@ struct client {
 	char		*descr;		/* client-provided self-description */
 	char            *user;          /* user name if authenticated */
 	unsigned int	uid;	        /* client-provided user/group ID */
-	int             gids[NGROUPS_MAX];/* group access list */
+	int             gidcount;       /* number of in group entries */
+	int             *gids;          /* group access list */
 	BOOL            auth_fail;	/* required identd check failed */
 	int		port;		/* accept socket to client */
 	struct sockaddr_in addr;	/* contains IP addr and port */
Index: plan-1.9/src/netplan.c
===================================================================
RCS file: /home/pere/src/cvsroot/src/plan/plan-1.9/src/netplan.c,v
retrieving revision 1.1.1.3
diff -u -3 -p -r1.1.1.3 netplan.c
--- plan-1.9/src/netplan.c	19 Feb 2005 10:39:37 -0000	1.1.1.3
+++ plan-1.9/src/netplan.c	23 Dec 2005 23:13:48 -0000
@@ -330,12 +330,12 @@ int main(
 				memset(cp, 0, sizeof(struct client));
 				memcpy(&cp->addr, &addr, n);
 				cp->uid     = nobody_uid;
+				cp->gids    = allocate(sizeof(*(cp->gids)));
+				cp->gidcount = 1;
 				cp->gids[0] = nobody_gid;
 				cp->descr   = mystrdup(nobody);
 				cp->user    = mystrdup(nobody);
 				cp->port    = netplan_port[c];
-				for (i=1; i < NGROUPS_MAX; i++)
-					cp->gids[i] = -1;
 
 				logger("client %d (%.200s) connected from %s\n"
 					       ,fd, cp->descr, ip_addr(&addr));
@@ -404,19 +404,29 @@ static void setup_gids(
 	struct group	*gr;
 	int		ngroups = 0;
 	char		**p;
+	int             groupcount;
 
+	/* Unspecified if the default gid is included or not, so add
+	   one just in case. */
+	groupcount = getgroups(0, NULL) + 1;
+	cp->gids = allocate(groupcount * sizeof(*(cp->gids)));
 	cp->gids[ngroups++] = gid;
 	setgrent();
 	while ((gr = getgrent()))
 		for (p=gr->gr_mem; *p; p++)
 			if (!strcmp(user, *p)) {
-				if (ngroups < NGROUPS_MAX)
+				if (ngroups < groupcount)
 					cp->gids[ngroups] = gr->gr_gid;
 				ngroups++;
 				break;
 			}
-	if (ngroups > NGROUPS_MAX)
-		logger("too many groups (%d, used %d)\n", ngroups,NGROUPS_MAX);
+	if (ngroups > groupcount) {
+		logger("too many groups (%d, used %d)\n", ngroups, groupcount);
+		cp->gidcount = groupcount;
+	}
+	else
+		cp->gidcount = ngroups;
+
 }
 
 
@@ -525,6 +535,7 @@ static void close_client(
 
 	for (fid=0; fid < max_files; fid++)
 		close_file(fid, fd);
+	release(c->gids);
 	release(c->descr);
 	release(c->user);
 	release(c->in.data);
@@ -650,7 +661,7 @@ static void eval_message(
 						"user %.100s, uid %d, gids",
 						fd, c->user, c->uid);
 				p = buf + strlen(buf);
-				for (i=0; i<NGROUPS_MAX && c->gids[i]>=0; i++){
+				for (i=0; i<c->gidcount && c->gids[i]>=0; i++){
 					sprintf(p, " %d", c->gids[i]);
 					p += strlen(p);
 				}
@@ -684,7 +695,7 @@ static void eval_message(
 			sprintf(buf, "client %d is %.200s (uid %d, gids",
 				 			fd, arg, c->uid);
 			p = buf + strlen(buf);
-			for (i=0; i < NGROUPS_MAX && c->gids[i] >= 0; i++) {
+			for (i=0; i < c->gidcount && c->gids[i] >= 0; i++) {
 				sprintf(p, " %d", c->gids[i]);
 				p += strlen(p);
 			}

Reply via email to