10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*2830Sdjl * Common Development and Distribution License (the "License"). 6*2830Sdjl * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 22*2830Sdjl * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/types.h> 290Sstevel@tonic-gate #include <sys/socket.h> 300Sstevel@tonic-gate #include <net/if.h> 310Sstevel@tonic-gate #include <netinet/in.h> 320Sstevel@tonic-gate #include <net/if_arp.h> 330Sstevel@tonic-gate #include <netinet/if_ether.h> 340Sstevel@tonic-gate #include "ldap_common.h" 350Sstevel@tonic-gate 360Sstevel@tonic-gate /* ether attributes filters */ 370Sstevel@tonic-gate #define _E_HOSTNAME "cn" 380Sstevel@tonic-gate #define _E_MACADDRESS "macaddress" 390Sstevel@tonic-gate #define _F_GETETHERBYHOST "(&(objectClass=ieee802Device)(cn=%s))" 400Sstevel@tonic-gate #define _F_GETETHERBYHOST_SSD "(&(%%s)(cn=%s))" 410Sstevel@tonic-gate #define _F_GETETHERBYETHER "(&(objectClass=ieee802Device)(macAddress=%s))" 420Sstevel@tonic-gate #define _F_GETETHERBYETHER_SSD "(&(%%s)(macAddress=%s))" 430Sstevel@tonic-gate 440Sstevel@tonic-gate static const char *ethers_attrs[] = { 450Sstevel@tonic-gate _E_HOSTNAME, 460Sstevel@tonic-gate _E_MACADDRESS, 470Sstevel@tonic-gate (char *)NULL 480Sstevel@tonic-gate }; 490Sstevel@tonic-gate 500Sstevel@tonic-gate /* 51*2830Sdjl * _nss_ldap_ethers2str is the data marshaling method for the ethers 52*2830Sdjl * ether_hostton/ether_ntohost backend processes. 53*2830Sdjl * This method is called after a successful ldap search has been performed. 54*2830Sdjl * This method will parse the ldap search values into the file format. 55*2830Sdjl * e.g. 560Sstevel@tonic-gate * 57*2830Sdjl * 8:0:20:8e:eb:8a8 borealis 580Sstevel@tonic-gate * 59*2830Sdjl * The front end marshaller str2ether uses argp->buf.result for a different 60*2830Sdjl * purpose so a flag be->db_type is set to work around this oddity. 610Sstevel@tonic-gate * 620Sstevel@tonic-gate */ 63*2830Sdjl /*ARGSUSED0*/ 640Sstevel@tonic-gate static int 65*2830Sdjl _nss_ldap_ethers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) 660Sstevel@tonic-gate { 670Sstevel@tonic-gate int nss_result; 680Sstevel@tonic-gate ns_ldap_result_t *result = be->result; 69*2830Sdjl char **host, **macaddress; 700Sstevel@tonic-gate 71*2830Sdjl if (result == NULL) 72*2830Sdjl return (NSS_STR_PARSE_PARSE); 73*2830Sdjl nss_result = NSS_STR_PARSE_SUCCESS; 74*2830Sdjl 75*2830Sdjl host = __ns_ldap_getAttr(result->entry, _E_HOSTNAME); 76*2830Sdjl if (host == NULL || host[0] == NULL || (strlen(host[0]) < 1)) { 77*2830Sdjl nss_result = NSS_STR_PARSE_PARSE; 78*2830Sdjl goto result_ea2str; 790Sstevel@tonic-gate } 80*2830Sdjl macaddress = __ns_ldap_getAttr(result->entry, _E_MACADDRESS); 81*2830Sdjl if (macaddress == NULL || macaddress[0] == NULL || 82*2830Sdjl (strlen(macaddress[0]) < 1)) { 83*2830Sdjl nss_result = NSS_STR_PARSE_PARSE; 84*2830Sdjl goto result_ea2str; 850Sstevel@tonic-gate } 86*2830Sdjl be->buflen = strlen(host[0]) + strlen(macaddress[0]) + 1; /* ' ' */ 87*2830Sdjl /* Add a trailing null for easy debug */ 88*2830Sdjl be->buffer = calloc(1, be->buflen + 1); 89*2830Sdjl if (be->buffer == NULL) { 90*2830Sdjl nss_result = NSS_STR_PARSE_PARSE; 91*2830Sdjl goto result_ea2str; 920Sstevel@tonic-gate } 930Sstevel@tonic-gate 94*2830Sdjl (void) snprintf(be->buffer, be->buflen + 1, "%s %s", 95*2830Sdjl macaddress[0], host[0]); 96*2830Sdjl be->db_type = NSS_LDAP_DB_ETHERS; 970Sstevel@tonic-gate 98*2830Sdjl result_ea2str: 990Sstevel@tonic-gate 1000Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 101*2830Sdjl return (nss_result); 1020Sstevel@tonic-gate } 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate /* 1050Sstevel@tonic-gate * getbyhost gets an ethernet address by hostname. This function 1060Sstevel@tonic-gate * constructs an ldap search filter using the hostname invocation 1070Sstevel@tonic-gate * parameter and the getetherbyhost search filter defined. Once 1080Sstevel@tonic-gate * the filter is constructed, we search for a matching entry and 1090Sstevel@tonic-gate * marshal the data results into uchar_t *ether for the frontend 1100Sstevel@tonic-gate * process. The function _nss_ldap_ethers2ent performs the data 1110Sstevel@tonic-gate * marshaling. 1120Sstevel@tonic-gate * 1130Sstevel@tonic-gate * RFC 2307, An Approach for Using LDAP as a Network Information Service, 1140Sstevel@tonic-gate * indicates that dn's be fully qualified. Host name searches will be on 1150Sstevel@tonic-gate * fully qualified host names (e.g., foo.bar.sun.com). 1160Sstevel@tonic-gate */ 1170Sstevel@tonic-gate 1180Sstevel@tonic-gate static nss_status_t 1190Sstevel@tonic-gate getbyhost(ldap_backend_ptr be, void *a) 1200Sstevel@tonic-gate { 1210Sstevel@tonic-gate char hostname[3 * MAXHOSTNAMELEN]; 1220Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 1230Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 1240Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 1250Sstevel@tonic-gate int ret; 126*2830Sdjl nss_status_t rc; 1270Sstevel@tonic-gate 1280Sstevel@tonic-gate if (_ldap_filter_name(hostname, argp->key.name, sizeof (hostname)) != 0) 1290Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 1320Sstevel@tonic-gate _F_GETETHERBYHOST, hostname); 133*2830Sdjl 1340Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 1350Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1360Sstevel@tonic-gate 1370Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), 1380Sstevel@tonic-gate _F_GETETHERBYHOST_SSD, hostname); 139*2830Sdjl 1400Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 1410Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1420Sstevel@tonic-gate 143*2830Sdjl rc = (nss_status_t)_nss_ldap_lookup(be, argp, 1440Sstevel@tonic-gate _ETHERS, searchfilter, NULL, 145*2830Sdjl _merge_SSD_filter, userdata); 146*2830Sdjl 147*2830Sdjl return (rc); 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate /* 1520Sstevel@tonic-gate * getbyether gets an ethernet address by ethernet address. This 1530Sstevel@tonic-gate * function constructs an ldap search filter using the ASCII 1540Sstevel@tonic-gate * ethernet address invocation parameter and the getetherbyether 1550Sstevel@tonic-gate * search filter defined. Once the filter is constructed, we 1560Sstevel@tonic-gate * search for a matching entry and marshal the data results into 1570Sstevel@tonic-gate * uchar_t *ether for the frontend process. The function 1580Sstevel@tonic-gate * _nss_ldap_ethers2ent performs the data marshaling. 1590Sstevel@tonic-gate */ 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate static nss_status_t 1620Sstevel@tonic-gate getbyether(ldap_backend_ptr be, void *a) 1630Sstevel@tonic-gate { 1640Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 1650Sstevel@tonic-gate char etherstr[18]; 1660Sstevel@tonic-gate uchar_t *e = argp->key.ether; 1670Sstevel@tonic-gate char searchfilter[SEARCHFILTERLEN]; 1680Sstevel@tonic-gate char userdata[SEARCHFILTERLEN]; 1690Sstevel@tonic-gate int ret; 1700Sstevel@tonic-gate 1710Sstevel@tonic-gate ret = snprintf(etherstr, sizeof (etherstr), "%x:%x:%x:%x:%x:%x", 1720Sstevel@tonic-gate *e, *(e + 1), *(e + 2), *(e + 3), *(e + 4), *(e + 5)); 1730Sstevel@tonic-gate if (ret >= sizeof (etherstr) || ret < 0) 1740Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1750Sstevel@tonic-gate 1760Sstevel@tonic-gate ret = snprintf(searchfilter, sizeof (searchfilter), 1770Sstevel@tonic-gate _F_GETETHERBYETHER, etherstr); 1780Sstevel@tonic-gate if (ret >= sizeof (searchfilter) || ret < 0) 1790Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1800Sstevel@tonic-gate 1810Sstevel@tonic-gate ret = snprintf(userdata, sizeof (userdata), 1820Sstevel@tonic-gate _F_GETETHERBYETHER_SSD, etherstr); 1830Sstevel@tonic-gate if (ret >= sizeof (userdata) || ret < 0) 1840Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 1850Sstevel@tonic-gate 1860Sstevel@tonic-gate return ((nss_status_t)_nss_ldap_lookup(be, argp, 1870Sstevel@tonic-gate _ETHERS, searchfilter, NULL, 1880Sstevel@tonic-gate _merge_SSD_filter, userdata)); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate static ldap_backend_op_t ethers_ops[] = { 1930Sstevel@tonic-gate _nss_ldap_destr, 1940Sstevel@tonic-gate getbyhost, 1950Sstevel@tonic-gate getbyether 1960Sstevel@tonic-gate }; 1970Sstevel@tonic-gate 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate /* 2000Sstevel@tonic-gate * _nss_ldap_ethers_constr is where life begins. This function calls the 2010Sstevel@tonic-gate * generic ldap constructor function to define and build the abstract 2020Sstevel@tonic-gate * data types required to support ldap operations. 2030Sstevel@tonic-gate */ 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate /*ARGSUSED0*/ 2060Sstevel@tonic-gate nss_backend_t * 2070Sstevel@tonic-gate _nss_ldap_ethers_constr(const char *dummy1, const char *dummy2, 2080Sstevel@tonic-gate const char *dummy3) 2090Sstevel@tonic-gate { 2100Sstevel@tonic-gate 2110Sstevel@tonic-gate return ((nss_backend_t *)_nss_ldap_constr(ethers_ops, 2120Sstevel@tonic-gate sizeof (ethers_ops)/sizeof (ethers_ops[0]), _ETHERS, 213*2830Sdjl ethers_attrs, _nss_ldap_ethers2str)); 2140Sstevel@tonic-gate } 215