Beispiel #1
0
int
main(void)
{
	cap_channel_t *capcas, *cappwd;

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

	capcas = cap_init();
	CHECKX(capcas != NULL);

	cappwd = cap_service_open(capcas, "system.pwd");
	CHECKX(cappwd != NULL);

	cap_close(capcas);

	/* No limits. */

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R | GETPWNAM |
	    GETPWNAM_R | GETPWUID | GETPWUID_R));

	test_cmds(cappwd);

	test_fields(cappwd);

	test_users(cappwd);

	cap_close(cappwd);

	exit(0);
}
Beispiel #2
0
void cap_del(cap_cx *cx)
{
	if(cx)
	{
		cap_close(cx);
		cap_assoc_set(cx->hwnd, NULL);
		DestroyWindow(cx->hwnd);
		free(cx);
	}
}
Beispiel #3
0
void
service_connection_remove(struct service *service,
    struct service_connection *sconn)
{

	PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC);
	PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC);

	TAILQ_REMOVE(&service->s_connections, sconn, sc_next);
	sconn->sc_magic = 0;
	nvlist_destroy(sconn->sc_limits);
	cap_close(sconn->sc_chan);
	free(sconn);
}
Beispiel #4
0
static void
test_cmds(cap_channel_t *origcappwd)
{
	cap_channel_t *cappwd;
	const char *cmds[7], *fields[10], *names[6];
	uid_t uids[5];

	fields[0] = "pw_name";
	fields[1] = "pw_passwd";
	fields[2] = "pw_uid";
	fields[3] = "pw_gid";
	fields[4] = "pw_change";
	fields[5] = "pw_class";
	fields[6] = "pw_gecos";
	fields[7] = "pw_dir";
	fields[8] = "pw_shell";
	fields[9] = "pw_expire";

	names[0] = "root";
	names[1] = "toor";
	names[2] = "daemon";
	names[3] = "operator";
	names[4] = "bin";
	names[5] = "kmem";

	uids[0] = 0;
	uids[1] = 1;
	uids[2] = 2;
	uids[3] = 3;
	uids[4] = 5;

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == 0);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: setpwent
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cap_setpwent(cappwd);

	cmds[0] = "getpwent";
	cmds[1] = "getpwent_r";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "setpwent";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 |
	    GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: setpwent
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cap_setpwent(cappwd);

	cmds[0] = "getpwent";
	cmds[1] = "getpwent_r";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "setpwent";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 | GETPWENT_R0 |
	    GETPWENT_R1 | GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwent
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent_r";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwent";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwent
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent_r";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwent";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT_R2 |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwent_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwent_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwnam, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwent_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwnam";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwent_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT0 | GETPWENT1 |
	    GETPWNAM | GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwnam
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwnam";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam_r,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwnam
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam_r";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwnam";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM_R | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwnam_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwnam_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam,
	 *       getpwuid, getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwnam_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwuid";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwnam_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWUID | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid_r
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwuid
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwuid";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid_r
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwuid
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwuid";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID_R));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid
	 * users:
	 *     names: root, toor, daemon, operator, bin, kmem
	 *     uids:
	 * Disallow:
	 * cmds: getpwuid_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID));

	cap_close(cappwd);

	/*
	 * Allow:
	 * cmds: setpwent, getpwent, getpwent_r, getpwnam, getpwnam_r,
	 *       getpwuid
	 * users:
	 *     names:
	 *     uids: 0, 1, 2, 3, 5
	 * Disallow:
	 * cmds: getpwuid_r
	 * users:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 6) == 0);
	cmds[0] = "setpwent";
	cmds[1] = "getpwent";
	cmds[2] = "getpwent_r";
	cmds[3] = "getpwnam";
	cmds[4] = "getpwnam_r";
	cmds[5] = "getpwuid";
	cmds[6] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 7) == -1 && errno == ENOTCAPABLE);
	cmds[0] = "getpwuid_r";
	CHECK(cap_pwd_limit_cmds(cappwd, cmds, 1) == -1 && errno == ENOTCAPABLE);
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 5) == 0);

	CHECK(runtest_cmds(cappwd) == (GETPWENT | GETPWENT_R |
	    GETPWNAM | GETPWNAM_R | GETPWUID));

	cap_close(cappwd);
}
Beispiel #5
0
static void
test_users(cap_channel_t *origcappwd)
{
	cap_channel_t *cappwd;
	const char *names[6];
	uid_t uids[6];

	/*
	 * Allow:
	 * users:
	 *     names: root, toor, daemon, operator, bin, tty
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "root";
	names[1] = "toor";
	names[2] = "daemon";
	names[3] = "operator";
	names[4] = "bin";
	names[5] = "tty";
	CHECK(cap_pwd_limit_users(cappwd, names, 6, NULL, 0) == 0);
	uids[0] = 0;
	uids[1] = 0;
	uids[2] = 1;
	uids[3] = 2;
	uids[4] = 3;
	uids[5] = 4;

	CHECK(runtest_users(cappwd, names, uids, 6));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names: daemon, operator, bin
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "operator";
	names[2] = "bin";
	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0);
	names[3] = "tty";
	CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "tty";
	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "daemon";
	uids[0] = 1;
	uids[1] = 2;
	uids[2] = 3;

	CHECK(runtest_users(cappwd, names, uids, 3));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names: daemon, bin, tty
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "bin";
	names[2] = "tty";
	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == 0);
	names[3] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 4, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "daemon";
	uids[0] = 1;
	uids[1] = 3;
	uids[2] = 4;

	CHECK(runtest_users(cappwd, names, uids, 3));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names:
	 *     uids: 1, 2, 3
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "operator";
	names[2] = "bin";
	uids[0] = 1;
	uids[1] = 2;
	uids[2] = 3;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0);
	uids[3] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 1;

	CHECK(runtest_users(cappwd, names, uids, 3));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names:
	 *     uids: 1, 3, 4
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "bin";
	names[2] = "tty";
	uids[0] = 1;
	uids[1] = 3;
	uids[2] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == 0);
	uids[3] = 5;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 4) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 5;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 1;

	CHECK(runtest_users(cappwd, names, uids, 3));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names: bin
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "bin";
	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == 0);
	names[1] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "bin";
	uids[0] = 3;

	CHECK(runtest_users(cappwd, names, uids, 1));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names: daemon, tty
	 *     uids:
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "tty";
	CHECK(cap_pwd_limit_users(cappwd, names, 2, NULL, 0) == 0);
	names[2] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 3, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "operator";
	CHECK(cap_pwd_limit_users(cappwd, names, 1, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	names[0] = "daemon";
	uids[0] = 1;
	uids[1] = 4;

	CHECK(runtest_users(cappwd, names, uids, 2));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names:
	 *     uids: 3
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "bin";
	uids[0] = 3;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == 0);
	uids[1] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 3;

	CHECK(runtest_users(cappwd, names, uids, 1));

	cap_close(cappwd);

	/*
	 * Allow:
	 * users:
	 *     names:
	 *     uids: 1, 4
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	names[0] = "daemon";
	names[1] = "tty";
	uids[0] = 1;
	uids[1] = 4;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 2) == 0);
	uids[2] = 3;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 3) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 3;
	CHECK(cap_pwd_limit_users(cappwd, NULL, 0, uids, 1) == -1 &&
	    errno == ENOTCAPABLE);
	uids[0] = 1;

	CHECK(runtest_users(cappwd, names, uids, 2));

	cap_close(cappwd);
}
Beispiel #6
0
static void
test_fields(cap_channel_t *origcappwd)
{
	cap_channel_t *cappwd;
	const char *fields[10];

	/* No limits. */

	CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID |
	    PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL |
	    PW_EXPIRE));

	/*
	 * Allow:
	 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change, pw_class,
	 *         pw_gecos, pw_dir, pw_shell, pw_expire
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_name";
	fields[1] = "pw_passwd";
	fields[2] = "pw_uid";
	fields[3] = "pw_gid";
	fields[4] = "pw_change";
	fields[5] = "pw_class";
	fields[6] = "pw_gecos";
	fields[7] = "pw_dir";
	fields[8] = "pw_shell";
	fields[9] = "pw_expire";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 10) == 0);

	CHECK(runtest_fields(origcappwd, PW_NAME | PW_PASSWD | PW_UID |
	    PW_GID | PW_CHANGE | PW_CLASS | PW_GECOS | PW_DIR | PW_SHELL |
	    PW_EXPIRE));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_name, pw_passwd, pw_uid, pw_gid, pw_change
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_name";
	fields[1] = "pw_passwd";
	fields[2] = "pw_uid";
	fields[3] = "pw_gid";
	fields[4] = "pw_change";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
	fields[5] = "pw_class";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_class";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_NAME | PW_PASSWD | PW_UID |
	    PW_GID | PW_CHANGE));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_class, pw_gecos, pw_dir, pw_shell, pw_expire
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_class";
	fields[1] = "pw_gecos";
	fields[2] = "pw_dir";
	fields[3] = "pw_shell";
	fields[4] = "pw_expire";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
	fields[5] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_CLASS | PW_GECOS | PW_DIR |
	    PW_SHELL | PW_EXPIRE));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_name, pw_uid, pw_change, pw_gecos, pw_shell
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_name";
	fields[1] = "pw_uid";
	fields[2] = "pw_change";
	fields[3] = "pw_gecos";
	fields[4] = "pw_shell";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
	fields[5] = "pw_class";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_class";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_NAME | PW_UID | PW_CHANGE |
	    PW_GECOS | PW_SHELL));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_passwd, pw_gid, pw_class, pw_dir, pw_expire
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_passwd";
	fields[1] = "pw_gid";
	fields[2] = "pw_class";
	fields[3] = "pw_dir";
	fields[4] = "pw_expire";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 5) == 0);
	fields[5] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 6) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_PASSWD | PW_GID | PW_CLASS |
	    PW_DIR | PW_EXPIRE));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_uid, pw_class, pw_shell
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_uid";
	fields[1] = "pw_class";
	fields[2] = "pw_shell";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 3) == 0);
	fields[3] = "pw_change";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 4) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_change";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_UID | PW_CLASS | PW_SHELL));

	cap_close(cappwd);

	/*
	 * Allow:
	 * fields: pw_change
	 */
	cappwd = cap_clone(origcappwd);
	CHECK(cappwd != NULL);

	fields[0] = "pw_change";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == 0);
	fields[1] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 2) == -1 &&
	    errno == ENOTCAPABLE);
	fields[0] = "pw_uid";
	CHECK(cap_pwd_limit_fields(cappwd, fields, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest_fields(cappwd, PW_CHANGE));

	cap_close(cappwd);
}
Beispiel #7
0
int
main(void)
{
	cap_channel_t *capcas, *capdns, *origcapdns;
	const char *types[2];
	int families[2];

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

	capcas = cap_init();
	CHECKX(capcas != NULL);

	origcapdns = capdns = cap_service_open(capcas, "system.dns");
	CHECKX(capdns != NULL);

	cap_close(capcas);

	/* No limits set. */

	CHECK(runtest(capdns) ==
	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));

	/*
	 * Allow:
	 * type: NAME, ADDR
	 * family: AF_INET, AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);

	CHECK(runtest(capdns) ==
	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));

	cap_close(capdns);

	/*
	 * Allow:
	 * type: NAME
	 * family: AF_INET, AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);

	CHECK(runtest(capdns) ==
	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6));

	cap_close(capdns);

	/*
	 * Allow:
	 * type: ADDR
	 * family: AF_INET, AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);

	CHECK(runtest(capdns) ==
	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6));

	cap_close(capdns);

	/*
	 * Allow:
	 * type: NAME, ADDR
	 * family: AF_INET
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) ==
	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET));

	cap_close(capdns);

	/*
	 * Allow:
	 * type: NAME, ADDR
	 * family: AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) ==
	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6));

	cap_close(capdns);

	/* Below we also test further limiting capability. */

	/*
	 * Allow:
	 * type: NAME
	 * family: AF_INET
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));

	cap_close(capdns);

	/*
	 * Allow:
	 * type: NAME
	 * family: AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) == GETHOSTBYNAME2_AF_INET6);

	cap_close(capdns);

	/*
	 * Allow:
	 * type: ADDR
	 * family: AF_INET
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET);

	cap_close(capdns);

	/*
	 * Allow:
	 * type: ADDR
	 * family: AF_INET6
	 */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	types[1] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
	families[1] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);

	cap_close(capdns);

	/* Trying to rise the limits. */

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);

	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);

	/* Do the limits still hold? */
	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));

	cap_close(capdns);

	capdns = cap_clone(origcapdns);
	CHECK(capdns != NULL);

	types[0] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
	families[0] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);

	types[0] = "NAME";
	types[1] = "ADDR";
	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	families[1] = AF_INET6;
	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
	    errno == ENOTCAPABLE);

	types[0] = "NAME";
	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
	    errno == ENOTCAPABLE);
	families[0] = AF_INET;
	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
	    errno == ENOTCAPABLE);

	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);
	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
	    errno == ENOTCAPABLE);

	/* Do the limits still hold? */
	CHECK(runtest(capdns) == GETHOSTBYADDR_AF_INET6);

	cap_close(capdns);

	cap_close(origcapdns);

	exit(0);
}