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 545916cd2Sjpk * Common Development and Distribution License (the "License"). 645916cd2Sjpk * 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*9f2fd570SJulian Pullen * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #include "ldap_common.h" 267c478bd9Sstevel@tonic-gate #include <malloc.h> 277c478bd9Sstevel@tonic-gate #include <synch.h> 287c478bd9Sstevel@tonic-gate #include <syslog.h> 297c478bd9Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 307c478bd9Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 317c478bd9Sstevel@tonic-gate #include <thread.h> 327c478bd9Sstevel@tonic-gate #include <ctype.h> 337c478bd9Sstevel@tonic-gate #include <stdlib.h> 347c478bd9Sstevel@tonic-gate #include <signal.h> 357c478bd9Sstevel@tonic-gate #include <sys/stat.h> 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /* getent attributes filters */ 387c478bd9Sstevel@tonic-gate #define _F_GETALIASENT "(objectClass=rfc822MailGroup)" 397c478bd9Sstevel@tonic-gate #define _F_GETAUTHNAME "(objectClass=SolarisAuthAttr)" 407c478bd9Sstevel@tonic-gate #define _F_GETAUUSERNAME "(objectClass=SolarisAuditUser)" 417c478bd9Sstevel@tonic-gate #define _F_GETEXECNAME "(objectClass=SolarisExecAttr)" 427c478bd9Sstevel@tonic-gate #define _F_GETGRENT "(objectClass=posixGroup)" 437c478bd9Sstevel@tonic-gate #define _F_GETHOSTENT "(objectClass=ipHost)" 447c478bd9Sstevel@tonic-gate #define _F_GETNETENT "(objectClass=ipNetwork)" 45cb5caa98Sdjl #define _F_GETPROFNAME \ 46cb5caa98Sdjl "(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*)))" 477c478bd9Sstevel@tonic-gate #define _F_GETPROTOENT "(objectClass=ipProtocol)" 487c478bd9Sstevel@tonic-gate #define _F_GETPWENT "(objectClass=posixAccount)" 497c478bd9Sstevel@tonic-gate #define _F_GETPRINTERENT "(objectClass=sunPrinter)" 507c478bd9Sstevel@tonic-gate #define _F_GETRPCENT "(objectClass=oncRpc)" 517c478bd9Sstevel@tonic-gate #define _F_GETSERVENT "(objectClass=ipService)" 527c478bd9Sstevel@tonic-gate #define _F_GETSPENT "(objectclass=shadowAccount)" 537c478bd9Sstevel@tonic-gate #define _F_GETUSERNAME "(objectClass=SolarisUserAttr)" 547c478bd9Sstevel@tonic-gate #define _F_GETPROJENT "(objectClass=SolarisProject)" 5545916cd2Sjpk #define _F_GETTNRHDB "(objectClass=ipTnetHost)" 5645916cd2Sjpk #define _F_GETTNRHTP "(&(objectClass=ipTnetTemplate)"\ 5745916cd2Sjpk "(SolarisAttrKeyValue=*))" 587c478bd9Sstevel@tonic-gate #define _F_GETENT_SSD "(%s)" 597c478bd9Sstevel@tonic-gate 60*9f2fd570SJulian Pullen /* getent sort attributes */ 61*9f2fd570SJulian Pullen #define _A_UID "uid" 62*9f2fd570SJulian Pullen #define _A_GIDNUMBER "gidnumber" 63*9f2fd570SJulian Pullen #define _A_CN "cn" 64*9f2fd570SJulian Pullen #define _A_IPNETWORKNUM "ipnetworknumber" 65*9f2fd570SJulian Pullen #define _A_PROJECTNAM "SolarisProjectName" 66*9f2fd570SJulian Pullen #define _A_IPTNETNUM "ipTnetNumber" 67*9f2fd570SJulian Pullen #define _A_IPTNETTMPLNAM "ipTnetTemplateName" 68*9f2fd570SJulian Pullen 697c478bd9Sstevel@tonic-gate static struct gettablefilter { 707c478bd9Sstevel@tonic-gate char *tablename; 717c478bd9Sstevel@tonic-gate char *tablefilter; 72*9f2fd570SJulian Pullen char *sortattr; 737c478bd9Sstevel@tonic-gate } gettablefilterent[] = { 74*9f2fd570SJulian Pullen {(char *)_PASSWD, (char *)_F_GETPWENT, (char *)_A_UID}, 75*9f2fd570SJulian Pullen {(char *)_SHADOW, (char *)_F_GETSPENT, (char *)_A_UID}, 76*9f2fd570SJulian Pullen {(char *)_GROUP, (char *)_F_GETGRENT, (char *)_A_GIDNUMBER}, 77*9f2fd570SJulian Pullen {(char *)_HOSTS, (char *)_F_GETHOSTENT, (char *)_A_CN}, 78*9f2fd570SJulian Pullen {(char *)_NETWORKS, (char *)_F_GETNETENT, 79*9f2fd570SJulian Pullen (char *)_A_IPNETWORKNUM}, 80*9f2fd570SJulian Pullen {(char *)_PROTOCOLS, (char *)_F_GETPROTOENT, (char *)_A_CN}, 81*9f2fd570SJulian Pullen {(char *)_RPC, (char *)_F_GETRPCENT, (char *)_A_CN}, 82*9f2fd570SJulian Pullen {(char *)_ALIASES, (char *)_F_GETALIASENT, (char *)_A_CN}, 83*9f2fd570SJulian Pullen {(char *)_SERVICES, (char *)_F_GETSERVENT, (char *)_A_CN}, 84*9f2fd570SJulian Pullen {(char *)_AUUSER, (char *)_F_GETAUUSERNAME, 85*9f2fd570SJulian Pullen (char *)_A_UID}, 86*9f2fd570SJulian Pullen {(char *)_AUTHATTR, (char *)_F_GETAUTHNAME, (char *)_A_CN}, 87*9f2fd570SJulian Pullen {(char *)_EXECATTR, (char *)_F_GETEXECNAME, (char *)_A_CN}, 88*9f2fd570SJulian Pullen {(char *)_PROFATTR, (char *)_F_GETPROFNAME, (char *)_A_CN}, 89*9f2fd570SJulian Pullen {(char *)_USERATTR, (char *)_F_GETUSERNAME, (char *)_A_UID}, 90*9f2fd570SJulian Pullen {(char *)_PROJECT, (char *)_F_GETPROJENT, (char *)_A_PROJECTNAM}, 91*9f2fd570SJulian Pullen {(char *)_PRINTERS, (char *)_F_GETPRINTERENT, (char *)_A_CN}, 92*9f2fd570SJulian Pullen {(char *)_TNRHDB, (char *)_F_GETTNRHDB, (char *)_A_IPTNETNUM}, 93*9f2fd570SJulian Pullen {(char *)_TNRHTP, (char *)_F_GETTNRHTP, 94*9f2fd570SJulian Pullen (char *)_A_IPTNETTMPLNAM}, 95*9f2fd570SJulian Pullen {(char *)NULL, (char *)NULL, (char *)NULL} 967c478bd9Sstevel@tonic-gate }; 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate 993d047983Smichen nss_status_t 1007c478bd9Sstevel@tonic-gate switch_err(int rc, ns_ldap_error_t *error) 1017c478bd9Sstevel@tonic-gate { 1027c478bd9Sstevel@tonic-gate switch (rc) { 1037c478bd9Sstevel@tonic-gate case NS_LDAP_SUCCESS: 1047c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 1057c478bd9Sstevel@tonic-gate 1067c478bd9Sstevel@tonic-gate case NS_LDAP_NOTFOUND: 1077c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 1087c478bd9Sstevel@tonic-gate 1097c478bd9Sstevel@tonic-gate case NS_LDAP_PARTIAL: 1107c478bd9Sstevel@tonic-gate return (NSS_TRYAGAIN); 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate case NS_LDAP_INTERNAL: 1137c478bd9Sstevel@tonic-gate if (error && (error->status == LDAP_SERVER_DOWN || 1147c478bd9Sstevel@tonic-gate error->status == LDAP_TIMEOUT)) 1157c478bd9Sstevel@tonic-gate return (NSS_TRYAGAIN); 1167c478bd9Sstevel@tonic-gate else 1177c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate default: 1207c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate } 123cb5caa98Sdjl /* ARGSUSED */ 1247c478bd9Sstevel@tonic-gate nss_status_t 1257c478bd9Sstevel@tonic-gate _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, 1267c478bd9Sstevel@tonic-gate char *database, char *searchfilter, char *domain, 1277c478bd9Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 1287c478bd9Sstevel@tonic-gate char **realfilter, const void *userdata), 1297c478bd9Sstevel@tonic-gate const void *userdata) 1307c478bd9Sstevel@tonic-gate { 1317c478bd9Sstevel@tonic-gate int callbackstat = 0; 1327c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 1337c478bd9Sstevel@tonic-gate int rc; 1347c478bd9Sstevel@tonic-gate 1357c478bd9Sstevel@tonic-gate #ifdef DEBUG 1367c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_lookup]\n"); 1377c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter); 1387c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 1397c478bd9Sstevel@tonic-gate "\tuserdata: %s\n", userdata ? userdata : "NULL"); 1407c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database); 1417c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb, 1467c478bd9Sstevel@tonic-gate be->attrs, NULL, 0, &be->result, &error, NULL, 1477c478bd9Sstevel@tonic-gate userdata)) != NS_LDAP_SUCCESS) { 1487c478bd9Sstevel@tonic-gate argp->returnval = 0; 1497c478bd9Sstevel@tonic-gate rc = switch_err(rc, error); 1507c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 151cb5caa98Sdjl 1527c478bd9Sstevel@tonic-gate return (rc); 1537c478bd9Sstevel@tonic-gate } 154cb5caa98Sdjl (void) __ns_ldap_freeError(&error); 1557c478bd9Sstevel@tonic-gate /* callback function */ 1567c478bd9Sstevel@tonic-gate if ((callbackstat = 157cb5caa98Sdjl be->ldapobj2str(be, argp)) != NSS_STR_PARSE_SUCCESS) { 158cb5caa98Sdjl goto error_out; 159cb5caa98Sdjl } 160cb5caa98Sdjl 161cb5caa98Sdjl /* 162cb5caa98Sdjl * publickey does not have a front end marshaller and expects 163cb5caa98Sdjl * a string to be returned in NSS. 164cb5caa98Sdjl * No need to convert file format -> struct. 165cb5caa98Sdjl * 166cb5caa98Sdjl */ 167cb5caa98Sdjl if (be->db_type == NSS_LDAP_DB_PUBLICKEY) { 168cb5caa98Sdjl argp->returnval = argp->buf.buffer; 169cb5caa98Sdjl argp->returnlen = strlen(argp->buf.buffer); 170cb5caa98Sdjl be->db_type = NSS_LDAP_DB_NONE; 171cb5caa98Sdjl return (NSS_SUCCESS); 172cb5caa98Sdjl } 173cb5caa98Sdjl /* 174cb5caa98Sdjl * Assume the switch engine wants the returned data in the file 175cb5caa98Sdjl * format when argp->buf.result == NULL. 176cb5caa98Sdjl * The front-end marshaller str2ether(ethers) uses 177cb5caa98Sdjl * ent (argp->buf.result) and buffer (argp->buf.buffer) 178cb5caa98Sdjl * for different purpose so ethers has to be treated differently. 179cb5caa98Sdjl */ 180cb5caa98Sdjl if (argp->buf.result != NULL || 181cb5caa98Sdjl be->db_type == NSS_LDAP_DB_ETHERS) { 182cb5caa98Sdjl /* file format -> struct */ 183cb5caa98Sdjl if (argp->str2ent == NULL) { 184cb5caa98Sdjl callbackstat = NSS_STR_PARSE_PARSE; 185cb5caa98Sdjl goto error_out; 186cb5caa98Sdjl } 187cb5caa98Sdjl 188cb5caa98Sdjl callbackstat = (*argp->str2ent)(be->buffer, 189cb5caa98Sdjl be->buflen, 190cb5caa98Sdjl argp->buf.result, 191cb5caa98Sdjl argp->buf.buffer, 192cb5caa98Sdjl argp->buf.buflen); 193cb5caa98Sdjl if (callbackstat == NSS_STR_PARSE_SUCCESS) { 194cb5caa98Sdjl if (be->db_type == NSS_LDAP_DB_ETHERS && 195cb5caa98Sdjl argp->buf.buffer != NULL) { 196cb5caa98Sdjl argp->returnval = argp->buf.buffer; 197cb5caa98Sdjl argp->returnlen = strlen(argp->buf.buffer); 198cb5caa98Sdjl } else { 1997c478bd9Sstevel@tonic-gate argp->returnval = argp->buf.result; 200cb5caa98Sdjl argp->returnlen = 1; /* irrelevant */ 201cb5caa98Sdjl } 202cb5caa98Sdjl if (be->buffer != NULL) { 203cb5caa98Sdjl free(be->buffer); 204cb5caa98Sdjl be->buffer = NULL; 205cb5caa98Sdjl be->buflen = 0; 206cb5caa98Sdjl be->db_type = NSS_LDAP_DB_NONE; 207cb5caa98Sdjl } 2087c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 2097c478bd9Sstevel@tonic-gate } 210cb5caa98Sdjl } else { 211cb5caa98Sdjl /* return file format in argp->buf.buffer */ 212cb5caa98Sdjl argp->returnval = argp->buf.buffer; 213cb5caa98Sdjl argp->returnlen = strlen(argp->buf.buffer); 214cb5caa98Sdjl return ((nss_status_t)NSS_SUCCESS); 215cb5caa98Sdjl } 2167c478bd9Sstevel@tonic-gate 217cb5caa98Sdjl error_out: 218cb5caa98Sdjl if (be->buffer != NULL) { 219cb5caa98Sdjl free(be->buffer); 220cb5caa98Sdjl be->buffer = NULL; 221cb5caa98Sdjl be->buflen = 0; 222cb5caa98Sdjl be->db_type = NSS_LDAP_DB_NONE; 223cb5caa98Sdjl } 2247c478bd9Sstevel@tonic-gate /* error */ 2257c478bd9Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_PARSE) { 2267c478bd9Sstevel@tonic-gate argp->returnval = 0; 2277c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2287c478bd9Sstevel@tonic-gate } 2297c478bd9Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_ERANGE) { 2307c478bd9Sstevel@tonic-gate argp->erange = 1; 2317c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2327c478bd9Sstevel@tonic-gate } 2337c478bd9Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_NO_ADDR) { 2347c478bd9Sstevel@tonic-gate /* No IPV4 address is found */ 2357c478bd9Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 2367c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2377c478bd9Sstevel@tonic-gate } 2387c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_UNAVAIL); 2397c478bd9Sstevel@tonic-gate } 2407c478bd9Sstevel@tonic-gate 2417c478bd9Sstevel@tonic-gate /* 2427c478bd9Sstevel@tonic-gate * This function is similar to _nss_ldap_lookup except it does not 2437c478bd9Sstevel@tonic-gate * do a callback. It is only used by getnetgrent.c 2447c478bd9Sstevel@tonic-gate */ 2457c478bd9Sstevel@tonic-gate 246cb5caa98Sdjl /* ARGSUSED */ 2477c478bd9Sstevel@tonic-gate nss_status_t 2487c478bd9Sstevel@tonic-gate _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, 2497c478bd9Sstevel@tonic-gate char *database, char *searchfilter, char *domain, 2507c478bd9Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 2517c478bd9Sstevel@tonic-gate char **realfilter, const void *userdata), 2527c478bd9Sstevel@tonic-gate const void *userdata) 2537c478bd9Sstevel@tonic-gate { 2547c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 2557c478bd9Sstevel@tonic-gate int rc; 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate #ifdef DEBUG 2587c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_nocb_lookup]\n"); 2597c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter); 2607c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database); 2617c478bd9Sstevel@tonic-gate (void) fprintf(stdout, 2627c478bd9Sstevel@tonic-gate "\tuserdata: %s\n", userdata ? userdata : "NULL"); 2637c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb, 2687c478bd9Sstevel@tonic-gate be->attrs, NULL, 0, &be->result, &error, NULL, 2697c478bd9Sstevel@tonic-gate userdata)) != NS_LDAP_SUCCESS) { 27018bdb8a7Smichen if (argp != NULL) 2717c478bd9Sstevel@tonic-gate argp->returnval = 0; 2727c478bd9Sstevel@tonic-gate rc = switch_err(rc, error); 2737c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 2747c478bd9Sstevel@tonic-gate return (rc); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 2787c478bd9Sstevel@tonic-gate } 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate 2817c478bd9Sstevel@tonic-gate /* 2827c478bd9Sstevel@tonic-gate * 2837c478bd9Sstevel@tonic-gate */ 2847c478bd9Sstevel@tonic-gate 2857c478bd9Sstevel@tonic-gate void 2867c478bd9Sstevel@tonic-gate _clean_ldap_backend(ldap_backend_ptr be) 2877c478bd9Sstevel@tonic-gate { 2887c478bd9Sstevel@tonic-gate ns_ldap_error_t *error; 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate #ifdef DEBUG 2917c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _clean_ldap_backend]\n"); 2927c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate if (be->tablename != NULL) 2957c478bd9Sstevel@tonic-gate free(be->tablename); 2967c478bd9Sstevel@tonic-gate if (be->result != NULL) 2977c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 2987c478bd9Sstevel@tonic-gate if (be->enumcookie != NULL) 2997c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error); 3007c478bd9Sstevel@tonic-gate if (be->services_cookie != NULL) 3017c478bd9Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie); 3027c478bd9Sstevel@tonic-gate if (be->toglue != NULL) { 3037c478bd9Sstevel@tonic-gate free(be->toglue); 3047c478bd9Sstevel@tonic-gate be->toglue = NULL; 3057c478bd9Sstevel@tonic-gate } 306cb5caa98Sdjl if (be->buffer != NULL) { 307cb5caa98Sdjl free(be->buffer); 308cb5caa98Sdjl be->buffer = NULL; 309cb5caa98Sdjl } 3107c478bd9Sstevel@tonic-gate free(be); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate /* 3157c478bd9Sstevel@tonic-gate * _nss_ldap_destr will free all smalloc'ed variable strings and structures 3167c478bd9Sstevel@tonic-gate * before exiting this nsswitch shared backend library. This function is 3177c478bd9Sstevel@tonic-gate * called before returning control back to nsswitch. 3187c478bd9Sstevel@tonic-gate */ 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 3217c478bd9Sstevel@tonic-gate nss_status_t 3227c478bd9Sstevel@tonic-gate _nss_ldap_destr(ldap_backend_ptr be, void *a) 3237c478bd9Sstevel@tonic-gate { 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate #ifdef DEBUG 3267c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_destr]\n"); 3277c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3287c478bd9Sstevel@tonic-gate 3297c478bd9Sstevel@tonic-gate (void) _clean_ldap_backend(be); 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate 3357c478bd9Sstevel@tonic-gate /* 3367c478bd9Sstevel@tonic-gate * _nss_ldap_setent called before _nss_ldap_getent. This function is 3377c478bd9Sstevel@tonic-gate * required by POSIX. 3387c478bd9Sstevel@tonic-gate */ 3397c478bd9Sstevel@tonic-gate 3407c478bd9Sstevel@tonic-gate nss_status_t 3417c478bd9Sstevel@tonic-gate _nss_ldap_setent(ldap_backend_ptr be, void *a) 3427c478bd9Sstevel@tonic-gate { 3437c478bd9Sstevel@tonic-gate struct gettablefilter *gtf; 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate #ifdef DEBUG 3467c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_setent]\n"); 3477c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate if (be->setcalled == 1) 3507c478bd9Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 3517c478bd9Sstevel@tonic-gate be->filter = NULL; 352*9f2fd570SJulian Pullen be->sortattr = NULL; 3537c478bd9Sstevel@tonic-gate for (gtf = gettablefilterent; gtf->tablename != (char *)NULL; gtf++) { 3547c478bd9Sstevel@tonic-gate if (strcmp(gtf->tablename, be->tablename)) 3557c478bd9Sstevel@tonic-gate continue; 3567c478bd9Sstevel@tonic-gate be->filter = (char *)gtf->tablefilter; 357*9f2fd570SJulian Pullen be->sortattr = (char *)gtf->sortattr; 3587c478bd9Sstevel@tonic-gate break; 3597c478bd9Sstevel@tonic-gate } 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate be->setcalled = 1; 3627c478bd9Sstevel@tonic-gate be->enumcookie = NULL; 3637c478bd9Sstevel@tonic-gate be->result = NULL; 3647c478bd9Sstevel@tonic-gate be->services_cookie = NULL; 365cb5caa98Sdjl be->buffer = NULL; 3667c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3677c478bd9Sstevel@tonic-gate } 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate /* 3717c478bd9Sstevel@tonic-gate * _nss_ldap_endent called after _nss_ldap_getent. This function is 3727c478bd9Sstevel@tonic-gate * required by POSIX. 3737c478bd9Sstevel@tonic-gate */ 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /*ARGSUSED1*/ 3767c478bd9Sstevel@tonic-gate nss_status_t 3777c478bd9Sstevel@tonic-gate _nss_ldap_endent(ldap_backend_ptr be, void *a) 3787c478bd9Sstevel@tonic-gate { 3797c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate #ifdef DEBUG 3827c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_endent]\n"); 3837c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate be->setcalled = 0; 3867c478bd9Sstevel@tonic-gate be->filter = NULL; 387*9f2fd570SJulian Pullen be->sortattr = NULL; 3887c478bd9Sstevel@tonic-gate if (be->enumcookie != NULL) { 3897c478bd9Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error); 3907c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 3917c478bd9Sstevel@tonic-gate } 3927c478bd9Sstevel@tonic-gate if (be->result != NULL) { 3937c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 3947c478bd9Sstevel@tonic-gate } 3957c478bd9Sstevel@tonic-gate if (be->services_cookie != NULL) { 3967c478bd9Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie); 3977c478bd9Sstevel@tonic-gate } 398cb5caa98Sdjl if (be->buffer != NULL) { 399cb5caa98Sdjl free(be->buffer); 400cb5caa98Sdjl be->buffer = NULL; 401cb5caa98Sdjl } 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 4047c478bd9Sstevel@tonic-gate } 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate /* 4087c478bd9Sstevel@tonic-gate * 4097c478bd9Sstevel@tonic-gate */ 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate nss_status_t 4127c478bd9Sstevel@tonic-gate _nss_ldap_getent(ldap_backend_ptr be, void *a) 4137c478bd9Sstevel@tonic-gate { 4147c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 4157c478bd9Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 4167c478bd9Sstevel@tonic-gate int parsestat = 0; 4177c478bd9Sstevel@tonic-gate int retcode = 0; 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate #ifdef DEBUG 4207c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_getent]\n"); 4217c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate if (be->setcalled == 0) 4247c478bd9Sstevel@tonic-gate (void) _nss_ldap_setent(be, a); 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate next_entry: 4277c478bd9Sstevel@tonic-gate if (be->enumcookie == NULL) { 4287c478bd9Sstevel@tonic-gate retcode = __ns_ldap_firstEntry(be->tablename, 429*9f2fd570SJulian Pullen be->filter, be->sortattr, _merge_SSD_filter, be->attrs, 430*9f2fd570SJulian Pullen NULL, 0, &be->enumcookie, 4317c478bd9Sstevel@tonic-gate &be->result, &error, _F_GETENT_SSD); 4327c478bd9Sstevel@tonic-gate } else { 4337c478bd9Sstevel@tonic-gate if (be->services_cookie == NULL) { 4347c478bd9Sstevel@tonic-gate retcode = __ns_ldap_nextEntry(be->enumcookie, 4357c478bd9Sstevel@tonic-gate &be->result, &error); 4367c478bd9Sstevel@tonic-gate } 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate if (retcode != NS_LDAP_SUCCESS) { 4397c478bd9Sstevel@tonic-gate retcode = switch_err(retcode, error); 4407c478bd9Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 4417c478bd9Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 4427c478bd9Sstevel@tonic-gate return (retcode); 443*9f2fd570SJulian Pullen } 444*9f2fd570SJulian Pullen 445*9f2fd570SJulian Pullen if (be->result == NULL) { 446*9f2fd570SJulian Pullen parsestat = NSS_STR_PARSE_NO_RESULT; 447*9f2fd570SJulian Pullen goto error_out; 448*9f2fd570SJulian Pullen } 449cb5caa98Sdjl /* ns_ldap_entry_t -> file format */ 450cb5caa98Sdjl if ((parsestat = be->ldapobj2str(be, argp)) 4517c478bd9Sstevel@tonic-gate == NSS_STR_PARSE_SUCCESS) { 452cb5caa98Sdjl if (argp->buf.result != NULL) { 453cb5caa98Sdjl /* file format -> struct */ 454cb5caa98Sdjl if (argp->str2ent == NULL) { 455*9f2fd570SJulian Pullen parsestat = NSS_STR_PARSE_NO_RESULT; 456cb5caa98Sdjl goto error_out; 457cb5caa98Sdjl } 458cb5caa98Sdjl parsestat = (*argp->str2ent)(be->buffer, 459cb5caa98Sdjl be->buflen, 460cb5caa98Sdjl argp->buf.result, 461cb5caa98Sdjl argp->buf.buffer, 462cb5caa98Sdjl argp->buf.buflen); 463cb5caa98Sdjl if (parsestat == NSS_STR_PARSE_SUCCESS) { 464cb5caa98Sdjl if (be->buffer != NULL) { 465cb5caa98Sdjl free(be->buffer); 466cb5caa98Sdjl be->buffer = NULL; 467cb5caa98Sdjl be->buflen = 0; 468cb5caa98Sdjl } 4697c478bd9Sstevel@tonic-gate be->result = NULL; 4707c478bd9Sstevel@tonic-gate argp->returnval = argp->buf.result; 471cb5caa98Sdjl argp->returnlen = 1; /* irrevelant */ 4727c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 4737c478bd9Sstevel@tonic-gate } 474cb5caa98Sdjl } else { 475cb5caa98Sdjl /* 476cb5caa98Sdjl * nscd is not caching the enumerated 477cb5caa98Sdjl * entries. This code path would be dormant. 478cb5caa98Sdjl * Keep this path for the future references. 479cb5caa98Sdjl */ 480cb5caa98Sdjl argp->returnval = argp->buf.buffer; 481cb5caa98Sdjl argp->returnlen = 482cb5caa98Sdjl strlen(argp->buf.buffer) + 1; 483cb5caa98Sdjl } 484cb5caa98Sdjl } 485cb5caa98Sdjl error_out: 486cb5caa98Sdjl if (be->buffer != NULL) { 487cb5caa98Sdjl free(be->buffer); 488cb5caa98Sdjl be->buffer = NULL; 489cb5caa98Sdjl be->buflen = 0; 490cb5caa98Sdjl } 4917c478bd9Sstevel@tonic-gate be->result = NULL; 492*9f2fd570SJulian Pullen if (parsestat == NSS_STR_PARSE_NO_RESULT) { 4937c478bd9Sstevel@tonic-gate argp->returnval = 0; 4947c478bd9Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 4957c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_ERANGE) { 4997c478bd9Sstevel@tonic-gate argp->erange = 1; 5007c478bd9Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 5017c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_NO_ADDR) 5047c478bd9Sstevel@tonic-gate /* 5057c478bd9Sstevel@tonic-gate * No IPV4 address is found in the current entry. 5067c478bd9Sstevel@tonic-gate * It indicates that the entry contains IPV6 addresses 5077c478bd9Sstevel@tonic-gate * only. Instead of calling _nss_ldap_endent to 5087c478bd9Sstevel@tonic-gate * terminate, get next entry to continue enumeration. 5097c478bd9Sstevel@tonic-gate * If it returned NSS_NOTFOUND here, 5107c478bd9Sstevel@tonic-gate * gethostent() would return NULL 5117c478bd9Sstevel@tonic-gate * and the enumeration would stop prematurely. 5127c478bd9Sstevel@tonic-gate */ 5137c478bd9Sstevel@tonic-gate goto next_entry; 514*9f2fd570SJulian Pullen 515*9f2fd570SJulian Pullen if (parsestat == NSS_STR_PARSE_PARSE) 516*9f2fd570SJulian Pullen /* 517*9f2fd570SJulian Pullen * There has been a parse error. Most likely some 518*9f2fd570SJulian Pullen * mandatory attributes are missing. Ignore the error 519*9f2fd570SJulian Pullen * and get the next entry. If we returned an error the 520*9f2fd570SJulian Pullen * enumeration would stop prematurely. 521*9f2fd570SJulian Pullen */ 522*9f2fd570SJulian Pullen goto next_entry; 5237c478bd9Sstevel@tonic-gate 5247c478bd9Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate /* 5297c478bd9Sstevel@tonic-gate * 5307c478bd9Sstevel@tonic-gate */ 5317c478bd9Sstevel@tonic-gate 5327c478bd9Sstevel@tonic-gate nss_backend_t * 5337c478bd9Sstevel@tonic-gate _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename, 534cb5caa98Sdjl const char **attrs, fnf ldapobj2str) 5357c478bd9Sstevel@tonic-gate { 5367c478bd9Sstevel@tonic-gate ldap_backend_ptr be; 5377c478bd9Sstevel@tonic-gate 5387c478bd9Sstevel@tonic-gate #ifdef DEBUG 5397c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_constr]\n"); 5407c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 5417c478bd9Sstevel@tonic-gate 542cb5caa98Sdjl if ((be = (ldap_backend_ptr) calloc(1, sizeof (*be))) == 0) 5437c478bd9Sstevel@tonic-gate return (0); 5447c478bd9Sstevel@tonic-gate be->ops = ops; 5457c478bd9Sstevel@tonic-gate be->nops = (nss_dbop_t)nops; 5467c478bd9Sstevel@tonic-gate be->tablename = (char *)strdup(tablename); 5477c478bd9Sstevel@tonic-gate be->attrs = attrs; 548cb5caa98Sdjl be->ldapobj2str = ldapobj2str; 5497c478bd9Sstevel@tonic-gate 5507c478bd9Sstevel@tonic-gate return ((nss_backend_t *)be); 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* 5557c478bd9Sstevel@tonic-gate * 5567c478bd9Sstevel@tonic-gate */ 5577c478bd9Sstevel@tonic-gate int 5587c478bd9Sstevel@tonic-gate chophostdomain(char *string, char *host, char *domain) 5597c478bd9Sstevel@tonic-gate { 5607c478bd9Sstevel@tonic-gate char *dot; 5617c478bd9Sstevel@tonic-gate 5627c478bd9Sstevel@tonic-gate if (string == NULL) 5637c478bd9Sstevel@tonic-gate return (-1); 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate if ((dot = strchr(string, '.')) == NULL) { 5667c478bd9Sstevel@tonic-gate return (0); 5677c478bd9Sstevel@tonic-gate } 5687c478bd9Sstevel@tonic-gate *dot = '\0'; 569cb5caa98Sdjl (void) strcpy(host, string); 570cb5caa98Sdjl (void) strcpy(domain, ++dot); 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate return (0); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate 5767c478bd9Sstevel@tonic-gate /* 5777c478bd9Sstevel@tonic-gate * 5787c478bd9Sstevel@tonic-gate */ 5797c478bd9Sstevel@tonic-gate int 5807c478bd9Sstevel@tonic-gate propersubdomain(char *domain, char *subdomain) 5817c478bd9Sstevel@tonic-gate { 5827c478bd9Sstevel@tonic-gate int domainlen, subdomainlen; 5837c478bd9Sstevel@tonic-gate 5847c478bd9Sstevel@tonic-gate /* sanity check */ 5857c478bd9Sstevel@tonic-gate if (domain == NULL || subdomain == NULL) 5867c478bd9Sstevel@tonic-gate return (-1); 5877c478bd9Sstevel@tonic-gate 5887c478bd9Sstevel@tonic-gate domainlen = strlen(domain); 5897c478bd9Sstevel@tonic-gate subdomainlen = strlen(subdomain); 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate /* is afterdot a substring of domain? */ 5927c478bd9Sstevel@tonic-gate if ((strncasecmp(domain, subdomain, subdomainlen)) != 0) 5937c478bd9Sstevel@tonic-gate return (-1); 5947c478bd9Sstevel@tonic-gate 5957c478bd9Sstevel@tonic-gate if (domainlen == subdomainlen) 5967c478bd9Sstevel@tonic-gate return (1); 5977c478bd9Sstevel@tonic-gate 5987c478bd9Sstevel@tonic-gate if (subdomainlen > domainlen) 5997c478bd9Sstevel@tonic-gate return (-1); 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate if (*(domain + subdomainlen) != '.') 6027c478bd9Sstevel@tonic-gate return (-1); 6037c478bd9Sstevel@tonic-gate 6047c478bd9Sstevel@tonic-gate return (1); 6057c478bd9Sstevel@tonic-gate } 606