1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate  *	dns_common.c
24*0Sstevel@tonic-gate  *
25*0Sstevel@tonic-gate  * Copyright (c) 1993,1998 by Sun Microsystems, Inc.
26*0Sstevel@tonic-gate  * All rights reserved.
27*0Sstevel@tonic-gate  */
28*0Sstevel@tonic-gate 
29*0Sstevel@tonic-gate #pragma	ident	"%Z%%M%	%I%	%E% SMI"
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #include "dns_common.h"
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate #define	DNS_ALIASES	0
34*0Sstevel@tonic-gate #define	DNS_ADDRLIST	1
35*0Sstevel@tonic-gate #define	DNS_MAPDLIST	2
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate static int
38*0Sstevel@tonic-gate dns_netdb_aliases(from_list, to_list, aliaspp, type, count, af_type)
39*0Sstevel@tonic-gate 	char	**from_list, **to_list,	**aliaspp;
40*0Sstevel@tonic-gate 	int	type, *count, af_type;
41*0Sstevel@tonic-gate {
42*0Sstevel@tonic-gate 	char		*fstr;
43*0Sstevel@tonic-gate 	int		cnt = 0;
44*0Sstevel@tonic-gate 	size_t		len;
45*0Sstevel@tonic-gate 
46*0Sstevel@tonic-gate 	*count = 0;
47*0Sstevel@tonic-gate 	if ((char *)to_list >= *aliaspp)
48*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_ERANGE);
49*0Sstevel@tonic-gate 
50*0Sstevel@tonic-gate 	for (fstr = from_list[cnt]; fstr != NULL; fstr = from_list[cnt]) {
51*0Sstevel@tonic-gate 		if (type == DNS_ALIASES)
52*0Sstevel@tonic-gate 			len = strlen(fstr) + 1;
53*0Sstevel@tonic-gate 		else
54*0Sstevel@tonic-gate 			len = (af_type == AF_INET) ? sizeof (struct in_addr)
55*0Sstevel@tonic-gate 						: sizeof (struct in6_addr);
56*0Sstevel@tonic-gate 		*aliaspp -= len;
57*0Sstevel@tonic-gate 		to_list[cnt] = *aliaspp;
58*0Sstevel@tonic-gate 		if (*aliaspp <= (char *)&to_list[cnt+1])
59*0Sstevel@tonic-gate 			return (NSS_STR_PARSE_ERANGE);
60*0Sstevel@tonic-gate 		if (type == DNS_MAPDLIST) {
61*0Sstevel@tonic-gate 			struct in6_addr *addr6p = (struct in6_addr *) *aliaspp;
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate 			(void) memset(addr6p, '\0', sizeof (struct in6_addr));
64*0Sstevel@tonic-gate 			(void) memcpy(&addr6p->s6_addr[12], fstr,
65*0Sstevel@tonic-gate 					sizeof (struct in_addr));
66*0Sstevel@tonic-gate 			addr6p->s6_addr[10] = 0xffU;
67*0Sstevel@tonic-gate 			addr6p->s6_addr[11] = 0xffU;
68*0Sstevel@tonic-gate 			++cnt;
69*0Sstevel@tonic-gate 		} else {
70*0Sstevel@tonic-gate 			(void) memcpy (*aliaspp, fstr, len);
71*0Sstevel@tonic-gate 			++cnt;
72*0Sstevel@tonic-gate 		}
73*0Sstevel@tonic-gate 	}
74*0Sstevel@tonic-gate 	to_list[cnt] = NULL;
75*0Sstevel@tonic-gate 
76*0Sstevel@tonic-gate 	*count = cnt;
77*0Sstevel@tonic-gate 	if (cnt == 0)
78*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_PARSE);
79*0Sstevel@tonic-gate 
80*0Sstevel@tonic-gate 	return (NSS_STR_PARSE_SUCCESS);
81*0Sstevel@tonic-gate }
82*0Sstevel@tonic-gate 
83*0Sstevel@tonic-gate 
84*0Sstevel@tonic-gate int
85*0Sstevel@tonic-gate ent2result(he, argp, af_type)
86*0Sstevel@tonic-gate 	struct hostent		*he;
87*0Sstevel@tonic-gate 	nss_XbyY_args_t		*argp;
88*0Sstevel@tonic-gate 	int			af_type;
89*0Sstevel@tonic-gate {
90*0Sstevel@tonic-gate 	char		*buffer, *limit;
91*0Sstevel@tonic-gate 	int		buflen = argp->buf.buflen;
92*0Sstevel@tonic-gate 	int		ret, count;
93*0Sstevel@tonic-gate 	size_t len;
94*0Sstevel@tonic-gate 	struct hostent 	*host;
95*0Sstevel@tonic-gate 	struct in_addr	*addrp;
96*0Sstevel@tonic-gate 	struct in6_addr	*addrp6;
97*0Sstevel@tonic-gate 
98*0Sstevel@tonic-gate 	limit = argp->buf.buffer + buflen;
99*0Sstevel@tonic-gate 	host = (struct hostent *) argp->buf.result;
100*0Sstevel@tonic-gate 	buffer = argp->buf.buffer;
101*0Sstevel@tonic-gate 
102*0Sstevel@tonic-gate 	/* h_addrtype and h_length */
103*0Sstevel@tonic-gate 	host->h_addrtype = af_type;
104*0Sstevel@tonic-gate 	host->h_length = (af_type == AF_INET) ? sizeof (struct in_addr)
105*0Sstevel@tonic-gate 					: sizeof (struct in6_addr);
106*0Sstevel@tonic-gate 
107*0Sstevel@tonic-gate 	/* h_name */
108*0Sstevel@tonic-gate 	len = strlen(he->h_name) + 1;
109*0Sstevel@tonic-gate 	host->h_name = buffer;
110*0Sstevel@tonic-gate 	if (host->h_name + len >= limit)
111*0Sstevel@tonic-gate 		return (NSS_STR_PARSE_ERANGE);
112*0Sstevel@tonic-gate 	(void) memcpy(host->h_name, he->h_name, len);
113*0Sstevel@tonic-gate 	buffer += len;
114*0Sstevel@tonic-gate 
115*0Sstevel@tonic-gate 	/* h_addr_list */
116*0Sstevel@tonic-gate 	if (af_type == AF_INET) {
117*0Sstevel@tonic-gate 		addrp = (struct in_addr *) ROUND_DOWN(limit, sizeof (*addrp));
118*0Sstevel@tonic-gate 		host->h_addr_list = (char **)
119*0Sstevel@tonic-gate 				ROUND_UP(buffer, sizeof (char **));
120*0Sstevel@tonic-gate 		ret = dns_netdb_aliases(he->h_addr_list, host->h_addr_list,
121*0Sstevel@tonic-gate 			(char **)&addrp, DNS_ADDRLIST, &count, af_type);
122*0Sstevel@tonic-gate 		if (ret != NSS_STR_PARSE_SUCCESS)
123*0Sstevel@tonic-gate 			return (ret);
124*0Sstevel@tonic-gate 		/* h_aliases */
125*0Sstevel@tonic-gate 		host->h_aliases = host->h_addr_list + count + 1;
126*0Sstevel@tonic-gate 		ret = dns_netdb_aliases(he->h_aliases, host->h_aliases,
127*0Sstevel@tonic-gate 			(char **)&addrp, DNS_ALIASES, &count, af_type);
128*0Sstevel@tonic-gate 	} else {
129*0Sstevel@tonic-gate 		addrp6 = (struct in6_addr *)
130*0Sstevel@tonic-gate 			ROUND_DOWN(limit, sizeof (*addrp6));
131*0Sstevel@tonic-gate 		host->h_addr_list = (char **)
132*0Sstevel@tonic-gate 			ROUND_UP(buffer, sizeof (char **));
133*0Sstevel@tonic-gate 		if (he->h_addrtype == AF_INET && af_type == AF_INET6) {
134*0Sstevel@tonic-gate 			ret = dns_netdb_aliases(he->h_addr_list,
135*0Sstevel@tonic-gate 				host->h_addr_list, (char **)&addrp6,
136*0Sstevel@tonic-gate 				DNS_MAPDLIST, &count, af_type);
137*0Sstevel@tonic-gate 		} else {
138*0Sstevel@tonic-gate 			ret = dns_netdb_aliases(he->h_addr_list,
139*0Sstevel@tonic-gate 				host->h_addr_list, (char **)&addrp6,
140*0Sstevel@tonic-gate 				DNS_ADDRLIST, &count, af_type);
141*0Sstevel@tonic-gate 		}
142*0Sstevel@tonic-gate 		if (ret != NSS_STR_PARSE_SUCCESS)
143*0Sstevel@tonic-gate 			return (ret);
144*0Sstevel@tonic-gate 		/* h_aliases */
145*0Sstevel@tonic-gate 		host->h_aliases = host->h_addr_list + count + 1;
146*0Sstevel@tonic-gate 		ret = dns_netdb_aliases(he->h_aliases, host->h_aliases,
147*0Sstevel@tonic-gate 			(char **)&addrp6, DNS_ALIASES, &count, af_type);
148*0Sstevel@tonic-gate 	}
149*0Sstevel@tonic-gate 	if (ret == NSS_STR_PARSE_PARSE)
150*0Sstevel@tonic-gate 		ret = NSS_STR_PARSE_SUCCESS;
151*0Sstevel@tonic-gate 
152*0Sstevel@tonic-gate 	return (ret);
153*0Sstevel@tonic-gate }
154*0Sstevel@tonic-gate 
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate nss_backend_t *
157*0Sstevel@tonic-gate _nss_dns_constr(dns_backend_op_t ops[], int n_ops)
158*0Sstevel@tonic-gate {
159*0Sstevel@tonic-gate 	dns_backend_ptr_t	be;
160*0Sstevel@tonic-gate 
161*0Sstevel@tonic-gate 	if ((be = (dns_backend_ptr_t) malloc(sizeof (*be))) == 0)
162*0Sstevel@tonic-gate 		return (0);
163*0Sstevel@tonic-gate 
164*0Sstevel@tonic-gate 	be->ops = ops;
165*0Sstevel@tonic-gate 	be->n_ops = n_ops;
166*0Sstevel@tonic-gate 	return ((nss_backend_t *) be);
167*0Sstevel@tonic-gate }
168