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: releng/11.0/tools/regression/capsicum/libcasper/dns.c 297982 2016-04-14 18:27:10Z oshogbo $");
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
51static 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
79static bool
80addrinfo_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
133static bool
134hostent_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
155static bool
156hostent_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
177static bool
178hostent_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
217static unsigned int
218runtest(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
327int
328main(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