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