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