xref: /freebsd/lib/libcasper/services/cap_dns/tests/dns_test.c (revision 8657387683946d0c03e09fe77029edfe309eeb20)
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Pawel Jakub Dawidek under sponsorship from
6  * the FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 #include <sys/capsicum.h>
34 
35 #include <arpa/inet.h>
36 #include <netinet/in.h>
37 
38 #include <assert.h>
39 #include <err.h>
40 #include <errno.h>
41 #include <netdb.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <unistd.h>
46 
47 #include <libcasper.h>
48 
49 #include <casper/cap_dns.h>
50 
51 static int ntest = 1;
52 
53 #define CHECK(expr)     do {						\
54 	if ((expr))							\
55 		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
56 	else								\
57 		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
58 	fflush(stdout);							\
59 	ntest++;							\
60 } while (0)
61 #define CHECKX(expr)     do {						\
62 	if ((expr)) {							\
63 		printf("ok %d # %s:%u\n", ntest, __FILE__, __LINE__);	\
64 	} else {							\
65 		printf("not ok %d # %s:%u\n", ntest, __FILE__, __LINE__); \
66 		exit(1);						\
67 	}								\
68 	fflush(stdout);							\
69 	ntest++;							\
70 } while (0)
71 
72 #define	GETHOSTBYNAME			0x01
73 #define	GETHOSTBYNAME2_AF_INET		0x02
74 #define	GETHOSTBYNAME2_AF_INET6		0x04
75 #define	GETHOSTBYADDR_AF_INET		0x08
76 #define	GETHOSTBYADDR_AF_INET6		0x10
77 #define	GETADDRINFO_AF_UNSPEC		0x20
78 #define	GETADDRINFO_AF_INET		0x40
79 #define	GETADDRINFO_AF_INET6		0x80
80 
81 static bool
82 addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1)
83 {
84 	struct addrinfo *at0, *at1;
85 
86 	if (ai0 == NULL && ai1 == NULL)
87 		return (true);
88 	if (ai0 == NULL || ai1 == NULL)
89 		return (false);
90 
91 	at0 = ai0;
92 	at1 = ai1;
93 	while (true) {
94 		if ((at0->ai_flags == at1->ai_flags) &&
95 		    (at0->ai_family == at1->ai_family) &&
96 		    (at0->ai_socktype == at1->ai_socktype) &&
97 		    (at0->ai_protocol == at1->ai_protocol) &&
98 		    (at0->ai_addrlen == at1->ai_addrlen) &&
99 		    (memcmp(at0->ai_addr, at1->ai_addr,
100 			at0->ai_addrlen) == 0)) {
101 			if (at0->ai_canonname != NULL &&
102 			    at1->ai_canonname != NULL) {
103 				if (strcmp(at0->ai_canonname,
104 				    at1->ai_canonname) != 0) {
105 					return (false);
106 				}
107 			}
108 
109 			if (at0->ai_canonname == NULL &&
110 			    at1->ai_canonname != NULL) {
111 				return (false);
112 			}
113 			if (at0->ai_canonname != NULL &&
114 			    at1->ai_canonname == NULL) {
115 				return (false);
116 			}
117 
118 			if (at0->ai_next == NULL && at1->ai_next == NULL)
119 				return (true);
120 			if (at0->ai_next == NULL || at1->ai_next == NULL)
121 				return (false);
122 
123 			at0 = at0->ai_next;
124 			at1 = at1->ai_next;
125 		} else {
126 			return (false);
127 		}
128 	}
129 
130 	/* NOTREACHED */
131 	fprintf(stderr, "Dead code reached in addrinfo_compare()\n");
132 	exit(1);
133 }
134 
135 static bool
136 hostent_aliases_compare(char **aliases0, char **aliases1)
137 {
138 	int i0, i1;
139 
140 	if (aliases0 == NULL && aliases1 == NULL)
141 		return (true);
142 	if (aliases0 == NULL || aliases1 == NULL)
143 		return (false);
144 
145 	for (i0 = 0; aliases0[i0] != NULL; i0++) {
146 		for (i1 = 0; aliases1[i1] != NULL; i1++) {
147 			if (strcmp(aliases0[i0], aliases1[i1]) == 0)
148 				break;
149 		}
150 		if (aliases1[i1] == NULL)
151 			return (false);
152 	}
153 
154 	return (true);
155 }
156 
157 static bool
158 hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length)
159 {
160 	int i0, i1;
161 
162 	if (addr_list0 == NULL && addr_list1 == NULL)
163 		return (true);
164 	if (addr_list0 == NULL || addr_list1 == NULL)
165 		return (false);
166 
167 	for (i0 = 0; addr_list0[i0] != NULL; i0++) {
168 		for (i1 = 0; addr_list1[i1] != NULL; i1++) {
169 			if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0)
170 				break;
171 		}
172 		if (addr_list1[i1] == NULL)
173 			return (false);
174 	}
175 
176 	return (true);
177 }
178 
179 static bool
180 hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
181 {
182 
183 	if (hp0 == NULL && hp1 != NULL)
184 		return (true);
185 
186 	if (hp0 == NULL || hp1 == NULL)
187 		return (false);
188 
189 	if (hp0->h_name != NULL || hp1->h_name != NULL) {
190 		if (hp0->h_name == NULL || hp1->h_name == NULL)
191 			return (false);
192 		if (strcmp(hp0->h_name, hp1->h_name) != 0)
193 			return (false);
194 	}
195 
196 	if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases))
197 		return (false);
198 	if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases))
199 		return (false);
200 
201 	if (hp0->h_addrtype != hp1->h_addrtype)
202 		return (false);
203 
204 	if (hp0->h_length != hp1->h_length)
205 		return (false);
206 
207 	if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list,
208 	    hp0->h_length)) {
209 		return (false);
210 	}
211 	if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list,
212 	    hp0->h_length)) {
213 		return (false);
214 	}
215 
216 	return (true);
217 }
218 
219 static unsigned int
220 runtest(cap_channel_t *capdns)
221 {
222 	unsigned int result;
223 	struct addrinfo *ais, *aic, hints, *hintsp;
224 	struct hostent *hps, *hpc;
225 	struct in_addr ip4;
226 	struct in6_addr ip6;
227 
228 	result = 0;
229 
230 	hps = gethostbyname("example.com");
231 	if (hps == NULL)
232 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
233 	hpc = cap_gethostbyname(capdns, "example.com");
234 	if (hostent_compare(hps, hpc))
235 		result |= GETHOSTBYNAME;
236 
237 	hps = gethostbyname2("example.com", AF_INET);
238 	if (hps == NULL)
239 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
240 	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
241 	if (hostent_compare(hps, hpc))
242 		result |= GETHOSTBYNAME2_AF_INET;
243 
244 	hps = gethostbyname2("example.com", AF_INET6);
245 	if (hps == NULL)
246 		fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
247 	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
248 	if (hostent_compare(hps, hpc))
249 		result |= GETHOSTBYNAME2_AF_INET6;
250 
251 	hints.ai_flags = 0;
252 	hints.ai_family = AF_UNSPEC;
253 	hints.ai_socktype = 0;
254 	hints.ai_protocol = 0;
255 	hints.ai_addrlen = 0;
256 	hints.ai_addr = NULL;
257 	hints.ai_canonname = NULL;
258 	hints.ai_next = NULL;
259 
260 	hintsp = &hints;
261 
262 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
263 		fprintf(stderr,
264 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
265 		    gai_strerror(errno));
266 	}
267 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
268 		if (addrinfo_compare(ais, aic))
269 			result |= GETADDRINFO_AF_UNSPEC;
270 		freeaddrinfo(ais);
271 		freeaddrinfo(aic);
272 	}
273 
274 	hints.ai_family = AF_INET;
275 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
276 		fprintf(stderr,
277 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
278 		    gai_strerror(errno));
279 	}
280 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
281 		if (addrinfo_compare(ais, aic))
282 			result |= GETADDRINFO_AF_INET;
283 		freeaddrinfo(ais);
284 		freeaddrinfo(aic);
285 	}
286 
287 	hints.ai_family = AF_INET6;
288 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
289 		fprintf(stderr,
290 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
291 		    gai_strerror(errno));
292 	}
293 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
294 		if (addrinfo_compare(ais, aic))
295 			result |= GETADDRINFO_AF_INET6;
296 		freeaddrinfo(ais);
297 		freeaddrinfo(aic);
298 	}
299 
300 	/* XXX: hardcoded addresses for "google-public-dns-a.google.com". */
301 #define	GOOGLE_DNS_IPV4	"8.8.8.8"
302 #define	GOOGLE_DNS_IPV6	"2001:4860:4860::8888"
303 
304 	inet_pton(AF_INET, GOOGLE_DNS_IPV4, &ip4);
305 	hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
306 	if (hps == NULL)
307 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV4);
308 	hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
309 	if (hostent_compare(hps, hpc))
310 		result |= GETHOSTBYADDR_AF_INET;
311 
312 	inet_pton(AF_INET6, GOOGLE_DNS_IPV6, &ip6);
313 	hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
314 	if (hps == NULL) {
315 		fprintf(stderr, "Unable to resolve %s.\n", GOOGLE_DNS_IPV6);
316 	}
317 	hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
318 	if (hostent_compare(hps, hpc))
319 		result |= GETHOSTBYADDR_AF_INET6;
320 	return (result);
321 }
322 
323 int
324 main(void)
325 {
326 	cap_channel_t *capcas, *capdns, *origcapdns;
327 	const char *types[2];
328 	int families[2];
329 
330 	printf("1..91\n");
331 	fflush(stdout);
332 
333 	capcas = cap_init();
334 	CHECKX(capcas != NULL);
335 
336 	origcapdns = capdns = cap_service_open(capcas, "system.dns");
337 	CHECKX(capdns != NULL);
338 
339 	cap_close(capcas);
340 
341 	/* No limits set. */
342 
343 	CHECK(runtest(capdns) ==
344 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
345 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
346 	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
347 
348 	/*
349 	 * Allow:
350 	 * type: NAME, ADDR
351 	 * family: AF_INET, AF_INET6
352 	 */
353 
354 	capdns = cap_clone(origcapdns);
355 	CHECK(capdns != NULL);
356 
357 	types[0] = "NAME";
358 	types[1] = "ADDR";
359 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
360 	families[0] = AF_INET;
361 	families[1] = AF_INET6;
362 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
363 
364 	CHECK(runtest(capdns) ==
365 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
366 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
367 	     GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
368 
369 	cap_close(capdns);
370 
371 	/*
372 	 * Allow:
373 	 * type: NAME
374 	 * family: AF_INET, AF_INET6
375 	 */
376 
377 	capdns = cap_clone(origcapdns);
378 	CHECK(capdns != NULL);
379 
380 	types[0] = "NAME";
381 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
382 	types[1] = "ADDR";
383 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
384 	    errno == ENOTCAPABLE);
385 	types[0] = "ADDR";
386 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
387 	    errno == ENOTCAPABLE);
388 	families[0] = AF_INET;
389 	families[1] = AF_INET6;
390 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
391 
392 	CHECK(runtest(capdns) ==
393 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6));
394 
395 	cap_close(capdns);
396 
397 	/*
398 	 * Allow:
399 	 * type: ADDR
400 	 * family: AF_INET, AF_INET6
401 	 */
402 
403 	capdns = cap_clone(origcapdns);
404 	CHECK(capdns != NULL);
405 
406 	types[0] = "ADDR";
407 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
408 	types[1] = "NAME";
409 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
410 	    errno == ENOTCAPABLE);
411 	types[0] = "NAME";
412 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
413 	    errno == ENOTCAPABLE);
414 	families[0] = AF_INET;
415 	families[1] = AF_INET6;
416 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
417 
418 	CHECK(runtest(capdns) ==
419 	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
420 	    GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
421 
422 	cap_close(capdns);
423 
424 	/*
425 	 * Allow:
426 	 * type: NAME, ADDR
427 	 * family: AF_INET
428 	 */
429 
430 	capdns = cap_clone(origcapdns);
431 	CHECK(capdns != NULL);
432 
433 	types[0] = "NAME";
434 	types[1] = "ADDR";
435 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
436 	families[0] = AF_INET;
437 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
438 	families[1] = AF_INET6;
439 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
440 	    errno == ENOTCAPABLE);
441 	families[0] = AF_INET6;
442 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
443 	    errno == ENOTCAPABLE);
444 
445 	CHECK(runtest(capdns) ==
446 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET |
447 	    GETADDRINFO_AF_INET));
448 
449 	cap_close(capdns);
450 
451 	/*
452 	 * Allow:
453 	 * type: NAME, ADDR
454 	 * family: AF_INET6
455 	 */
456 
457 	capdns = cap_clone(origcapdns);
458 	CHECK(capdns != NULL);
459 
460 	types[0] = "NAME";
461 	types[1] = "ADDR";
462 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
463 	families[0] = AF_INET6;
464 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
465 	families[1] = AF_INET;
466 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
467 	    errno == ENOTCAPABLE);
468 	families[0] = AF_INET;
469 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
470 	    errno == ENOTCAPABLE);
471 
472 	CHECK(runtest(capdns) ==
473 	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 |
474 	    GETADDRINFO_AF_INET6));
475 
476 	cap_close(capdns);
477 
478 	/* Below we also test further limiting capability. */
479 
480 	/*
481 	 * Allow:
482 	 * type: NAME
483 	 * family: AF_INET
484 	 */
485 
486 	capdns = cap_clone(origcapdns);
487 	CHECK(capdns != NULL);
488 
489 	types[0] = "NAME";
490 	types[1] = "ADDR";
491 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
492 	families[0] = AF_INET;
493 	families[1] = AF_INET6;
494 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
495 	types[0] = "NAME";
496 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
497 	types[1] = "ADDR";
498 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
499 	    errno == ENOTCAPABLE);
500 	types[0] = "ADDR";
501 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
502 	    errno == ENOTCAPABLE);
503 	families[0] = AF_INET;
504 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
505 	families[1] = AF_INET6;
506 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
507 	    errno == ENOTCAPABLE);
508 	families[0] = AF_INET6;
509 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
510 	    errno == ENOTCAPABLE);
511 
512 	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
513 
514 	cap_close(capdns);
515 
516 	/*
517 	 * Allow:
518 	 * type: NAME
519 	 * family: AF_INET6
520 	 */
521 
522 	capdns = cap_clone(origcapdns);
523 	CHECK(capdns != NULL);
524 
525 	types[0] = "NAME";
526 	types[1] = "ADDR";
527 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
528 	families[0] = AF_INET;
529 	families[1] = AF_INET6;
530 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
531 	types[0] = "NAME";
532 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
533 	types[1] = "ADDR";
534 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
535 	    errno == ENOTCAPABLE);
536 	types[0] = "ADDR";
537 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
538 	    errno == ENOTCAPABLE);
539 	families[0] = AF_INET6;
540 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
541 	families[1] = AF_INET;
542 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
543 	    errno == ENOTCAPABLE);
544 	families[0] = AF_INET;
545 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
546 	    errno == ENOTCAPABLE);
547 
548 	CHECK(runtest(capdns) == GETHOSTBYNAME2_AF_INET6);
549 
550 	cap_close(capdns);
551 
552 	/*
553 	 * Allow:
554 	 * type: ADDR
555 	 * family: AF_INET
556 	 */
557 
558 	capdns = cap_clone(origcapdns);
559 	CHECK(capdns != NULL);
560 
561 	types[0] = "NAME";
562 	types[1] = "ADDR";
563 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
564 	families[0] = AF_INET;
565 	families[1] = AF_INET6;
566 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
567 	types[0] = "ADDR";
568 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
569 	types[1] = "NAME";
570 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
571 	    errno == ENOTCAPABLE);
572 	types[0] = "NAME";
573 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
574 	    errno == ENOTCAPABLE);
575 	families[0] = AF_INET;
576 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
577 	families[1] = AF_INET6;
578 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
579 	    errno == ENOTCAPABLE);
580 	families[0] = AF_INET6;
581 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
582 	    errno == ENOTCAPABLE);
583 
584 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET | GETADDRINFO_AF_INET));
585 
586 	cap_close(capdns);
587 
588 	/*
589 	 * Allow:
590 	 * type: ADDR
591 	 * family: AF_INET6
592 	 */
593 
594 	capdns = cap_clone(origcapdns);
595 	CHECK(capdns != NULL);
596 
597 	types[0] = "NAME";
598 	types[1] = "ADDR";
599 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
600 	families[0] = AF_INET;
601 	families[1] = AF_INET6;
602 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
603 	types[0] = "ADDR";
604 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
605 	types[1] = "NAME";
606 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
607 	    errno == ENOTCAPABLE);
608 	types[0] = "NAME";
609 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
610 	    errno == ENOTCAPABLE);
611 	families[0] = AF_INET6;
612 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
613 	families[1] = AF_INET;
614 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
615 	    errno == ENOTCAPABLE);
616 	families[0] = AF_INET;
617 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
618 	    errno == ENOTCAPABLE);
619 
620 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 |
621 	    GETADDRINFO_AF_INET6));
622 
623 	cap_close(capdns);
624 
625 	/* Trying to rise the limits. */
626 
627 	capdns = cap_clone(origcapdns);
628 	CHECK(capdns != NULL);
629 
630 	types[0] = "NAME";
631 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
632 	families[0] = AF_INET;
633 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
634 
635 	types[0] = "NAME";
636 	types[1] = "ADDR";
637 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
638 	    errno == ENOTCAPABLE);
639 	families[0] = AF_INET;
640 	families[1] = AF_INET6;
641 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
642 	    errno == ENOTCAPABLE);
643 
644 	types[0] = "ADDR";
645 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
646 	    errno == ENOTCAPABLE);
647 	families[0] = AF_INET6;
648 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
649 	    errno == ENOTCAPABLE);
650 
651 	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
652 	    errno == ENOTCAPABLE);
653 	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
654 	    errno == ENOTCAPABLE);
655 
656 	/* Do the limits still hold? */
657 	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
658 
659 	cap_close(capdns);
660 
661 	capdns = cap_clone(origcapdns);
662 	CHECK(capdns != NULL);
663 
664 	types[0] = "ADDR";
665 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
666 	families[0] = AF_INET6;
667 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
668 
669 	types[0] = "NAME";
670 	types[1] = "ADDR";
671 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
672 	    errno == ENOTCAPABLE);
673 	families[0] = AF_INET;
674 	families[1] = AF_INET6;
675 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
676 	    errno == ENOTCAPABLE);
677 
678 	types[0] = "NAME";
679 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
680 	    errno == ENOTCAPABLE);
681 	families[0] = AF_INET;
682 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
683 	    errno == ENOTCAPABLE);
684 
685 	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
686 	    errno == ENOTCAPABLE);
687 	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
688 	    errno == ENOTCAPABLE);
689 
690 	/* Do the limits still hold? */
691 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 |
692 	    GETADDRINFO_AF_INET6));
693 
694 	cap_close(capdns);
695 
696 	cap_close(origcapdns);
697 
698 	exit(0);
699 }
700