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 * Copyright 1998-2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <pwd.h> 30*0Sstevel@tonic-gate #include <strings.h> 31*0Sstevel@tonic-gate #include <sys/mman.h> 32*0Sstevel@tonic-gate #include <sys/door.h> 33*0Sstevel@tonic-gate #include <errno.h> 34*0Sstevel@tonic-gate #include <fcntl.h> 35*0Sstevel@tonic-gate #include <synch.h> 36*0Sstevel@tonic-gate #include <getxby_door.h> 37*0Sstevel@tonic-gate #include <nss_dbdefs.h> 38*0Sstevel@tonic-gate #include "nss.h" 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #ifdef PIC 41*0Sstevel@tonic-gate 42*0Sstevel@tonic-gate static struct hostent *__process_getipnode(struct hostent *, char *, int, int *, 43*0Sstevel@tonic-gate nsc_data_t *); 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate struct hostent * 46*0Sstevel@tonic-gate _door_getipnodebyname_r(const char *name, struct hostent *result, char *buffer, 47*0Sstevel@tonic-gate int buflen, int af_family, int flags, int *h_errnop) 48*0Sstevel@tonic-gate { 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate /* 51*0Sstevel@tonic-gate * allocate space on the stack for the nscd to return 52*0Sstevel@tonic-gate * host and host alias information 53*0Sstevel@tonic-gate */ 54*0Sstevel@tonic-gate union { 55*0Sstevel@tonic-gate nsc_data_t s_d; 56*0Sstevel@tonic-gate char s_b[8192]; 57*0Sstevel@tonic-gate } space; 58*0Sstevel@tonic-gate nsc_data_t *sptr; 59*0Sstevel@tonic-gate int ndata; 60*0Sstevel@tonic-gate int adata; 61*0Sstevel@tonic-gate struct hostent *resptr = NULL; 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate if ((name == (const char *)NULL) || 64*0Sstevel@tonic-gate (strlen(name) >= (sizeof (space) - sizeof (nsc_data_t) 65*0Sstevel@tonic-gate - 2 * sizeof (int)))) { 66*0Sstevel@tonic-gate errno = ERANGE; 67*0Sstevel@tonic-gate if (h_errnop) 68*0Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 69*0Sstevel@tonic-gate return (NULL); 70*0Sstevel@tonic-gate } 71*0Sstevel@tonic-gate 72*0Sstevel@tonic-gate adata = (sizeof (nsc_call_t) + strlen(name) + 1 + 2 * sizeof (int)); 73*0Sstevel@tonic-gate ndata = sizeof (space); 74*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_callnumber = GETIPNODEBYNAME; 75*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_u.ipnode.af_family = af_family; 76*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_u.ipnode.flags = flags; 77*0Sstevel@tonic-gate strcpy(space.s_d.nsc_call.nsc_u.ipnode.name, name); 78*0Sstevel@tonic-gate sptr = &space.s_d; 79*0Sstevel@tonic-gate 80*0Sstevel@tonic-gate switch (_nsc_trydoorcall(&sptr, &ndata, &adata)) { 81*0Sstevel@tonic-gate case SUCCESS: /* positive cache hit */ 82*0Sstevel@tonic-gate break; 83*0Sstevel@tonic-gate case NOTFOUND: /* negative cache hit */ 84*0Sstevel@tonic-gate if (h_errnop) 85*0Sstevel@tonic-gate *h_errnop = space.s_d.nsc_ret.nsc_errno; 86*0Sstevel@tonic-gate return (NULL); 87*0Sstevel@tonic-gate default: 88*0Sstevel@tonic-gate return ((struct hostent *)_switch_getipnodebyname_r(name, 89*0Sstevel@tonic-gate result, buffer, buflen, af_family, flags, h_errnop)); 90*0Sstevel@tonic-gate } 91*0Sstevel@tonic-gate resptr = __process_getipnode(result, buffer, buflen, h_errnop, sptr); 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate /* 94*0Sstevel@tonic-gate * check if doors realloced buffer underneath of us.... 95*0Sstevel@tonic-gate * munmap or suffer a memory leak 96*0Sstevel@tonic-gate */ 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate if (sptr != &space.s_d) { 99*0Sstevel@tonic-gate munmap((char *)sptr, ndata); /* return memory */ 100*0Sstevel@tonic-gate } 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate return (resptr); 103*0Sstevel@tonic-gate } 104*0Sstevel@tonic-gate 105*0Sstevel@tonic-gate struct hostent * 106*0Sstevel@tonic-gate _door_getipnodebyaddr_r(const char *addr, int length, int type, 107*0Sstevel@tonic-gate struct hostent *result, char *buffer, int buflen, int *h_errnop) 108*0Sstevel@tonic-gate { 109*0Sstevel@tonic-gate /* 110*0Sstevel@tonic-gate * allocate space on the stack for the nscd to return 111*0Sstevel@tonic-gate * host and host alias information 112*0Sstevel@tonic-gate */ 113*0Sstevel@tonic-gate union { 114*0Sstevel@tonic-gate nsc_data_t s_d; 115*0Sstevel@tonic-gate char s_b[8192]; 116*0Sstevel@tonic-gate } space; 117*0Sstevel@tonic-gate nsc_data_t *sptr; 118*0Sstevel@tonic-gate int ndata; 119*0Sstevel@tonic-gate int adata; 120*0Sstevel@tonic-gate struct hostent *resptr = NULL; 121*0Sstevel@tonic-gate 122*0Sstevel@tonic-gate if (addr == (const char *)NULL) { 123*0Sstevel@tonic-gate if (h_errnop) 124*0Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 125*0Sstevel@tonic-gate return (NULL); 126*0Sstevel@tonic-gate } 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate ndata = sizeof (space); 129*0Sstevel@tonic-gate adata = length + sizeof (nsc_call_t) + 1; 130*0Sstevel@tonic-gate sptr = &space.s_d; 131*0Sstevel@tonic-gate 132*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_callnumber = GETIPNODEBYADDR; 133*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_u.addr.a_type = type; 134*0Sstevel@tonic-gate space.s_d.nsc_call.nsc_u.addr.a_length = length; 135*0Sstevel@tonic-gate memcpy(space.s_d.nsc_call.nsc_u.addr.a_data, addr, length); 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate switch (_nsc_trydoorcall(&sptr, &ndata, &adata)) { 138*0Sstevel@tonic-gate case SUCCESS: /* positive cache hit */ 139*0Sstevel@tonic-gate break; 140*0Sstevel@tonic-gate case NOTFOUND: /* negative cache hit */ 141*0Sstevel@tonic-gate if (h_errnop) 142*0Sstevel@tonic-gate *h_errnop = space.s_d.nsc_ret.nsc_errno; 143*0Sstevel@tonic-gate return (NULL); 144*0Sstevel@tonic-gate default: 145*0Sstevel@tonic-gate return ((struct hostent *)_switch_getipnodebyaddr_r(addr, 146*0Sstevel@tonic-gate length, type, result, buffer, buflen, h_errnop)); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate resptr = __process_getipnode(result, buffer, buflen, h_errnop, sptr); 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate /* 152*0Sstevel@tonic-gate * check if doors realloced buffer underneath of us.... 153*0Sstevel@tonic-gate * munmap it or suffer a memory leak 154*0Sstevel@tonic-gate */ 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate if (sptr != &space.s_d) { 157*0Sstevel@tonic-gate munmap((char *)sptr, ndata); /* return memory */ 158*0Sstevel@tonic-gate } 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate return (resptr); 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate #if !defined(_LP64) 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate static struct hostent * 166*0Sstevel@tonic-gate __process_getipnode(struct hostent *result, char *buffer, int buflen, 167*0Sstevel@tonic-gate int *h_errnop, nsc_data_t *sptr) 168*0Sstevel@tonic-gate { 169*0Sstevel@tonic-gate int i; 170*0Sstevel@tonic-gate 171*0Sstevel@tonic-gate char *fixed; 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate fixed = (char *)ROUND_UP((int)buffer, sizeof (char *)); 174*0Sstevel@tonic-gate buflen -= fixed - buffer; 175*0Sstevel@tonic-gate buffer = fixed; 176*0Sstevel@tonic-gate 177*0Sstevel@tonic-gate if (buflen + sizeof (struct hostent) 178*0Sstevel@tonic-gate < sptr->nsc_ret.nsc_bufferbytesused) { 179*0Sstevel@tonic-gate /* 180*0Sstevel@tonic-gate * no enough space allocated by user 181*0Sstevel@tonic-gate */ 182*0Sstevel@tonic-gate errno = ERANGE; 183*0Sstevel@tonic-gate if (h_errnop) 184*0Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 185*0Sstevel@tonic-gate return (NULL); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate memcpy(buffer, sptr->nsc_ret.nsc_u.buff + sizeof (struct hostent), 189*0Sstevel@tonic-gate sptr->nsc_ret.nsc_bufferbytesused - sizeof (struct hostent)); 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_name += (int)buffer; 192*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_aliases = 193*0Sstevel@tonic-gate (char **)((char *)sptr->nsc_ret.nsc_u.hst.h_aliases + (int)buffer); 194*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_addr_list = 195*0Sstevel@tonic-gate (char **)((char *)sptr->nsc_ret.nsc_u.hst.h_addr_list + 196*0Sstevel@tonic-gate (int)buffer); 197*0Sstevel@tonic-gate for (i = 0; sptr->nsc_ret.nsc_u.hst.h_aliases[i]; i++) { 198*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_aliases[i] += (int)buffer; 199*0Sstevel@tonic-gate } 200*0Sstevel@tonic-gate for (i = 0; sptr->nsc_ret.nsc_u.hst.h_addr_list[i]; i++) { 201*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_addr_list[i] += (int)buffer; 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate *result = sptr->nsc_ret.nsc_u.hst; 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate return (result); 207*0Sstevel@tonic-gate } 208*0Sstevel@tonic-gate 209*0Sstevel@tonic-gate #else /* _LP64 */ 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate static struct hostent * 212*0Sstevel@tonic-gate __process_getipnode(struct hostent *result, char *buffer, int buflen, 213*0Sstevel@tonic-gate int *h_errnop, nsc_data_t *sptr) 214*0Sstevel@tonic-gate { 215*0Sstevel@tonic-gate char *fixed; 216*0Sstevel@tonic-gate char *dest; 217*0Sstevel@tonic-gate char *start; 218*0Sstevel@tonic-gate char **aliaseslist; 219*0Sstevel@tonic-gate char **addrlist; 220*0Sstevel@tonic-gate int *alias; 221*0Sstevel@tonic-gate int *address; 222*0Sstevel@tonic-gate size_t strs; 223*0Sstevel@tonic-gate int numaliases; 224*0Sstevel@tonic-gate int numaddrs; 225*0Sstevel@tonic-gate int i; 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate fixed = (char *)ROUND_UP(buffer, sizeof (char *)); 228*0Sstevel@tonic-gate buflen -= fixed - buffer; 229*0Sstevel@tonic-gate buffer = fixed; 230*0Sstevel@tonic-gate if (buflen < 0) { 231*0Sstevel@tonic-gate /* no enough space allocated by user */ 232*0Sstevel@tonic-gate errno = ERANGE; 233*0Sstevel@tonic-gate if (h_errnop) 234*0Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 235*0Sstevel@tonic-gate return (NULL); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate 238*0Sstevel@tonic-gate /* 239*0Sstevel@tonic-gate * find out whether the user has provided sufficient space 240*0Sstevel@tonic-gate */ 241*0Sstevel@tonic-gate start = sptr->nsc_ret.nsc_u.buff + sizeof (struct hostent32); 242*0Sstevel@tonic-gate /* 243*0Sstevel@tonic-gate * Length of hostname + null 244*0Sstevel@tonic-gate */ 245*0Sstevel@tonic-gate strs = 1 + strlen(sptr->nsc_ret.nsc_u.hst.h_name + start); 246*0Sstevel@tonic-gate /* 247*0Sstevel@tonic-gate * length of all aliases + null 248*0Sstevel@tonic-gate */ 249*0Sstevel@tonic-gate alias = (int *)(start + sptr->nsc_ret.nsc_u.hst.h_aliases); 250*0Sstevel@tonic-gate for (numaliases = 0; alias[numaliases]; numaliases++) 251*0Sstevel@tonic-gate strs += 1 + strlen(start + alias[numaliases]); 252*0Sstevel@tonic-gate /* 253*0Sstevel@tonic-gate * Realign on word boundary 254*0Sstevel@tonic-gate */ 255*0Sstevel@tonic-gate strs = ROUND_UP(strs, sizeof (char *)); 256*0Sstevel@tonic-gate /* 257*0Sstevel@tonic-gate * Count the array of pointers to all aliases + null pointer 258*0Sstevel@tonic-gate */ 259*0Sstevel@tonic-gate strs += sizeof (char *) * (numaliases + 1); 260*0Sstevel@tonic-gate /* 261*0Sstevel@tonic-gate * length of all addresses + null. Also, account for word alignment. 262*0Sstevel@tonic-gate */ 263*0Sstevel@tonic-gate address = (int *)(start + sptr->nsc_ret.nsc_u.hst.h_addr_list); 264*0Sstevel@tonic-gate for (numaddrs = 0; address[numaddrs]; numaddrs++) { 265*0Sstevel@tonic-gate strs += sptr->nsc_ret.nsc_u.hst.h_length; 266*0Sstevel@tonic-gate strs = ROUND_UP(strs, sizeof (char *)); 267*0Sstevel@tonic-gate } 268*0Sstevel@tonic-gate /* 269*0Sstevel@tonic-gate * Count the array of pointers to all addresses + null pointer 270*0Sstevel@tonic-gate */ 271*0Sstevel@tonic-gate strs += sizeof (char *) * (numaddrs + 1); 272*0Sstevel@tonic-gate 273*0Sstevel@tonic-gate if (buflen < strs) { 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate /* no enough space allocated by user */ 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate errno = ERANGE; 278*0Sstevel@tonic-gate if (h_errnop) 279*0Sstevel@tonic-gate *h_errnop = HOST_NOT_FOUND; 280*0Sstevel@tonic-gate return (NULL); 281*0Sstevel@tonic-gate } 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate /* 284*0Sstevel@tonic-gate * allocat the h_aliases list and the h_addr_list first to align 'em. 285*0Sstevel@tonic-gate */ 286*0Sstevel@tonic-gate dest = buffer; 287*0Sstevel@tonic-gate aliaseslist = (char **)dest; 288*0Sstevel@tonic-gate dest += sizeof (char *) * (numaliases + 1); 289*0Sstevel@tonic-gate addrlist = (char **)dest; 290*0Sstevel@tonic-gate dest += sizeof (char *) * (numaddrs + 1); 291*0Sstevel@tonic-gate /* 292*0Sstevel@tonic-gate * fill out h_name 293*0Sstevel@tonic-gate */ 294*0Sstevel@tonic-gate start = sptr->nsc_ret.nsc_u.buff + sizeof (struct hostent32); 295*0Sstevel@tonic-gate strcpy(dest, sptr->nsc_ret.nsc_u.hst.h_name + start); 296*0Sstevel@tonic-gate strs = 1 + strlen(sptr->nsc_ret.nsc_u.hst.h_name + start); 297*0Sstevel@tonic-gate result->h_name = dest; 298*0Sstevel@tonic-gate dest += strs; 299*0Sstevel@tonic-gate /* 300*0Sstevel@tonic-gate * fill out the h_aliases list 301*0Sstevel@tonic-gate */ 302*0Sstevel@tonic-gate alias = (int *)(start + sptr->nsc_ret.nsc_u.hst.h_aliases); 303*0Sstevel@tonic-gate for (i = 0; i < numaliases; i++) { 304*0Sstevel@tonic-gate strcpy(dest, start + alias[i]); 305*0Sstevel@tonic-gate aliaseslist[i] = dest; 306*0Sstevel@tonic-gate dest += 1 + strlen(start + alias[i]); 307*0Sstevel@tonic-gate } 308*0Sstevel@tonic-gate aliaseslist[i] = 0; /* null term ptr chain */ 309*0Sstevel@tonic-gate result->h_aliases = aliaseslist; 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate /* 312*0Sstevel@tonic-gate * fill out the h_addr list 313*0Sstevel@tonic-gate */ 314*0Sstevel@tonic-gate dest = (char *)ROUND_UP(dest, sizeof (char *)); 315*0Sstevel@tonic-gate address = (int *)(start + sptr->nsc_ret.nsc_u.hst.h_addr_list); 316*0Sstevel@tonic-gate for (i = 0; i < numaddrs; i++) { 317*0Sstevel@tonic-gate memcpy(dest, start + address[i], 318*0Sstevel@tonic-gate sptr->nsc_ret.nsc_u.hst.h_length); 319*0Sstevel@tonic-gate addrlist[i] = dest; 320*0Sstevel@tonic-gate dest += sptr->nsc_ret.nsc_u.hst.h_length; 321*0Sstevel@tonic-gate dest = (char *)ROUND_UP(dest, sizeof (char *)); 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate addrlist[i] = 0; /* null term ptr chain */ 325*0Sstevel@tonic-gate 326*0Sstevel@tonic-gate result->h_addr_list = addrlist; 327*0Sstevel@tonic-gate 328*0Sstevel@tonic-gate result->h_length = sptr->nsc_ret.nsc_u.hst.h_length; 329*0Sstevel@tonic-gate result->h_addrtype = sptr->nsc_ret.nsc_u.hst.h_addrtype; 330*0Sstevel@tonic-gate 331*0Sstevel@tonic-gate return (result); 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate #endif /* _LP64 */ 334*0Sstevel@tonic-gate 335*0Sstevel@tonic-gate #endif /* PIC */ 336