コード例 #1
0
ファイル: getpwent.c プロジェクト: djmasde/bitrig
static struct passwd *
__yppwlookup(int lookup, char *name, uid_t uid, struct passwd *pw,
    char *buf, size_t buflen, int *flagsp)
{
	char bf[1 + _PW_NAME_LEN], *ypcurrent = NULL, *map = NULL;
	int yp_pw_flags = 0, ypcurrentlen, r, s = -1, pw_keynum;
	static long long yppbuf[_PW_BUF_LEN / sizeof(long long)];
	struct _ypexclude *ypexhead = NULL;
	const char *host, *user, *dom;
	DBT key;

	for (pw_keynum = 1; pw_keynum; pw_keynum++) {
		bf[0] = _PW_KEYBYNUM;
		bcopy((char *)&pw_keynum, &bf[1], sizeof(pw_keynum));
		key.data = (u_char *)bf;
		key.size = 1 + sizeof(pw_keynum);
		if (__hashpw(&key, buf, buflen, pw, flagsp) == 0)
			break;
		switch (pw->pw_name[0]) {
		case '+':
			if (!__ypdomain) {
				if (_yp_check(&__ypdomain) == 0)
					continue;
			}
			__ypproto_set(pw, yppbuf, *flagsp, &yp_pw_flags);
			if (!map) {
				if (lookup == LOOKUP_BYNAME) {
					map = PASSWD_BYNAME;
					name = strdup(name);
				} else {
					map = PASSWD_BYUID;
					asprintf(&name, "%u", uid);
				}
			}

			switch (pw->pw_name[1]) {
			case '\0':
				if (ypcurrent) {
					free(ypcurrent);
					ypcurrent = NULL;
				}
				r = yp_match(__ypdomain, map,
				    name, strlen(name),
				    &ypcurrent, &ypcurrentlen);
				if (r != 0 || ypcurrentlen > buflen) {
					if (ypcurrent)
						free(ypcurrent);
					ypcurrent = NULL;
					continue;
				}
				break;
			case '@':
pwnam_netgrp:
				if (ypcurrent) {
					free(ypcurrent);
					ypcurrent = NULL;
				}
				if (s == -1)	/* first time */
					setnetgrent(pw->pw_name + 2);
				s = getnetgrent(&host, &user, &dom);
				if (s == 0) {	/* end of group */
					endnetgrent();
					s = -1;
					continue;
				} else {
					if (user && *user) {
						r = yp_match(__ypdomain, map,
						    user, strlen(user),
						    &ypcurrent, &ypcurrentlen);
					} else
						goto pwnam_netgrp;
					if (r != 0 || ypcurrentlen > buflen) {
						if (ypcurrent)
							free(ypcurrent);
						ypcurrent = NULL;
						/*
						 * just because this
						 * user is bad, doesn't
						 * mean they all are.
						 */
						goto pwnam_netgrp;
					}
				}
				break;
			default:
				if (ypcurrent) {
					free(ypcurrent);
					ypcurrent = NULL;
				}
				user = pw->pw_name + 1;
				r = yp_match(__ypdomain, map,
				    user, strlen(user),
				    &ypcurrent, &ypcurrentlen);
				if (r != 0 || ypcurrentlen > buflen) {
					if (ypcurrent)
						free(ypcurrent);
					ypcurrent = NULL;
					continue;
				}
				break;
			}
			bcopy(ypcurrent, buf, ypcurrentlen);
			buf[ypcurrentlen] = '\0';
			if (__ypparse(pw, buf, yp_pw_flags) ||
			    __ypexclude_is(&ypexhead, pw->pw_name)) {
				if (s == 1)	/* inside netgrp */
					goto pwnam_netgrp;
				continue;
			}
			break;
		case '-':
			/* attempted exclusion */
			switch (pw->pw_name[1]) {
			case '\0':
				break;
			case '@':
				setnetgrent(pw->pw_name + 2);
				while (getnetgrent(&host, &user, &dom)) {
					if (user && *user)
						__ypexclude_add(&ypexhead, user);
				}
				endnetgrent();
				break;
			default:
				__ypexclude_add(&ypexhead, pw->pw_name + 1);
				break;
			}
			break;
		}
		if ((lookup == LOOKUP_BYUID && pw->pw_uid == uid) ||
		    (lookup == LOOKUP_BYNAME && strcmp(pw->pw_name, name) == 0))
			goto done;
		if (s == 1)	/* inside netgrp */
			goto pwnam_netgrp;
		continue;
	}
	pw = NULL;
done:
	__ypexclude_free(&ypexhead);
	__ypproto = NULL;
	if (ypcurrent)
		free(ypcurrent);
	ypcurrent = NULL;
	if (map)
		free(name);
	return (pw);
}
コード例 #2
0
static int
grscan(int search, gid_t gid, const char *name, struct group *p_gr,
    struct group_storage *gs, int *foundyp)
{
	char *cp, **m;
	char *bp, *endp;
	u_long ul;
#ifdef YP
	char *key, *data;
	int keylen, datalen;
	int r;
#endif
	char **members;
	char *line;
	int saved_errno;

	if (gs == NULL)
		return 0;
	members = gs->members;
	line = gs->line;
	saved_errno = errno;

	for (;;) {
#ifdef YP
		if (__ypmode) {
			if (__ypcurrent) {
				r = yp_next(__ypdomain, "group.byname",
				    __ypcurrent, __ypcurrentlen,
				    &key, &keylen, &data, &datalen);
				free(__ypcurrent);
				__ypcurrent = key;
				__ypcurrentlen = keylen;
			} else {
				r = yp_first(__ypdomain, "group.byname",
				    &__ypcurrent, &__ypcurrentlen,
				    &data, &datalen);
			}
			if (r) {
				__ypmode = 0;
				__ypcurrent = NULL;
				if (r == YPERR_NOMORE)
					continue;
				else
					return 0;
			}
			bcopy(data, line, datalen);
			free(data);
			line[datalen] = '\0';
			bp = line;
			goto parse;
		}
#endif
		if (!fgets(line, sizeof(gs->line), _gr_fp)) {
			if (feof(_gr_fp) && !ferror(_gr_fp))
				errno = saved_errno;
			return 0;
		}
		bp = line;
		/* skip lines that are too big */
		if (!strchr(line, '\n')) {
			int ch;

			while ((ch = getc_unlocked(_gr_fp)) != '\n' &&
			    ch != EOF)
				;
			continue;
		}
#ifdef YP
		if (line[0] == '+' || line[0] == '-') {
			if (__ypdomain == NULL &&
			    yp_get_default_domain(&__ypdomain))
				goto parse;
			switch (yp_bind(__ypdomain)) {
			case 0:
				break;
			case YPERR_BADARGS:
			case YPERR_YPBIND:
				goto parse;
			default:
				return 0;
			}
		}
		if (line[0] == '+') {
			switch (line[1]) {
			case ':':
			case '\0':
			case '\n':
				if (foundyp) {
					*foundyp = 1;
					errno = saved_errno;
					return 0;
				}
				if (!search) {
					__ypmode = 1;
					continue;
				}
				if (name) {
					r = yp_match(__ypdomain,
					    "group.byname", name, strlen(name),
					    &data, &datalen);
				} else {
					char buf[20];
					snprintf(buf, sizeof buf, "%u", gid);
					r = yp_match(__ypdomain, "group.bygid",
					    buf, strlen(buf), &data, &datalen);
				}
				switch (r) {
				case 0:
					break;
				case YPERR_KEY:
					continue;
				default:
					return 0;
				}
				bcopy(data, line, datalen);
				free(data);
				line[datalen] = '\0';
				bp = line;
				p_gr->gr_name = strsep(&bp, ":\n");
				if (__ypexclude_is(&__ypexhead, p_gr->gr_name))
					continue;
				p_gr->gr_passwd = strsep(&bp, ":\n");
				if (!(cp = strsep(&bp, ":\n")))
					continue;
				if (name) {
					ul = strtoul(cp, &endp, 10);
					if (*endp != '\0' || endp == cp ||
					    ul >= GID_MAX)
						continue;
					p_gr->gr_gid = ul;
				} else
					p_gr->gr_gid = gid;
				goto found_it;
			default:
				bp = strsep(&bp, ":\n") + 1;
				if ((search && name && strcmp(bp, name)) ||
				    __ypexclude_is(&__ypexhead, bp))
					continue;
				r = yp_match(__ypdomain, "group.byname",
				    bp, strlen(bp), &data, &datalen);
				switch (r) {
				case 0:
					break;
				case YPERR_KEY:
					continue;
				default:
					return 0;
				}
				bcopy(data, line, datalen);
				free(data);
				line[datalen] = '\0';
				bp = line;
			}
		} else if (line[0] == '-') {
			if (__ypexclude_add(&__ypexhead,
			    strsep(&line, ":\n") + 1))
				return 0;
			if (foundyp) {
				*foundyp = -1;
				errno = saved_errno;
				return 0;
			}
			continue;
		}
parse:
#endif
		p_gr->gr_name = strsep(&bp, ":\n");
		if (search && name && strcmp(p_gr->gr_name, name))
			continue;
#ifdef YP
		if (__ypmode && __ypexclude_is(&__ypexhead, p_gr->gr_name))
			continue;
#endif
		p_gr->gr_passwd = strsep(&bp, ":\n");
		if (!(cp = strsep(&bp, ":\n")))
			continue;
		ul = strtoul(cp, &endp, 10);
		if (endp == cp || *endp != '\0' || ul >= GID_MAX)
			continue;
		p_gr->gr_gid = ul;
		if (search && name == NULL && p_gr->gr_gid != gid)
			continue;
#ifdef YP
	found_it:
#endif
		cp = NULL;
		if (bp == NULL)
			continue;
		for (m = p_gr->gr_mem = members;; bp++) {
			if (m == &members[MAXGRP - 1])
				break;
			if (*bp == ',') {
				if (cp) {
					*bp = '\0';
					*m++ = cp;
					cp = NULL;
				}
			} else if (*bp == '\0' || *bp == '\n' || *bp == ' ') {
				if (cp) {
					*bp = '\0';
					*m++ = cp;
				}
				break;
			} else if (cp == NULL)
				cp = bp;
		}
		*m = NULL;
		errno = saved_errno;
		return 1;
	}
	/* NOTREACHED */
}
コード例 #3
0
ファイル: getpwent.c プロジェクト: djmasde/bitrig
struct passwd *
getpwent(void)
{
#ifdef YP
	static char *name = NULL;
	char *map;
#endif
	char bf[1 + sizeof(_pw_keynum)];
	struct passwd *pw = NULL;
	DBT key;

	_THREAD_PRIVATE_MUTEX_LOCK(pw);
	if (!_pw_db && !__initdb())
		goto done;

#ifdef YP
	map = PASSWD_BYNAME;

	if (__getpwent_has_yppw == -1)
		__getpwent_has_yppw = __has_yppw();

again:
	if (__getpwent_has_yppw && (__ypmode != YPMODE_NONE)) {
		const char *user, *host, *dom;
		int keylen, datalen, r, s;
		char *key, *data = NULL;

		if (!__ypdomain) {
			if (_yp_check(&__ypdomain) == 0) {
				__ypmode = YPMODE_NONE;
				goto again;
			}
		}
		switch (__ypmode) {
		case YPMODE_FULL:
			if (__ypcurrent) {
				r = yp_next(__ypdomain, map,
				    __ypcurrent, __ypcurrentlen,
				    &key, &keylen, &data, &datalen);
				free(__ypcurrent);
				__ypcurrent = NULL;
				if (r != 0) {
					__ypmode = YPMODE_NONE;
					if (data)
						free(data);
					goto again;
				}
				__ypcurrent = key;
				__ypcurrentlen = keylen;
			} else {
				r = yp_first(__ypdomain, map,
				    &__ypcurrent, &__ypcurrentlen,
				    &data, &datalen);
				if (r != 0 ||
				    __ypcurrentlen > sizeof(__ypline)) {
					__ypmode = YPMODE_NONE;
					if (data)
						free(data);
					goto again;
				}
			}
			bcopy(data, __ypline, datalen);
			free(data);
			break;
		case YPMODE_NETGRP:
			s = getnetgrent(&host, &user, &dom);
			if (s == 0) {	/* end of group */
				endnetgrent();
				__ypmode = YPMODE_NONE;
				goto again;
			}
			if (user && *user) {
				r = yp_match(__ypdomain, map,
				    user, strlen(user), &data, &datalen);
			} else
				goto again;
			if (r != 0 ||
			    __ypcurrentlen > sizeof(__ypline)) {
				/*
				 * if the netgroup is invalid, keep looking
				 * as there may be valid users later on.
				 */
				if (data)
					free(data);
				goto again;
			}
			bcopy(data, __ypline, datalen);
			free(data);
			break;
		case YPMODE_USER:
			if (name) {
				r = yp_match(__ypdomain, map,
				    name, strlen(name), &data, &datalen);
				__ypmode = YPMODE_NONE;
				free(name);
				name = NULL;
				if (r != 0 ||
				    __ypcurrentlen > sizeof(__ypline)) {
					if (data)
						free(data);
					goto again;
				}
				bcopy(data, __ypline, datalen);
				free(data);
			} else {		/* XXX */
				__ypmode = YPMODE_NONE;
				goto again;
			}
			break;
		case YPMODE_NONE:
			/* NOTREACHED */
			break;
		}

		__ypline[datalen] = '\0';
		if (__ypparse(&_pw_passwd, __ypline, __yp_pw_flags))
			goto again;
		pw = &_pw_passwd;
		goto done;
	}
#endif

	++_pw_keynum;
	bf[0] = _PW_KEYBYNUM;
	bcopy((char *)&_pw_keynum, &bf[1], sizeof(_pw_keynum));
	key.data = (u_char *)bf;
	key.size = 1 + sizeof(_pw_keynum);
	if (__hashpw(&key, _pw_string, sizeof _pw_string,
	    &_pw_passwd, &_pw_flags)) {
#ifdef YP
		static long long __yppbuf[_PW_BUF_LEN / sizeof(long long)];
		const char *user, *host, *dom;

		/* if we don't have YP at all, don't bother. */
		if (__getpwent_has_yppw) {
			if (_pw_passwd.pw_name[0] == '+') {
				/* set the mode */
				switch (_pw_passwd.pw_name[1]) {
				case '\0':
					__ypmode = YPMODE_FULL;
					break;
				case '@':
					__ypmode = YPMODE_NETGRP;
					setnetgrent(_pw_passwd.pw_name + 2);
					break;
				default:
					__ypmode = YPMODE_USER;
					name = strdup(_pw_passwd.pw_name + 1);
					break;
				}

				__ypproto_set(&_pw_passwd, __yppbuf,
				    _pw_flags, &__yp_pw_flags);
				goto again;
			} else if (_pw_passwd.pw_name[0] == '-') {
				/* an attempted exclusion */
				switch (_pw_passwd.pw_name[1]) {
				case '\0':
					break;
				case '@':
					setnetgrent(_pw_passwd.pw_name + 2);
					while (getnetgrent(&host, &user, &dom)) {
						if (user && *user)
							__ypexclude_add(&__ypexhead,
							    user);
					}
					endnetgrent();
					break;
				default:
					__ypexclude_add(&__ypexhead,
					    _pw_passwd.pw_name + 1);
					break;
				}
				goto again;
			}
		}
#endif
		pw = &_pw_passwd;
		goto done;
	}

done:
	_THREAD_PRIVATE_MUTEX_UNLOCK(pw);
	return (pw);
}