]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libcasper/services/cap_dns/tests/dns_test.c
MFCr340141:
[FreeBSD/FreeBSD.git] / lib / libcasper / services / cap_dns / tests / dns_test.c
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] = "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             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] = "ADDR";
411         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
412         types[1] = "NAME";
413         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
414             errno == ENOTCAPABLE);
415         types[0] = "NAME";
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] = "NAME";
436         types[1] = "ADDR";
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] = "NAME";
463         types[1] = "ADDR";
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] = "NAME";
492         types[1] = "ADDR";
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] = "NAME";
498         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
499         types[1] = "ADDR";
500         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
501             errno == ENOTCAPABLE);
502         types[0] = "ADDR";
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] = "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) ==
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] = "NAME";
566         types[1] = "ADDR";
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] = "ADDR";
572         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
573         types[1] = "NAME";
574         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
575             errno == ENOTCAPABLE);
576         types[0] = "NAME";
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] = "NAME";
602         types[1] = "ADDR";
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] = "ADDR";
608         CHECK(cap_dns_type_limit(capdns, types, 1) == 0);
609         types[1] = "NAME";
610         CHECK(cap_dns_type_limit(capdns, types, 2) == -1 &&
611             errno == ENOTCAPABLE);
612         types[0] = "NAME";
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] = "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             GETADDRINFO_AF_INET));
662
663         cap_close(capdns);
664
665         capdns = cap_clone(origcapdns);
666         CHECK(capdns != NULL);
667
668         types[0] = "ADDR";
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] = "NAME";
674         types[1] = "ADDR";
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] = "NAME";
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 }