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