Example #1
0
int
zygote_clone(zygote_func_t *func, int flags, int *chanfdp, int *procfdp)
{
	nvlist_t *nvl;
	int error;

	if (zygote_sock == -1) {
		/* Zygote didn't start. */
		errno = ENXIO;
		return (-1);
	}

	nvl = nvlist_create(0);
	nvlist_add_number(nvl, "func", (uint64_t)(uintptr_t)func);
	nvlist_add_number(nvl, "flags", (uint64_t)flags);
	nvl = nvlist_xfer(zygote_sock, nvl);
	if (nvl == NULL)
		return (-1);
	if (nvlist_exists_number(nvl, "error")) {
		error = (int)nvlist_get_number(nvl, "error");
		nvlist_destroy(nvl);
		errno = error;
		return (-1);
	}

	*chanfdp = nvlist_take_descriptor(nvl, "chanfd");
	*procfdp = nvlist_take_descriptor(nvl, "procfd");

	nvlist_destroy(nvl);
	return (0);
}
Example #2
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);
}
Example #3
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);
}
Example #4
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);
}
int
cap_grp_limit_groups(cap_channel_t *chan, const char * const *names,
    size_t nnames, gid_t *gids, size_t ngids)
{
	nvlist_t *limits, *groups;
	unsigned int i;
	char nvlname[64];
	int n;

	if (cap_limit_get(chan, &limits) < 0)
		return (-1);
	if (limits == NULL) {
		limits = nvlist_create(0);
	} else {
		if (nvlist_exists_nvlist(limits, "groups"))
			nvlist_free_nvlist(limits, "groups");
	}
	groups = nvlist_create(0);
	for (i = 0; i < ngids; i++) {
		n = snprintf(nvlname, sizeof(nvlname), "gid%u", i);
		assert(n > 0 && n < (int)sizeof(nvlname));
		nvlist_add_number(groups, nvlname, (uint64_t)gids[i]);
	}
	for (i = 0; i < nnames; i++) {
		n = snprintf(nvlname, sizeof(nvlname), "gid%u", i);
		assert(n > 0 && n < (int)sizeof(nvlname));
		nvlist_add_string(groups, nvlname, names[i]);
	}
	nvlist_move_nvlist(limits, "groups", groups);
	return (cap_limit_set(chan, limits));
}
Example #6
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);
}
Example #7
0
int
cap_pwd_limit_users(cap_channel_t *chan, const char * const *names,
    size_t nnames, uid_t *uids, size_t nuids)
{
	nvlist_t *limits, *users;
	char nvlname[64];
	unsigned int i;
	int n;

	if (cap_limit_get(chan, &limits) < 0)
		return (-1);
	if (limits == NULL) {
		limits = nvlist_create(0);
	} else {
		if (nvlist_exists_nvlist(limits, "users"))
			nvlist_free_nvlist(limits, "users");
	}
	users = nvlist_create(0);
	for (i = 0; i < nuids; i++) {
		n = snprintf(nvlname, sizeof(nvlname), "uid%u", i);
		assert(n > 0 && n < (int)sizeof(nvlname));
		nvlist_add_number(users, nvlname, (uint64_t)uids[i]);
	}
	for (i = 0; i < nnames; i++) {
		n = snprintf(nvlname, sizeof(nvlname), "name%u", i);
		assert(n > 0 && n < (int)sizeof(nvlname));
		nvlist_add_string(users, nvlname, names[i]);
	}
	nvlist_move_nvlist(limits, "users", users);
	return (cap_limit_set(chan, limits));
}
Example #8
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);
}
Example #9
0
static bool
grp_pack(const nvlist_t *limits, const struct group *grp, nvlist_t *nvl)
{
	char nvlname[64];
	int n;

	if (grp == NULL)
		return (true);

	/*
	 * If either name or GID is allowed, we allow it.
	 */
	if (!grp_allowed_group(limits, grp->gr_name, grp->gr_gid))
		return (false);

	if (grp_allowed_field(limits, "gr_name"))
		nvlist_add_string(nvl, "gr_name", grp->gr_name);
	else
		nvlist_add_string(nvl, "gr_name", "");
	if (grp_allowed_field(limits, "gr_passwd"))
		nvlist_add_string(nvl, "gr_passwd", grp->gr_passwd);
	else
		nvlist_add_string(nvl, "gr_passwd", "");
	if (grp_allowed_field(limits, "gr_gid"))
		nvlist_add_number(nvl, "gr_gid", (uint64_t)grp->gr_gid);
	else
		nvlist_add_number(nvl, "gr_gid", (uint64_t)-1);
	if (grp_allowed_field(limits, "gr_mem") && grp->gr_mem[0] != NULL) {
		unsigned int ngroups;

		for (ngroups = 0; grp->gr_mem[ngroups] != NULL; ngroups++) {
			n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]",
			    ngroups);
			assert(n > 0 && n < (ssize_t)sizeof(nvlname));
			nvlist_add_string(nvl, nvlname, grp->gr_mem[ngroups]);
		}
		nvlist_add_number(nvl, "gr_nmem", (uint64_t)ngroups);
	}

	return (true);
}
Example #10
0
static void
child(int sock)
{
	nvlist_t *nvl;

	nvl = nvlist_create(0);

	nvlist_add_bool(nvl, "nvlist/bool/true", true);
	nvlist_add_bool(nvl, "nvlist/bool/false", false);
	nvlist_add_number(nvl, "nvlist/number/0", 0);
	nvlist_add_number(nvl, "nvlist/number/1", 1);
	nvlist_add_number(nvl, "nvlist/number/-1", -1);
	nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
	nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
	nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
	nvlist_add_string(nvl, "nvlist/string/", "");
	nvlist_add_string(nvl, "nvlist/string/x", "x");
	nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz");
	nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO);
	nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
	nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz"));
	nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);

	nvlist_send(sock, nvl);

	nvlist_destroy(nvl);
}
Example #11
0
int
cap_dns_family_limit(cap_channel_t *chan, const int *families,
    size_t nfamilies)
{
	nvlist_t *limits;
	unsigned int i;
	char nvlname[64];
	int n;

	if (cap_limit_get(chan, &limits) < 0)
		return (-1);
	if (limits == NULL)
		limits = nvlist_create(0);
	else
		limit_remove(limits, "family");
	for (i = 0; i < nfamilies; i++) {
		n = snprintf(nvlname, sizeof(nvlname), "family%u", i);
		assert(n > 0 && n < (int)sizeof(nvlname));
		nvlist_add_number(limits, nvlname, (uint64_t)families[i]);
	}
	return (cap_limit_set(chan, limits));
}
Example #12
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);
}
Example #13
0
static int
sysctl_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin,
    nvlist_t *nvlout)
{
	const char *name;
	const void *newp;
	void *oldp;
	uint64_t operation;
	size_t oldlen, newlen;
	size_t *oldlenp;
	int error;

	if (strcmp(cmd, "sysctl") != 0)
		return (EINVAL);
	error = sysctl_check_one(nvlin, false);
	if (error != 0)
		return (error);

	name = nvlist_get_string(nvlin, "name");
	operation = nvlist_get_number(nvlin, "operation");
	if (!sysctl_allowed(limits, name, operation))
		return (ENOTCAPABLE);

	if ((operation & CAP_SYSCTL_WRITE) != 0) {
		if (!nvlist_exists_binary(nvlin, "newp"))
			return (EINVAL);
		newp = nvlist_get_binary(nvlin, "newp", &newlen);
		assert(newp != NULL && newlen > 0);
	} else {
		newp = NULL;
		newlen = 0;
	}

	if ((operation & CAP_SYSCTL_READ) != 0) {
		if (nvlist_exists_null(nvlin, "justsize")) {
			oldp = NULL;
			oldlen = 0;
			oldlenp = &oldlen;
		} else {
			if (!nvlist_exists_number(nvlin, "oldlen"))
				return (EINVAL);
			oldlen = (size_t)nvlist_get_number(nvlin, "oldlen");
			if (oldlen == 0)
				return (EINVAL);
			oldp = calloc(1, oldlen);
			if (oldp == NULL)
				return (ENOMEM);
			oldlenp = &oldlen;
		}
	} else {
		oldp = NULL;
		oldlen = 0;
		oldlenp = NULL;
	}

	if (sysctlbyname(name, oldp, oldlenp, newp, newlen) == -1) {
		error = errno;
		free(oldp);
		return (error);
	}

	if ((operation & CAP_SYSCTL_READ) != 0) {
		if (nvlist_exists_null(nvlin, "justsize"))
			nvlist_add_number(nvlout, "oldlen", (uint64_t)oldlen);
		else
			nvlist_move_binary(nvlout, "oldp", oldp, oldlen);
	}

	return (0);
}
Example #14
0
static bool
pwd_pack(const nvlist_t *limits, const struct passwd *pwd, nvlist_t *nvl)
{
	int fields;

	if (pwd == NULL)
		return (true);

	/*
	 * If either name or UID is allowed, we allow it.
	 */
	if (!pwd_allowed_user(limits, pwd->pw_name, pwd->pw_uid))
		return (false);

	fields = pwd->pw_fields;

	if (pwd_allowed_field(limits, "pw_name")) {
		nvlist_add_string(nvl, "pw_name", pwd->pw_name);
	} else {
		nvlist_add_string(nvl, "pw_name", "");
		fields &= ~_PWF_NAME;
	}
	if (pwd_allowed_field(limits, "pw_uid")) {
		nvlist_add_number(nvl, "pw_uid", (uint64_t)pwd->pw_uid);
	} else {
		nvlist_add_number(nvl, "pw_uid", (uint64_t)-1);
		fields &= ~_PWF_UID;
	}
	if (pwd_allowed_field(limits, "pw_gid")) {
		nvlist_add_number(nvl, "pw_gid", (uint64_t)pwd->pw_gid);
	} else {
		nvlist_add_number(nvl, "pw_gid", (uint64_t)-1);
		fields &= ~_PWF_GID;
	}
	if (pwd_allowed_field(limits, "pw_change")) {
		nvlist_add_number(nvl, "pw_change", (uint64_t)pwd->pw_change);
	} else {
		nvlist_add_number(nvl, "pw_change", (uint64_t)0);
		fields &= ~_PWF_CHANGE;
	}
	if (pwd_allowed_field(limits, "pw_passwd")) {
		nvlist_add_string(nvl, "pw_passwd", pwd->pw_passwd);
	} else {
		nvlist_add_string(nvl, "pw_passwd", "");
		fields &= ~_PWF_PASSWD;
	}
	if (pwd_allowed_field(limits, "pw_class")) {
		nvlist_add_string(nvl, "pw_class", pwd->pw_class);
	} else {
		nvlist_add_string(nvl, "pw_class", "");
		fields &= ~_PWF_CLASS;
	}
	if (pwd_allowed_field(limits, "pw_gecos")) {
		nvlist_add_string(nvl, "pw_gecos", pwd->pw_gecos);
	} else {
		nvlist_add_string(nvl, "pw_gecos", "");
		fields &= ~_PWF_GECOS;
	}
	if (pwd_allowed_field(limits, "pw_dir")) {
		nvlist_add_string(nvl, "pw_dir", pwd->pw_dir);
	} else {
		nvlist_add_string(nvl, "pw_dir", "");
		fields &= ~_PWF_DIR;
	}
	if (pwd_allowed_field(limits, "pw_shell")) {
		nvlist_add_string(nvl, "pw_shell", pwd->pw_shell);
	} else {
		nvlist_add_string(nvl, "pw_shell", "");
		fields &= ~_PWF_SHELL;
	}
	if (pwd_allowed_field(limits, "pw_expire")) {
		nvlist_add_number(nvl, "pw_expire", (uint64_t)pwd->pw_expire);
	} else {
		nvlist_add_number(nvl, "pw_expire", (uint64_t)0);
		fields &= ~_PWF_EXPIRE;
	}
	nvlist_add_number(nvl, "pw_fields", (uint64_t)fields);

	return (true);
}
Example #15
0
static int
u_sysctl_do_sysctl(struct nvlist *nvl, int ns,
    void *oldp,
    size_t *oldlenp,
    const void *newp,
    size_t newlen)
{
	nvlist_t *nvl_resp = NULL;
	int retval = 0;
	int r_errno;
	const char *rbuf;
	size_t r_len;

	/* XXX Eventually this should be in a sysctl transaction struct */
	int shm_fd = -1;
	char *shm_mem = NULL;
	size_t shm_len = 0;
	char shm_path[128];

	/* Setup request and response buffer information */

	/*
	 * If the requested size is provided and it's greater than the
	 * maximum size allowed, we'll flip to using shm
	 */
	if (oldlenp != NULL && *oldlenp >= U_SYSCTL_MAX_REQ_BUF_LEN) {
		/* Construct a shm path */
		/* XXX should make this less guessable */
		snprintf(shm_path, 128, "/sysctl.%ld", (long) arc4random());

		/* Open it */
		shm_fd = shm_open(shm_path, O_CREAT | O_RDWR, 0640);
		if (shm_fd < 0) {
			warn("shm_open (%s)", shm_path);
			retval = -1;
			goto done;
		}

		/*
		 * Calculate a mmap size that's a multiple of
		 * the system page length.
		 */
		shm_len = round_page(*oldlenp);

		/* make it that big! */
		if (ftruncate(shm_fd, shm_len) < 0) {
			warn("ftruncate");
			goto done;
		}

		/* mmap it */
		shm_mem = mmap(NULL, shm_len, PROT_READ | PROT_WRITE,
		    0, shm_fd, 0);
		if (shm_mem == NULL) {
			warn("mmap");
			goto done;
		}

		/* add the shm path to the outbound request */
		nvlist_add_string(nvl, "sysctl_respbuf_shm_path", shm_path);
		nvlist_add_number(nvl, "sysctl_respbuf_shm_len", shm_len);
	}

	/*
	 * Writing a value may pass in a NULL oldlenp, so only conditionally
	 * send it.
	 */
	if (oldlenp != NULL)
		nvlist_add_number(nvl, "sysctl_respbuf_len", *oldlenp);

	if (newlen > 0) {
		nvlist_add_binary(nvl, "sysctl_reqbuf", newp, newlen);
	}

	/* Send command */
	if (nvlist_send(ns, nvl) < 0) {
		warn("nvlist_send");
		retval = -1;
		goto done;
	}

	/* Read response */
	nvl_resp = nvlist_recv(ns);
	if (nvl_resp == NULL) {
		warn("nvlist_recv");
		retval = -1;
		goto done;
	}

	if (! nvlist_exists_number(nvl_resp, "sysctl_errno")) {
		fprintf(stderr, "response: no errno?\n");
		goto done;
	}
	r_errno = (int) nvlist_get_number(nvl_resp, "sysctl_errno");

	/* XXX validate r_len versus oldlenp */
	if (nvlist_exists_binary(nvl_resp, "sysctl_respbuf")) {
		rbuf = nvlist_get_binary(nvl_resp, "sysctl_respbuf", &r_len);
		memcpy(oldp, rbuf, r_len);
	} else if (shm_mem != NULL) {
		memcpy(oldp, shm_mem, r_len);
		r_len = nvlist_get_number(nvl_resp, "sysctl_respbuf_shm_len");
	} else if (nvlist_exists_number(nvl_resp, "sysctl_respbuf_len")) {
		r_len = nvlist_get_number(nvl_resp, "sysctl_respbuf_len");
	} else {
		r_len = 0;
	}

	if (oldlenp != NULL)
		*oldlenp = r_len;

	if (r_errno == 0) {
		retval = 0;
	} else {
		retval = -1;
		errno = r_errno;
	}

done:
	if (shm_mem != NULL)
		munmap(shm_mem, shm_len);
	if (shm_fd != -1) {
		close(shm_fd);
		shm_unlink(shm_path);
	}
	if (nvl_resp)
		nvlist_destroy(nvl_resp);
	return (retval);
}
Example #16
0
void
service_message(struct service *service, struct service_connection *sconn)
{
	nvlist_t *nvlin, *nvlout;
	const char *cmd;
	int error;

	nvlin = cap_recv_nvlist(service_connection_get_chan(sconn));
	if (nvlin == NULL) {
		if (errno == ENOTCONN) {
			pjdlog_debug(1, "Connection closed by the client.");
		} else {
			pjdlog_errno(LOG_ERR,
			    "Unable to receive message from client");
		}
		service_connection_remove(service, sconn);
		return;
	}

	error = EDOOFUS;
	nvlout = nvlist_create(0);

	cmd = nvlist_get_string(nvlin, "cmd");
	pjdlog_debug(1, "Command received from client: %s.", cmd);
	if (pjdlog_debug_get() >= 2)
		nvlist_fdump(nvlin, stderr);
	if (strcmp(cmd, "limit_set") == 0) {
		nvlist_t *nvllim;

		nvllim = nvlist_take_nvlist(nvlin, "limits");
		error = service->s_limit(service_connection_get_limits(sconn),
		    nvllim);
		if (error == 0) {
			service_connection_set_limits(sconn, nvllim);
			/* Function consumes nvllim. */
		} else {
			nvlist_destroy(nvllim);
		}
	} else if (strcmp(cmd, "limit_get") == 0) {
		const nvlist_t *nvllim;

		nvllim = service_connection_get_limits(sconn);
		if (nvllim != NULL)
			nvlist_add_nvlist(nvlout, "limits", nvllim);
		else
			nvlist_add_null(nvlout, "limits");
		error = 0;
	} else if (strcmp(cmd, "clone") == 0) {
		int sock;

		sock = service_connection_clone(service, sconn);
		if (sock == -1) {
			error = errno;
		} else {
			nvlist_add_descriptor(nvlout, "sock", sock);
			error = 0;
		}
	} else {
		nvlout = nvlist_create(0);
		error = service->s_command(cmd,
		    service_connection_get_limits(sconn), nvlin, nvlout);
	}

	nvlist_destroy(nvlin);
	nvlist_add_number(nvlout, "error", (uint64_t)error);
	pjdlog_debug(1, "Sending reply to client (error=%d).", error);
	if (pjdlog_debug_get() >= 2)
		nvlist_fdump(nvlout, stderr);

	if (cap_send_nvlist(service_connection_get_chan(sconn), nvlout) == -1) {
		pjdlog_errno(LOG_ERR, "Unable to send message to client");
		service_connection_remove(service, sconn);
		return;
	}
}
Example #17
0
int
main(void)
{
	const nvlist_t *cnvl;
	nvlist_t *nvl;

	printf("1..94\n");

	nvl = nvlist_create(0);

	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	nvlist_add_null(nvl, "nvlist/null");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_null(nvl, "nvlist/null"));

	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/true"));
	nvlist_add_bool(nvl, "nvlist/bool/true", true);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool/true"));

	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/false"));
	nvlist_add_bool(nvl, "nvlist/bool/false", false);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool/false"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/0"));
	nvlist_add_number(nvl, "nvlist/number/0", 0);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/0"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/1"));
	nvlist_add_number(nvl, "nvlist/number/1", 1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/1"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/-1"));
	nvlist_add_number(nvl, "nvlist/number/-1", -1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/-1"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/UINT64_MAX"));
	nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/UINT64_MAX"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MIN"));
	nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/INT64_MIN"));

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MAX"));
	nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_number(nvl, "nvlist/number/INT64_MAX"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/"));
	nvlist_add_string(nvl, "nvlist/string/", "");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/string/"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/x"));
	nvlist_add_string(nvl, "nvlist/string/x", "x");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/string/x"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"));
	nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/stringf/"));
	nvlist_add_stringf(nvl, "nvlist/stringf/", "%s", "");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/stringf/x"));
	nvlist_add_stringf(nvl, "nvlist/stringf/x", "%s", "x");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/x"));

	CHECK(!nvlist_exists_string(nvl, "nvlist/stringf/666Xabc"));
	nvlist_add_stringf(nvl, "nvlist/stringf/666Xabc", "%d%c%s", 666, 'X', "abc");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/666Xabc"));

	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"));
	nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"));

	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/x"));
	nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary/x"));

	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz"));
	nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz"));
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz"));

	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));

	CHECK(nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool/true"));
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool/false"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/0"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/1"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/-1"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/UINT64_MAX"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/INT64_MIN"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number/INT64_MAX"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string/"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string/x"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"));
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/"));
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/x"));
	CHECK(nvlist_exists_string(nvl, "nvlist/stringf/666Xabc"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary/x"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));

	cnvl = nvlist_get_nvlist(nvl, "nvlist/nvlist");
	CHECK(nvlist_exists_null(cnvl, "nvlist/null"));
	CHECK(nvlist_exists_bool(cnvl, "nvlist/bool/true"));
	CHECK(nvlist_exists_bool(cnvl, "nvlist/bool/false"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/0"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/1"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/-1"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/UINT64_MAX"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/INT64_MIN"));
	CHECK(nvlist_exists_number(cnvl, "nvlist/number/INT64_MAX"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/string/"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/string/x"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/stringf/"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/stringf/x"));
	CHECK(nvlist_exists_string(cnvl, "nvlist/stringf/666Xabc"));
	CHECK(nvlist_exists_descriptor(cnvl, "nvlist/descriptor/STDERR_FILENO"));
	CHECK(nvlist_exists_binary(cnvl, "nvlist/binary/x"));
	CHECK(nvlist_exists_binary(cnvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz"));

	nvlist_destroy(nvl);

	return (0);
}
Example #18
0
/*
 * This function creates sandboxes on-demand whoever has access to it via
 * 'sock' socket. Function sends two descriptors to the caller: process
 * descriptor of the sandbox and socket pair descriptor for communication
 * between sandbox and its owner.
 */
static void
zygote_main(int sock)
{
	int error, fd, flags, procfd;
	int chanfd[2];
	nvlist_t *nvlin, *nvlout;
	zygote_func_t *func;
	pid_t pid;

	assert(sock > STDERR_FILENO);

	setproctitle("zygote");

	if (pjdlog_mode_get() != PJDLOG_MODE_STD)
		stdnull();
	for (fd = STDERR_FILENO + 1; fd < sock; fd++)
		close(fd);
	closefrom(sock + 1);

	for (;;) {
		nvlin = nvlist_recv(sock);
		if (nvlin == NULL) {
			if (errno == ENOTCONN) {
				/* Casperd exited. */
				exit(0);
			}
			continue;
		}
		func = (zygote_func_t *)(uintptr_t)nvlist_get_number(nvlin,
		    "func");
		flags = (int)nvlist_get_number(nvlin, "flags");
		nvlist_destroy(nvlin);

		/*
		 * Someone is requesting a new process, create one.
		 */
		procfd = -1;
		chanfd[0] = -1;
		chanfd[1] = -1;
		error = 0;
		if (socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0,
		    chanfd) == -1) {
			error = errno;
			goto send;
		}
		pid = pdfork(&procfd, 0);
		switch (pid) {
		case -1:
			/* Failure. */
			error = errno;
			break;
		case 0:
			/* Child. */
			close(sock);
			close(chanfd[0]);
			func(chanfd[1]);
			/* NOTREACHED */
			exit(1);
		default:
			/* Parent. */
			close(chanfd[1]);
			break;
		}
send:
		nvlout = nvlist_create(0);
		if (error != 0) {
			nvlist_add_number(nvlout, "error", (uint64_t)error);
			if (chanfd[0] >= 0)
				close(chanfd[0]);
			if (procfd >= 0)
				close(procfd);
		} else {
			nvlist_move_descriptor(nvlout, "chanfd", chanfd[0]);
			nvlist_move_descriptor(nvlout, "procfd", procfd);
		}
		(void)nvlist_send(sock, nvlout);
		nvlist_destroy(nvlout);
	}
	/* NOTREACHED */
}
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);
}
Example #20
0
int
main(int argc, char *argv[])
{
    int fd[2];
    socketpair(PF_UNIX, SOCK_STREAM, 0, fd);

    int kq = kqueue();
    struct kevent ke;
    memset(&ke, 0, sizeof(ke));
    EV_SET(&ke, fd[0], EVFILT_READ, EV_ADD, 0, 0, NULL);
    kevent(kq, &ke, 1, NULL, 0, NULL);
    memset(&ke, 0, sizeof(ke));
    EV_SET(&ke, fd[1], EVFILT_READ, EV_ADD, 0, 0, NULL);
    kevent(kq, &ke, 1, NULL, 0, NULL);

    signal(SIGWINCH, resize);

    nvlist_t *nvl = NULL;

    for (;;) {
        if (res) {
            struct winsize size;
            ioctl(1, TIOCGWINSZ, &size);

            nvl = nvlist_create(0);
            nvlist_add_string(nvl, "type", "resize");
            nvlist_add_number(nvl, "rows", size.ws_row);
            nvlist_add_number(nvl, "cols", size.ws_col);
            if (nvlist_send(fd[0], nvl) < 0)
                err(1, "nvlist_send()");
            nvlist_destroy(nvl);

            res = 0;
        }

        memset(&ke, 0, sizeof(ke));
        int i = kevent(kq, NULL, 0, &ke, 1, NULL);
        if (i == -1) {
            if (errno == EINTR)
                continue;
            err(1, "kevent()");
        } else if (i == 0)
            continue;

        if (ke.ident == fd[0]) {
            nvl = nvlist_recv(fd[0]);
            if (nvl == NULL)
                err(1, "nvlist_recv()");
            const char *type = nvlist_get_string(nvl, "type");
            if (strcmp(type, "ack") == 0) {
                int ok = nvlist_get_bool(nvl, "ok");
                printf("received ack, ok?: %s\n", ok ? "true" : "false");
            }
            nvlist_destroy(nvl);
        } else if (ke.ident == fd[1]) {
            nvl = nvlist_recv(fd[1]);
            if (nvl == NULL)
                err(1, "nvlist_recv()");
            const char *type = nvlist_get_string(nvl, "type");
            if (strcmp(type, "resize") == 0) {
                int rows = nvlist_get_number(nvl, "rows");
                int cows = nvlist_get_number(nvl, "cols");
                printf("got resize signal. new size: %d %d\n", rows, cows);
            }
            nvlist_destroy(nvl);
            nvl = nvlist_create(0);
            nvlist_add_string(nvl, "type", "ack");
            nvlist_add_bool(nvl, "ok", 1);
            if (nvlist_send(fd[1], nvl) < 0)
                err(1, "nvlist_send()");
            nvlist_destroy(nvl);
        }
    }
}
int
main(void)
{
	nvlist_t *nvl;

	printf("1..232\n");

	nvl = nvlist_create(0);

	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/null"));
	nvlist_add_null(nvl, "nvlist/null");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/null"));
	CHECK(nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/null"));

	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/bool"));
	nvlist_add_bool(nvl, "nvlist/bool", true);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/bool"));
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/bool"));

	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/number"));
	nvlist_add_number(nvl, "nvlist/number", 0);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/number"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/number"));

	CHECK(!nvlist_exists(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/string"));
	nvlist_add_string(nvl, "nvlist/string", "test");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/string"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/string"));

	CHECK(!nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/nvlist"));
	nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/nvlist"));

	CHECK(!nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/descriptor"));
	nvlist_add_descriptor(nvl, "nvlist/descriptor", STDERR_FILENO);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/descriptor"));

	CHECK(!nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary"));
	nvlist_add_binary(nvl, "nvlist/binary", "test", 4);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/binary"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	CHECK(nvlist_exists(nvl, "nvlist/null"));
	CHECK(nvlist_exists(nvl, "nvlist/bool"));
	CHECK(nvlist_exists(nvl, "nvlist/number"));
	CHECK(nvlist_exists(nvl, "nvlist/string"));
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_null(nvl, "nvlist/null");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(nvlist_exists(nvl, "nvlist/bool"));
	CHECK(nvlist_exists(nvl, "nvlist/number"));
	CHECK(nvlist_exists(nvl, "nvlist/string"));
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_bool(nvl, "nvlist/bool");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(nvlist_exists(nvl, "nvlist/number"));
	CHECK(nvlist_exists(nvl, "nvlist/string"));
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_number(nvl, "nvlist/number");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(nvlist_exists(nvl, "nvlist/string"));
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_string(nvl, "nvlist/string");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists(nvl, "nvlist/string"));
	CHECK(nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_nvlist(nvl, "nvlist/nvlist");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists(nvl, "nvlist/string"));
	CHECK(!nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_descriptor(nvl, "nvlist/descriptor");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists(nvl, "nvlist/string"));
	CHECK(!nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(nvlist_exists_binary(nvl, "nvlist/binary"));

	nvlist_free_binary(nvl, "nvlist/binary");
	CHECK(!nvlist_exists(nvl, "nvlist/null"));
	CHECK(!nvlist_exists(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists(nvl, "nvlist/number"));
	CHECK(!nvlist_exists(nvl, "nvlist/string"));
	CHECK(!nvlist_exists(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists(nvl, "nvlist/binary"));
	CHECK(!nvlist_exists_null(nvl, "nvlist/null"));
	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool"));
	CHECK(!nvlist_exists_number(nvl, "nvlist/number"));
	CHECK(!nvlist_exists_string(nvl, "nvlist/string"));
	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor"));
	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary"));

	CHECK(nvlist_empty(nvl));

	nvlist_destroy(nvl);

	return (0);
}
Example #22
0
int
main(void)
{
	const nvlist_t *cnvl;
	nvlist_t *nvl;
	size_t size;

	printf("1..83\n");

	nvl = nvlist_create(0);

	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/true"));
	nvlist_add_bool(nvl, "nvlist/bool/true", true);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_get_bool(nvl, "nvlist/bool/true") == true);

	CHECK(!nvlist_exists_bool(nvl, "nvlist/bool/false"));
	nvlist_add_bool(nvl, "nvlist/bool/false", false);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_get_bool(nvl, "nvlist/bool/false") == false);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/0"));
	nvlist_add_number(nvl, "nvlist/number/0", 0);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_get_number(nvl, "nvlist/number/0") == 0);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/1"));
	nvlist_add_number(nvl, "nvlist/number/1", 1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_get_number(nvl, "nvlist/number/1") == 1);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/-1"));
	nvlist_add_number(nvl, "nvlist/number/-1", -1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK((int)nvlist_get_number(nvl, "nvlist/number/-1") == -1);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/UINT64_MAX"));
	nvlist_add_number(nvl, "nvlist/number/UINT64_MAX", UINT64_MAX);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(nvlist_get_number(nvl, "nvlist/number/UINT64_MAX") == UINT64_MAX);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MIN"));
	nvlist_add_number(nvl, "nvlist/number/INT64_MIN", INT64_MIN);
	CHECK(nvlist_error(nvl) == 0);
	CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MIN") == INT64_MIN);

	CHECK(!nvlist_exists_number(nvl, "nvlist/number/INT64_MAX"));
	nvlist_add_number(nvl, "nvlist/number/INT64_MAX", INT64_MAX);
	CHECK(nvlist_error(nvl) == 0);
	CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MAX") == INT64_MAX);

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/"));
	nvlist_add_string(nvl, "nvlist/string/", "");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/"), "") == 0);

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/x"));
	nvlist_add_string(nvl, "nvlist/string/x", "x");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/x"), "x") == 0);

	CHECK(!nvlist_exists_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"));
	nvlist_add_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz");
	CHECK(nvlist_error(nvl) == 0);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0);

	CHECK(!nvlist_exists_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO"));
	nvlist_add_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO", STDERR_FILENO);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(fd_is_valid(nvlist_get_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO")));

	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/x"));
	nvlist_add_binary(nvl, "nvlist/binary/x", "x", 1);
	CHECK(nvlist_error(nvl) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", NULL), "x", 1) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", &size), "x", 1) == 0);
	CHECK(size == 1);

	CHECK(!nvlist_exists_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz"));
	nvlist_add_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz"));
	CHECK(nvlist_error(nvl) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));

	CHECK(!nvlist_exists_nvlist(nvl, "nvlist/nvlist"));
	nvlist_add_nvlist(nvl, "nvlist/nvlist", nvl);
	CHECK(nvlist_error(nvl) == 0);
	cnvl = nvlist_get_nvlist(nvl, "nvlist/nvlist");
	CHECK(nvlist_get_bool(cnvl, "nvlist/bool/true") == true);
	CHECK(nvlist_get_bool(cnvl, "nvlist/bool/false") == false);
	CHECK(nvlist_get_number(cnvl, "nvlist/number/0") == 0);
	CHECK(nvlist_get_number(cnvl, "nvlist/number/1") == 1);
	CHECK((int)nvlist_get_number(cnvl, "nvlist/number/-1") == -1);
	CHECK(nvlist_get_number(cnvl, "nvlist/number/UINT64_MAX") == UINT64_MAX);
	CHECK((int64_t)nvlist_get_number(cnvl, "nvlist/number/INT64_MIN") == INT64_MIN);
	CHECK((int64_t)nvlist_get_number(cnvl, "nvlist/number/INT64_MAX") == INT64_MAX);
	CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/"), "") == 0);
	CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/x"), "x") == 0);
	CHECK(strcmp(nvlist_get_string(cnvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0);
	/* TODO */
	CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/x", NULL), "x", 1) == 0);
	CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/x", &size), "x", 1) == 0);
	CHECK(size == 1);
	CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(memcmp(nvlist_get_binary(cnvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));

	CHECK(nvlist_get_bool(nvl, "nvlist/bool/true") == true);
	CHECK(nvlist_get_bool(nvl, "nvlist/bool/false") == false);
	CHECK(nvlist_get_number(nvl, "nvlist/number/0") == 0);
	CHECK(nvlist_get_number(nvl, "nvlist/number/1") == 1);
	CHECK((int)nvlist_get_number(nvl, "nvlist/number/-1") == -1);
	CHECK(nvlist_get_number(nvl, "nvlist/number/UINT64_MAX") == UINT64_MAX);
	CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MIN") == INT64_MIN);
	CHECK((int64_t)nvlist_get_number(nvl, "nvlist/number/INT64_MAX") == INT64_MAX);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/"), "") == 0);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/x"), "x") == 0);
	CHECK(strcmp(nvlist_get_string(nvl, "nvlist/string/abcdefghijklmnopqrstuvwxyz"), "abcdefghijklmnopqrstuvwxyz") == 0);
	CHECK(fd_is_valid(nvlist_get_descriptor(nvl, "nvlist/descriptor/STDERR_FILENO")));
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", NULL), "x", 1) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/x", &size), "x", 1) == 0);
	CHECK(size == 1);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", NULL), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(memcmp(nvlist_get_binary(nvl, "nvlist/binary/abcdefghijklmnopqrstuvwxyz", &size), "abcdefghijklmnopqrstuvwxyz", sizeof("abcdefghijklmnopqrstuvwxyz")) == 0);
	CHECK(size == sizeof("abcdefghijklmnopqrstuvwxyz"));

	nvlist_destroy(nvl);

	return (0);
}