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
switch_err(int rc,ns_ldap_error_t * error)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
_nss_ldap_lookup(ldap_backend_ptr be,nss_XbyY_args_t * argp,char * database,char * searchfilter,char * domain,int (* init_filter_cb)(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata),const void * userdata)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
_nss_ldap_nocb_lookup(ldap_backend_ptr be,nss_XbyY_args_t * argp,char * database,char * searchfilter,char * domain,int (* init_filter_cb)(const ns_ldap_search_desc_t * desc,char ** realfilter,const void * userdata),const void * userdata)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
_clean_ldap_backend(ldap_backend_ptr be)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
_nss_ldap_destr(ldap_backend_ptr be,void * a)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
_nss_ldap_setent(ldap_backend_ptr be,void * a)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
_nss_ldap_endent(ldap_backend_ptr be,void * a)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
_nss_ldap_getent(ldap_backend_ptr be,void * a)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 *
_nss_ldap_constr(ldap_backend_op_t ops[],int nops,char * tablename,const char ** attrs,fnf ldapobj2str)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
chophostdomain(char * string,char * host,char * domain)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
propersubdomain(char * domain,char * subdomain)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