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 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 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 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 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 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 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 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 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 * 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 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 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