示例#1
0
static int
nis_setservent(void *result, void *mdata, va_list ap)
{
	struct nis_state *st;
	int rv;

	rv = nis_getstate(&st);
	if (rv != 0)
		return (NS_UNAVAIL);

	switch ((enum constants)mdata) {
	case SETSERVENT:
	case ENDSERVENT:
		free(st->yp_key);
		st->yp_key = NULL;
		st->yp_stepping = 0;
		break;
	default:
		break;
	};

	return (NS_UNAVAIL);
}
示例#2
0
static int
nis_setrpcent(void *retval, void *mdata, va_list ap)
{
	struct nis_state	*st;
	int	rv;

	rv = nis_getstate(&st);
	if (rv != 0)
		return (NS_UNAVAIL);

	switch ((enum constants)mdata)
	{
	case SETRPCENT:
	case ENDRPCENT:
		free(st->current);
		st->current = NULL;
		st->stepping = 0;
		break;
	default:
		break;
	}

	return (NS_UNAVAIL);
}
示例#3
0
static int
nis_servent(void *retval, void *mdata, va_list ap)
{
	char *resultbuf, *lastkey;
	int resultbuflen;
	char buf[YPMAXRECORD + 2];

	struct nis_state *st;
	int rv;

	enum nss_lookup_type how;
	char *name;
	char *proto;
	int port;

	struct servent *serv;
	char *buffer;
	size_t bufsize;
	int *errnop;

	name = NULL;
	proto = NULL;
	how = (enum nss_lookup_type)mdata;
	switch (how) {
	case nss_lt_name:
		name = va_arg(ap, char *);
		proto = va_arg(ap, char *);
		break;
	case nss_lt_id:
		port = va_arg(ap, int);
		proto = va_arg(ap, char *);
		break;
	case nss_lt_all:
		break;
	default:
		return NS_NOTFOUND;
	};

	serv = va_arg(ap, struct servent *);
	buffer  = va_arg(ap, char *);
	bufsize = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);

	*errnop = nis_getstate(&st);
	if (*errnop != 0)
		return (NS_UNAVAIL);

	if (st->yp_domain[0] == '\0') {
		if (getdomainname(st->yp_domain, sizeof st->yp_domain)) {
			*errnop = errno;
			return (NS_UNAVAIL);
		}
	}

	do {
		switch (how) {
		case nss_lt_name:
			snprintf(buf, sizeof(buf), "%s/%s", name, proto);
			if (yp_match(st->yp_domain, "services.byname", buf,
			    strlen(buf), &resultbuf, &resultbuflen)) {
				rv = NS_NOTFOUND;
				goto fin;
			}
			break;
		case nss_lt_id:
			snprintf(buf, sizeof(buf), "%d/%s", ntohs(port),
			    proto);

			/*
			 * We have to be a little flexible
			 * here. Ideally you're supposed to have both
			 * a services.byname and a services.byport
			 * map, but some systems have only
			 * services.byname. FreeBSD cheats a little by
			 * putting the services.byport information in
			 * the same map as services.byname so that
			 * either case will work. We allow for both
			 * possibilities here: if there is no
			 * services.byport map, we try services.byname
			 * instead.
			 */
			rv = yp_match(st->yp_domain, "services.byport", buf,
			    strlen(buf), &resultbuf, &resultbuflen);
			if (rv) {
				if (rv == YPERR_MAP) {
					if (yp_match(st->yp_domain,
					    "services.byname", buf,
					    strlen(buf), &resultbuf,
					    &resultbuflen)) {
						rv = NS_NOTFOUND;
						goto fin;
					}
				} else {
					rv = NS_NOTFOUND;
					goto fin;
				}
			}

			break;
		case nss_lt_all:
			if (!st->yp_stepping) {
				free(st->yp_key);
				rv = yp_first(st->yp_domain, "services.byname",
				    &st->yp_key, &st->yp_keylen, &resultbuf,
				    &resultbuflen);
				if (rv) {
					rv = NS_NOTFOUND;
					goto fin;
				}
				st->yp_stepping = 1;
			} else {
				lastkey = st->yp_key;
				rv = yp_next(st->yp_domain, "services.byname",
				    st->yp_key, st->yp_keylen, &st->yp_key,
				    &st->yp_keylen, &resultbuf, &resultbuflen);
				free(lastkey);
				if (rv) {
					st->yp_stepping = 0;
					rv = NS_NOTFOUND;
					goto fin;
				}
			}
			break;
		};

		rv = parse_result(serv, buffer, bufsize, resultbuf,
		    resultbuflen, errnop);
		free(resultbuf);

	} while (!(rv & NS_TERMINATE) && how == nss_lt_all);

fin:
	if (rv == NS_SUCCESS && retval != NULL)
		*(struct servent **)retval = serv;

	return (rv);
}
示例#4
0
static int
nis_rpcent(void *retval, void *mdata, va_list ap)
{
	char		*name;
	int		number;
	struct rpcent	*rpc;
	char		*buffer;
	size_t	bufsize;
	int		*errnop;

	char		**rp;
	char		**aliases;
	int		aliases_size;

	char	*lastkey;
	char	*resultbuf;
	int	resultbuflen;
	char	buf[YPMAXRECORD + 2];

	struct nis_state	*st;
	int		rv;
	enum nss_lookup_type	how;
	int	no_name_active;

	how = (enum nss_lookup_type)mdata;
	switch (how)
	{
	case nss_lt_name:
		name = va_arg(ap, char *);
		break;
	case nss_lt_id:
		number = va_arg(ap, int);
		break;
	case nss_lt_all:
		break;
	default:
		return (NS_NOTFOUND);
	}

	rpc = va_arg(ap, struct rpcent *);
	buffer = va_arg(ap, char *);
	bufsize = va_arg(ap, size_t);
	errnop = va_arg(ap, int *);

	*errnop = nis_getstate(&st);
	if (*errnop != 0)
		return (NS_UNAVAIL);

	if (st->domain[0] == '\0') {
		if (getdomainname(st->domain, sizeof(st->domain)) != 0) {
			*errnop = errno;
			return (NS_UNAVAIL);
		}
	}

	no_name_active = 0;
	do {
		switch (how)
		{
		case nss_lt_name:
			if (!st->no_name_map)
			{
				snprintf(buf, sizeof buf, "%s", name);
				rv = yp_match(st->domain, "rpc.byname", buf,
			    		strlen(buf), &resultbuf, &resultbuflen);

				switch (rv) {
				case 0:
					break;
				case YPERR_MAP:
					st->stepping = 0;
					no_name_active = 1;
					how = nss_lt_all;

					rv = NS_NOTFOUND;
					continue;
				default:
					rv = NS_NOTFOUND;
					goto fin;
				}
			} else {
				st->stepping = 0;
				no_name_active = 1;
				how = nss_lt_all;

				rv = NS_NOTFOUND;
				continue;
			}
		break;
		case nss_lt_id:
			snprintf(buf, sizeof buf, "%d", number);
			if (yp_match(st->domain, "rpc.bynumber", buf,
			    	strlen(buf), &resultbuf, &resultbuflen)) {
				rv = NS_NOTFOUND;
				goto fin;
			}
			break;
		case nss_lt_all:
				if (!st->stepping) {
					rv = yp_first(st->domain, "rpc.bynumber",
				    		&st->current,
						&st->currentlen, &resultbuf,
				    		&resultbuflen);
					if (rv) {
						rv = NS_NOTFOUND;
						goto fin;
					}
					st->stepping = 1;
				} else {
					lastkey = st->current;
					rv = yp_next(st->domain, "rpc.bynumber",
				    		st->current,
						st->currentlen, &st->current,
				    		&st->currentlen,
						&resultbuf,	&resultbuflen);
					free(lastkey);
					if (rv) {
						st->stepping = 0;
						rv = NS_NOTFOUND;
						goto fin;
					}
				}
			break;
		}

		/* we need a room for additional \n symbol */
		if (bufsize <= resultbuflen + 1 + _ALIGNBYTES +
		    sizeof(char *)) {
			*errnop = ERANGE;
			rv = NS_RETURN;
			break;
		}

		aliases=(char **)_ALIGN(&buffer[resultbuflen+2]);
		aliases_size = (buffer + bufsize - (char *)aliases) /
			sizeof(char *);
		if (aliases_size < 1) {
			*errnop = ERANGE;
			rv = NS_RETURN;
			break;
		}

		/*
		 * rpcent_unpack expects lines terminated with \n -- make it happy
		 */
		memcpy(buffer, resultbuf, resultbuflen);
		buffer[resultbuflen] = '\n';
		buffer[resultbuflen+1] = '\0';
		free(resultbuf);

		if (rpcent_unpack(buffer, rpc, aliases, aliases_size,
		    errnop) != 0) {
			if (*errnop == 0)
				rv = NS_NOTFOUND;
			else
				rv = NS_RETURN;
		} else {
			if ((how == nss_lt_all) && (no_name_active != 0)) {
				if (strcmp(rpc->r_name, name) == 0)
					goto done;
				for (rp = rpc->r_aliases; *rp != NULL; rp++) {
					if (strcmp(*rp, name) == 0)
						goto done;
				}
				rv = NS_NOTFOUND;
				continue;
done:
				rv = NS_SUCCESS;
			} else
				rv = NS_SUCCESS;
		}

	} while (!(rv & NS_TERMINATE) && (how == nss_lt_all));

fin:
	if ((rv == NS_SUCCESS) && (retval != NULL))
		*((struct rpcent **)retval) = rpc;

	return (rv);
}