17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5cb5caa98Sdjl * Common Development and Distribution License (the "License"). 6cb5caa98Sdjl * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*b6131d8fSchinlong * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <netdb.h> 297c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 307c478bd9Sstevel@tonic-gate #include <netinet/in.h> 317c478bd9Sstevel@tonic-gate #include <sys/socket.h> 327c478bd9Sstevel@tonic-gate #include <syslog.h> 337c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 347c478bd9Sstevel@tonic-gate #include "ns_internal.h" 357c478bd9Sstevel@tonic-gate #include "ldap_common.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* host attributes filters */ 387c478bd9Sstevel@tonic-gate #define _H_DN "dn" 397c478bd9Sstevel@tonic-gate #define _H_NAME "cn" 407c478bd9Sstevel@tonic-gate #define _H_ADDR "iphostnumber" 417c478bd9Sstevel@tonic-gate #define _F_GETHOSTBYNAME "(&(objectClass=ipHost)(cn=%s))" 427c478bd9Sstevel@tonic-gate #define _F_GETHOSTBYNAME_SSD "(&(%%s)(cn=%s))" 437c478bd9Sstevel@tonic-gate #define _F_GETHOSTDOTTEDBYNAME "(&(objectClass=ipHost)(|(cn=%s)(cn=%s)))" 447c478bd9Sstevel@tonic-gate #define _F_GETHOSTDOTTEDBYNAME_SSD "(&(%%s)(|(cn=%s)(cn=%s)))" 457c478bd9Sstevel@tonic-gate #define _F_GETHOSTBYADDR "(&(objectClass=ipHost)(ipHostNumber=%s))" 467c478bd9Sstevel@tonic-gate #define _F_GETHOSTBYADDR_SSD "(&(%%s)(ipHostNumber=%s))" 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate static const char *hosts_attrs[] = { 497c478bd9Sstevel@tonic-gate _H_NAME, 507c478bd9Sstevel@tonic-gate _H_ADDR, 517c478bd9Sstevel@tonic-gate (char *)NULL 527c478bd9Sstevel@tonic-gate }; 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate /* 55cb5caa98Sdjl * _nss_ldap_hosts2str is the data marshaling method for the hosts getXbyY 56cb5caa98Sdjl * system call gethostbyname() and gethostbyaddr. 57cb5caa98Sdjl * This method is called after a successful search has been performed. 58cb5caa98Sdjl * This method will parse the search results into the file format. 59cb5caa98Sdjl * e.g. 60cb5caa98Sdjl * 61cb5caa98Sdjl * 9.9.9.9 jurassic jurassic1 jurassic2 62cb5caa98Sdjl * 10.10.10.10 puppy 63cb5caa98Sdjl * 647c478bd9Sstevel@tonic-gate */ 65cb5caa98Sdjl int 66cb5caa98Sdjl _nss_ldap_hosts2str_int(int af, ldap_backend_ptr be, nss_XbyY_args_t *argp) 677c478bd9Sstevel@tonic-gate { 68cb5caa98Sdjl uint_t i; 697c478bd9Sstevel@tonic-gate int nss_result; 70cb5caa98Sdjl int buflen, buflen1, buflen2, len; 71cb5caa98Sdjl int firstimedn = 1, first_entry; 72cb5caa98Sdjl int validaddress = 0, copy_cname; 73cb5caa98Sdjl char *cname = NULL, *h_name = NULL; 74cb5caa98Sdjl char *buffer = NULL; 75cb5caa98Sdjl char *name; 767c478bd9Sstevel@tonic-gate ns_ldap_result_t *result = be->result; 77cb5caa98Sdjl ns_ldap_attr_t *names; 787c478bd9Sstevel@tonic-gate ns_ldap_entry_t *entry; 79cb5caa98Sdjl char **ips = NULL, **dns = NULL; 80cb5caa98Sdjl char *first_host = NULL, *other_hosts = NULL; 81cb5caa98Sdjl char *buf1, *buf2; 827c478bd9Sstevel@tonic-gate 83cb5caa98Sdjl if (result == NULL) 84cb5caa98Sdjl return (NSS_STR_PARSE_PARSE); 85cb5caa98Sdjl buflen = buflen1 = buflen2 = argp->buf.buflen; 86cb5caa98Sdjl 87cb5caa98Sdjl if (argp->buf.result != NULL) { 88cb5caa98Sdjl if ((be->buffer = calloc(1, buflen)) == NULL) { 89cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 90cb5caa98Sdjl goto result_host2str; 91cb5caa98Sdjl } 92cb5caa98Sdjl buffer = be->buffer; 93cb5caa98Sdjl } else 947c478bd9Sstevel@tonic-gate buffer = argp->buf.buffer; 95cb5caa98Sdjl if ((first_host = calloc(1, buflen1)) == NULL) { 96cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 97cb5caa98Sdjl goto result_host2str; 98cb5caa98Sdjl } 99cb5caa98Sdjl if ((other_hosts = calloc(1, buflen2)) == NULL) { 100cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 101cb5caa98Sdjl goto result_host2str; 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 104cb5caa98Sdjl nss_result = NSS_STR_PARSE_SUCCESS; 1057c478bd9Sstevel@tonic-gate (void) memset(argp->buf.buffer, 0, buflen); 106cb5caa98Sdjl /* 107cb5caa98Sdjl * Multiple lines return will be sepereated by newlines 108cb5caa98Sdjl * Single line return or last line does not have newline 109cb5caa98Sdjl * e.g. 110cb5caa98Sdjl * 111cb5caa98Sdjl * 8.8.8.8 hostname 112cb5caa98Sdjl * 113cb5caa98Sdjl * or the search for hostname h1 returns 3 entries 114cb5caa98Sdjl * 115cb5caa98Sdjl * 9.9.9.9 h1 116cb5caa98Sdjl * 10.10.10.10 h1 xx 117cb5caa98Sdjl * 20.20.20.20 h1 yyy 118cb5caa98Sdjl * 119cb5caa98Sdjl * str2hostent expects all name/aliases in the first entry 120cb5caa98Sdjl * so the string is organized as 121cb5caa98Sdjl * 122cb5caa98Sdjl * "9.9.9.9 h1 xx yy\n10.10.10.10 \n20.20.20.20 " 123cb5caa98Sdjl * 124cb5caa98Sdjl * Use first_host to hold "9.9.9.9 h1 xx yy" and other_hosts to hold 125cb5caa98Sdjl * "\n10.10.10.10 \n20.20.20.20 " 126cb5caa98Sdjl * 127cb5caa98Sdjl */ 128cb5caa98Sdjl buf1 = first_host; 129cb5caa98Sdjl buf2 = other_hosts; 130cb5caa98Sdjl first_entry = 1; 1317c478bd9Sstevel@tonic-gate for (entry = result->entry; entry != NULL; entry = entry->next) { 1327c478bd9Sstevel@tonic-gate if (firstimedn) { 133cb5caa98Sdjl dns = __ns_ldap_getAttr(entry, _H_DN); 134*b6131d8fSchinlong if (dns == NULL || dns[0] == NULL || strlen(dns[0]) 135*b6131d8fSchinlong < 1) { 136cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 137cb5caa98Sdjl goto result_host2str; 138cb5caa98Sdjl } 1397c478bd9Sstevel@tonic-gate /* get domain name associated with this dn */ 140cb5caa98Sdjl be->toglue = _get_domain_name(dns[0]); 141cb5caa98Sdjl firstimedn = 0; 1427c478bd9Sstevel@tonic-gate } 1437c478bd9Sstevel@tonic-gate 144cb5caa98Sdjl /* Get IP */ 145cb5caa98Sdjl ips = __ns_ldap_getAttr(entry, _H_ADDR); 146cb5caa98Sdjl if (ips == NULL || ips[0] == NULL || strlen(ips[0]) < 1) { 147cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 148cb5caa98Sdjl goto result_host2str; 1497c478bd9Sstevel@tonic-gate } 150cb5caa98Sdjl /* Skip IPV6 address in AF_INET mode */ 151cb5caa98Sdjl if (af == AF_INET && 152cb5caa98Sdjl (inet_addr(_strip_quotes(ips[0])) == (in_addr_t)-1)) 1537c478bd9Sstevel@tonic-gate continue; 154cb5caa98Sdjl 155cb5caa98Sdjl /* A valid address for either af mode */ 156cb5caa98Sdjl validaddress++; 157cb5caa98Sdjl 158cb5caa98Sdjl if (first_entry) { 159cb5caa98Sdjl len = snprintf(buf1, buflen1, "%s", ips[0]); 160cb5caa98Sdjl TEST_AND_ADJUST(len, buf1, buflen1, result_host2str); 161cb5caa98Sdjl } else { 162cb5caa98Sdjl len = snprintf(buf2, buflen2, "\n%s ", ips[0]); 163cb5caa98Sdjl TEST_AND_ADJUST(len, buf2, buflen2, result_host2str); 1647c478bd9Sstevel@tonic-gate } 165cb5caa98Sdjl 166cb5caa98Sdjl /* Get host names */ 167cb5caa98Sdjl names = __ns_ldap_getAttrStruct(entry, _H_NAME); 168cb5caa98Sdjl if (names == NULL || names->attrvalue == NULL) { 169cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 170cb5caa98Sdjl goto result_host2str; 171cb5caa98Sdjl } 172cb5caa98Sdjl 173cb5caa98Sdjl /* Get canonical name of each entry */ 174*b6131d8fSchinlong cname = __s_api_get_canonical_name(entry, names, 1); 175cb5caa98Sdjl if (cname == NULL || strlen(cname) < 1) { 176cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 177cb5caa98Sdjl goto result_host2str; 178cb5caa98Sdjl } 179cb5caa98Sdjl 180cb5caa98Sdjl /* Filter cname that's identical to h_name */ 181cb5caa98Sdjl if (first_entry) { 182cb5caa98Sdjl h_name = cname; 183cb5caa98Sdjl first_entry = 0; 184cb5caa98Sdjl copy_cname = 1; 185cb5caa98Sdjl } else if (strcasecmp(cname, h_name) != 0) { 186cb5caa98Sdjl copy_cname = 1; 187cb5caa98Sdjl } else 188cb5caa98Sdjl copy_cname = 0; 189cb5caa98Sdjl 190cb5caa98Sdjl if (copy_cname) { 191cb5caa98Sdjl /* Use the canonical name as the host name */ 192*b6131d8fSchinlong if (be->toglue == NULL || DOTTEDSUBDOMAIN(cname)) 193cb5caa98Sdjl len = snprintf(buf1, buflen1, " %s", cname); 194cb5caa98Sdjl else 195cb5caa98Sdjl /* append domain name */ 196cb5caa98Sdjl len = snprintf(buf1, buflen1, " %s.%s", cname, 197cb5caa98Sdjl be->toglue); 198cb5caa98Sdjl 199cb5caa98Sdjl TEST_AND_ADJUST(len, buf1, buflen1, result_host2str); 200cb5caa98Sdjl } 201cb5caa98Sdjl 202cb5caa98Sdjl /* Append aliases */ 203cb5caa98Sdjl for (i = 0; i < names->value_count; i++) { 204cb5caa98Sdjl name = names->attrvalue[i]; 205cb5caa98Sdjl if (name == NULL) { 206cb5caa98Sdjl nss_result = NSS_STR_PARSE_PARSE; 207cb5caa98Sdjl goto result_host2str; 208cb5caa98Sdjl } 209cb5caa98Sdjl /* Skip the canonical name and h_name */ 210cb5caa98Sdjl if (strcasecmp(name, cname) != 0 && 211cb5caa98Sdjl strcasecmp(name, h_name) != 0) { 212*b6131d8fSchinlong if (be->toglue == NULL || DOTTEDSUBDOMAIN(name)) 213*b6131d8fSchinlong len = snprintf(buf1, buflen1, " %s", 214*b6131d8fSchinlong name); 215cb5caa98Sdjl else 216cb5caa98Sdjl /* append domain name */ 217cb5caa98Sdjl len = snprintf(buf1, buflen1, " %s.%s", 218cb5caa98Sdjl name, be->toglue); 219*b6131d8fSchinlong TEST_AND_ADJUST(len, buf1, buflen1, 220*b6131d8fSchinlong result_host2str); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate } 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate if (validaddress == 0) { 226cb5caa98Sdjl /* 227cb5caa98Sdjl * For AF_INET mode, it found an IPv6 address and skipped it. 228cb5caa98Sdjl */ 229cb5caa98Sdjl nss_result = NSS_STR_PARSE_NO_ADDR; 230cb5caa98Sdjl goto result_host2str; 2317c478bd9Sstevel@tonic-gate } 232cb5caa98Sdjl /* Combine 2 strings */ 233cb5caa98Sdjl len = snprintf(buffer, buflen, "%s%s", first_host, other_hosts); 234cb5caa98Sdjl TEST_AND_ADJUST(len, buffer, buflen, result_host2str); 2357c478bd9Sstevel@tonic-gate 236cb5caa98Sdjl /* The front end marshaller doesn't need to copy trailing nulls */ 237cb5caa98Sdjl if (argp->buf.result != NULL) 238cb5caa98Sdjl be->buflen = strlen(be->buffer); 2397c478bd9Sstevel@tonic-gate 240cb5caa98Sdjl result_host2str: 241cb5caa98Sdjl if (first_host) 242cb5caa98Sdjl free(first_host); 243cb5caa98Sdjl if (other_hosts) 244cb5caa98Sdjl free(other_hosts); 2452f1c59b1Schinlong if (be->toglue) { 2462f1c59b1Schinlong free(be->toglue); 2472f1c59b1Schinlong be->toglue = NULL; 2482f1c59b1Schinlong } 2497c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 250cb5caa98Sdjl return (nss_result); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 253cb5caa98Sdjl static int 254cb5caa98Sdjl _nss_ldap_hosts2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { 255cb5caa98Sdjl return (_nss_ldap_hosts2str_int(AF_INET, be, argp)); 256cb5caa98Sdjl } 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate /* 2597c478bd9Sstevel@tonic-gate * getbyname gets a struct hostent by hostname. This function constructs 2607c478bd9Sstevel@tonic-gate * an ldap search filter using the name invocation parameter and the 2617c478bd9Sstevel@tonic-gate * gethostbyname search filter defined. Once the filter is constructed, 2627c478bd9Sstevel@tonic-gate * we search for a matching entry and marshal the data results into 2637c478bd9Sstevel@tonic-gate * struct hostent for the frontend process. Host name searches will be 2647c478bd9Sstevel@tonic-gate * on fully qualified host names (foo.bar.sun.com) 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate static nss_status_t 2687c478bd9Sstevel@tonic-gate getbyname(ldap_backend_ptr be, void *a) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate char hostname[3 * MAXHOSTNAMELEN]; 2717c478bd9Sstevel@tonic-gate char realdomain[BUFSIZ]; 2727c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 2737c478bd9Sstevel@tonic-gate nss_status_t lstat; 2747c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 2757c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 2767c478bd9Sstevel@tonic-gate int rc; 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate if (_ldap_filter_name(hostname, argp->key.name, sizeof (hostname)) != 0) 2797c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate rc = snprintf(searchfilter, sizeof (searchfilter), _F_GETHOSTBYNAME, 2827c478bd9Sstevel@tonic-gate hostname); 2837c478bd9Sstevel@tonic-gate if (rc >= sizeof (searchfilter) || rc < 0) 2847c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate rc = snprintf(userdata, sizeof (userdata), _F_GETHOSTBYNAME_SSD, 2877c478bd9Sstevel@tonic-gate hostname); 2887c478bd9Sstevel@tonic-gate if (rc >= sizeof (userdata) || rc < 0) 2897c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate /* get the domain we are in */ 2927c478bd9Sstevel@tonic-gate rc = sysinfo(SI_SRPC_DOMAIN, realdomain, BUFSIZ); 2937c478bd9Sstevel@tonic-gate if (rc <= 0) 2947c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate /* Is this a request for a host.domain */ 2977c478bd9Sstevel@tonic-gate if (DOTTEDSUBDOMAIN(hostname)) { 2987c478bd9Sstevel@tonic-gate char host[MAXHOSTNAMELEN]; 2997c478bd9Sstevel@tonic-gate char domain[MAXHOSTNAMELEN]; 3007c478bd9Sstevel@tonic-gate char hname[3 * MAXHOSTNAMELEN]; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate /* separate host and domain. this function */ 3037c478bd9Sstevel@tonic-gate /* will munge hname, so use argp->keyname */ 3047c478bd9Sstevel@tonic-gate /* from here on for original string */ 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate (void) strcpy(hname, hostname); 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate if (chophostdomain(hname, host, domain) == -1) { 3097c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate /* if domain is a proper subset of realdomain */ 3137c478bd9Sstevel@tonic-gate /* ie. domain = "eng" and realdomain */ 3147c478bd9Sstevel@tonic-gate /* = "eng.wiz.com", we try to lookup both" */ 3157c478bd9Sstevel@tonic-gate /* host.domain and host */ 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (propersubdomain(realdomain, domain) == 1) { 3187c478bd9Sstevel@tonic-gate /* yes, it is a proper domain */ 3197c478bd9Sstevel@tonic-gate rc = snprintf(searchfilter, sizeof (searchfilter), 3207c478bd9Sstevel@tonic-gate _F_GETHOSTDOTTEDBYNAME, hostname, host); 3217c478bd9Sstevel@tonic-gate if (rc >= sizeof (searchfilter) || rc < 0) 3227c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate rc = snprintf(userdata, sizeof (userdata), 3257c478bd9Sstevel@tonic-gate _F_GETHOSTDOTTEDBYNAME_SSD, hostname, host); 3267c478bd9Sstevel@tonic-gate if (rc >= sizeof (userdata) || rc < 0) 3277c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3287c478bd9Sstevel@tonic-gate } else { 3297c478bd9Sstevel@tonic-gate /* it is not a proper domain, so only try to look up */ 3307c478bd9Sstevel@tonic-gate /* host.domain */ 3317c478bd9Sstevel@tonic-gate rc = snprintf(searchfilter, sizeof (searchfilter), 3327c478bd9Sstevel@tonic-gate _F_GETHOSTBYNAME, hostname); 3337c478bd9Sstevel@tonic-gate if (rc >= sizeof (searchfilter) || rc < 0) 3347c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate rc = snprintf(userdata, sizeof (userdata), 3377c478bd9Sstevel@tonic-gate _F_GETHOSTBYNAME_SSD, hostname); 3387c478bd9Sstevel@tonic-gate if (rc >= sizeof (userdata) || rc < 0) 3397c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate } else { 3427c478bd9Sstevel@tonic-gate rc = snprintf(searchfilter, sizeof (searchfilter), 3437c478bd9Sstevel@tonic-gate _F_GETHOSTBYNAME, hostname); 3447c478bd9Sstevel@tonic-gate if (rc >= sizeof (searchfilter) || rc < 0) 3457c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate rc = snprintf(userdata, sizeof (userdata), 3487c478bd9Sstevel@tonic-gate _F_GETHOSTBYNAME_SSD, hostname); 3497c478bd9Sstevel@tonic-gate if (rc >= sizeof (userdata) || rc < 0) 3507c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3517c478bd9Sstevel@tonic-gate } 352*b6131d8fSchinlong lstat = (nss_status_t)_nss_ldap_lookup(be, argp, _HOSTS, searchfilter, 353*b6131d8fSchinlong NULL, _merge_SSD_filter, userdata); 3547c478bd9Sstevel@tonic-gate if (lstat == (nss_status_t)NS_LDAP_SUCCESS) 3557c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate argp->h_errno = __nss2herrno(lstat); 3587c478bd9Sstevel@tonic-gate return ((nss_status_t)lstat); 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate 3627c478bd9Sstevel@tonic-gate /* 3637c478bd9Sstevel@tonic-gate * getbyaddr gets a struct hostent by host address. This function 3647c478bd9Sstevel@tonic-gate * constructs an ldap search filter using the host address invocation 3657c478bd9Sstevel@tonic-gate * parameter and the gethostbyaddr search filter defined. Once the 3667c478bd9Sstevel@tonic-gate * filter is constructed, we search for a matching entry and marshal 3677c478bd9Sstevel@tonic-gate * the data results into struct hostent for the frontend process. 3687c478bd9Sstevel@tonic-gate * 3697c478bd9Sstevel@tonic-gate * extern char *inet_ntoa_r() not an advertised function from libnsl. 3707c478bd9Sstevel@tonic-gate * There is no man page and no prototype. 3717c478bd9Sstevel@tonic-gate */ 3727c478bd9Sstevel@tonic-gate 3737c478bd9Sstevel@tonic-gate static nss_status_t 3747c478bd9Sstevel@tonic-gate getbyaddr(ldap_backend_ptr be, void *a) 3757c478bd9Sstevel@tonic-gate { 3767c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 3777c478bd9Sstevel@tonic-gate struct in_addr addr; 3787c478bd9Sstevel@tonic-gate char buf[18]; 3797c478bd9Sstevel@tonic-gate nss_status_t lstat; 3807c478bd9Sstevel@tonic-gate extern char *inet_ntoa_r(); 3817c478bd9Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 3827c478bd9Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 3837c478bd9Sstevel@tonic-gate int ret; 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate argp->h_errno = 0; 3867c478bd9Sstevel@tonic-gate if ((argp->key.hostaddr.type != AF_INET) || 3877c478bd9Sstevel@tonic-gate (argp->key.hostaddr.len != sizeof (addr))) 3887c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); 3917c478bd9Sstevel@tonic-gate (void) inet_ntoa_r(addr, buf); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETHOSTBYADDR, 3947c478bd9Sstevel@tonic-gate buf); 3957c478bd9Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 3967c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 3977c478bd9Sstevel@tonic-gate 3987c478bd9Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), _F_GETHOSTBYADDR_SSD, buf); 3997c478bd9Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 4007c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 4017c478bd9Sstevel@tonic-gate 402*b6131d8fSchinlong lstat = (nss_status_t)_nss_ldap_lookup(be, argp, _HOSTS, searchfilter, 403*b6131d8fSchinlong NULL, _merge_SSD_filter, userdata); 4047c478bd9Sstevel@tonic-gate if (lstat == (nss_status_t)NS_LDAP_SUCCESS) 4057c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate argp->h_errno = __nss2herrno(lstat); 4087c478bd9Sstevel@tonic-gate return ((nss_status_t)lstat); 4097c478bd9Sstevel@tonic-gate } 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate static ldap_backend_op_t hosts_ops[] = { 4127c478bd9Sstevel@tonic-gate _nss_ldap_destr, 4137c478bd9Sstevel@tonic-gate _nss_ldap_endent, 4147c478bd9Sstevel@tonic-gate _nss_ldap_setent, 4157c478bd9Sstevel@tonic-gate _nss_ldap_getent, 4167c478bd9Sstevel@tonic-gate getbyname, 4177c478bd9Sstevel@tonic-gate getbyaddr 4187c478bd9Sstevel@tonic-gate }; 4197c478bd9Sstevel@tonic-gate 4207c478bd9Sstevel@tonic-gate 4217c478bd9Sstevel@tonic-gate /* 4227c478bd9Sstevel@tonic-gate * _nss_ldap_hosts_constr is where life begins. This function calls the generic 4237c478bd9Sstevel@tonic-gate * ldap constructor function to define and build the abstract data types 4247c478bd9Sstevel@tonic-gate * required to support ldap operations. 4257c478bd9Sstevel@tonic-gate */ 4267c478bd9Sstevel@tonic-gate 4277c478bd9Sstevel@tonic-gate /*ARGSUSED0*/ 4287c478bd9Sstevel@tonic-gate nss_backend_t * 4297c478bd9Sstevel@tonic-gate _nss_ldap_hosts_constr(const char *dummy1, const char *dummy2, 4307c478bd9Sstevel@tonic-gate const char *dummy3) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(hosts_ops, 4347c478bd9Sstevel@tonic-gate sizeof (hosts_ops)/sizeof (hosts_ops[0]), _HOSTS, 435cb5caa98Sdjl hosts_attrs, _nss_ldap_hosts2str)); 4367c478bd9Sstevel@tonic-gate } 437