Пример #1
0
int
cap_getnameinfo(cap_channel_t *chan, const struct sockaddr *sa, socklen_t salen,
    char *host, size_t hostlen, char *serv, size_t servlen, int flags)
{
	nvlist_t *nvl;
	int error;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "getnameinfo");
	nvlist_add_number(nvl, "hostlen", (uint64_t)hostlen);
	nvlist_add_number(nvl, "servlen", (uint64_t)servlen);
	nvlist_add_binary(nvl, "sa", sa, (size_t)salen);
	nvlist_add_number(nvl, "flags", (uint64_t)flags);
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL)
		return (EAI_MEMORY);
	if (nvlist_get_number(nvl, "error") != 0) {
		error = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (error);
	}

	if (host != NULL)
		strlcpy(host, nvlist_get_string(nvl, "host"), hostlen + 1);
	if (serv != NULL)
		strlcpy(serv, nvlist_get_string(nvl, "serv"), servlen + 1);
	nvlist_destroy(nvl);
	return (0);
}
Пример #2
0
struct hostent *
cap_gethostbyaddr(cap_channel_t *chan, const void *addr, socklen_t len,
    int type)
{
	struct hostent *hp;
	nvlist_t *nvl;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "gethostbyaddr");
	nvlist_add_binary(nvl, "addr", addr, (size_t)len);
	nvlist_add_number(nvl, "family", (uint64_t)type);
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL) {
		h_errno = NO_RECOVERY;
		return (NULL);
	}
	if (nvlist_get_number(nvl, "error") != 0) {
		h_errno = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (NULL);
	}
	hp = hostent_unpack(nvl, &hent);
	nvlist_destroy(nvl);
	return (hp);
}
Пример #3
0
struct hostent *
cap_gethostbyname2(cap_channel_t *chan, const char *name, int type)
{
	struct hostent *hp;
	nvlist_t *nvl;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "gethostbyname");
	nvlist_add_number(nvl, "family", (uint64_t)type);
	nvlist_add_string(nvl, "name", name);
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL) {
		h_errno = NO_RECOVERY;
		return (NULL);
	}
	if (nvlist_get_number(nvl, "error") != 0) {
		h_errno = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (NULL);
	}

	hp = hostent_unpack(nvl, &hent);
	nvlist_destroy(nvl);
	return (hp);
}
Пример #4
0
int
cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname,
    const struct addrinfo *hints, struct addrinfo **res)
{
	struct addrinfo *firstai, *prevai, *curai;
	unsigned int ii;
	const nvlist_t *nvlai;
	nvlist_t *nvl;
	int error;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "getaddrinfo");
	nvlist_add_string(nvl, "hostname", hostname);
	nvlist_add_string(nvl, "servname", servname);
	if (hints != NULL) {
		nvlist_add_number(nvl, "hints.ai_flags",
		    (uint64_t)hints->ai_flags);
		nvlist_add_number(nvl, "hints.ai_family",
		    (uint64_t)hints->ai_family);
		nvlist_add_number(nvl, "hints.ai_socktype",
		    (uint64_t)hints->ai_socktype);
		nvlist_add_number(nvl, "hints.ai_protocol",
		    (uint64_t)hints->ai_protocol);
	}
	nvl = cap_xfer_nvlist(chan, nvl);
	if (nvl == NULL)
		return (EAI_MEMORY);
	if (nvlist_get_number(nvl, "error") != 0) {
		error = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (error);
	}

	nvlai = NULL;
	firstai = prevai = curai = NULL;
	for (ii = 0; ; ii++) {
		if (!nvlist_existsf_nvlist(nvl, "res%u", ii))
			break;
		nvlai = nvlist_getf_nvlist(nvl, "res%u", ii);
		curai = addrinfo_unpack(nvlai);
		if (curai == NULL)
			break;
		if (prevai != NULL)
			prevai->ai_next = curai;
		else if (firstai == NULL)
			firstai = curai;
		prevai = curai;
	}
	nvlist_destroy(nvl);
	if (curai == NULL && nvlai != NULL) {
		if (firstai == NULL)
			freeaddrinfo(firstai);
		return (EAI_MEMORY);
	}

	*res = firstai;
	return (0);
}
void
cap_endgrent(cap_channel_t *chan)
{
	nvlist_t *nvl;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "endgrent");
	/* Ignore any errors, we have no way to report them. */
	nvlist_destroy(cap_xfer_nvlist(chan, nvl, 0));
}
Пример #6
0
static void
cap_set_end_pwent(cap_channel_t *chan, const char *cmd)
{
	nvlist_t *nvl;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", cmd);
	/* Ignore any errors, we have no way to report them. */
	nvlist_destroy(cap_xfer_nvlist(chan, nvl));
}
Пример #7
0
int
cap_sysctlbyname(cap_channel_t *chan, const char *name, void *oldp,
    size_t *oldlenp, const void *newp, size_t newlen)
{
	nvlist_t *nvl;
	const uint8_t *retoldp;
	uint8_t operation;
	size_t oldlen;

	operation = 0;
	if (oldp != NULL)
		operation |= CAP_SYSCTL_READ;
	if (newp != NULL)
		operation |= CAP_SYSCTL_WRITE;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "sysctl");
	nvlist_add_string(nvl, "name", name);
	nvlist_add_number(nvl, "operation", (uint64_t)operation);
	if (oldp == NULL && oldlenp != NULL)
		nvlist_add_null(nvl, "justsize");
	else if (oldlenp != NULL)
		nvlist_add_number(nvl, "oldlen", (uint64_t)*oldlenp);
	if (newp != NULL)
		nvlist_add_binary(nvl, "newp", newp, newlen);
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL)
		return (-1);
	if (nvlist_get_number(nvl, "error") != 0) {
		errno = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (-1);
	}

	if (oldp == NULL && oldlenp != NULL) {
		*oldlenp = (size_t)nvlist_get_number(nvl, "oldlen");
	} else if (oldp != NULL) {
		retoldp = nvlist_get_binary(nvl, "oldp", &oldlen);
		memcpy(oldp, retoldp, oldlen);
		if (oldlenp != NULL)
			*oldlenp = oldlen;
	}
	nvlist_destroy(nvl);

	return (0);
}
int
cap_setgrent(cap_channel_t *chan)
{
	nvlist_t *nvl;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", "setgrent");
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL)
		return (0);
	if (nvlist_get_number(nvl, "error") != 0) {
		errno = nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		return (0);
	}
	nvlist_destroy(nvl);

	return (1);
}
Пример #9
0
int
cap_random_buf(cap_channel_t *chan, void *buf, size_t nbytes)
{
	nvlist_t *nvl;
	const void *randbuf;
	uint8_t *ptr;
	size_t left, randbufsize;

	left = nbytes;
	ptr = buf;

	while (left > 0) {
		nvl = nvlist_create(0);
		nvlist_add_string(nvl, "cmd", "generate");
		nvlist_add_number(nvl, "size",
		    (uint64_t)(left > MAXSIZE ? MAXSIZE : left));
		nvl = cap_xfer_nvlist(chan, nvl, 0);
		if (nvl == NULL)
			return (-1);
		if (nvlist_get_number(nvl, "error") != 0) {
			errno = (int)nvlist_get_number(nvl, "error");
			nvlist_destroy(nvl);
			return (-1);
		}

		randbuf = nvlist_get_binary(nvl, "data", &randbufsize);
		memcpy(ptr, randbuf, randbufsize);

		nvlist_destroy(nvl);

		ptr += randbufsize;
		assert(left >= randbufsize);
		left -= randbufsize;
	}

	return (0);
}
static int
cap_getgrcommon_r(cap_channel_t *chan, const char *cmd, const char *name,
    gid_t gid, struct group *grp, char *buffer, size_t bufsize,
    struct group **result)
{
	nvlist_t *nvl;
	bool getgr_r;
	int error;

	nvl = nvlist_create(0);
	nvlist_add_string(nvl, "cmd", cmd);
	if (strcmp(cmd, "getgrent") == 0 || strcmp(cmd, "getgrent_r") == 0) {
		/* Add nothing. */
	} else if (strcmp(cmd, "getgrnam") == 0 ||
	    strcmp(cmd, "getgrnam_r") == 0) {
		nvlist_add_string(nvl, "name", name);
	} else if (strcmp(cmd, "getgrgid") == 0 ||
	    strcmp(cmd, "getgrgid_r") == 0) {
		nvlist_add_number(nvl, "gid", (uint64_t)gid);
	} else {
		abort();
	}
	nvl = cap_xfer_nvlist(chan, nvl, 0);
	if (nvl == NULL) {
		assert(errno != 0);
		*result = NULL;
		return (errno);
	}
	error = (int)nvlist_get_number(nvl, "error");
	if (error != 0) {
		nvlist_destroy(nvl);
		*result = NULL;
		return (error);
	}

	if (!nvlist_exists_string(nvl, "gr_name")) {
		/* Not found. */
		nvlist_destroy(nvl);
		*result = NULL;
		return (0);
	}

	getgr_r = (strcmp(cmd, "getgrent_r") == 0 ||
	    strcmp(cmd, "getgrnam_r") == 0 || strcmp(cmd, "getgrgid_r") == 0);

	for (;;) {
		error = group_unpack(nvl, grp, buffer, bufsize);
		if (getgr_r || error != ERANGE)
			break;
		assert(buffer == gbuffer);
		assert(bufsize == gbufsize);
		error = group_resize();
		if (error != 0)
			break;
		/* Update pointers after resize. */
		buffer = gbuffer;
		bufsize = gbufsize;
	}

	nvlist_destroy(nvl);

	if (error == 0)
		*result = grp;
	else
		*result = NULL;

	return (error);
}