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 2004 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 <sys/systeminfo.h> 30 #include "ldap_common.h" 31 32 33 #ifdef DEBUG 34 /* 35 * Debugging routine for printing the value of a result 36 * structure 37 */ 38 int 39 printresult(ns_ldap_result_t *result) 40 { 41 int i, j, k; 42 ns_ldap_entry_t *curEntry; 43 44 printf("--------------------------------------\n"); 45 printf("entries_count %d\n", result->entries_count); 46 curEntry = result->entry; 47 for (i = 0; i < result->entries_count; i++) { 48 printf("entry %d has attr_count = %d \n", 49 i, curEntry->attr_count); 50 for (j = 0; j < curEntry->attr_count; j++) { 51 printf("entry %d has attr_pair[%d] = %s \n", 52 i, j, curEntry->attr_pair[j]->attrname); 53 for (k = 0; 54 (k < curEntry->attr_pair[j]->value_count) && 55 (curEntry->attr_pair[j]->attrvalue[k]); 56 k++) 57 printf("entry %d has " 58 "attr_pair[%d]->attrvalue[%d] = %s \n", 59 i, j, k, 60 curEntry->attr_pair[j]->attrvalue[k]); 61 } 62 printf("\n--------------------------------------\n"); 63 curEntry = curEntry->next; 64 } 65 return (1); 66 } 67 #endif 68 69 70 /* 71 * 72 */ 73 74 ns_ldap_attr_t * 75 getattr(ns_ldap_result_t *result, int i) 76 { 77 ns_ldap_entry_t *entry; 78 79 #ifdef DEBUG 80 (void) fprintf(stdout, "\n[ldap_utils.c: getattr]\n"); 81 #endif /* DEBUG */ 82 83 if (result != NULL) { 84 entry = result->entry; 85 } else { 86 return (NULL); 87 } 88 if (result->entries_count == 0) { 89 return (NULL); 90 } else { 91 return (entry->attr_pair[i]); 92 } 93 } 94 95 /* 96 * _get_domain_name() passes the dn one level up from cdn, e.g., 97 * a pointer pointing to "ou= ..." for the cdn's listed below: 98 * dn: cn=hostname+ipHostNumber="109.34.54.76", ou= ... 99 * dn: echo+IpServiceProtocol=udp, ou= ... 100 * to __ns_ldap_dn2domain() to retrieve the domain name associated 101 * with cdn. 102 */ 103 104 char * 105 _get_domain_name(char *cdn) 106 { 107 char **rdns; 108 char *pdn, *domain = NULL; 109 int nrdns; 110 int len = 0; 111 const ns_cred_t *cred = NULL; 112 ns_ldap_error_t *error; 113 114 /* break the cdn into its components */ 115 rdns = ldap_explode_dn(cdn, 0); 116 if (rdns == NULL || *rdns == NULL) 117 return (NULL); 118 119 /* construct parent dn */ 120 for (nrdns = 1; rdns[nrdns]; nrdns++) 121 len += strlen(rdns[nrdns]) + 1; 122 if (len == 0) 123 len = strlen(rdns[0]); 124 pdn = (char *)malloc(len + 1); 125 if (pdn == NULL) { 126 ldap_value_free(rdns); 127 return (NULL); 128 } 129 130 *pdn = '\0'; 131 if (nrdns == 1) 132 (void) strcat(pdn, rdns[0]); 133 else { 134 for (nrdns = 1; rdns[nrdns]; nrdns++) { 135 (void) strcat(pdn, rdns[nrdns]); 136 (void) strcat(pdn, ","); 137 } 138 /* remove the last ',' */ 139 pdn[strlen(pdn) - 1] = '\0'; 140 } 141 /* get domain name */ 142 (void) __ns_ldap_dn2domain(pdn, &domain, cred, &error); 143 144 ldap_value_free(rdns); 145 free(pdn); 146 return (domain); 147 } 148 149 150 /* 151 * "109.34.54.76" -> 109.34.54.76 152 */ 153 154 const char * 155 _strip_quotes(char *ipaddress) 156 { 157 char *cp = (char *)NULL; 158 159 /* look for first " */ 160 if ((cp = strchr(ipaddress, '"')) == NULL) 161 return ((char *)ipaddress); 162 ipaddress++; 163 /* look for last " */ 164 if ((cp = strchr(ipaddress, '"')) == NULL) 165 return ((char *)ipaddress); 166 *cp++ = '\0'; 167 168 return (ipaddress); 169 } 170 171 172 /* 173 * This is a copy of a routine in libnsl/nss/netdir_inet.c. It is 174 * here because /etc/lib/nss_ldap.so.1 cannot call routines in 175 * libnsl. Care should be taken to keep the two copies in sync. 176 */ 177 178 int 179 __nss2herrno(nss_status_t nsstat) 180 { 181 switch (nsstat) { 182 case NSS_SUCCESS: 183 return (0); 184 case NSS_NOTFOUND: 185 return (HOST_NOT_FOUND); 186 case NSS_TRYAGAIN: 187 return (TRY_AGAIN); 188 case NSS_UNAVAIL: 189 default: /* keep gcc happy */ 190 return (NO_RECOVERY); 191 } 192 /* NOTREACHED */ 193 } 194 195 /* 196 * This is a generic filter call back function for 197 * merging the filter from service search descriptor with 198 * an existing search filter. This routine expects userdata 199 * contain a format string with a single %s in it, and will 200 * use the format string with sprintf() to insert the SSD filter. 201 * 202 * This routine is passed to the __ns_ldap_list() or 203 * __ns_ldap_firstEntry() APIs as the filter call back 204 * together with the userdata. For example, 205 * the gethostbyname processing may call __ns_ldap_list() with 206 * "(&(objectClass=ipHost)(cn=sys1))" as filter, this function 207 * as the filter call back, and "(&(%s)(cn=sys1))" as the 208 * userdata, this routine will in turn gets call to produce 209 * "(&(department=sds)(cn=sys1))" as the real search 210 * filter, if the input SSD contains a filter "department=sds". 211 */ 212 int 213 _merge_SSD_filter(const ns_ldap_search_desc_t *desc, 214 char **realfilter, 215 const void *userdata) 216 { 217 int len; 218 219 #ifdef DEBUG 220 (void) fprintf(stdout, "\n[ldap_utils.c: _merge_SSD_filter]\n"); 221 #endif /* DEBUG */ 222 223 /* sanity check */ 224 if (realfilter == NULL) 225 return (NS_LDAP_INVALID_PARAM); 226 *realfilter = NULL; 227 228 if (desc == NULL || desc->filter == NULL || 229 userdata == NULL) 230 return (NS_LDAP_INVALID_PARAM); 231 232 #ifdef DEBUG 233 (void) fprintf(stdout, "\n[userdata: %s]\n", (char *)userdata); 234 (void) fprintf(stdout, "\n[SSD filter: %s]\n", desc->filter); 235 #endif /* DEBUG */ 236 237 len = strlen(userdata) + strlen(desc->filter) + 1; 238 239 *realfilter = (char *)malloc(len); 240 if (*realfilter == NULL) 241 return (NS_LDAP_MEMORY); 242 243 (void) sprintf(*realfilter, (char *)userdata, 244 desc->filter); 245 246 #ifdef DEBUG 247 (void) fprintf(stdout, "\n[new filter: %s]\n", *realfilter); 248 #endif /* DEBUG */ 249 250 return (NS_LDAP_SUCCESS); 251 } 252 253 static char 254 hex_char(int n) 255 { 256 return ("0123456789abcdef"[n & 0xf]); 257 } 258 259 int 260 _ldap_filter_name(char *filter_name, const char *name, int filter_name_size) 261 { 262 char *end = filter_name + filter_name_size; 263 char c; 264 265 for (; *name; name++) { 266 c = *name; 267 switch (c) { 268 case '*': 269 case '(': 270 case ')': 271 case '\\': 272 if (end <= filter_name + 3) 273 return (-1); 274 *filter_name++ = '\\'; 275 *filter_name++ = hex_char(c >> 4); 276 *filter_name++ = hex_char(c & 0xf); 277 break; 278 default: 279 if (end <= filter_name + 1) 280 return (-1); 281 *filter_name++ = c; 282 break; 283 } 284 } 285 if (end <= filter_name) 286 return (-1); 287 *filter_name = '\0'; 288 return (0); 289 } 290