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