10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
51676Sjpk * Common Development and Distribution License (the "License").
61676Sjpk * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
210Sstevel@tonic-gate /*
22*12758SJulian.Pullen@Sun.COM * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate */
240Sstevel@tonic-gate
250Sstevel@tonic-gate #include "ldap_common.h"
260Sstevel@tonic-gate #include <malloc.h>
270Sstevel@tonic-gate #include <synch.h>
280Sstevel@tonic-gate #include <syslog.h>
290Sstevel@tonic-gate #include <rpcsvc/ypclnt.h>
300Sstevel@tonic-gate #include <rpcsvc/yp_prot.h>
310Sstevel@tonic-gate #include <thread.h>
320Sstevel@tonic-gate #include <ctype.h>
330Sstevel@tonic-gate #include <stdlib.h>
340Sstevel@tonic-gate #include <signal.h>
350Sstevel@tonic-gate #include <sys/stat.h>
360Sstevel@tonic-gate
370Sstevel@tonic-gate /* getent attributes filters */
380Sstevel@tonic-gate #define _F_GETALIASENT "(objectClass=rfc822MailGroup)"
390Sstevel@tonic-gate #define _F_GETAUTHNAME "(objectClass=SolarisAuthAttr)"
400Sstevel@tonic-gate #define _F_GETAUUSERNAME "(objectClass=SolarisAuditUser)"
410Sstevel@tonic-gate #define _F_GETEXECNAME "(objectClass=SolarisExecAttr)"
420Sstevel@tonic-gate #define _F_GETGRENT "(objectClass=posixGroup)"
430Sstevel@tonic-gate #define _F_GETHOSTENT "(objectClass=ipHost)"
440Sstevel@tonic-gate #define _F_GETNETENT "(objectClass=ipNetwork)"
452830Sdjl #define _F_GETPROFNAME \
462830Sdjl "(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*)))"
470Sstevel@tonic-gate #define _F_GETPROTOENT "(objectClass=ipProtocol)"
480Sstevel@tonic-gate #define _F_GETPWENT "(objectClass=posixAccount)"
490Sstevel@tonic-gate #define _F_GETPRINTERENT "(objectClass=sunPrinter)"
500Sstevel@tonic-gate #define _F_GETRPCENT "(objectClass=oncRpc)"
510Sstevel@tonic-gate #define _F_GETSERVENT "(objectClass=ipService)"
520Sstevel@tonic-gate #define _F_GETSPENT "(objectclass=shadowAccount)"
530Sstevel@tonic-gate #define _F_GETUSERNAME "(objectClass=SolarisUserAttr)"
540Sstevel@tonic-gate #define _F_GETPROJENT "(objectClass=SolarisProject)"
551676Sjpk #define _F_GETTNRHDB "(objectClass=ipTnetHost)"
561676Sjpk #define _F_GETTNRHTP "(&(objectClass=ipTnetTemplate)"\
571676Sjpk "(SolarisAttrKeyValue=*))"
580Sstevel@tonic-gate #define _F_GETENT_SSD "(%s)"
590Sstevel@tonic-gate
60*12758SJulian.Pullen@Sun.COM /* getent sort attributes */
61*12758SJulian.Pullen@Sun.COM #define _A_UID "uid"
62*12758SJulian.Pullen@Sun.COM #define _A_GIDNUMBER "gidnumber"
63*12758SJulian.Pullen@Sun.COM #define _A_CN "cn"
64*12758SJulian.Pullen@Sun.COM #define _A_IPNETWORKNUM "ipnetworknumber"
65*12758SJulian.Pullen@Sun.COM #define _A_PROJECTNAM "SolarisProjectName"
66*12758SJulian.Pullen@Sun.COM #define _A_IPTNETNUM "ipTnetNumber"
67*12758SJulian.Pullen@Sun.COM #define _A_IPTNETTMPLNAM "ipTnetTemplateName"
68*12758SJulian.Pullen@Sun.COM
690Sstevel@tonic-gate static struct gettablefilter {
700Sstevel@tonic-gate char *tablename;
710Sstevel@tonic-gate char *tablefilter;
72*12758SJulian.Pullen@Sun.COM char *sortattr;
730Sstevel@tonic-gate } gettablefilterent[] = {
74*12758SJulian.Pullen@Sun.COM {(char *)_PASSWD, (char *)_F_GETPWENT, (char *)_A_UID},
75*12758SJulian.Pullen@Sun.COM {(char *)_SHADOW, (char *)_F_GETSPENT, (char *)_A_UID},
76*12758SJulian.Pullen@Sun.COM {(char *)_GROUP, (char *)_F_GETGRENT, (char *)_A_GIDNUMBER},
77*12758SJulian.Pullen@Sun.COM {(char *)_HOSTS, (char *)_F_GETHOSTENT, (char *)_A_CN},
78*12758SJulian.Pullen@Sun.COM {(char *)_NETWORKS, (char *)_F_GETNETENT,
79*12758SJulian.Pullen@Sun.COM (char *)_A_IPNETWORKNUM},
80*12758SJulian.Pullen@Sun.COM {(char *)_PROTOCOLS, (char *)_F_GETPROTOENT, (char *)_A_CN},
81*12758SJulian.Pullen@Sun.COM {(char *)_RPC, (char *)_F_GETRPCENT, (char *)_A_CN},
82*12758SJulian.Pullen@Sun.COM {(char *)_ALIASES, (char *)_F_GETALIASENT, (char *)_A_CN},
83*12758SJulian.Pullen@Sun.COM {(char *)_SERVICES, (char *)_F_GETSERVENT, (char *)_A_CN},
84*12758SJulian.Pullen@Sun.COM {(char *)_AUUSER, (char *)_F_GETAUUSERNAME,
85*12758SJulian.Pullen@Sun.COM (char *)_A_UID},
86*12758SJulian.Pullen@Sun.COM {(char *)_AUTHATTR, (char *)_F_GETAUTHNAME, (char *)_A_CN},
87*12758SJulian.Pullen@Sun.COM {(char *)_EXECATTR, (char *)_F_GETEXECNAME, (char *)_A_CN},
88*12758SJulian.Pullen@Sun.COM {(char *)_PROFATTR, (char *)_F_GETPROFNAME, (char *)_A_CN},
89*12758SJulian.Pullen@Sun.COM {(char *)_USERATTR, (char *)_F_GETUSERNAME, (char *)_A_UID},
90*12758SJulian.Pullen@Sun.COM {(char *)_PROJECT, (char *)_F_GETPROJENT, (char *)_A_PROJECTNAM},
91*12758SJulian.Pullen@Sun.COM {(char *)_PRINTERS, (char *)_F_GETPRINTERENT, (char *)_A_CN},
92*12758SJulian.Pullen@Sun.COM {(char *)_TNRHDB, (char *)_F_GETTNRHDB, (char *)_A_IPTNETNUM},
93*12758SJulian.Pullen@Sun.COM {(char *)_TNRHTP, (char *)_F_GETTNRHTP,
94*12758SJulian.Pullen@Sun.COM (char *)_A_IPTNETTMPLNAM},
95*12758SJulian.Pullen@Sun.COM {(char *)NULL, (char *)NULL, (char *)NULL}
960Sstevel@tonic-gate };
970Sstevel@tonic-gate
980Sstevel@tonic-gate
994953Smichen nss_status_t
switch_err(int rc,ns_ldap_error_t * error)1000Sstevel@tonic-gate switch_err(int rc, ns_ldap_error_t *error)
1010Sstevel@tonic-gate {
1020Sstevel@tonic-gate switch (rc) {
1034953Smichen case NS_LDAP_SUCCESS:
1040Sstevel@tonic-gate return (NSS_SUCCESS);
1050Sstevel@tonic-gate
1064953Smichen case NS_LDAP_NOTFOUND:
1070Sstevel@tonic-gate return (NSS_NOTFOUND);
1080Sstevel@tonic-gate
1094953Smichen case NS_LDAP_PARTIAL:
1100Sstevel@tonic-gate return (NSS_TRYAGAIN);
1110Sstevel@tonic-gate
1124953Smichen case NS_LDAP_INTERNAL:
1134953Smichen if (error && (error->status == LDAP_SERVER_DOWN ||
1144953Smichen error->status == LDAP_TIMEOUT))
1154953Smichen return (NSS_TRYAGAIN);
1164953Smichen else
1174953Smichen return (NSS_UNAVAIL);
1180Sstevel@tonic-gate
1194953Smichen default:
1200Sstevel@tonic-gate return (NSS_UNAVAIL);
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate }
1232830Sdjl /* ARGSUSED */
1240Sstevel@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)1250Sstevel@tonic-gate _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp,
1260Sstevel@tonic-gate char *database, char *searchfilter, char *domain,
1270Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
1280Sstevel@tonic-gate char **realfilter, const void *userdata),
1290Sstevel@tonic-gate const void *userdata)
1300Sstevel@tonic-gate {
1310Sstevel@tonic-gate int callbackstat = 0;
1320Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
1330Sstevel@tonic-gate int rc;
1340Sstevel@tonic-gate
1350Sstevel@tonic-gate #ifdef DEBUG
1360Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_lookup]\n");
1370Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter);
1380Sstevel@tonic-gate (void) fprintf(stdout,
1394953Smichen "\tuserdata: %s\n", userdata ? userdata : "NULL");
1400Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database);
1410Sstevel@tonic-gate #endif /* DEBUG */
1420Sstevel@tonic-gate
1430Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result);
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb,
1464953Smichen be->attrs, NULL, 0, &be->result, &error, NULL,
1474953Smichen userdata)) != NS_LDAP_SUCCESS) {
1480Sstevel@tonic-gate argp->returnval = 0;
1490Sstevel@tonic-gate rc = switch_err(rc, error);
1500Sstevel@tonic-gate (void) __ns_ldap_freeError(&error);
1512830Sdjl
1520Sstevel@tonic-gate return (rc);
1530Sstevel@tonic-gate }
1542830Sdjl (void) __ns_ldap_freeError(&error);
1550Sstevel@tonic-gate /* callback function */
1560Sstevel@tonic-gate if ((callbackstat =
1574953Smichen be->ldapobj2str(be, argp)) != NSS_STR_PARSE_SUCCESS) {
1582830Sdjl goto error_out;
1592830Sdjl }
1602830Sdjl
1612830Sdjl /*
1622830Sdjl * publickey does not have a front end marshaller and expects
1632830Sdjl * a string to be returned in NSS.
1642830Sdjl * No need to convert file format -> struct.
1652830Sdjl *
1662830Sdjl */
1672830Sdjl if (be->db_type == NSS_LDAP_DB_PUBLICKEY) {
1682830Sdjl argp->returnval = argp->buf.buffer;
1692830Sdjl argp->returnlen = strlen(argp->buf.buffer);
1702830Sdjl be->db_type = NSS_LDAP_DB_NONE;
1712830Sdjl return (NSS_SUCCESS);
1720Sstevel@tonic-gate }
1732830Sdjl /*
1742830Sdjl * Assume the switch engine wants the returned data in the file
1752830Sdjl * format when argp->buf.result == NULL.
1762830Sdjl * The front-end marshaller str2ether(ethers) uses
1772830Sdjl * ent (argp->buf.result) and buffer (argp->buf.buffer)
1782830Sdjl * for different purpose so ethers has to be treated differently.
1792830Sdjl */
1802830Sdjl if (argp->buf.result != NULL ||
1814953Smichen be->db_type == NSS_LDAP_DB_ETHERS) {
1822830Sdjl /* file format -> struct */
1832830Sdjl if (argp->str2ent == NULL) {
1842830Sdjl callbackstat = NSS_STR_PARSE_PARSE;
1852830Sdjl goto error_out;
1862830Sdjl }
1870Sstevel@tonic-gate
1882830Sdjl callbackstat = (*argp->str2ent)(be->buffer,
1894953Smichen be->buflen,
1904953Smichen argp->buf.result,
1914953Smichen argp->buf.buffer,
1924953Smichen argp->buf.buflen);
1932830Sdjl if (callbackstat == NSS_STR_PARSE_SUCCESS) {
1942830Sdjl if (be->db_type == NSS_LDAP_DB_ETHERS &&
1954953Smichen argp->buf.buffer != NULL) {
1962830Sdjl argp->returnval = argp->buf.buffer;
1972830Sdjl argp->returnlen = strlen(argp->buf.buffer);
1982830Sdjl } else {
1992830Sdjl argp->returnval = argp->buf.result;
2002830Sdjl argp->returnlen = 1; /* irrelevant */
2012830Sdjl }
2022830Sdjl if (be->buffer != NULL) {
2032830Sdjl free(be->buffer);
2042830Sdjl be->buffer = NULL;
2052830Sdjl be->buflen = 0;
2062830Sdjl be->db_type = NSS_LDAP_DB_NONE;
2072830Sdjl }
2082830Sdjl return ((nss_status_t)NSS_SUCCESS);
2092830Sdjl }
2102830Sdjl } else {
2112830Sdjl /* return file format in argp->buf.buffer */
2122830Sdjl argp->returnval = argp->buf.buffer;
2132830Sdjl argp->returnlen = strlen(argp->buf.buffer);
2142830Sdjl return ((nss_status_t)NSS_SUCCESS);
2152830Sdjl }
2162830Sdjl
2172830Sdjl error_out:
2182830Sdjl if (be->buffer != NULL) {
2192830Sdjl free(be->buffer);
2202830Sdjl be->buffer = NULL;
2212830Sdjl be->buflen = 0;
2222830Sdjl be->db_type = NSS_LDAP_DB_NONE;
2232830Sdjl }
2240Sstevel@tonic-gate /* error */
2250Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_PARSE) {
2260Sstevel@tonic-gate argp->returnval = 0;
2270Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
2280Sstevel@tonic-gate }
2290Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_ERANGE) {
2300Sstevel@tonic-gate argp->erange = 1;
2310Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_NO_ADDR) {
2340Sstevel@tonic-gate /* No IPV4 address is found */
2350Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND;
2360Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND);
2370Sstevel@tonic-gate }
2380Sstevel@tonic-gate return ((nss_status_t)NSS_UNAVAIL);
2390Sstevel@tonic-gate }
2400Sstevel@tonic-gate
2410Sstevel@tonic-gate /*
2420Sstevel@tonic-gate * This function is similar to _nss_ldap_lookup except it does not
2430Sstevel@tonic-gate * do a callback. It is only used by getnetgrent.c
2440Sstevel@tonic-gate */
2450Sstevel@tonic-gate
2462830Sdjl /* ARGSUSED */
2470Sstevel@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)2480Sstevel@tonic-gate _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp,
2490Sstevel@tonic-gate char *database, char *searchfilter, char *domain,
2500Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc,
2510Sstevel@tonic-gate char **realfilter, const void *userdata),
2520Sstevel@tonic-gate const void *userdata)
2530Sstevel@tonic-gate {
2540Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
2550Sstevel@tonic-gate int rc;
2560Sstevel@tonic-gate
2570Sstevel@tonic-gate #ifdef DEBUG
2580Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_nocb_lookup]\n");
2590Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter);
2600Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database);
2610Sstevel@tonic-gate (void) fprintf(stdout,
2624953Smichen "\tuserdata: %s\n", userdata ? userdata : "NULL");
2630Sstevel@tonic-gate #endif /* DEBUG */
2640Sstevel@tonic-gate
2650Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result);
2660Sstevel@tonic-gate
2670Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb,
2684953Smichen be->attrs, NULL, 0, &be->result, &error, NULL,
2694953Smichen userdata)) != NS_LDAP_SUCCESS) {
2705362Smichen if (argp != NULL)
2715362Smichen argp->returnval = 0;
2720Sstevel@tonic-gate rc = switch_err(rc, error);
2730Sstevel@tonic-gate (void) __ns_ldap_freeError(&error);
2740Sstevel@tonic-gate return (rc);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
2780Sstevel@tonic-gate }
2790Sstevel@tonic-gate
2800Sstevel@tonic-gate
2810Sstevel@tonic-gate /*
2820Sstevel@tonic-gate *
2830Sstevel@tonic-gate */
2840Sstevel@tonic-gate
2850Sstevel@tonic-gate void
_clean_ldap_backend(ldap_backend_ptr be)2860Sstevel@tonic-gate _clean_ldap_backend(ldap_backend_ptr be)
2870Sstevel@tonic-gate {
2880Sstevel@tonic-gate ns_ldap_error_t *error;
2890Sstevel@tonic-gate
2900Sstevel@tonic-gate #ifdef DEBUG
2910Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _clean_ldap_backend]\n");
2920Sstevel@tonic-gate #endif /* DEBUG */
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate if (be->tablename != NULL)
2950Sstevel@tonic-gate free(be->tablename);
2960Sstevel@tonic-gate if (be->result != NULL)
2970Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result);
2980Sstevel@tonic-gate if (be->enumcookie != NULL)
2990Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error);
3000Sstevel@tonic-gate if (be->services_cookie != NULL)
3010Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie);
3020Sstevel@tonic-gate if (be->toglue != NULL) {
3030Sstevel@tonic-gate free(be->toglue);
3040Sstevel@tonic-gate be->toglue = NULL;
3050Sstevel@tonic-gate }
3062830Sdjl if (be->buffer != NULL) {
3072830Sdjl free(be->buffer);
3082830Sdjl be->buffer = NULL;
3092830Sdjl }
3100Sstevel@tonic-gate free(be);
3110Sstevel@tonic-gate }
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate
3140Sstevel@tonic-gate /*
3150Sstevel@tonic-gate * _nss_ldap_destr will free all smalloc'ed variable strings and structures
3160Sstevel@tonic-gate * before exiting this nsswitch shared backend library. This function is
3170Sstevel@tonic-gate * called before returning control back to nsswitch.
3180Sstevel@tonic-gate */
3190Sstevel@tonic-gate
3200Sstevel@tonic-gate /*ARGSUSED1*/
3210Sstevel@tonic-gate nss_status_t
_nss_ldap_destr(ldap_backend_ptr be,void * a)3220Sstevel@tonic-gate _nss_ldap_destr(ldap_backend_ptr be, void *a)
3230Sstevel@tonic-gate {
3240Sstevel@tonic-gate
3250Sstevel@tonic-gate #ifdef DEBUG
3260Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_destr]\n");
3270Sstevel@tonic-gate #endif /* DEBUG */
3280Sstevel@tonic-gate
3290Sstevel@tonic-gate (void) _clean_ldap_backend(be);
3300Sstevel@tonic-gate
3310Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
3320Sstevel@tonic-gate }
3330Sstevel@tonic-gate
3340Sstevel@tonic-gate
3350Sstevel@tonic-gate /*
3360Sstevel@tonic-gate * _nss_ldap_setent called before _nss_ldap_getent. This function is
3370Sstevel@tonic-gate * required by POSIX.
3380Sstevel@tonic-gate */
3390Sstevel@tonic-gate
3400Sstevel@tonic-gate nss_status_t
_nss_ldap_setent(ldap_backend_ptr be,void * a)3410Sstevel@tonic-gate _nss_ldap_setent(ldap_backend_ptr be, void *a)
3420Sstevel@tonic-gate {
3430Sstevel@tonic-gate struct gettablefilter *gtf;
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate #ifdef DEBUG
3460Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_setent]\n");
3470Sstevel@tonic-gate #endif /* DEBUG */
3480Sstevel@tonic-gate
3490Sstevel@tonic-gate if (be->setcalled == 1)
3500Sstevel@tonic-gate (void) _nss_ldap_endent(be, a);
3510Sstevel@tonic-gate be->filter = NULL;
352*12758SJulian.Pullen@Sun.COM be->sortattr = NULL;
3530Sstevel@tonic-gate for (gtf = gettablefilterent; gtf->tablename != (char *)NULL; gtf++) {
3540Sstevel@tonic-gate if (strcmp(gtf->tablename, be->tablename))
3550Sstevel@tonic-gate continue;
3560Sstevel@tonic-gate be->filter = (char *)gtf->tablefilter;
357*12758SJulian.Pullen@Sun.COM be->sortattr = (char *)gtf->sortattr;
3580Sstevel@tonic-gate break;
3590Sstevel@tonic-gate }
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate be->setcalled = 1;
3620Sstevel@tonic-gate be->enumcookie = NULL;
3630Sstevel@tonic-gate be->result = NULL;
3640Sstevel@tonic-gate be->services_cookie = NULL;
3652830Sdjl be->buffer = NULL;
3660Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
3670Sstevel@tonic-gate }
3680Sstevel@tonic-gate
3690Sstevel@tonic-gate
3700Sstevel@tonic-gate /*
3710Sstevel@tonic-gate * _nss_ldap_endent called after _nss_ldap_getent. This function is
3720Sstevel@tonic-gate * required by POSIX.
3730Sstevel@tonic-gate */
3740Sstevel@tonic-gate
3750Sstevel@tonic-gate /*ARGSUSED1*/
3760Sstevel@tonic-gate nss_status_t
_nss_ldap_endent(ldap_backend_ptr be,void * a)3770Sstevel@tonic-gate _nss_ldap_endent(ldap_backend_ptr be, void *a)
3780Sstevel@tonic-gate {
3790Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate #ifdef DEBUG
3820Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_endent]\n");
3830Sstevel@tonic-gate #endif /* DEBUG */
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate be->setcalled = 0;
3860Sstevel@tonic-gate be->filter = NULL;
387*12758SJulian.Pullen@Sun.COM be->sortattr = NULL;
3880Sstevel@tonic-gate if (be->enumcookie != NULL) {
3890Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error);
3900Sstevel@tonic-gate (void) __ns_ldap_freeError(&error);
3910Sstevel@tonic-gate }
3920Sstevel@tonic-gate if (be->result != NULL) {
3930Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result);
3940Sstevel@tonic-gate }
3950Sstevel@tonic-gate if (be->services_cookie != NULL) {
3960Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie);
3970Sstevel@tonic-gate }
3982830Sdjl if (be->buffer != NULL) {
3992830Sdjl free(be->buffer);
4002830Sdjl be->buffer = NULL;
4012830Sdjl }
4020Sstevel@tonic-gate
4030Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
4040Sstevel@tonic-gate }
4050Sstevel@tonic-gate
4060Sstevel@tonic-gate
4070Sstevel@tonic-gate /*
4080Sstevel@tonic-gate *
4090Sstevel@tonic-gate */
4100Sstevel@tonic-gate
4110Sstevel@tonic-gate nss_status_t
_nss_ldap_getent(ldap_backend_ptr be,void * a)4120Sstevel@tonic-gate _nss_ldap_getent(ldap_backend_ptr be, void *a)
4130Sstevel@tonic-gate {
4140Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a;
4150Sstevel@tonic-gate ns_ldap_error_t *error = NULL;
4160Sstevel@tonic-gate int parsestat = 0;
4170Sstevel@tonic-gate int retcode = 0;
4180Sstevel@tonic-gate
4190Sstevel@tonic-gate #ifdef DEBUG
4200Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_getent]\n");
4210Sstevel@tonic-gate #endif /* DEBUG */
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate if (be->setcalled == 0)
4240Sstevel@tonic-gate (void) _nss_ldap_setent(be, a);
4250Sstevel@tonic-gate
4260Sstevel@tonic-gate next_entry:
4270Sstevel@tonic-gate if (be->enumcookie == NULL) {
4280Sstevel@tonic-gate retcode = __ns_ldap_firstEntry(be->tablename,
429*12758SJulian.Pullen@Sun.COM be->filter, be->sortattr, _merge_SSD_filter, be->attrs,
430*12758SJulian.Pullen@Sun.COM NULL, 0, &be->enumcookie,
4314953Smichen &be->result, &error, _F_GETENT_SSD);
4320Sstevel@tonic-gate } else {
4330Sstevel@tonic-gate if (be->services_cookie == NULL) {
4340Sstevel@tonic-gate retcode = __ns_ldap_nextEntry(be->enumcookie,
4354953Smichen &be->result, &error);
4360Sstevel@tonic-gate }
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate if (retcode != NS_LDAP_SUCCESS) {
4390Sstevel@tonic-gate retcode = switch_err(retcode, error);
4400Sstevel@tonic-gate (void) __ns_ldap_freeError(&error);
4410Sstevel@tonic-gate (void) _nss_ldap_endent(be, a);
4420Sstevel@tonic-gate return (retcode);
443*12758SJulian.Pullen@Sun.COM }
444*12758SJulian.Pullen@Sun.COM
445*12758SJulian.Pullen@Sun.COM if (be->result == NULL) {
446*12758SJulian.Pullen@Sun.COM parsestat = NSS_STR_PARSE_NO_RESULT;
447*12758SJulian.Pullen@Sun.COM goto error_out;
448*12758SJulian.Pullen@Sun.COM }
449*12758SJulian.Pullen@Sun.COM /* ns_ldap_entry_t -> file format */
450*12758SJulian.Pullen@Sun.COM if ((parsestat = be->ldapobj2str(be, argp))
451*12758SJulian.Pullen@Sun.COM == NSS_STR_PARSE_SUCCESS) {
452*12758SJulian.Pullen@Sun.COM if (argp->buf.result != NULL) {
453*12758SJulian.Pullen@Sun.COM /* file format -> struct */
454*12758SJulian.Pullen@Sun.COM if (argp->str2ent == NULL) {
455*12758SJulian.Pullen@Sun.COM parsestat = NSS_STR_PARSE_NO_RESULT;
456*12758SJulian.Pullen@Sun.COM goto error_out;
457*12758SJulian.Pullen@Sun.COM }
458*12758SJulian.Pullen@Sun.COM parsestat = (*argp->str2ent)(be->buffer,
459*12758SJulian.Pullen@Sun.COM be->buflen,
460*12758SJulian.Pullen@Sun.COM argp->buf.result,
461*12758SJulian.Pullen@Sun.COM argp->buf.buffer,
462*12758SJulian.Pullen@Sun.COM argp->buf.buflen);
463*12758SJulian.Pullen@Sun.COM if (parsestat == NSS_STR_PARSE_SUCCESS) {
464*12758SJulian.Pullen@Sun.COM if (be->buffer != NULL) {
465*12758SJulian.Pullen@Sun.COM free(be->buffer);
466*12758SJulian.Pullen@Sun.COM be->buffer = NULL;
467*12758SJulian.Pullen@Sun.COM be->buflen = 0;
4682830Sdjl }
469*12758SJulian.Pullen@Sun.COM be->result = NULL;
470*12758SJulian.Pullen@Sun.COM argp->returnval = argp->buf.result;
471*12758SJulian.Pullen@Sun.COM argp->returnlen = 1; /* irrevelant */
472*12758SJulian.Pullen@Sun.COM return ((nss_status_t)NSS_SUCCESS);
4732830Sdjl }
474*12758SJulian.Pullen@Sun.COM } else {
475*12758SJulian.Pullen@Sun.COM /*
476*12758SJulian.Pullen@Sun.COM * nscd is not caching the enumerated
477*12758SJulian.Pullen@Sun.COM * entries. This code path would be dormant.
478*12758SJulian.Pullen@Sun.COM * Keep this path for the future references.
479*12758SJulian.Pullen@Sun.COM */
480*12758SJulian.Pullen@Sun.COM argp->returnval = argp->buf.buffer;
481*12758SJulian.Pullen@Sun.COM argp->returnlen =
482*12758SJulian.Pullen@Sun.COM strlen(argp->buf.buffer) + 1;
4830Sstevel@tonic-gate }
484*12758SJulian.Pullen@Sun.COM }
485*12758SJulian.Pullen@Sun.COM error_out:
486*12758SJulian.Pullen@Sun.COM if (be->buffer != NULL) {
487*12758SJulian.Pullen@Sun.COM free(be->buffer);
488*12758SJulian.Pullen@Sun.COM be->buffer = NULL;
489*12758SJulian.Pullen@Sun.COM be->buflen = 0;
490*12758SJulian.Pullen@Sun.COM }
491*12758SJulian.Pullen@Sun.COM be->result = NULL;
492*12758SJulian.Pullen@Sun.COM if (parsestat == NSS_STR_PARSE_NO_RESULT) {
493*12758SJulian.Pullen@Sun.COM argp->returnval = 0;
494*12758SJulian.Pullen@Sun.COM (void) _nss_ldap_endent(be, a);
495*12758SJulian.Pullen@Sun.COM return ((nss_status_t)NSS_NOTFOUND);
496*12758SJulian.Pullen@Sun.COM }
4970Sstevel@tonic-gate
498*12758SJulian.Pullen@Sun.COM if (parsestat == NSS_STR_PARSE_ERANGE) {
499*12758SJulian.Pullen@Sun.COM argp->erange = 1;
500*12758SJulian.Pullen@Sun.COM (void) _nss_ldap_endent(be, a);
501*12758SJulian.Pullen@Sun.COM return ((nss_status_t)NSS_NOTFOUND);
5020Sstevel@tonic-gate }
503*12758SJulian.Pullen@Sun.COM if (parsestat == NSS_STR_PARSE_NO_ADDR)
504*12758SJulian.Pullen@Sun.COM /*
505*12758SJulian.Pullen@Sun.COM * No IPV4 address is found in the current entry.
506*12758SJulian.Pullen@Sun.COM * It indicates that the entry contains IPV6 addresses
507*12758SJulian.Pullen@Sun.COM * only. Instead of calling _nss_ldap_endent to
508*12758SJulian.Pullen@Sun.COM * terminate, get next entry to continue enumeration.
509*12758SJulian.Pullen@Sun.COM * If it returned NSS_NOTFOUND here,
510*12758SJulian.Pullen@Sun.COM * gethostent() would return NULL
511*12758SJulian.Pullen@Sun.COM * and the enumeration would stop prematurely.
512*12758SJulian.Pullen@Sun.COM */
513*12758SJulian.Pullen@Sun.COM goto next_entry;
514*12758SJulian.Pullen@Sun.COM
515*12758SJulian.Pullen@Sun.COM if (parsestat == NSS_STR_PARSE_PARSE)
516*12758SJulian.Pullen@Sun.COM /*
517*12758SJulian.Pullen@Sun.COM * There has been a parse error. Most likely some
518*12758SJulian.Pullen@Sun.COM * mandatory attributes are missing. Ignore the error
519*12758SJulian.Pullen@Sun.COM * and get the next entry. If we returned an error the
520*12758SJulian.Pullen@Sun.COM * enumeration would stop prematurely.
521*12758SJulian.Pullen@Sun.COM */
522*12758SJulian.Pullen@Sun.COM goto next_entry;
5230Sstevel@tonic-gate
5240Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS);
5250Sstevel@tonic-gate }
5260Sstevel@tonic-gate
5270Sstevel@tonic-gate
5280Sstevel@tonic-gate /*
5290Sstevel@tonic-gate *
5300Sstevel@tonic-gate */
5310Sstevel@tonic-gate
5320Sstevel@tonic-gate nss_backend_t *
_nss_ldap_constr(ldap_backend_op_t ops[],int nops,char * tablename,const char ** attrs,fnf ldapobj2str)5330Sstevel@tonic-gate _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename,
5342830Sdjl const char **attrs, fnf ldapobj2str)
5350Sstevel@tonic-gate {
5360Sstevel@tonic-gate ldap_backend_ptr be;
5370Sstevel@tonic-gate
5380Sstevel@tonic-gate #ifdef DEBUG
5390Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_constr]\n");
5400Sstevel@tonic-gate #endif /* DEBUG */
5410Sstevel@tonic-gate
5422830Sdjl if ((be = (ldap_backend_ptr) calloc(1, sizeof (*be))) == 0)
5430Sstevel@tonic-gate return (0);
5440Sstevel@tonic-gate be->ops = ops;
5450Sstevel@tonic-gate be->nops = (nss_dbop_t)nops;
5460Sstevel@tonic-gate be->tablename = (char *)strdup(tablename);
5470Sstevel@tonic-gate be->attrs = attrs;
5482830Sdjl be->ldapobj2str = ldapobj2str;
5490Sstevel@tonic-gate
5500Sstevel@tonic-gate return ((nss_backend_t *)be);
5510Sstevel@tonic-gate }
5520Sstevel@tonic-gate
5530Sstevel@tonic-gate
5540Sstevel@tonic-gate /*
5550Sstevel@tonic-gate *
5560Sstevel@tonic-gate */
5570Sstevel@tonic-gate int
chophostdomain(char * string,char * host,char * domain)5580Sstevel@tonic-gate chophostdomain(char *string, char *host, char *domain)
5590Sstevel@tonic-gate {
5600Sstevel@tonic-gate char *dot;
5610Sstevel@tonic-gate
5620Sstevel@tonic-gate if (string == NULL)
5630Sstevel@tonic-gate return (-1);
5640Sstevel@tonic-gate
5650Sstevel@tonic-gate if ((dot = strchr(string, '.')) == NULL) {
5660Sstevel@tonic-gate return (0);
5670Sstevel@tonic-gate }
5680Sstevel@tonic-gate *dot = '\0';
5692830Sdjl (void) strcpy(host, string);
5702830Sdjl (void) strcpy(domain, ++dot);
5710Sstevel@tonic-gate
5720Sstevel@tonic-gate return (0);
5730Sstevel@tonic-gate }
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate
5760Sstevel@tonic-gate /*
5770Sstevel@tonic-gate *
5780Sstevel@tonic-gate */
5790Sstevel@tonic-gate int
propersubdomain(char * domain,char * subdomain)5800Sstevel@tonic-gate propersubdomain(char *domain, char *subdomain)
5810Sstevel@tonic-gate {
5820Sstevel@tonic-gate int domainlen, subdomainlen;
5830Sstevel@tonic-gate
5840Sstevel@tonic-gate /* sanity check */
5850Sstevel@tonic-gate if (domain == NULL || subdomain == NULL)
5860Sstevel@tonic-gate return (-1);
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate domainlen = strlen(domain);
5890Sstevel@tonic-gate subdomainlen = strlen(subdomain);
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate /* is afterdot a substring of domain? */
5920Sstevel@tonic-gate if ((strncasecmp(domain, subdomain, subdomainlen)) != 0)
5930Sstevel@tonic-gate return (-1);
5940Sstevel@tonic-gate
5950Sstevel@tonic-gate if (domainlen == subdomainlen)
5960Sstevel@tonic-gate return (1);
5970Sstevel@tonic-gate
5980Sstevel@tonic-gate if (subdomainlen > domainlen)
5990Sstevel@tonic-gate return (-1);
6000Sstevel@tonic-gate
6010Sstevel@tonic-gate if (*(domain + subdomainlen) != '.')
6020Sstevel@tonic-gate return (-1);
6030Sstevel@tonic-gate
6040Sstevel@tonic-gate return (1);
6050Sstevel@tonic-gate }
606