Esempio n. 1
0
static gint
get_user_groups (ActUser *user,
                 gid_t *primary,
                 gid_t **groups)
{
    struct passwd *pwd;
    const gchar *name;
    gint res;
    gint ngroups;

    name = act_user_get_user_name (user);
    pwd = getpwnam_alloc (name);
    if (pwd == NULL)
    {
        *primary = -1;
        *groups = NULL;
        return 0;
    }

    *primary = pwd->pw_gid;

    ngroups = 0;
    res = getgrouplist (name, *primary, NULL, &ngroups);

    g_debug ("user %s has %d groups", name, ngroups);
    *groups = g_new (gid_t, ngroups);
    res = getgrouplist (name, *primary, *groups, &ngroups);

    g_free (pwd);
    return res;
}
Esempio n. 2
0
static int check_group(const char *group, const char *name, const gid_t gid) {
	int match = 0;
	int i, ng = 0;
	gid_t *groups = NULL;
	struct group gbuf, *grent = NULL;

	long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
	if (rbuflen <= 0)
		return 0;
	char *rbuf = malloc(rbuflen);
	if (rbuf == NULL)
		return 0;

	if (getgrnam_r(group, &gbuf, rbuf, rbuflen, 
		       &grent) != 0)
		goto done;

	if (getgrouplist(name, gid, NULL, &ng) < 0) {
		groups = (gid_t *) malloc(sizeof (gid_t) * ng);
		if (!groups) goto done;
		if (getgrouplist(name, gid, groups, &ng) < 0) goto done;
	}

	for (i = 0; i < ng; i++) {
		if (grent->gr_gid == groups[i]) {
			match = 1;
			goto done;
		}
	}

 done:
	free(groups);
	free(rbuf);
	return match;
}
Esempio n. 3
0
/**
 * Gets the group IDs for a given user. The groups argument is allocated
 * internally, and it contains the list of groups. The ngroups is updated to 
 * the number of groups
 * Returns 0 on success (on success, the caller must free the memory allocated
 * internally)
 */
int getGroupIDList(const char *user, int *ngroups, gid_t **groups) {
  int getPW(const char *user, char **pwbuf);
  *ngroups = 0;
  char *pwbuf = NULL;
  *groups = NULL;
  /*Look up the password database first*/
  int error = getPW(user, &pwbuf);
  if (error != 0) {
    if (pwbuf != NULL) {
      free(pwbuf);
    }
    return error;
  } 
  struct passwd *pw = (struct passwd*)pwbuf;
  int ng = 0;
  /*Get the groupIDs that this user belongs to*/
  if (getgrouplist(user, pw->pw_gid, NULL, &ng) < 0) {
    *ngroups = ng;
    *groups = (gid_t *) malloc(ng * sizeof (gid_t));
    if (!*groups) {
      *ngroups = 0;
      free(pwbuf);
      return ENOMEM;
    }
    if (getgrouplist(user, pw->pw_gid, *groups, &ng) < 0) {
      *ngroups = 0;
      free(pwbuf);
      free(*groups);
      *groups = NULL;
      return ENOENT;
    }
  }
  free(pwbuf);
  return 0;
}
Esempio n. 4
0
/* Allocate supplementary groups buffer */
static bool my_getgrouplist_alloc(char *user,
				  gid_t gid,
				  struct group_data *gdata)
{
	int ngroups = 0;
	gid_t *groups, *groups2;

	/* We call getgrouplist() with 0 ngroups first. This should always
	 * return -1, and ngroups should be set to the actual number of
	 * groups the user is in.  The manpage doesn't say anything
	 * about errno value, it was usually zero but was set to 34
	 * (ERANGE) under some environments. ngroups was set correctly
	 * no matter what the errno value is!
	 *
	 * We assume that ngroups is correctly set, no matter what the
	 * errno value is. The man page says, "The ngroups argument
	 * is a value-result argument: on  return  it always contains
	 * the  number  of  groups found for user."
	 */
	(void)getgrouplist(user, gid, NULL, &ngroups);

	/* Allocate gdata->groups with the right size then call
	 * getgrouplist() a second time to get the actual group list
	 */
	groups = gsh_malloc(ngroups * sizeof(gid_t));
	if (groups == NULL)
		return false;

	if (getgrouplist(user, gid, groups, &ngroups) == -1) {
		LogEvent(COMPONENT_IDMAPPER,
			 "getgrouplist for user: %s failed retrying", user);

		gsh_free(groups);

		/* Try with the largest ngroups we support */
		ngroups = 1000;
		groups2 = gsh_malloc(ngroups * sizeof(gid_t));
		if (groups2 == NULL)
			return false;

		if (getgrouplist(user, gid, groups2, &ngroups) == -1) {
			LogWarn(COMPONENT_IDMAPPER,
				"getgrouplist for user:%s failed, ngroups: %d",
				user, ngroups);
			gsh_free(groups2);
			return false;
		}

		/* Resize the buffer */
		groups = gsh_realloc(groups2, ngroups * sizeof(gid_t));
		if (groups == NULL) /* Use the large buffer! */
			groups = groups2;
	}

	gdata->groups = groups;
	gdata->nbgroups = ngroups;

	return true;
}
int main(int argc, char *argv[])
{
	int i = 0;
	int ng = 1;
	char *user;
	gid_t *groups = NULL;
	gid_t gid;
	struct group *mygroup = NULL;
	struct passwd *pw = NULL;

	if (argc != 2) {
		printf("\nLists the groups a given username is part of using the getgrouplist(3) function.\n");
		printf("Usage: %s <username>\n\n", argv[0]);
		exit(1);
	}

	user = strdup(argv[1]);
	if ((pw = getpwnam(user)) == NULL) {
		printf("Error: user '%s' doesn't exist.\n", user);
		exit(1);
	}

	if ((groups = (gid_t *) malloc(ng * sizeof(gid_t))) == NULL) {
		printf("Error, out of memory.\n");
		exit(1);
	}
	
	if (getgrouplist(user, pw->pw_gid, groups, &ng) == -1) {
		/* use realloc... */
		free(groups);
		groups = malloc((size_t)(ng * sizeof(gid_t)));
		if (groups == NULL) {
			printf("Error, out of memory.\n");
			exit(1);
		}
		if (getgrouplist(user, pw->pw_gid, groups, &ng) == -1) {
			printf("getgrouplist(): error fetching list of groups.\n");
			exit(1);
		}
	}

	for(i = 0; i < ng; i++) {
		mygroup = getgrgid(groups[i]);
		if (mygroup != NULL)
			printf("%s", mygroup->gr_name);
		else
			continue;
		if (i < ng - 1)
			printf(",");
		else
			printf("\n");
	}
	free(groups);
	free(user);
	return 0;
}
Esempio n. 6
0
static int check_group(const char *group, const char *name, const gid_t gid) {
	int match = 0;
	int i, ng = 0;
	gid_t *groups = NULL;
	struct group gbuf, *grent = NULL;

	long rbuflen = sysconf(_SC_GETGR_R_SIZE_MAX);
	if (rbuflen <= 0)
		return 0;
	char *rbuf;

	while(1) {
		rbuf = malloc(rbuflen);
		if (rbuf == NULL)
			return 0;
		int retval = getgrnam_r(group, &gbuf, rbuf, 
				rbuflen, &grent);
		if ( retval == ERANGE )
		{
			free(rbuf);
			rbuflen = rbuflen * 2;
		} else if ( retval != 0 || grent == NULL )
		{
			goto done;
		} else
		{
			break;
		}
	}

	if (getgrouplist(name, gid, NULL, &ng) < 0) {
		if (ng == 0)
			goto done;
		groups = calloc(ng, sizeof(*groups));
		if (!groups)
			goto done;
		if (getgrouplist(name, gid, groups, &ng) < 0)
			goto done;
	} else {
		/* WTF?  ng was 0 and we didn't fail? Are we in 0 groups? */
		goto done;
	}

	for (i = 0; i < ng; i++) {
		if (grent->gr_gid == groups[i]) {
			match = 1;
			goto done;
		}
	}

 done:
	free(groups);
	free(rbuf);
	return match;
}
Esempio n. 7
0
GSList *getugroups(char *username, gid_t gid)
{
	GSList *grouplist = NULL;
	int i, ng = 0;
	gid_t *groups = NULL;

	/* need to lock as position is common to all thread */
	g_static_mutex_lock(&group_mutex);

#ifdef PERF_DISPLAY_ENABLE
	{
		struct timeval tvstart, tvend, result;
		if (nuauthconf->debug_areas & DEBUG_AREA_PERF) {
			gettimeofday(&tvstart, NULL);
		}
#endif
		if (system_glibc_cant_guess_maxgroups) {
			ng = system_glibc_cant_guess_maxgroups;
		} else {
			if (getgrouplist(username, gid, NULL, &ng) >= 0) {
				return NULL;
			}
		}

		groups = g_new0(gid_t, ng);
		getgrouplist(username, gid, groups, &ng);

		for (i = 0; i < ng; i++) {
			grouplist =
			    g_slist_prepend(grouplist,
					    GINT_TO_POINTER(groups[i]));
		}

		g_free(groups);

#ifdef PERF_DISPLAY_ENABLE
		if (nuauthconf->debug_areas & DEBUG_AREA_PERF) {
			gettimeofday(&tvend, NULL);
			timeval_substract(&result, &tvend, &tvstart);
			log_message(INFO, DEBUG_AREA_PERF,
					"Group list fetching duration: %.1f msec",
					(double)result.tv_sec*1000+
						(double)(result.tv_usec/1000));
		}
	}
#endif

	/* release lock */
	g_static_mutex_unlock(&group_mutex);

	return grouplist;
}
int hadoop_user_info_getgroups(struct hadoop_user_info *uinfo)
{
  int ret, ngroups;
  gid_t *ngids;

  if (!uinfo->pwd.pw_name) {
    // invalid user info
    return EINVAL;
  }
  uinfo->num_gids = 0;
  if (!uinfo->gids) {
    uinfo->gids = malloc(sizeof(uinfo->gids[0]) * INITIAL_GIDS_SIZE);
    if (!uinfo->gids) {
      return ENOMEM;
    }
    uinfo->gids_size = INITIAL_GIDS_SIZE;
  }
  ngroups = uinfo->gids_size;
  ret = getgrouplist(uinfo->pwd.pw_name, uinfo->pwd.pw_gid, 
                         uinfo->gids, &ngroups);
  if (ret > 0) {
    uinfo->num_gids = ngroups;
    ret = put_primary_gid_first(uinfo);
    if (ret) {
      return ret;
    }
    return 0;
  } else if (ret != -1) {
    // Any return code that is not -1 is considered as error.
    // Since the user lookup was successful, there should be at least one
    // group for this user.
    return EIO;
  }
  ngids = realloc(uinfo->gids, sizeof(uinfo->gids[0]) * ngroups);
  if (!ngids) {
    return ENOMEM;
  }
  uinfo->gids = ngids;
  uinfo->gids_size = ngroups;
  ret = getgrouplist(uinfo->pwd.pw_name, uinfo->pwd.pw_gid, 
                         uinfo->gids, &ngroups);
  if (ret < 0) {
    return EIO;
  }
  uinfo->num_gids = ngroups;
  ret = put_primary_gid_first(uinfo);
  return ret;
}
Esempio n. 9
0
static void
group(struct passwd *pw, int nflag)
{
	struct group *gr;
	int cnt, id, lastid, ngroups;
	gid_t groups[NGROUPS + 1];
	const char *fmt;

	if (pw) {
		ngroups = NGROUPS + 1;
		getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
	} else {
		groups[0] = getgid();
		ngroups = getgroups(NGROUPS, groups + 1) + 1;
	}
	fmt = nflag ? "%s" : "%u";
	for (lastid = -1, cnt = 0; cnt < ngroups; ++cnt) {
		if (lastid == (id = groups[cnt]))
			continue;
		if (nflag) {
			if ((gr = getgrgid(id)))
				printf(fmt, gr->gr_name);
			else
				printf(*fmt == ' ' ? " %u" : "%u",
				    id);
			fmt = " %s";
		} else {
			printf(fmt, id);
			fmt = " %u";
		}
		lastid = id;
	}
	printf("\n");
}
Esempio n. 10
0
static void
user(struct passwd *pw)
{
	struct group *gr;
	const char *fmt;
	int cnt, ngroups;
	gid_t gid, lastgid, groups[NGROUPS + 1];

	printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
	gid = pw->pw_gid;
	printf(" gid=%u", gid);
	if ((gr = getgrgid(gid)))
		printf("(%s)", gr->gr_name);
	ngroups = NGROUPS + 1;
	getgrouplist(pw->pw_name, gid, groups, &ngroups);
	fmt = " groups=%u";
	for (lastgid = -1, cnt = 0; cnt < ngroups; ++cnt) {
		if (lastgid == (gid = groups[cnt]))
			continue;
		printf(fmt, gid);
		fmt = ", %u";
		if ((gr = getgrgid(gid)))
			printf("(%s)", gr->gr_name);
		lastgid = gid;
	}
	printf("\n");
}
Esempio n. 11
0
File: init.c Progetto: fchiba/tcpeek
static void
tcpeek_init_setuid(void) {
	struct passwd *passwd;
	gid_t groups[128];
	int ngroups;

	if(strisempty(g.option.user)) {
		return;
	}
	passwd = strisdigit(g.option.user) ? getpwuid((uid_t)strtol(g.option.user, NULL, 10)) : getpwnam(g.option.user);
	if(!passwd) {
		error_abort("%s", strerror(errno));
	}
	ngroups = sizeof(groups);
	if(getgrouplist(g.option.user, passwd->pw_gid, groups, &ngroups) == -1) {
		error_abort("getgrouplist: %s", strerror(errno));
	}
	if(setgroups(ngroups, groups) == -1) {
		error_abort("setgroups: %s", strerror(errno));
	}
	if(setgid(passwd->pw_gid) == -1) {
		error_abort("setgid: %s", strerror(errno));
	}
	if(setuid(passwd->pw_uid) == -1) {
		error_abort("setuid: %s", strerror(errno));
	}
}
Esempio n. 12
0
APIE process_set_identity(uid_t uid, gid_t gid) {
	APIE error_code;
	struct passwd *pw;
	gid_t groups[128]; // FIXME: maybe allocate this dynamically
	int length = sizeof(groups) / sizeof(gid_t);

	// get username
	pw = getpwuid(uid);

	if (pw == NULL) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not get passwd entry for user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// get (secondary) groups
	if (getgrouplist(pw->pw_name, pw->pw_gid, groups, &length) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not get secondary groups for user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// set (primary) group
	if (setregid(gid, gid) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not change real and effective group ID to %u: %s (%d)",
		          gid, get_errno_name(errno), errno);

		return error_code;
	}

	// set (secondary) groups
	if (setgroups(length, groups) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not set secondary group IDs of user ID %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	// set user
	if (setreuid(uid, uid) < 0) {
		error_code = api_get_error_code_from_errno();

		log_error("Could not change real and effective user ID to %u: %s (%d)",
		          uid, get_errno_name(errno), errno);

		return error_code;
	}

	return API_E_SUCCESS;
}
Esempio n. 13
0
File: id.c Progetto: luckboy/toybox
void do_id(char *username)
{
  int flags, i, ngroups, cmd_groups = toys.which->name[0] == 'g';
  struct passwd *pw;
  struct group *grp;
  uid_t uid = getuid(), euid = geteuid();
  gid_t gid = getgid(), egid = getegid(), *groups;

  if (cmd_groups)
      toys.optflags |= FLAG_G | FLAG_n;

  flags = toys.optflags;

  // check if a username is given
  if (username) {
    pw = xgetpwnam(username);
    uid = euid = pw->pw_uid;
    gid = egid = pw->pw_gid;
    if (cmd_groups) printf("%s : ", pw->pw_name);
  }

  i = flags & FLAG_r;
  pw = xgetpwuid(i ? uid : euid);
  if (flags & FLAG_u) s_or_u(pw->pw_name, pw->pw_uid, 1);

  grp = xgetgrgid(i ? gid : egid);
  if (flags & FLAG_g) s_or_u(grp->gr_name, grp->gr_gid, 1);

  if (!(flags & FLAG_G)) {
    showid("uid=", pw->pw_uid, pw->pw_name);
    showid(" gid=", grp->gr_gid, grp->gr_name);

    if (!i) {
      if (uid != euid) {
        pw = xgetpwuid(euid);
        showid(" euid=", pw->pw_uid, pw->pw_name);
      }
      if (gid != egid) {
        grp = xgetgrgid(egid);
        showid(" egid=", grp->gr_gid, grp->gr_name);
      }
    }

    showid(" groups=", grp->gr_gid, grp->gr_name);
  }

  groups = (gid_t *)toybuf;
  i = sizeof(toybuf)/sizeof(gid_t);
  ngroups = username ? getgrouplist(username, gid, groups, &i)
    : getgroups(i, groups);
  if (ngroups<0) perror_exit(0);

  for (i = 0; i<ngroups; i++) {
    if (i) xputc(' ');
    if (!(grp = getgrgid(groups[i]))) perror_msg(0);
    else if (flags & FLAG_G) s_or_u(grp->gr_name, grp->gr_gid, 0);
    else if (grp->gr_gid != egid) showid("", grp->gr_gid, grp->gr_name);
  }
  xputc('\n');
}
Esempio n. 14
0
static int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
	int retval;
	bool winbind_env;

	DEBUG(10,("sys_getgrouplist: user [%s]\n", user));

	/* This is only ever called for Unix users, remote memberships are
	 * always determined by the info3 coming back from auth3 or the
	 * PAC. */
	winbind_env = winbind_env_set();
	(void)winbind_off();

#ifdef HAVE_GETGROUPLIST
	retval = getgrouplist(user, gid, groups, grpcnt);
#else
#ifdef HAVE_GETGRSET
	retval = getgrouplist_getgrset(user, gid, groups, grpcnt);
#else
	become_root();
	retval = getgrouplist_internals(user, gid, groups, grpcnt);
	unbecome_root();
#endif /* HAVE_GETGRSET */
#endif /* HAVE_GETGROUPLIST */

	/* allow winbindd lookups, but only if they were not already disabled */
	if (!winbind_env) {
		(void)winbind_on();
	}

	return retval;
}
Esempio n. 15
0
void
group(struct passwd *pw, int nflag)
{
	int cnt, ngroups;
	gid_t gid, groups[NGROUPS + 1];
	struct group *gr;
	char *fmt;

	if (pw) {
		ngroups = NGROUPS + 1;
		(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
	} else {
		groups[0] = getgid();
		ngroups = getgroups(NGROUPS, groups + 1) + 1;
	}
	fmt = nflag ? "%s" : "%u";
	for (cnt = 0; cnt < ngroups;) {
		gid = groups[cnt];
		if (nflag) {
			if ((gr = getgrgid(gid)))
				(void)printf(fmt, gr->gr_name);
			else
				(void)printf(*fmt == ' ' ? " %u" : "%u",
				    gid);
			fmt = " %s";
		} else {
			(void)printf(fmt, gid);
			fmt = " %u";
		}
		/* Skip same gid entries. */
		while (++cnt < ngroups && gid == groups[cnt]);
	}
	(void)printf("\n");
}
Esempio n. 16
0
void
user(struct passwd *pw)
{
	gid_t gid, groups[NGROUPS + 1];
	int cnt, ngroups;
	uid_t uid;
	struct group *gr;
	char *fmt;

	uid = pw->pw_uid;
	(void)printf("uid=%u(%s)", uid, pw->pw_name);
	(void)printf(" gid=%u", pw->pw_gid);
	if ((gr = getgrgid(pw->pw_gid)))
		(void)printf("(%s)", gr->gr_name);
	ngroups = NGROUPS + 1;
	(void) getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
	fmt = " groups=%u";
	for (cnt = 0; cnt < ngroups;) {
		gid = groups[cnt];
		(void)printf(fmt, gid);
		fmt = ", %u";
		if ((gr = getgrgid(gid)))
			(void)printf("(%s)", gr->gr_name);
		/* Skip same gid entries. */
		while (++cnt < ngroups && gid == groups[cnt]);
	}
	(void)printf("\n");
}
Esempio n. 17
0
int initgroups(const char *user, gid_t gid)
{
	gid_t groups[NGROUPS_MAX];
	int count;
	if (getgrouplist(user, gid, groups, &count) < 0) return -1;
	return setgroups(count, groups);
}
Esempio n. 18
0
void ch_user(void)
{
	int jid, ngroups;
	uid_t huid;
	struct passwd *husername, *jusername;
	gid_t groups[NGROUPS];
	login_cap_t *lcap;

	/* Get the current user ID and user name in the host system */
	huid = getuid();
	husername = getpwuid(huid);

	/* Get the user name in the jail */
	jusername = getpwuid(huid);
	if (jusername == NULL || strcmp(husername->pw_name, jusername->pw_name) != 0)
		err(1, "Username mapping failed");
	lcap = login_getpwclass(jusername);
	if (lcap == NULL) {
	  err(1, "getpwclass: %s", jusername->pw_name);
        }
	ngroups = NGROUPS;
	if (getgrouplist(jusername->pw_name, jusername->pw_gid, groups, &ngroups) != 0)	
		err(1, "getgrouplist: %s", jusername->pw_name);
	if (setgroups(ngroups, groups) != 0)
		err(1, "setgroups");
	if (setgid(jusername->pw_gid) != 0)
		err(1, "setgid");
	if (setusercontext(lcap, jusername, jusername->pw_uid,
	    LOGIN_SETALL & ~LOGIN_SETGROUP & ~LOGIN_SETLOGIN) != 0)
		err(1, "setusercontext");
	login_close(lcap);
}
Esempio n. 19
0
int sys_getgrouplist(const char *user, gid_t gid, gid_t *groups, int *grpcnt)
{
	char *p;
	int retval;

	DEBUG(10,("sys_getgrouplist: user [%s]\n", user));
	
	/* see if we should disable winbindd lookups for local users */
	if ( (p = strchr(user, *lp_winbind_separator())) == NULL ) {
		if ( !winbind_off() )
			DEBUG(0,("sys_getgroup_list: Insufficient environment space for %s\n",
				WINBINDD_DONT_ENV));
		else
			DEBUG(10,("sys_getgrouplist(): disabled winbindd for group lookup [user == %s]\n",
				user));
	}

#ifdef HAVE_GETGROUPLIST
	retval = getgrouplist(user, gid, groups, grpcnt);
#else
	become_root();
	retval = getgrouplist_internals(user, gid, groups, grpcnt);
	unbecome_root();
#endif

	/* allow winbindd lookups */
	winbind_on();
	
	return retval;
}
Esempio n. 20
0
/* This needs to be called with the usercache lock held.
 * I don't think it's thread safe. -jg
 */
static int
_getgrouplist (Npsrv *srv, Npuser *u)
{
    int i, ret = -1;
    gid_t *sgcpy;

    u->nsg = sysconf(_SC_NGROUPS_MAX);
    if (u->nsg < 65536)
        u->nsg = 65536;
    if (!(u->sg = malloc (u->nsg * sizeof (gid_t)))) {
        np_uerror (ENOMEM);
        np_logerr (srv, "_alloc_user: %s", u->uname);
        goto done;
    }
    if (getgrouplist(u->uname, u->gid, u->sg, &u->nsg) == -1) {
        np_logerr (srv, "_alloc_user: %s: getgrouplist", u->uname);
        if (np_rerror () == 0)
            np_uerror (EPERM);
        goto done;
    }
    if ((sgcpy = malloc (u->nsg * sizeof (gid_t)))) {
        for (i = 0; i < u->nsg; i++)
            sgcpy[i] = u->sg[i];
        free (u->sg);
        u->sg = sgcpy;
    }
    ret = 0;
done:
    return ret;
}
Esempio n. 21
0
/*
 * Initialize group access list for user with primary (base) and
 * supplementary groups.  Return the number of groups in the list.
 */
int
ga_init(const char *user, gid_t base)
{
	gid_t *groups_bygid;
	int i, j;
	struct group *gr;

	if (ngroups > 0)
		ga_free();

	ngroups = NGROUPS_MAX;
#if defined(HAVE_SYSCONF) && defined(_SC_NGROUPS_MAX)
	ngroups = MAX(NGROUPS_MAX, sysconf(_SC_NGROUPS_MAX));
#endif

	groups_bygid = xcalloc(ngroups, sizeof(*groups_bygid));
	groups_byname = xcalloc(ngroups, sizeof(*groups_byname));

	if (getgrouplist(user, base, groups_bygid, &ngroups) == -1)
		logit("getgrouplist: groups list too small");
	for (i = 0, j = 0; i < ngroups; i++)
		if ((gr = getgrgid(groups_bygid[i])) != NULL)
			groups_byname[j++] = xstrdup(gr->gr_name);
	xfree(groups_bygid);
	return (ngroups = j);
}
Esempio n. 22
0
File: id.c Progetto: nawawi/busybox
/* On error set *n < 0 and return >= 0
 * If *n is too small, update it and return < 0
 * (ok to trash groups[] in both cases)
 * Otherwise fill in groups[] and return >= 0
 */
static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n)
{
	int m;

	if (username) {
		/* If the user is a member of more than
		 * *n groups, then -1 is returned. Otherwise >= 0.
		 * (and no defined way of detecting errors?!) */
		m = getgrouplist(username, rgid, groups, n);
		/* I guess *n < 0 might indicate error. Anyway,
		 * malloc'ing -1 bytes won't be good, so: */
		if (*n < 0)
			return 0;
		return m;
	}

	*n = getgroups(*n, groups);
	if (*n >= 0)
		return *n;
	/* Error */
	if (errno == EINVAL) /* *n is too small? */
		*n = getgroups(0, groups); /* get needed *n */
	/* if *n >= 0, return -1 (got new *n), else return 0 (error): */
	return -(*n >= 0);
}
Esempio n. 23
0
static int is_gr_member(const char *login, const struct group_workspace *buf)
{
	struct passwd *pw;
	int ngroups = buf->ngroups;
	int rc;

	pw = getpwnam(login);
	if (!pw)
		return 0;

	if (buf->requested_group == pw->pw_gid)
		return 1;

	rc = getgrouplist(login, pw->pw_gid, buf->groups, &ngroups);
	if (rc < 0) {
		/* buffer too small, not sure how this can happen, since
		   we used sysconf to get the size... */
		errx(EXIT_FAILURE,
			_("getgrouplist found more groups than sysconf allows"));
	}

	for (; ngroups >= 0; --ngroups) {
		if (buf->requested_group == (gid_t) buf->groups[ngroups])
			return 1;
	}

	return 0;
}
Esempio n. 24
0
/* On error set *n < 0 and return >= 0
 * If *n is too small, update it and return < 0
 *  (ok to trash groups[] in both cases)
 * Otherwise fill in groups[] and return >= 0
 */
static int get_groups(const char *username, gid_t rgid, gid_t *groups, int *n)
{
	int m;

	if (username) {
		/* If the user is a member of more than
		 * *n groups, then -1 is returned. Otherwise >= 0.
		 * (and no defined way of detecting errors?!) */
		m = getgrouplist(username, rgid, groups, n);
		/* I guess *n < 0 might indicate error. Anyway,
		 * malloc'ing -1 bytes won't be good, so: */
		//if (*n < 0)
		//	return 0;
		//return m;
		//commented out here, happens below anyway
	} else {
		/* On error -1 is returned, which ends up in *n */
		int nn = getgroups(*n, groups);
		/* 0: nn <= *n, groups[] was big enough; -1 otherwise */
		m = - (nn > *n);
		*n = nn;
	}
	if (*n < 0)
		return 0; /* error, don't return < 0! */
	return m;
}
Esempio n. 25
0
int
acl_can_connect(struct Creds *cred)
{
    gid_t gids[64];
    int nr_gids = 64;
    struct passwd *pw;
    int i, j;

    // root always allowed
    if (cred->uid == 0)
        return 1;

    pw = getpwuid(cred->uid);
    if (!pw) return 0;
    if (getgrouplist(pw->pw_name, cred->gid, &gids[0], &nr_gids) < 0) {
        nr_gids = 63;
    }

    for (i = 0; i < nr_gids; i++) {
        for (j = 0; j < acl_nr_allowed_gids; j++) {
            if (gids[i] == acl_allowed_gids[j])
                return 1;
        }
    }

    return 0;
}
Esempio n. 26
0
static int
check_acl(int node, struct Creds *cred)
{
    gid_t gids[64];
    int nr_gids = 64;
    struct passwd *pw;
    struct acl_class *ac;
    struct acl_group *ag;
    void *acptr = &ac;
    int level;
    int i, j;

    model_acl_get(model_parent(node), acptr, &level);
    if (!ac) return 0;

    pw = getpwuid(cred->uid);
    if (!pw) return 0;
    if (getgrouplist(pw->pw_name, cred->gid, &gids[0], &nr_gids) < 0) {
        nr_gids = 63;
    }

    for (i = 0; i < nr_gids; i++) {
        for (j = 0; j < ac->nr_groups; j++) {
            ag = &ac->group[j];
            if (gids[i] == ag->gid) {
                if (ag->level <= level)
                    return 1;
                else
                    break;
            }
        }
    }

    return 0;
}
gint
get_user_groups (const gchar  *user,
                 gid_t         group,
                 gid_t       **groups)
{
        gint res;
        gint ngroups;

        ngroups = 0;
        res = getgrouplist (user, group, NULL, &ngroups);

        g_debug ("user %s has %d groups", user, ngroups);
        *groups = g_new (gid_t, ngroups);
        res = getgrouplist (user, group, *groups, &ngroups);

        return res;
}
static void
setCredentials(char *user)
{
    struct passwd *pwd;
    int ngroups;
    gid_t *groups;

    /* Look up user in user database */

    pwd = getpwnam(user);
    if (pwd == NULL) {
        fprintf(stderr, "Unknown user: %s\n", user);
        exit(EXIT_FAILURE);
    }

    /* Find out how many supplementary groups the user is a member of */

    ngroups = 0;
    getgrouplist(user, pwd->pw_gid, NULL, &ngroups);

    /* Allocate an array for supplementary group IDs */

    groups = calloc(ngroups, sizeof(gid_t));
    if (groups == NULL)
        errExit("calloc");

    /* Get supplementary group list of 'user' from group database */

    if (getgrouplist(user, pwd->pw_gid, groups, &ngroups) == -1)
        errExit("getgrouplist");

    /* Set the supplementary group list */

    if (setgroups(ngroups, groups) == -1)
        errExit("setgroups");

    /* Set all group IDs to GID of this user */

    if (setresgid(pwd->pw_gid, pwd->pw_gid, pwd->pw_gid) == -1)
        errExit("setresgid");

    /* Set all user IDs to UID of this user */

    if (setresuid(pwd->pw_uid, pwd->pw_uid, pwd->pw_uid) == -1)
        errExit("setresuid");
}
Esempio n. 29
0
int push_groups4(PerThreadContext* ctx, uid_t uid, gid_t gid) {

   TRY_DECLS();

   // check for two pushes without a pop
   if (ctx->pushed_groups) {
      LOG(LOG_ERR, "double-push (groups) -> %u\n", uid);
      errno = EPERM;
      return -1;
   }

   // save the group-list for the current process
   ctx->group_ct = getgroups(sizeof ctx->groups / sizeof (gid_t), ctx->groups);
   if (ctx->group_ct < 0) {
      // ctx->group_ct = 0; // ?
      LOG(LOG_ERR, "getgroups() failed\n");
      return -1;
   }

   // find user-name from uid
   struct passwd  pwd;
   struct passwd* result;
   const size_t   STR_BUF_LEN = 1024; // probably enough
   char           str_buf[STR_BUF_LEN];
   if (getpwuid_r(uid, &pwd, str_buf, STR_BUF_LEN, &result)) {
      LOG(LOG_ERR, "getpwuid_r() failed: %s\n", strerror(errno));
      return -EINVAL;
   }
   else if (! result) {
      LOG(LOG_ERR, "No passwd entries found, for uid %u\n", uid);
      return -EINVAL;
   }
   LOG(LOG_INFO, "uid %u = user '%s'\n",
       uid, result->pw_name);
      

   // find group-membership of user, using user-name
   gid_t groups[NGROUPS_MAX +1];
   int   ngroups = NGROUPS_MAX +1;
   int   group_ct = getgrouplist(result->pw_name, gid, groups, &ngroups);
   if (group_ct < 0) {
      LOG(LOG_ERR, "No passwd entries found, for user '%s'\n",
          result->pw_name);
      return -1;
   }

   // DEBUGGING
   int i;
   for (i=0; i<group_ct; ++i) {
      LOG(LOG_INFO, "group = %u\n", groups[i]);
   }

   // change group membership of process
   TRY0( setgroups(ngroups, groups) );

   ctx->pushed_groups = 1;   // so we can pop
   return 0;
}
Esempio n. 30
0
File: users.c Progetto: hdwilber/um
void _populate_users(Users *us) {
  UsersItem *u;
  struct passwd *usr = NULL;
  us->list = NULL;
  /*Abre el archivo por defecto para la lectura de los usuarios.*/
  setpwent();
  usr = getpwent();
  while (usr != NULL) {
    u = NULL;
    u = (UsersItem *)(malloc (sizeof(UsersItem)));
    if (u != NULL) {
      if (usr->pw_uid >= 1000 && usr->pw_uid < 60000) {
        u->uid = usr->pw_uid;
        u->gid = usr->pw_gid;
        u->name = strdup(usr->pw_name);
        /*u->fullname = strdup(usr->pw_gecos);*/
        _parse_gecos(u, usr->pw_gecos);
        u->home= strdup (usr->pw_dir);
        u->shell = strdup (usr->pw_shell);
        u->is_new = FALSE;

        us->list = g_list_append (us->list, u);
        u->n_groups = 1;
        u->groups = malloc (sizeof(gid_t));
        
        /*Obtiene la lista de grupos auxiliares al que pertenec el usuario actual a ser leido
         * La primera vez, getgrouplist devuelve en el puntero de entero de entrada
         * en este caso n->groups la cantidad de grupos que realmente tiene el usuario
         * Para lo cual, una vez obtenido la cantidad total de grupos, se realiza una
         * segunda llamada con la memoria reservada para la cantidad total.
         */
        if (getgrouplist (u->name, u->gid, u->groups, &u->n_groups)) {
          g_free(u->groups);
          u->groups = malloc (u->n_groups * sizeof(gid_t));
          getgrouplist (u->name, u->gid, u->groups, &u->n_groups);
          g_print ("Group: %i\n", u->groups[1]);

        }
      }
    }
    usr = getpwent();
  }
  endpwent();

}