86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.6 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <config.h>
 | 
						|
 | 
						|
#ifdef HAVE_SETGROUPS
 | 
						|
 | 
						|
#include "prototypes.h"
 | 
						|
#include "defines.h"
 | 
						|
 | 
						|
#include <stdio.h>
 | 
						|
#include <grp.h>
 | 
						|
#include <errno.h>
 | 
						|
 | 
						|
#ident "$Id$"
 | 
						|
 | 
						|
#define SEP ",:"
 | 
						|
/*
 | 
						|
 * Add groups with names from LIST (separated by commas or colons)
 | 
						|
 * to the supplementary group set.  Silently ignore groups which are
 | 
						|
 * already there.  Warning: uses strtok().
 | 
						|
 */
 | 
						|
int add_groups (const char *list)
 | 
						|
{
 | 
						|
	GETGROUPS_T *grouplist, *tmp;
 | 
						|
	int i, ngroups, added;
 | 
						|
	struct group *grp;
 | 
						|
	char *token;
 | 
						|
	char buf[1024];
 | 
						|
 | 
						|
	if (strlen (list) >= sizeof (buf)) {
 | 
						|
		errno = EINVAL;
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
	strcpy (buf, list);
 | 
						|
 | 
						|
	i = 16;
 | 
						|
	for (;;) {
 | 
						|
		grouplist = (gid_t *) malloc (i * sizeof (GETGROUPS_T));
 | 
						|
		if (!grouplist)
 | 
						|
			return -1;
 | 
						|
		ngroups = getgroups (i, grouplist);
 | 
						|
		if (i > ngroups)
 | 
						|
			break;
 | 
						|
		/* not enough room, so try allocating a larger buffer */
 | 
						|
		free (grouplist);
 | 
						|
		i *= 2;
 | 
						|
	}
 | 
						|
	if (ngroups < 0) {
 | 
						|
		free (grouplist);
 | 
						|
		return -1;
 | 
						|
	}
 | 
						|
 | 
						|
	added = 0;
 | 
						|
	for (token = strtok (buf, SEP); token; token = strtok (NULL, SEP)) {
 | 
						|
 | 
						|
		grp = getgrnam (token);
 | 
						|
		if (!grp) {
 | 
						|
			fprintf (stderr, _("Warning: unknown group %s\n"),
 | 
						|
				 token);
 | 
						|
			continue;
 | 
						|
		}
 | 
						|
 | 
						|
		for (i = 0; i < ngroups && grouplist[i] != grp->gr_gid; i++);
 | 
						|
 | 
						|
		if (i < ngroups)
 | 
						|
			continue;
 | 
						|
 | 
						|
		if (ngroups >= sysconf (_SC_NGROUPS_MAX)) {
 | 
						|
			fprintf (stderr, _("Warning: too many groups\n"));
 | 
						|
			break;
 | 
						|
		}
 | 
						|
		tmp = (gid_t *) realloc (grouplist, (ngroups + 1) * sizeof (GETGROUPS_T));
 | 
						|
		if (!tmp) {
 | 
						|
			free (grouplist);
 | 
						|
			return -1;
 | 
						|
		}
 | 
						|
		tmp[ngroups++] = grp->gr_gid;
 | 
						|
		grouplist = tmp;
 | 
						|
		added++;
 | 
						|
	}
 | 
						|
 | 
						|
	if (added)
 | 
						|
		return setgroups (ngroups, grouplist);
 | 
						|
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
#endif
 |