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 * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <netdb.h> 30 #include <netinet/in.h> 31 #include <arpa/inet.h> 32 #include <sys/socket.h> 33 #include "ldap_common.h" 34 35 /* netmasks attributes filters */ 36 #define _N_NETWORK "ipnetworknumber" 37 #define _N_NETMASK "ipnetmasknumber" 38 39 #define _F_GETMASKBYNET "(&(objectClass=ipNetwork)(ipNetworkNumber=%s))" 40 #define _F_GETMASKBYNET_SSD "(&(%%s)(ipNetworkNumber=%s))" 41 42 static const char *netmasks_attrs[] = { 43 _N_NETWORK, 44 _N_NETMASK, 45 (char *)NULL 46 }; 47 48 49 /* 50 * _nss_ldap_netmasks2ent is the data marshaling method for the netmasks 51 * getXbyY * (e.g., getbynet()) backend processes. This method is called 52 * after a successful ldap search has been performed. This method will 53 * parse the ldap search values into struct in_addr *mask = argp->buf.result 54 * only if argp->buf.result is initialized (not NULL). Three error 55 * conditions are expected and returned to nsswitch. 56 */ 57 58 static int 59 _nss_ldap_netmasks2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) 60 { 61 int i, j; 62 int nss_result; 63 unsigned long len = 0L; 64 #ifdef DEBUG 65 char maskstr[16]; 66 #endif /* DEBUG */ 67 struct in_addr addr; 68 struct in_addr *mask = (struct in_addr *)NULL; 69 ns_ldap_result_t *result = be->result; 70 ns_ldap_attr_t *attrptr; 71 72 mask = (struct in_addr *)argp->buf.result; 73 nss_result = (int)NSS_STR_PARSE_SUCCESS; 74 75 attrptr = getattr(result, 0); 76 if (attrptr == NULL) { 77 nss_result = (int)NSS_STR_PARSE_PARSE; 78 goto result_nmks2ent; 79 } 80 81 for (i = 0; i < result->entry->attr_count; i++) { 82 attrptr = getattr(result, i); 83 if (attrptr == NULL) { 84 nss_result = (int)NSS_STR_PARSE_PARSE; 85 goto result_nmks2ent; 86 } 87 if (strcasecmp(attrptr->attrname, _N_NETMASK) == 0) { 88 for (j = 0; j < attrptr->value_count; j++) { 89 if (mask == NULL) 90 continue; 91 if ((attrptr->attrvalue[j] == NULL) || 92 (len = strlen(attrptr->attrvalue[j])) < 1) { 93 nss_result = (int)NSS_STR_PARSE_PARSE; 94 goto result_nmks2ent; 95 } 96 /* addr a IPv4 address and 32 bits */ 97 addr.s_addr = inet_addr(attrptr->attrvalue[j]); 98 if (addr.s_addr == 0xffffffffUL) { 99 nss_result = (int)NSS_STR_PARSE_PARSE; 100 goto result_nmks2ent; 101 } 102 mask->s_addr = addr.s_addr; 103 #ifdef DEBUG 104 strlcpy(maskstr, attrptr->attrvalue[j], 105 sizeof (maskstr)); 106 #endif /* DEBUG */ 107 continue; 108 } 109 } 110 } 111 112 #ifdef DEBUG 113 (void) fprintf(stdout, "\n[netmasks.c: _nss_ldap_netmasks2ent]\n"); 114 (void) fprintf(stdout, " netmask: [%s]\n", maskstr); 115 #endif /* DEBUG */ 116 117 result_nmks2ent: 118 119 (void) __ns_ldap_freeResult(&be->result); 120 return ((int)nss_result); 121 } 122 123 124 /* 125 * getbynet gets a network mask by address. This function constructs an 126 * ldap search filter using the netmask name invocation parameter and the 127 * getmaskbynet search filter defined. Once the filter is constructed, we 128 * search for a matching entry and marshal the data results into struct 129 * in_addr for the frontend process. The function _nss_ldap_netmasks2ent 130 * performs the data marshaling. 131 */ 132 133 static nss_status_t 134 getbynet(ldap_backend_ptr be, void *a) 135 { 136 nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 137 char searchfilter[SEARCHFILTERLEN]; 138 char userdata[SEARCHFILTERLEN]; 139 char netnumber[SEARCHFILTERLEN]; 140 int ret; 141 142 if (_ldap_filter_name(netnumber, argp->key.name, sizeof (netnumber)) 143 != 0) 144 return ((nss_status_t)NSS_NOTFOUND); 145 146 ret = snprintf(searchfilter, sizeof (searchfilter), 147 _F_GETMASKBYNET, netnumber); 148 if (ret >= sizeof (searchfilter) || ret < 0) 149 return ((nss_status_t)NSS_NOTFOUND); 150 151 ret = snprintf(userdata, sizeof (userdata), 152 _F_GETMASKBYNET_SSD, netnumber); 153 if (ret >= sizeof (userdata) || ret < 0) 154 return ((nss_status_t)NSS_NOTFOUND); 155 156 return ((nss_status_t)_nss_ldap_lookup(be, argp, 157 _NETMASKS, searchfilter, NULL, 158 _merge_SSD_filter, userdata)); 159 } 160 161 162 static ldap_backend_op_t netmasks_ops[] = { 163 _nss_ldap_destr, 164 getbynet 165 }; 166 167 168 /* 169 * _nss_ldap_netmasks_constr is where life begins. This function calls 170 * the generic ldap constructor function to define and build the abstract 171 * data types required to support ldap operations. 172 */ 173 174 /*ARGSUSED0*/ 175 nss_backend_t * 176 _nss_ldap_netmasks_constr(const char *dummy1, const char *dummy2, 177 const char *dummy3) 178 { 179 180 return ((nss_backend_t *)_nss_ldap_constr(netmasks_ops, 181 sizeof (netmasks_ops)/sizeof (netmasks_ops[0]), _NETMASKS, 182 netmasks_attrs, _nss_ldap_netmasks2ent)); 183 } 184