Ejemplo n.º 1
0
void
scan_passwd (void)
{
  int i = 1;
  struct passwd *p;
#ifdef _REENTRANT
  char buf[1024];
  struct passwd pbuf;
#endif


#ifdef _REENTRANT
#if GETHOSTBYNAME_R_ARGS == 6
  while (getpwent_r (&pbuf, buf, sizeof (buf), &p) == 0 && p != NULL)
#else
  while ((p = getpwent_r (&pbuf, buf, sizeof (buf))) != NULL)
#endif
#else
  while ((p = getpwent ()) != NULL)
#endif
    {
      printf ("%s:%s:%d:%d:%s:%s:%s\n",
	      p->pw_name,
	      p->pw_passwd,
	      p->pw_uid, p->pw_gid, p->pw_gecos, p->pw_dir, p->pw_shell);
      i++;
    }
}
Ejemplo n.º 2
0
int getpwentries(HDF *hdf)
{
  int ret = 0;
  NEOERR *err = NULL;
  struct passwd pw, *pwp;
  char buf[BUFLEN];

  setpwent();
  while (1) {
    if (getpwent_r(&pw, buf, BUFLEN, &pwp))
      break;

    err = hdf_set_valuef(hdf, "system.passwd.%s.uid=%d", pwp->pw_name,
                                                         pwp->pw_uid);
    err = hdf_set_valuef(hdf, "system.passwd.%s.gid=%d", pwp->pw_name,
                                                         pwp->pw_gid);
    err = hdf_set_valuef(hdf, "system.passwd.%s.gecos=%s", pwp->pw_name,
                                                           pwp->pw_gecos);
    err = hdf_set_valuef(hdf, "system.passwd.%s.dir=%s", pwp->pw_name,
                                                         pwp->pw_dir);
    err = hdf_set_valuef(hdf, "system.passwd.%s.shell=%s", pwp->pw_name, 
                                                           pwp->pw_shell);
    if (err != STATUS_OK)
    {
      nerr_log_error(err);
      ret -1;
    }

  }
  endpwent();

  return ret;
}
Ejemplo n.º 3
0
/* Give preference to /etc/passwd than HOME */
const gchar *
g_get_home_dir (void)
{
	if (home_dir == NULL){
		pthread_mutex_lock (&home_lock);
		if (home_dir == NULL){
#ifdef HAVE_GETPWENT_R
			struct passwd pwbuf, *track;
			char buf [4096];
			uid_t uid;
			
			uid = getuid ();

			setpwent ();
			
			while (getpwent_r (&pwbuf, buf, sizeof (buf), &track) == 0){
				if (pwbuf.pw_uid == uid){
					home_dir = g_strdup (pwbuf.pw_dir);
					break;
				}
			}
			endpwent ();
#endif
			if (home_dir == NULL)
				home_dir = g_getenv ("HOME");
			pthread_mutex_unlock (&home_lock);
		}
	}
	return home_dir;
}
Ejemplo n.º 4
0
struct passwd *
getpwent(void)
{
	nss_XbyY_buf_t *b = get_pwbuf();

	return (b == NULL ? NULL :
	    getpwent_r(b->result, b->buffer, b->buflen));
}
Ejemplo n.º 5
0
struct passwd *getpwent(void)
{
    static char line_buff[PWD_BUFFER_SIZE];
    static struct passwd pwd;

    if (getpwent_r(&pwd, line_buff, sizeof(line_buff), NULL) != -1) {
	return &pwd;
    }
    return NULL;
}
Ejemplo n.º 6
0
int getpwuid_r(uid_t uid,
	       struct passwd *res, char *buf, size_t buflen,
	       struct passwd **res_sig) {
  while (!getpwent_r(res,buf,buflen,res_sig))
    if (uid==res->pw_uid)
      goto ok;
  *res_sig=0;
ok:
  endpwent();
  return *res_sig?0:-1;
}
struct passwd *getpwent(void)
{
    int ret;
    static char line_buff[PWD_BUFFER_SIZE];
    static struct passwd pwd;
    struct passwd *result;

    if ((ret=getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) == 0) {
        return &pwd;
    }
    __set_errno(ret);
    return NULL;
}
Ejemplo n.º 8
0
static void username_tab_completion(char *ud, char *with_shash_flg)
{
	struct passwd *entry;
	int userlen;

	ud++;                           /* ~user/... to user/... */
	userlen = strlen(ud);

	if (with_shash_flg) {           /* "~/..." or "~user/..." */
		char *sav_ud = ud - 1;
		char *home = NULL;
		char *temp;

		if (*ud == '/') {       /* "~/..."     */
			home = home_pwd_buf;
		} else {
			/* "~user/..." */
			temp = strchr(ud, '/');
			*temp = 0;              /* ~user\0 */
			entry = getpwnam(ud);
			*temp = '/';            /* restore ~user/... */
			ud = temp;
			if (entry)
				home = entry->pw_dir;
		}
		if (home) {
			if ((userlen + strlen(home) + 1) < MAX_LINELEN) {
				char temp2[MAX_LINELEN];     /* argument size */

				/* /home/user/... */
				sprintf(temp2, "%s%s", home, ud);
				strcpy(sav_ud, temp2);
			}
		}
	} else {
		/* "~[^/]*" */
		/* Using _r function to avoid pulling in static buffers */
		char line_buff[256];
		struct passwd pwd;
		struct passwd *result;

		setpwent();
		while (!getpwent_r(&pwd, line_buff, sizeof(line_buff), &result)) {
			/* Null usernames should result in all users as possible completions. */
			if (/*!userlen || */ strncmp(ud, pwd.pw_name, userlen) == 0) {
				add_match(xasprintf("~%s/", pwd.pw_name));
			}
		}
		endpwent();
	}
}
Ejemplo n.º 9
0
int main(int argc,char *argv[]) {
#ifndef OLD
    struct passwd pw,*tmp;
    char buf[1000];
    while (getpwent_r(&pw,buf,sizeof(buf),&tmp)==0) {
        printf("name %s\npassword %s\nuid %u\ngid %u\ngecos %s\ndir %s\nshell %s\n",
               pw.pw_name,pw.pw_passwd,pw.pw_uid,pw.pw_gid,pw.pw_gecos,pw.pw_dir,
               pw.pw_shell);
    }
#else
    struct passwd *pw;
    while (pw=getpwent()) {
        printf("name %s\npassword %s\nuid %u\ngid %u\ngecos %s\ndir %s\nshell %s\n",
               pw->pw_name,pw->pw_passwd,pw->pw_uid,pw->pw_gid,pw->pw_gecos,pw->pw_dir,
               pw->pw_shell);
    }
#endif
    return 0;
}
Ejemplo n.º 10
0
struct passwd *getpwent(void)
{
    pw_tls_t *p;
    struct passwd *ent;
    int err;
    PRINT(("%s()\n", __FUNCTION__));
    p = get_pw_tls();
    if (!p) {
        /* we are really bork */
        __set_errno(ENOMEM);
        return NULL;
    }
    err = getpwent_r(&p->pwent, p->pwbuff, PWBUFFSZ, &ent);
    if (err < 0) {
        __set_errno(err);
        return NULL;
    }
    if (!ent)
        return NULL;
    PRINT(("getpwent(); returning entry for %s\n", ent->pw_name));
    return ent;
}
Ejemplo n.º 11
0
Archivo: groups.c Proyecto: VURM/slurm
/*
 * get_group_members - identify the users in a given group name
 * IN group_name - a single group name
 * RET a zero terminated list of its UIDs or NULL on error
 * NOTE: User root has implicitly access to every group
 * NOTE: The caller must xfree non-NULL return values
 */
extern uid_t *get_group_members(char *group_name)
{
	char grp_buffer[PW_BUF_SIZE];
  	struct group grp,  *grp_result = NULL;
	struct passwd *pwd_result = NULL;
	uid_t *group_uids = NULL, my_uid;
	gid_t my_gid;
	int i, j, uid_cnt;
#ifdef HAVE_AIX
	FILE *fp = NULL;
#elif defined (__APPLE__) || defined (__CYGWIN__)
#else
	char pw_buffer[PW_BUF_SIZE];
	struct passwd pw;
#endif

	group_uids = _get_group_cache(group_name);
	if (group_uids)	{	/* We found in cache */
		_log_group_members(group_name, group_uids);
		return group_uids;
	}

	/* We need to check for !grp_result, since it appears some
	 * versions of this function do not return an error on failure.
	 */
	if (getgrnam_r(group_name, &grp, grp_buffer, PW_BUF_SIZE,
		       &grp_result) || (grp_result == NULL)) {
		error("Could not find configured group %s", group_name);
		return NULL;
	}
	my_gid = grp_result->gr_gid;

	j = 0;
	uid_cnt = 0;
#ifdef HAVE_AIX
	setgrent_r(&fp);
	while (!getgrent_r(&grp, grp_buffer, PW_BUF_SIZE, &fp)) {
		grp_result = &grp;
#elif defined (__APPLE__) || defined (__CYGWIN__)
	setgrent();
	while ((grp_result = getgrent()) != NULL) {
#else
	setgrent();
	while (getgrent_r(&grp, grp_buffer, PW_BUF_SIZE,
			  &grp_result) == 0 && grp_result != NULL) {
#endif
	        if (grp_result->gr_gid == my_gid) {
			if (strcmp(grp_result->gr_name, group_name)) {
				debug("including members of group '%s' as it "
				      "corresponds to the same gid as group"
				      " '%s'",grp_result->gr_name,group_name);
			}

		        for (i=0; grp_result->gr_mem[i]; i++) {
				if (uid_from_string(grp_result->gr_mem[i],
						    &my_uid) < 0) {
					/* Group member without valid login */
					continue;
				}
				if (my_uid == 0)
					continue;
				if (j >= uid_cnt) {
					uid_cnt += 100;
					xrealloc(group_uids, 
						 (sizeof(uid_t) * uid_cnt));
				}
				group_uids[j++] = my_uid;
			}
		}
	}
#ifdef HAVE_AIX
	endgrent_r(&fp);
	setpwent_r(&fp);
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) {
		pwd_result = &pw;
#else
	endgrent();
	setpwent();
#if defined (__sun)
	while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) {
#elif defined (__APPLE__) || defined (__CYGWIN__)
	while ((pwd_result = getpwent()) != NULL) {
#else
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) {
#endif
#endif
 		if (pwd_result->pw_gid != my_gid)
			continue;
		if (j >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids, (sizeof(uid_t) * uid_cnt));
		}
		group_uids[j++] = pwd_result->pw_uid;
	}
#ifdef HAVE_AIX
	endpwent_r(&fp);
#else
	endpwent();
#endif

	_put_group_cache(group_name, group_uids, uid_cnt);
	_log_group_members(group_name, group_uids);
	return group_uids;
}

/* Delete our group/uid cache */
extern void clear_group_cache(void)
{
	pthread_mutex_lock(&group_cache_mutex);
	if (group_cache_list) {
		list_destroy(group_cache_list);
		group_cache_list = NULL;
	}
	pthread_mutex_unlock(&group_cache_mutex);
}

/* Get a record from our group/uid cache. 
 * Return NULL if not found. */
static uid_t *_get_group_cache(char *group_name)
{
	ListIterator iter;
	struct group_cache_rec *cache_rec;
	uid_t *group_uids = NULL;
	int sz;

	pthread_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		pthread_mutex_unlock(&group_cache_mutex);
		return NULL;
	}

	iter = list_iterator_create(group_cache_list);
	if (!iter)
		fatal("list_iterator_create: malloc failure");
	while ((cache_rec = (struct group_cache_rec *) list_next(iter))) {
		if (strcmp(group_name, cache_rec->group_name))
			continue;
		sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1);
		group_uids = (uid_t *) xmalloc(sz);
		memcpy(group_uids, cache_rec->group_uids, sz);
		break;
	}
	list_iterator_destroy(iter);
	pthread_mutex_unlock(&group_cache_mutex);
	return group_uids;
}

/* Delete a record from the group/uid cache, used by list functions */
static void _cache_del_func(void *x)
{
	struct group_cache_rec *cache_rec;

	cache_rec = (struct group_cache_rec *) x;
	xfree(cache_rec->group_name);
	xfree(cache_rec->group_uids);
	xfree(cache_rec);
}

/* Put a record on our group/uid cache */
static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt)
{
	struct group_cache_rec *cache_rec;
	int sz;

	pthread_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		group_cache_list = list_create(_cache_del_func);
		if (!group_cache_list)
			fatal("list_create: malloc failure:");
	}

	sz = sizeof(uid_t) * (uid_cnt + 1);
	cache_rec = xmalloc(sizeof(struct group_cache_rec));
	cache_rec->group_name = xstrdup(group_name);
	cache_rec->uid_cnt    = uid_cnt;
	cache_rec->group_uids = (uid_t *) xmalloc(sz);
	if (uid_cnt > 0)
		memcpy(cache_rec->group_uids, group_uids, sz);
	list_append(group_cache_list, cache_rec);
	pthread_mutex_unlock(&group_cache_mutex);
}

static void _log_group_members(char *group_name, uid_t *group_uids)
{
#if _DEBUG
	int i;

	if ((group_uids == NULL) || (group_uids[0] == 0)) {
		info("Group %s has no users", group_name);
		return;
	}

	info("Group %s contains uids:", group_name);
	for (i=0; group_uids && group_uids[i]; i++)
		info("  %u", group_uids[i]);
#endif
}
Ejemplo n.º 12
0
bool
Setup::checkClientUsers(const string& uname)
{
	bool status = true;
    struct passwd *pwp = NULL;
	int i = 0;
#ifdef _linux_
    struct passwd pw;
    char buf[BUFLEN];
#else
    static Mutex mutex;
    ScopedMutex lock(&mutex);
#endif
    
	setpwent();
	while (1 && getuid() == 0) {
#ifdef _linux_
        i = getpwent_r(&pw, buf, BUFLEN, &pwp);
#else
		pwp = getpwent();
#endif
		if (i)
		{
			break;
		}
		if (pwp == NULL)
		{
			return true;
		}
		if ((uname.empty() && pwp->pw_uid >= INETFS_MIN_UID && pwp->pw_uid <= INETFS_MAX_UID)
			|| (uname.length() > 0 && uname == pwp->pw_name))
		{
			string name = pwp->pw_name;
			int uid = pwp->pw_uid;
			int gid = pwp->pw_gid;
			string home = pwp->pw_dir;
			// .inetfs dir
			string local = home + string("/.inetfs");
			::mkdir(local.c_str(), 0700);
			::chown(local.c_str(), uid, gid);
			string passwd = home + string("/.inetfs/passwd");
			::mkdir(passwd.c_str(), 0700);
			::chown(passwd.c_str(), uid, gid);

#ifdef UID_LINKS_ENABLED
			string links = home + string("/.inetfs/links");
			::mkdir(links.c_str(), 0700);
			::chown(links.c_str(), uid, gid);
			local = home + string("/.inetfs/links");
			if (!file_exists(local.c_str()) && !dir_exists(local.c_str()))
			{
				::symlink(links.c_str(), local.c_str());
				::chown(local.c_str(), uid, gid);
				::chmod(local.c_str(), 0700);
			}
#endif
		}
	}
	endpwent();
	return status;
}
Ejemplo n.º 13
0
static unsigned int
runtest_cmds(cap_channel_t *cappwd)
{
	char bufs[1024], bufc[1024];
	unsigned int result;
	struct passwd *pwds, *pwdc;
	struct passwd sts, stc;

	result = 0;

	setpwent();
	cap_setpwent(cappwd);

	pwds = getpwent();
	pwdc = cap_getpwent(cappwd);
	if (passwd_compare(pwds, pwdc)) {
		result |= GETPWENT0;
		pwds = getpwent();
		pwdc = cap_getpwent(cappwd);
		if (passwd_compare(pwds, pwdc))
			result |= GETPWENT1;
	}

	getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
	cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
	if (passwd_compare(pwds, pwdc)) {
		result |= GETPWENT_R0;
		getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
		cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
		if (passwd_compare(pwds, pwdc))
			result |= GETPWENT_R1;
	}

	setpwent();
	cap_setpwent(cappwd);

	getpwent_r(&sts, bufs, sizeof(bufs), &pwds);
	cap_getpwent_r(cappwd, &stc, bufc, sizeof(bufc), &pwdc);
	if (passwd_compare(pwds, pwdc))
		result |= GETPWENT_R2;

	pwds = getpwent();
	pwdc = cap_getpwent(cappwd);
	if (passwd_compare(pwds, pwdc))
		result |= GETPWENT2;

	pwds = getpwnam("root");
	pwdc = cap_getpwnam(cappwd, "root");
	if (passwd_compare(pwds, pwdc)) {
		pwds = getpwnam("operator");
		pwdc = cap_getpwnam(cappwd, "operator");
		if (passwd_compare(pwds, pwdc))
			result |= GETPWNAM;
	}

	getpwnam_r("root", &sts, bufs, sizeof(bufs), &pwds);
	cap_getpwnam_r(cappwd, "root", &stc, bufc, sizeof(bufc), &pwdc);
	if (passwd_compare(pwds, pwdc)) {
		getpwnam_r("operator", &sts, bufs, sizeof(bufs), &pwds);
		cap_getpwnam_r(cappwd, "operator", &stc, bufc, sizeof(bufc),
		    &pwdc);
		if (passwd_compare(pwds, pwdc))
			result |= GETPWNAM_R;
	}

	pwds = getpwuid(UID_ROOT);
	pwdc = cap_getpwuid(cappwd, UID_ROOT);
	if (passwd_compare(pwds, pwdc)) {
		pwds = getpwuid(UID_OPERATOR);
		pwdc = cap_getpwuid(cappwd, UID_OPERATOR);
		if (passwd_compare(pwds, pwdc))
			result |= GETPWUID;
	}

	getpwuid_r(UID_ROOT, &sts, bufs, sizeof(bufs), &pwds);
	cap_getpwuid_r(cappwd, UID_ROOT, &stc, bufc, sizeof(bufc), &pwdc);
	if (passwd_compare(pwds, pwdc)) {
		getpwuid_r(UID_OPERATOR, &sts, bufs, sizeof(bufs), &pwds);
		cap_getpwuid_r(cappwd, UID_OPERATOR, &stc, bufc, sizeof(bufc),
		    &pwdc);
		if (passwd_compare(pwds, pwdc))
			result |= GETPWUID_R;
	}

	return (result);
}
Ejemplo n.º 14
0
/*.......................................................................
 * The _hd_scan_user_home_dirs() function calls a user-provided function
 * for each username known by the system, passing the function both
 * the name and the home directory of the user.
 *
 * Input:
 *  home             HomeDir *  The resource object for reading home
 *                              directories.
 *  prefix        const char *  Only information for usernames that
 *                              start with this prefix will be
 *                              returned. Note that the empty
 &                              string "", matches all usernames.
 *  data                void *  Anonymous data to be passed to the
 *                              callback function.
 *  callback_fn  HOME_DIR_FN(*) The function to call for each user.
 * Output:
 *  return               int    0 - Successful completion.
 *                              1 - An error occurred. A description
 *                                  of the error can be obtained by
 *                                  calling _hd_last_home_dir_error().
 */
int _hd_scan_user_home_dirs(HomeDir *home, const char *prefix,
			    void *data, HOME_DIR_FN(*callback_fn))
{
  int waserr = 0;       /* True after errors */
  int prefix_len;       /* The length of prefix[] */
/*
 * Check the arguments.
 */
  if(!home || !prefix || !callback_fn) {
    if(home) {
      _err_record_msg(home->err,
		      "_hd_scan_user_home_dirs: Missing callback function",
		      END_ERR_MSG);
    };
    return 1;
  };
/*
 * Get the length of the username prefix.
 */
  prefix_len = strlen(prefix);
/*
 * There are no reentrant versions of getpwent() etc for scanning
 * the password file, so disable username completion when the
 * library is compiled to be reentrant.
 */
#if defined(PREFER_REENTRANT) && defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199506L
#if defined __sun && defined __SVR4
  if(0)
#else
  if(1)
#endif
  {
    struct passwd pwd_buffer;  /* A returned password entry */
    struct passwd *pwd;        /* A pointer to pwd_buffer */
    char buffer[512];          /* The buffer in which the string members of */
                               /* pwd_buffer are stored. */
/*
 * See if the prefix that is being completed is a complete username.
 */
    if(!waserr && getpwnam_r(prefix, &pwd_buffer, buffer, sizeof(buffer),
			     &pwd) == 0 && pwd != NULL) {
      waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir,
			   _err_get_msg(home->err), ERR_MSG_LEN);
    };
/*
 * See if the username of the current user minimally matches the prefix.
 */
    if(!waserr && getpwuid_r(getuid(), &pwd_buffer, buffer, sizeof(buffer),
			     &pwd) == 0 && pwd != NULL &&
                             strncmp(prefix, pwd->pw_name, prefix_len)==0) {
      waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir,
			   _err_get_msg(home->err), ERR_MSG_LEN);
    };
/*
 * Reentrancy not required?
 */
  } else
#endif
  {
    struct passwd pwd_buffer;  /* A returned password entry */
    struct passwd *pwd;   /* The pointer to the latest password entry */
/*
 * Open the password file.
 */
    setpwent();
/*
 * Read the contents of the password file, looking for usernames
 * that start with the specified prefix, and adding them to the
 * list of matches.
 */
#if defined __sun && defined __SVR4
    while((pwd = getpwent_r(&pwd_buffer, home->buffer, home->buflen)) != NULL && !waserr) {
#else
    while((pwd = getpwent()) != NULL && !waserr) {
#endif
      if(strncmp(prefix, pwd->pw_name, prefix_len) == 0) {
	waserr = callback_fn(data, pwd->pw_name, pwd->pw_dir,
			     _err_get_msg(home->err), ERR_MSG_LEN);
      };
    };
/*
 * Close the password file.
 */
    endpwent();
  };
/*
 * Under ksh ~+ stands for the absolute pathname of the current working
 * directory.
 */
  if(!waserr && strncmp(prefix, "+", prefix_len) == 0) {
    const char *pwd = hd_getpwd(home);
    if(pwd) {
      waserr = callback_fn(data, "+", pwd, _err_get_msg(home->err),ERR_MSG_LEN);
    } else {
      waserr = 1;
      _err_record_msg(home->err, "Can't determine current directory.",
		      END_ERR_MSG);
    };
  };
  return waserr;
}

/*.......................................................................
 * Return the value of getenv("PWD") if this points to the current
 * directory, or the return value of getcwd() otherwise. The reason for
 * prefering PWD over getcwd() is that the former preserves the history
 * of symbolic links that have been traversed to reach the current
 * directory. This function is designed to provide the equivalent
 * expansion of the ksh ~+ directive, which normally returns its value
 * of PWD.
 *
 * Input:
 *  home      HomeDir *  The resource object for reading home directories.
 * Output:
 *  return const char *  A pointer to either home->buffer, where the
 *                       pathname is recorded, the string returned by
 *                       getenv("PWD"), or NULL on error.
 */
static const char *hd_getpwd(HomeDir *home)
{
/*
 * Get the absolute path of the current working directory.
 */
  char *cwd = getcwd(home->buffer, home->buflen);
/*
 * Some shells set PWD with the path of the current working directory.
 * This will differ from cwd in that it won't have had symbolic links
 * expanded.
 */
  const char *pwd = getenv("PWD");
/*
 * If PWD was set, and it points to the same directory as cwd, return
 * its value. Note that it won't be the same if the current shell or
 * the current program has changed directories, after inheriting PWD
 * from a parent shell.
 */
  struct stat cwdstat, pwdstat;
  if(pwd && cwd && stat(cwd, &cwdstat)==0 && stat(pwd, &pwdstat)==0 &&
     cwdstat.st_dev == pwdstat.st_dev && cwdstat.st_ino == pwdstat.st_ino)
    return pwd;
/*
 * Also return pwd if getcwd() failed, since it represents the best
 * information that we have access to.
 */
  if(!cwd)
    return pwd;
/*
 * In the absence of a valid PWD, return cwd.
 */
  return cwd;
}
Ejemplo n.º 15
0
int deluser_main(int argc, char **argv)
{
	/* User or group name */
	char *name;
	/* Username (non-NULL only in "delgroup USER GROUP" case) */
	char *member;
	/* Name of passwd or group file */
	const char *pfile;
	/* Name of shadow or gshadow file */
	const char *sfile;
	/* Are we deluser or delgroup? */
	int do_deluser = (ENABLE_DELUSER && (!ENABLE_DELGROUP || applet_name[3] == 'u'));

	if (geteuid() != 0)
		bb_error_msg_and_die(bb_msg_perm_denied_are_you_root);

	name = argv[1];
	member = NULL;

	switch (argc) {
	case 3:
		if (!ENABLE_FEATURE_DEL_USER_FROM_GROUP || do_deluser)
			break;
		/* It's "delgroup USER GROUP" */
		member = name;
		name = argv[2];
		/* Fallthrough */

	case 2:
		if (do_deluser) {
			/* "deluser USER" */
			xgetpwnam(name); /* bail out if USER is wrong */
			pfile = bb_path_passwd_file;
			if (ENABLE_FEATURE_SHADOWPASSWDS)
				sfile = bb_path_shadow_file;
		} else {
			struct group *gr;
 do_delgroup:
			/* "delgroup GROUP" or "delgroup USER GROUP" */
			if (do_deluser < 0) { /* delgroup after deluser? */
				gr = getgrnam(name);
				if (!gr)
					return EXIT_SUCCESS;
			} else {
				gr = xgetgrnam(name); /* bail out if GROUP is wrong */
			}
			if (!member) {
				/* "delgroup GROUP" */
				struct passwd *pw;
				struct passwd pwent;
				/* Check if the group is in use */
#define passwd_buf bb_common_bufsiz1
				while (!getpwent_r(&pwent, passwd_buf, sizeof(passwd_buf), &pw)) {
					if (pwent.pw_gid == gr->gr_gid)
						bb_error_msg_and_die("'%s' still has '%s' as their primary group!", pwent.pw_name, name);
				}
				//endpwent();
			}
			pfile = bb_path_group_file;
			if (ENABLE_FEATURE_SHADOWPASSWDS)
				sfile = bb_path_gshadow_file;
		}

		/* Modify pfile, then sfile */
		do {
			if (update_passwd(pfile, name, NULL, member) == -1)
				return EXIT_FAILURE;
			if (ENABLE_FEATURE_SHADOWPASSWDS) {
				pfile = sfile;
				sfile = NULL;
			}
		} while (ENABLE_FEATURE_SHADOWPASSWDS && pfile);

		if (ENABLE_DELGROUP && do_deluser > 0) {
			/* "deluser USER" also should try to delete
			 * same-named group. IOW: do "delgroup USER"
			 */
// On debian deluser is a perl script that calls userdel.
// From man userdel:
//  If USERGROUPS_ENAB is defined to yes in /etc/login.defs, userdel will
//  delete the group with the same name as the user.
			do_deluser = -1;
			goto do_delgroup;
		}
		return EXIT_SUCCESS;
	}
	/* Reached only if number of command line args is wrong */
	bb_show_usage();
}
Ejemplo n.º 16
0
/*
 * Determine the default path to the persistent storage file and create it if it doesn't exist.
 */
TSS_RESULT
get_user_ps_path(char **file)
{
	TSS_RESULT result;
	char *file_name = NULL, *home_dir = NULL;
	struct passwd *pwp;
#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
	struct passwd pw;
#endif
	struct stat stat_buf;
	char buf[PASSWD_BUFSIZE];
	uid_t euid;
	int rc;

	if ((file_name = getenv("TSS_USER_PS_FILE"))) {
		*file = strdup(file_name);
		return (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY);
	}
#if (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__))
	MUTEX_LOCK(user_ps_path);
#endif

	euid = geteuid();

#if defined (SOLARIS)
	/*
         * Solaris keeps user PS in a local directory instead of
         * in the user's home directory, which may be shared
         * by multiple systems.
         *
         * The directory path on Solaris is /var/tpm/userps/[EUID]/
         */
        rc = snprintf(buf, sizeof (buf), "%s/%d", TSS_USER_PS_DIR, euid);
#else
	setpwent();
	while (1) {
#if (defined (__linux) || defined (linux) || defined(__GLIBC__))
		rc = getpwent_r(&pw, buf, PASSWD_BUFSIZE, &pwp);
		if (rc) {
			LogDebugFn("USER PS: Error getting path to home directory: getpwent_r: %s",
				   strerror(rc));
			endpwent();
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}

#elif (defined (__FreeBSD__) || defined (__OpenBSD__) || defined(__NetBSD__))
		if ((pwp = getpwent()) == NULL) {
			LogDebugFn("USER PS: Error getting path to home directory: getpwent: %s",
                                   strerror(rc));
			endpwent();
			MUTEX_UNLOCK(user_ps_path);
			return TSPERR(TSS_E_INTERNAL_ERROR);
		}
#endif
		if (euid == pwp->pw_uid) {
                        home_dir = strdup(pwp->pw_dir);
                        break;
                }
        }
        endpwent();

	if (!home_dir)
		return TSPERR(TSS_E_OUTOFMEMORY);

	/* Tack on TSS_USER_PS_DIR and see if it exists */
	rc = snprintf(buf, sizeof (buf), "%s/%s", home_dir, TSS_USER_PS_DIR);
#endif /* SOLARIS */
	if (rc == sizeof (buf)) {
		LogDebugFn("USER PS: Path to file too long! (> %d bytes)", PASSWD_BUFSIZE);
		result = TSPERR(TSS_E_INTERNAL_ERROR);
		goto done;
	}

	errno = 0;
	if ((rc = stat(buf, &stat_buf)) == -1) {
		if (errno == ENOENT) {
			errno = 0;
			/* Create the user's ps directory if it is not there. */
			if ((rc = mkdir(buf, 0700)) == -1) {
				LogDebugFn("USER PS: Error creating dir: %s: %s", buf,
					   strerror(errno));
				result = TSPERR(TSS_E_INTERNAL_ERROR);
				goto done;
			}
		} else {
			LogDebugFn("USER PS: Error stating dir: %s: %s", buf, strerror(errno));
			result = TSPERR(TSS_E_INTERNAL_ERROR);
			goto done;
		}
	}

	/* Directory exists or has been created, return the path to the file */
#if defined (SOLARIS)
	rc = snprintf(buf, sizeof (buf), "%s/%d/%s", TSS_USER_PS_DIR, euid,
		      TSS_USER_PS_FILE);
#else
	rc = snprintf(buf, sizeof (buf), "%s/%s/%s", home_dir, TSS_USER_PS_DIR,
		      TSS_USER_PS_FILE);
#endif
	if (rc == sizeof (buf)) {
		LogDebugFn("USER PS: Path to file too long! (> %zd bytes)", sizeof (buf));
	} else
		*file = strdup(buf);

	result = (*file) ? TSS_SUCCESS : TSPERR(TSS_E_OUTOFMEMORY);
done:
	free(home_dir);
	return result;
}
Ejemplo n.º 17
0
static semanage_list_t *get_home_dirs(genhomedircon_settings_t * s)
{
	semanage_list_t *homedir_list = NULL;
	semanage_list_t *shells = NULL;
	fc_match_handle_t hand;
	char *rbuf = NULL;
	char *path = NULL;
	long rbuflen;
	uid_t temp, minuid = 500, maxuid = 60000;
	int minuid_set = 0;
	struct passwd pwstorage, *pwbuf;
	struct stat buf;
	int retval;

	path = semanage_findval(PATH_ETC_USERADD, "HOME", "=");
	if (path && *path) {
		if (semanage_list_push(&homedir_list, path))
			goto fail;
	}
	free(path);

	path = semanage_findval(PATH_ETC_LIBUSER, "LU_HOMEDIRECTORY", "=");
	if (path && *path) {
		if (semanage_list_push(&homedir_list, path))
			goto fail;
	}
	free(path);
	path = NULL;

	if (!homedir_list) {
		if (semanage_list_push(&homedir_list, PATH_DEFAULT_HOME)) {
			goto fail;
		}
	}

	if (!stat(PATH_EXPORT_HOME, &buf)) {
		if (S_ISDIR(buf.st_mode)) {
			if (semanage_list_push(&homedir_list, PATH_EXPORT_HOME)) {
				goto fail;
			}
		}
	}

	if (!(s->usepasswd))
		return homedir_list;

	shells = get_shell_list();
	assert(shells);

	path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MIN", NULL);
	if (path && *path) {
		temp = atoi(path);
		minuid = temp;
		minuid_set = 1;
	}
	free(path);
	path = NULL;

	path = semanage_findval(PATH_ETC_LOGIN_DEFS, "UID_MAX", NULL);
	if (path && *path) {
		temp = atoi(path);
		maxuid = temp;
	}
	free(path);
	path = NULL;

	path = semanage_findval(PATH_ETC_LIBUSER, "LU_UIDNUMBER", "=");
	if (path && *path) {
		temp = atoi(path);
		if (!minuid_set || temp < minuid) {
			minuid = temp;
			minuid_set = 1;
		}
	}
	free(path);
	path = NULL;

	rbuflen = sysconf(_SC_GETPW_R_SIZE_MAX);
	if (rbuflen <= 0)
		goto fail;
	rbuf = malloc(rbuflen);
	if (rbuf == NULL)
		goto fail;
	setpwent();
	while ((retval = getpwent_r(&pwstorage, rbuf, rbuflen, &pwbuf)) == 0) {
		if (pwbuf->pw_uid < minuid || pwbuf->pw_uid > maxuid)
			continue;
		if (!semanage_list_find(shells, pwbuf->pw_shell))
			continue;
		int len = strlen(pwbuf->pw_dir) -1;
		for(; len > 0 && pwbuf->pw_dir[len] == '/'; len--) {
			pwbuf->pw_dir[len] = '\0';
		}
		if (strcmp(pwbuf->pw_dir, "/") == 0)
			continue;
		if (ignore(pwbuf->pw_dir))
			continue;
		if (semanage_str_count(pwbuf->pw_dir, '/') <= 1)
			continue;
		if (!(path = strdup(pwbuf->pw_dir))) {
			break;
		}

		semanage_rtrim(path, '/');

		if (!semanage_list_find(homedir_list, path)) {
			/*
			 * Now check for an existing file context that matches
			 * so we don't label a non-homedir as a homedir.
			 */
			hand.dir = path;
			hand.matched = 0;
			if (semanage_fcontext_iterate(s->h_semanage,
			    fcontext_matches, &hand) == STATUS_ERR)
				goto fail;

			/* NOTE: old genhomedircon printed a warning on match */
			if (hand.matched) {
				WARN(s->h_semanage, "%s homedir %s or its parent directory conflicts with a file context already specified in the policy.  This usually indicates an incorrectly defined system account.  If it is a system account please make sure its uid is less than %u or greater than %u or its login shell is /sbin/nologin.", pwbuf->pw_name, pwbuf->pw_dir, minuid, maxuid);
			} else {
				if (semanage_list_push(&homedir_list, path))
					goto fail;
			}
		}
		free(path);
		path = NULL;
	}

	if (retval && retval != ENOENT) {
		WARN(s->h_semanage, "Error while fetching users.  "
		     "Returning list so far.");
	}

	if (semanage_list_sort(&homedir_list))
		goto fail;

	endpwent();
	free(rbuf);
	semanage_list_destroy(&shells);

	return homedir_list;

      fail:
	endpwent();
	free(rbuf);
	free(path);
	semanage_list_destroy(&homedir_list);
	semanage_list_destroy(&shells);
	return NULL;
}
Ejemplo n.º 18
0
/*
 * get_group_members - identify the users in a given group name
 * IN group_name - a single group name
 * RET a zero terminated list of its UIDs or NULL on error
 * NOTE: User root has implicitly access to every group
 * NOTE: The caller must xfree non-NULL return values
 */
extern uid_t *get_group_members(char *group_name)
{
	char *grp_buffer = NULL;
  	struct group grp,  *grp_result = NULL;
	struct passwd *pwd_result = NULL;
	uid_t *group_uids = NULL, my_uid;
	gid_t my_gid;
	int buflen = PW_BUF_SIZE, i, j, res, uid_cnt;
#ifdef HAVE_AIX
	FILE *fp = NULL;
#elif defined (__APPLE__) || defined (__CYGWIN__)
#else
	char pw_buffer[PW_BUF_SIZE];
	struct passwd pw;
#endif

	group_uids = _get_group_cache(group_name);
	if (group_uids)	{	/* We found in cache */
		_log_group_members(group_name, group_uids);
		return group_uids;
	}

#if defined(_SC_GETGR_R_SIZE_MAX)
	i = sysconf(_SC_GETGR_R_SIZE_MAX);
	buflen = MAX(buflen, i);
#endif
	grp_buffer = xmalloc(buflen);
	while (1) {
		slurm_seterrno(0);
		res = getgrnam_r(group_name, &grp, grp_buffer, buflen,
				 &grp_result);

		/* We need to check for !grp_result, since it appears some
		 * versions of this function do not return an error on
		 * failure.
		 */
		if (res != 0 || !grp_result) {
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			error("%s: Could not find configured group %s",
			      __func__, group_name);
			xfree(grp_buffer);
			return NULL;
		}
		break;
	}
	my_gid = grp_result->gr_gid;

	j = 0;
	uid_cnt = 0;

	/* Get the members from the getgrnam_r() call.
	 */
	for (i = 0; grp_result->gr_mem[i]; i++) {

		if (uid_from_string(grp_result->gr_mem[i],
				    &my_uid) < 0) {
			continue;
		}
		if (my_uid == 0)
			continue;
		if (j + 1 >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids,
				 (sizeof(uid_t) * uid_cnt));
		}

		group_uids[j++] = my_uid;
	}

#ifdef HAVE_AIX
	setgrent_r(&fp);
	while (1) {
		slurm_seterrno(0);
		res = getgrent_r(&grp, grp_buffer, buflen, &fp);
		if (res != 0) {
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			break;
		}
		grp_result = &grp;
#elif defined (__APPLE__) || defined (__CYGWIN__)
	setgrent();
	while (1) {
		if ((grp_result = getgrent()) == NULL)
			break;
#else
	setgrent();
	while (1) {
		/* MH-CEA workaround to handle different group entries with
		 * the same gid
		 */
		slurm_seterrno(0);
		res = getgrent_r(&grp, grp_buffer, buflen, &grp_result);
		if (res != 0 || grp_result == NULL) {
			/* FreeBSD returns 0 and sets the grp_result to NULL
			 * unlike linux which returns ENOENT.
			 */
			if (errno == ERANGE) {
				buflen *= 2;
				xrealloc(grp_buffer, buflen);
				continue;
			}
			break;
		}
#endif
	        if (grp_result->gr_gid == my_gid) {
			if (strcmp(grp_result->gr_name, group_name)) {
				debug("including members of group '%s' as it "
				      "corresponds to the same gid as group"
				      " '%s'",grp_result->gr_name,group_name);
			}

		        for (i=0; grp_result->gr_mem[i]; i++) {
				if (uid_from_string(grp_result->gr_mem[i],
						    &my_uid) < 0) {
					/* Group member without valid login */
					continue;
				}
				if (my_uid == 0)
					continue;
				if (j+1 >= uid_cnt) {
					uid_cnt += 100;
					xrealloc(group_uids,
						 (sizeof(uid_t) * uid_cnt));
				}
				group_uids[j++] = my_uid;
			}
		}
	}
#ifdef HAVE_AIX
	endgrent_r(&fp);
	setpwent_r(&fp);
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &fp)) {
		pwd_result = &pw;
#else
	endgrent();
	setpwent();
#if defined (__sun)
	while ((pwd_result = getpwent_r(&pw, pw_buffer, PW_BUF_SIZE)) != NULL) {
#elif defined (__APPLE__) || defined (__CYGWIN__)
	while ((pwd_result = getpwent()) != NULL) {
#else
	while (!getpwent_r(&pw, pw_buffer, PW_BUF_SIZE, &pwd_result)) {
#endif
#endif
		/* At eof FreeBSD returns 0 unlike Linux
		 * which returns ENOENT.
		 */
		if (pwd_result == NULL)
			break;
 		if (pwd_result->pw_gid != my_gid)
			continue;
		if (j+1 >= uid_cnt) {
			uid_cnt += 100;
			xrealloc(group_uids, (sizeof(uid_t) * uid_cnt));
		}
		group_uids[j++] = pwd_result->pw_uid;
	}
#ifdef HAVE_AIX
	endpwent_r(&fp);
#else
	endpwent();
#endif
	xfree(grp_buffer);
	_put_group_cache(group_name, group_uids, j);
	_log_group_members(group_name, group_uids);
	return group_uids;
}

/* Delete our group/uid cache */
extern void clear_group_cache(void)
{
	slurm_mutex_lock(&group_cache_mutex);
	FREE_NULL_LIST(group_cache_list);
	slurm_mutex_unlock(&group_cache_mutex);
}

/* Get a record from our group/uid cache.
 * Return NULL if not found. */
static uid_t *_get_group_cache(char *group_name)
{
	ListIterator iter;
	struct group_cache_rec *cache_rec;
	uid_t *group_uids = NULL;
	int sz;

	slurm_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		slurm_mutex_unlock(&group_cache_mutex);
		return NULL;
	}

	iter = list_iterator_create(group_cache_list);
	while ((cache_rec = (struct group_cache_rec *) list_next(iter))) {
		if (strcmp(group_name, cache_rec->group_name))
			continue;
		sz = sizeof(uid_t) * (cache_rec->uid_cnt + 1);
		group_uids = (uid_t *) xmalloc(sz);
		memcpy(group_uids, cache_rec->group_uids, sz);
		break;
	}
	list_iterator_destroy(iter);
	slurm_mutex_unlock(&group_cache_mutex);
	return group_uids;
}

/* Delete a record from the group/uid cache, used by list functions */
static void _cache_del_func(void *x)
{
	struct group_cache_rec *cache_rec;

	cache_rec = (struct group_cache_rec *) x;
	xfree(cache_rec->group_name);
	xfree(cache_rec->group_uids);
	xfree(cache_rec);
}

/* Put a record on our group/uid cache */
static void _put_group_cache(char *group_name, void *group_uids, int uid_cnt)
{
	struct group_cache_rec *cache_rec;
	int sz;

	slurm_mutex_lock(&group_cache_mutex);
	if (!group_cache_list) {
		group_cache_list = list_create(_cache_del_func);
	}

	sz = sizeof(uid_t) * (uid_cnt);
	cache_rec = xmalloc(sizeof(struct group_cache_rec));
	cache_rec->group_name = xstrdup(group_name);
	cache_rec->uid_cnt    = uid_cnt;
	cache_rec->group_uids = (uid_t *) xmalloc(sizeof(uid_t) + sz);
	if (uid_cnt > 0)
		memcpy(cache_rec->group_uids, group_uids, sz);
	list_append(group_cache_list, cache_rec);
	slurm_mutex_unlock(&group_cache_mutex);
}

static void _log_group_members(char *group_name, uid_t *group_uids)
{
#if _DEBUG
	int i;

	if ((group_uids == NULL) || (group_uids[0] == 0)) {
		info("Group %s has no users", group_name);
		return;
	}

	info("Group %s contains uids:", group_name);
	for (i=0; group_uids && group_uids[i]; i++)
		info("  %u", group_uids[i]);
#endif
}