xref: /freebsd/lib/libcasper/services/cap_dns/tests/dns_test.c (revision 63d1fd5970ec814904aa0f4580b10a0d302d08b2)
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 	ntest++;							\
59 } while (0)
60 #define CHECKX(expr)     do {						\
61 	if ((expr)) {							\
62 		printf("ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
63 	} else {							\
64 		printf("not ok %d %s:%u\n", ntest, __FILE__, __LINE__);	\
65 		exit(1);						\
66 	}								\
67 	ntest++;							\
68 } while (0)
69 
70 #define	GETHOSTBYNAME			0x01
71 #define	GETHOSTBYNAME2_AF_INET		0x02
72 #define	GETHOSTBYNAME2_AF_INET6		0x04
73 #define	GETHOSTBYADDR_AF_INET		0x08
74 #define	GETHOSTBYADDR_AF_INET6		0x10
75 #define	GETADDRINFO_AF_UNSPEC		0x20
76 #define	GETADDRINFO_AF_INET		0x40
77 #define	GETADDRINFO_AF_INET6		0x80
78 
79 static bool
80 addrinfo_compare(struct addrinfo *ai0, struct addrinfo *ai1)
81 {
82 	struct addrinfo *at0, *at1;
83 
84 	if (ai0 == NULL && ai1 == NULL)
85 		return (true);
86 	if (ai0 == NULL || ai1 == NULL)
87 		return (false);
88 
89 	at0 = ai0;
90 	at1 = ai1;
91 	while (true) {
92 		if ((at0->ai_flags == at1->ai_flags) &&
93 		    (at0->ai_family == at1->ai_family) &&
94 		    (at0->ai_socktype == at1->ai_socktype) &&
95 		    (at0->ai_protocol == at1->ai_protocol) &&
96 		    (at0->ai_addrlen == at1->ai_addrlen) &&
97 		    (memcmp(at0->ai_addr, at1->ai_addr,
98 			at0->ai_addrlen) == 0)) {
99 			if (at0->ai_canonname != NULL &&
100 			    at1->ai_canonname != NULL) {
101 				if (strcmp(at0->ai_canonname,
102 				    at1->ai_canonname) != 0) {
103 					return (false);
104 				}
105 			}
106 
107 			if (at0->ai_canonname == NULL &&
108 			    at1->ai_canonname != NULL) {
109 				return (false);
110 			}
111 			if (at0->ai_canonname != NULL &&
112 			    at1->ai_canonname == NULL) {
113 				return (false);
114 			}
115 
116 			if (at0->ai_next == NULL && at1->ai_next == NULL)
117 				return (true);
118 			if (at0->ai_next == NULL || at1->ai_next == NULL)
119 				return (false);
120 
121 			at0 = at0->ai_next;
122 			at1 = at1->ai_next;
123 		} else {
124 			return (false);
125 		}
126 	}
127 
128 	/* NOTREACHED */
129 	fprintf(stderr, "Dead code reached in addrinfo_compare()\n");
130 	exit(1);
131 }
132 
133 static bool
134 hostent_aliases_compare(char **aliases0, char **aliases1)
135 {
136 	int i0, i1;
137 
138 	if (aliases0 == NULL && aliases1 == NULL)
139 		return (true);
140 	if (aliases0 == NULL || aliases1 == NULL)
141 		return (false);
142 
143 	for (i0 = 0; aliases0[i0] != NULL; i0++) {
144 		for (i1 = 0; aliases1[i1] != NULL; i1++) {
145 			if (strcmp(aliases0[i0], aliases1[i1]) == 0)
146 				break;
147 		}
148 		if (aliases1[i1] == NULL)
149 			return (false);
150 	}
151 
152 	return (true);
153 }
154 
155 static bool
156 hostent_addr_list_compare(char **addr_list0, char **addr_list1, int length)
157 {
158 	int i0, i1;
159 
160 	if (addr_list0 == NULL && addr_list1 == NULL)
161 		return (true);
162 	if (addr_list0 == NULL || addr_list1 == NULL)
163 		return (false);
164 
165 	for (i0 = 0; addr_list0[i0] != NULL; i0++) {
166 		for (i1 = 0; addr_list1[i1] != NULL; i1++) {
167 			if (memcmp(addr_list0[i0], addr_list1[i1], length) == 0)
168 				break;
169 		}
170 		if (addr_list1[i1] == NULL)
171 			return (false);
172 	}
173 
174 	return (true);
175 }
176 
177 static bool
178 hostent_compare(const struct hostent *hp0, const struct hostent *hp1)
179 {
180 
181 	if (hp0 == NULL && hp1 != NULL)
182 		return (true);
183 
184 	if (hp0 == NULL || hp1 == NULL)
185 		return (false);
186 
187 	if (hp0->h_name != NULL || hp1->h_name != NULL) {
188 		if (hp0->h_name == NULL || hp1->h_name == NULL)
189 			return (false);
190 		if (strcmp(hp0->h_name, hp1->h_name) != 0)
191 			return (false);
192 	}
193 
194 	if (!hostent_aliases_compare(hp0->h_aliases, hp1->h_aliases))
195 		return (false);
196 	if (!hostent_aliases_compare(hp1->h_aliases, hp0->h_aliases))
197 		return (false);
198 
199 	if (hp0->h_addrtype != hp1->h_addrtype)
200 		return (false);
201 
202 	if (hp0->h_length != hp1->h_length)
203 		return (false);
204 
205 	if (!hostent_addr_list_compare(hp0->h_addr_list, hp1->h_addr_list,
206 	    hp0->h_length)) {
207 		return (false);
208 	}
209 	if (!hostent_addr_list_compare(hp1->h_addr_list, hp0->h_addr_list,
210 	    hp0->h_length)) {
211 		return (false);
212 	}
213 
214 	return (true);
215 }
216 
217 static unsigned int
218 runtest(cap_channel_t *capdns)
219 {
220 	unsigned int result;
221 	struct addrinfo *ais, *aic, hints, *hintsp;
222 	struct hostent *hps, *hpc;
223 	struct in_addr ip4;
224 	struct in6_addr ip6;
225 
226 	result = 0;
227 
228 	hps = gethostbyname("example.com");
229 	if (hps == NULL)
230 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
231 	hpc = cap_gethostbyname(capdns, "example.com");
232 	if (hostent_compare(hps, hpc))
233 		result |= GETHOSTBYNAME;
234 
235 	hps = gethostbyname2("example.com", AF_INET);
236 	if (hps == NULL)
237 		fprintf(stderr, "Unable to resolve %s IPv4.\n", "example.com");
238 	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET);
239 	if (hostent_compare(hps, hpc))
240 		result |= GETHOSTBYNAME2_AF_INET;
241 
242 	hps = gethostbyname2("example.com", AF_INET6);
243 	if (hps == NULL)
244 		fprintf(stderr, "Unable to resolve %s IPv6.\n", "example.com");
245 	hpc = cap_gethostbyname2(capdns, "example.com", AF_INET6);
246 	if (hostent_compare(hps, hpc))
247 		result |= GETHOSTBYNAME2_AF_INET6;
248 
249 	hints.ai_flags = 0;
250 	hints.ai_family = AF_UNSPEC;
251 	hints.ai_socktype = 0;
252 	hints.ai_protocol = 0;
253 	hints.ai_addrlen = 0;
254 	hints.ai_addr = NULL;
255 	hints.ai_canonname = NULL;
256 	hints.ai_next = NULL;
257 
258 	hintsp = &hints;
259 
260 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
261 		fprintf(stderr,
262 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
263 		    gai_strerror(errno));
264 	}
265 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
266 		if (addrinfo_compare(ais, aic))
267 			result |= GETADDRINFO_AF_UNSPEC;
268 		freeaddrinfo(ais);
269 		freeaddrinfo(aic);
270 	}
271 
272 	hints.ai_family = AF_INET;
273 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
274 		fprintf(stderr,
275 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
276 		    gai_strerror(errno));
277 	}
278 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
279 		if (addrinfo_compare(ais, aic))
280 			result |= GETADDRINFO_AF_INET;
281 		freeaddrinfo(ais);
282 		freeaddrinfo(aic);
283 	}
284 
285 	hints.ai_family = AF_INET6;
286 	if (getaddrinfo("freebsd.org", "25", hintsp, &ais) != 0) {
287 		fprintf(stderr,
288 		    "Unable to issue [system] getaddrinfo() for AF_UNSPEC: %s\n",
289 		    gai_strerror(errno));
290 	}
291 	if (cap_getaddrinfo(capdns, "freebsd.org", "25", hintsp, &aic) == 0) {
292 		if (addrinfo_compare(ais, aic))
293 			result |= GETADDRINFO_AF_INET6;
294 		freeaddrinfo(ais);
295 		freeaddrinfo(aic);
296 	}
297 
298 	/*
299 	 * 8.8.178.135 is IPv4 address of freefall.freebsd.org
300 	 * as of 27 October 2013.
301 	 */
302 	inet_pton(AF_INET, "8.8.178.135", &ip4);
303 	hps = gethostbyaddr(&ip4, sizeof(ip4), AF_INET);
304 	if (hps == NULL)
305 		fprintf(stderr, "Unable to resolve %s.\n", "8.8.178.135");
306 	hpc = cap_gethostbyaddr(capdns, &ip4, sizeof(ip4), AF_INET);
307 	if (hostent_compare(hps, hpc))
308 		result |= GETHOSTBYADDR_AF_INET;
309 
310 	/*
311 	 * 2001:1900:2254:206c::16:87 is IPv6 address of freefall.freebsd.org
312 	 * as of 27 October 2013.
313 	 */
314 	inet_pton(AF_INET6, "2001:1900:2254:206c::16:87", &ip6);
315 	hps = gethostbyaddr(&ip6, sizeof(ip6), AF_INET6);
316 	if (hps == NULL) {
317 		fprintf(stderr, "Unable to resolve %s.\n",
318 		    "2001:1900:2254:206c::16:87");
319 	}
320 	hpc = cap_gethostbyaddr(capdns, &ip6, sizeof(ip6), AF_INET6);
321 	if (hostent_compare(hps, hpc))
322 		result |= GETHOSTBYADDR_AF_INET6;
323 
324 	return (result);
325 }
326 
327 int
328 main(void)
329 {
330 	cap_channel_t *capcas, *capdns, *origcapdns;
331 	const char *types[2];
332 	int families[2];
333 
334 	printf("1..91\n");
335 
336 	capcas = cap_init();
337 	CHECKX(capcas != NULL);
338 
339 	origcapdns = capdns = cap_service_open(capcas, "system.dns");
340 	CHECKX(capdns != NULL);
341 
342 	cap_close(capcas);
343 
344 	/* No limits set. */
345 
346 	CHECK(runtest(capdns) ==
347 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
348 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
349 	     GETADDRINFO_AF_UNSPEC | GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
350 
351 	/*
352 	 * Allow:
353 	 * type: NAME, ADDR
354 	 * family: AF_INET, AF_INET6
355 	 */
356 
357 	capdns = cap_clone(origcapdns);
358 	CHECK(capdns != NULL);
359 
360 	types[0] = "NAME";
361 	types[1] = "ADDR";
362 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
363 	families[0] = AF_INET;
364 	families[1] = AF_INET6;
365 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
366 
367 	CHECK(runtest(capdns) ==
368 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6 |
369 	     GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
370 	     GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
371 
372 	cap_close(capdns);
373 
374 	/*
375 	 * Allow:
376 	 * type: NAME
377 	 * family: AF_INET, AF_INET6
378 	 */
379 
380 	capdns = cap_clone(origcapdns);
381 	CHECK(capdns != NULL);
382 
383 	types[0] = "NAME";
384 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
385 	types[1] = "ADDR";
386 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
387 	    errno == ENOTCAPABLE);
388 	types[0] = "ADDR";
389 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
390 	    errno == ENOTCAPABLE);
391 	families[0] = AF_INET;
392 	families[1] = AF_INET6;
393 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
394 
395 	CHECK(runtest(capdns) ==
396 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYNAME2_AF_INET6));
397 
398 	cap_close(capdns);
399 
400 	/*
401 	 * Allow:
402 	 * type: ADDR
403 	 * family: AF_INET, AF_INET6
404 	 */
405 
406 	capdns = cap_clone(origcapdns);
407 	CHECK(capdns != NULL);
408 
409 	types[0] = "ADDR";
410 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
411 	types[1] = "NAME";
412 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
413 	    errno == ENOTCAPABLE);
414 	types[0] = "NAME";
415 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
416 	    errno == ENOTCAPABLE);
417 	families[0] = AF_INET;
418 	families[1] = AF_INET6;
419 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
420 
421 	CHECK(runtest(capdns) ==
422 	    (GETHOSTBYADDR_AF_INET | GETHOSTBYADDR_AF_INET6 |
423 	    GETADDRINFO_AF_INET | GETADDRINFO_AF_INET6));
424 
425 	cap_close(capdns);
426 
427 	/*
428 	 * Allow:
429 	 * type: NAME, ADDR
430 	 * family: AF_INET
431 	 */
432 
433 	capdns = cap_clone(origcapdns);
434 	CHECK(capdns != NULL);
435 
436 	types[0] = "NAME";
437 	types[1] = "ADDR";
438 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
439 	families[0] = AF_INET;
440 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
441 	families[1] = AF_INET6;
442 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
443 	    errno == ENOTCAPABLE);
444 	families[0] = AF_INET6;
445 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
446 	    errno == ENOTCAPABLE);
447 
448 	CHECK(runtest(capdns) ==
449 	    (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET | GETHOSTBYADDR_AF_INET |
450 	    GETADDRINFO_AF_INET));
451 
452 	cap_close(capdns);
453 
454 	/*
455 	 * Allow:
456 	 * type: NAME, ADDR
457 	 * family: AF_INET6
458 	 */
459 
460 	capdns = cap_clone(origcapdns);
461 	CHECK(capdns != NULL);
462 
463 	types[0] = "NAME";
464 	types[1] = "ADDR";
465 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
466 	families[0] = AF_INET6;
467 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
468 	families[1] = AF_INET;
469 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
470 	    errno == ENOTCAPABLE);
471 	families[0] = AF_INET;
472 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
473 	    errno == ENOTCAPABLE);
474 
475 	CHECK(runtest(capdns) ==
476 	    (GETHOSTBYNAME2_AF_INET6 | GETHOSTBYADDR_AF_INET6 |
477 	    GETADDRINFO_AF_INET6));
478 
479 	cap_close(capdns);
480 
481 	/* Below we also test further limiting capability. */
482 
483 	/*
484 	 * Allow:
485 	 * type: NAME
486 	 * family: AF_INET
487 	 */
488 
489 	capdns = cap_clone(origcapdns);
490 	CHECK(capdns != NULL);
491 
492 	types[0] = "NAME";
493 	types[1] = "ADDR";
494 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
495 	families[0] = AF_INET;
496 	families[1] = AF_INET6;
497 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
498 	types[0] = "NAME";
499 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
500 	types[1] = "ADDR";
501 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
502 	    errno == ENOTCAPABLE);
503 	types[0] = "ADDR";
504 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
505 	    errno == ENOTCAPABLE);
506 	families[0] = AF_INET;
507 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
508 	families[1] = AF_INET6;
509 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
510 	    errno == ENOTCAPABLE);
511 	families[0] = AF_INET6;
512 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
513 	    errno == ENOTCAPABLE);
514 
515 	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
516 
517 	cap_close(capdns);
518 
519 	/*
520 	 * Allow:
521 	 * type: NAME
522 	 * family: AF_INET6
523 	 */
524 
525 	capdns = cap_clone(origcapdns);
526 	CHECK(capdns != NULL);
527 
528 	types[0] = "NAME";
529 	types[1] = "ADDR";
530 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
531 	families[0] = AF_INET;
532 	families[1] = AF_INET6;
533 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
534 	types[0] = "NAME";
535 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
536 	types[1] = "ADDR";
537 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
538 	    errno == ENOTCAPABLE);
539 	types[0] = "ADDR";
540 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
541 	    errno == ENOTCAPABLE);
542 	families[0] = AF_INET6;
543 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
544 	families[1] = AF_INET;
545 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
546 	    errno == ENOTCAPABLE);
547 	families[0] = AF_INET;
548 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
549 	    errno == ENOTCAPABLE);
550 
551 	CHECK(runtest(capdns) == GETHOSTBYNAME2_AF_INET6);
552 
553 	cap_close(capdns);
554 
555 	/*
556 	 * Allow:
557 	 * type: ADDR
558 	 * family: AF_INET
559 	 */
560 
561 	capdns = cap_clone(origcapdns);
562 	CHECK(capdns != NULL);
563 
564 	types[0] = "NAME";
565 	types[1] = "ADDR";
566 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
567 	families[0] = AF_INET;
568 	families[1] = AF_INET6;
569 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
570 	types[0] = "ADDR";
571 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
572 	types[1] = "NAME";
573 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
574 	    errno == ENOTCAPABLE);
575 	types[0] = "NAME";
576 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
577 	    errno == ENOTCAPABLE);
578 	families[0] = AF_INET;
579 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
580 	families[1] = AF_INET6;
581 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
582 	    errno == ENOTCAPABLE);
583 	families[0] = AF_INET6;
584 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
585 	    errno == ENOTCAPABLE);
586 
587 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET | GETADDRINFO_AF_INET));
588 
589 	cap_close(capdns);
590 
591 	/*
592 	 * Allow:
593 	 * type: ADDR
594 	 * family: AF_INET6
595 	 */
596 
597 	capdns = cap_clone(origcapdns);
598 	CHECK(capdns != NULL);
599 
600 	types[0] = "NAME";
601 	types[1] = "ADDR";
602 	CHECK(cap_dns_type_limit(capdns, types, 2) == 0);
603 	families[0] = AF_INET;
604 	families[1] = AF_INET6;
605 	CHECK(cap_dns_family_limit(capdns, families, 2) == 0);
606 	types[0] = "ADDR";
607 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
608 	types[1] = "NAME";
609 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
610 	    errno == ENOTCAPABLE);
611 	types[0] = "NAME";
612 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
613 	    errno == ENOTCAPABLE);
614 	families[0] = AF_INET6;
615 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
616 	families[1] = AF_INET;
617 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
618 	    errno == ENOTCAPABLE);
619 	families[0] = AF_INET;
620 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
621 	    errno == ENOTCAPABLE);
622 
623 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 |
624 	    GETADDRINFO_AF_INET6));
625 
626 	cap_close(capdns);
627 
628 	/* Trying to rise the limits. */
629 
630 	capdns = cap_clone(origcapdns);
631 	CHECK(capdns != NULL);
632 
633 	types[0] = "NAME";
634 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
635 	families[0] = AF_INET;
636 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
637 
638 	types[0] = "NAME";
639 	types[1] = "ADDR";
640 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
641 	    errno == ENOTCAPABLE);
642 	families[0] = AF_INET;
643 	families[1] = AF_INET6;
644 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
645 	    errno == ENOTCAPABLE);
646 
647 	types[0] = "ADDR";
648 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
649 	    errno == ENOTCAPABLE);
650 	families[0] = AF_INET6;
651 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
652 	    errno == ENOTCAPABLE);
653 
654 	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
655 	    errno == ENOTCAPABLE);
656 	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
657 	    errno == ENOTCAPABLE);
658 
659 	/* Do the limits still hold? */
660 	CHECK(runtest(capdns) == (GETHOSTBYNAME | GETHOSTBYNAME2_AF_INET));
661 
662 	cap_close(capdns);
663 
664 	capdns = cap_clone(origcapdns);
665 	CHECK(capdns != NULL);
666 
667 	types[0] = "ADDR";
668 	CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
669 	families[0] = AF_INET6;
670 	CHECK(cap_dns_family_limit(capdns, families, 1) == 0);
671 
672 	types[0] = "NAME";
673 	types[1] = "ADDR";
674 	CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
675 	    errno == ENOTCAPABLE);
676 	families[0] = AF_INET;
677 	families[1] = AF_INET6;
678 	CHECK(cap_dns_family_limit(capdns, families, 2) == -1 &&
679 	    errno == ENOTCAPABLE);
680 
681 	types[0] = "NAME";
682 	CHECK(cap_dns_type_limit(capdns, types, 1) == -1 &&
683 	    errno == ENOTCAPABLE);
684 	families[0] = AF_INET;
685 	CHECK(cap_dns_family_limit(capdns, families, 1) == -1 &&
686 	    errno == ENOTCAPABLE);
687 
688 	CHECK(cap_dns_type_limit(capdns, NULL, 0) == -1 &&
689 	    errno == ENOTCAPABLE);
690 	CHECK(cap_dns_family_limit(capdns, NULL, 0) == -1 &&
691 	    errno == ENOTCAPABLE);
692 
693 	/* Do the limits still hold? */
694 	CHECK(runtest(capdns) == (GETHOSTBYADDR_AF_INET6 |
695 	    GETADDRINFO_AF_INET6));
696 
697 	cap_close(capdns);
698 
699 	cap_close(origcapdns);
700 
701 	exit(0);
702 }
703