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 /* 224953Smichen * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include "ldap_common.h" 290Sstevel@tonic-gate #include <malloc.h> 300Sstevel@tonic-gate #include <synch.h> 310Sstevel@tonic-gate #include <syslog.h> 320Sstevel@tonic-gate #include <rpcsvc/ypclnt.h> 330Sstevel@tonic-gate #include <rpcsvc/yp_prot.h> 340Sstevel@tonic-gate #include <thread.h> 350Sstevel@tonic-gate #include <ctype.h> 360Sstevel@tonic-gate #include <stdlib.h> 370Sstevel@tonic-gate #include <signal.h> 380Sstevel@tonic-gate #include <sys/stat.h> 390Sstevel@tonic-gate 400Sstevel@tonic-gate /* getent attributes filters */ 410Sstevel@tonic-gate #define _F_GETALIASENT "(objectClass=rfc822MailGroup)" 420Sstevel@tonic-gate #define _F_GETAUTHNAME "(objectClass=SolarisAuthAttr)" 430Sstevel@tonic-gate #define _F_GETAUUSERNAME "(objectClass=SolarisAuditUser)" 440Sstevel@tonic-gate #define _F_GETEXECNAME "(objectClass=SolarisExecAttr)" 450Sstevel@tonic-gate #define _F_GETGRENT "(objectClass=posixGroup)" 460Sstevel@tonic-gate #define _F_GETHOSTENT "(objectClass=ipHost)" 470Sstevel@tonic-gate #define _F_GETNETENT "(objectClass=ipNetwork)" 482830Sdjl #define _F_GETPROFNAME \ 492830Sdjl "(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*)))" 500Sstevel@tonic-gate #define _F_GETPROTOENT "(objectClass=ipProtocol)" 510Sstevel@tonic-gate #define _F_GETPWENT "(objectClass=posixAccount)" 520Sstevel@tonic-gate #define _F_GETPRINTERENT "(objectClass=sunPrinter)" 530Sstevel@tonic-gate #define _F_GETRPCENT "(objectClass=oncRpc)" 540Sstevel@tonic-gate #define _F_GETSERVENT "(objectClass=ipService)" 550Sstevel@tonic-gate #define _F_GETSPENT "(objectclass=shadowAccount)" 560Sstevel@tonic-gate #define _F_GETUSERNAME "(objectClass=SolarisUserAttr)" 570Sstevel@tonic-gate #define _F_GETPROJENT "(objectClass=SolarisProject)" 581676Sjpk #define _F_GETTNRHDB "(objectClass=ipTnetHost)" 591676Sjpk #define _F_GETTNRHTP "(&(objectClass=ipTnetTemplate)"\ 601676Sjpk "(SolarisAttrKeyValue=*))" 610Sstevel@tonic-gate #define _F_GETENT_SSD "(%s)" 620Sstevel@tonic-gate 630Sstevel@tonic-gate static struct gettablefilter { 640Sstevel@tonic-gate char *tablename; 650Sstevel@tonic-gate char *tablefilter; 660Sstevel@tonic-gate } gettablefilterent[] = { 670Sstevel@tonic-gate {(char *)_PASSWD, (char *)_F_GETPWENT}, 680Sstevel@tonic-gate {(char *)_SHADOW, (char *)_F_GETSPENT}, 690Sstevel@tonic-gate {(char *)_GROUP, (char *)_F_GETGRENT}, 700Sstevel@tonic-gate {(char *)_HOSTS, (char *)_F_GETHOSTENT}, 710Sstevel@tonic-gate {(char *)_NETWORKS, (char *)_F_GETNETENT}, 720Sstevel@tonic-gate {(char *)_PROTOCOLS, (char *)_F_GETPROTOENT}, 730Sstevel@tonic-gate {(char *)_RPC, (char *)_F_GETRPCENT}, 740Sstevel@tonic-gate {(char *)_ALIASES, (char *)_F_GETALIASENT}, 750Sstevel@tonic-gate {(char *)_SERVICES, (char *)_F_GETSERVENT}, 760Sstevel@tonic-gate {(char *)_AUUSER, (char *)_F_GETAUUSERNAME}, 770Sstevel@tonic-gate {(char *)_AUTHATTR, (char *)_F_GETAUTHNAME}, 780Sstevel@tonic-gate {(char *)_EXECATTR, (char *)_F_GETEXECNAME}, 790Sstevel@tonic-gate {(char *)_PROFATTR, (char *)_F_GETPROFNAME}, 800Sstevel@tonic-gate {(char *)_USERATTR, (char *)_F_GETUSERNAME}, 810Sstevel@tonic-gate {(char *)_PROJECT, (char *)_F_GETPROJENT}, 820Sstevel@tonic-gate {(char *)_PRINTERS, (char *)_F_GETPRINTERENT}, 831676Sjpk {(char *)_TNRHDB, (char *)_F_GETTNRHDB}, 841676Sjpk {(char *)_TNRHTP, (char *)_F_GETTNRHTP}, 850Sstevel@tonic-gate {(char *)NULL, (char *)NULL} 860Sstevel@tonic-gate }; 870Sstevel@tonic-gate 880Sstevel@tonic-gate 894953Smichen nss_status_t 900Sstevel@tonic-gate switch_err(int rc, ns_ldap_error_t *error) 910Sstevel@tonic-gate { 920Sstevel@tonic-gate switch (rc) { 934953Smichen case NS_LDAP_SUCCESS: 940Sstevel@tonic-gate return (NSS_SUCCESS); 950Sstevel@tonic-gate 964953Smichen case NS_LDAP_NOTFOUND: 970Sstevel@tonic-gate return (NSS_NOTFOUND); 980Sstevel@tonic-gate 994953Smichen case NS_LDAP_PARTIAL: 1000Sstevel@tonic-gate return (NSS_TRYAGAIN); 1010Sstevel@tonic-gate 1024953Smichen case NS_LDAP_INTERNAL: 1034953Smichen if (error && (error->status == LDAP_SERVER_DOWN || 1044953Smichen error->status == LDAP_TIMEOUT)) 1054953Smichen return (NSS_TRYAGAIN); 1064953Smichen else 1074953Smichen return (NSS_UNAVAIL); 1080Sstevel@tonic-gate 1094953Smichen default: 1100Sstevel@tonic-gate return (NSS_UNAVAIL); 1110Sstevel@tonic-gate } 1120Sstevel@tonic-gate } 1132830Sdjl /* ARGSUSED */ 1140Sstevel@tonic-gate nss_status_t 1150Sstevel@tonic-gate _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, 1160Sstevel@tonic-gate char *database, char *searchfilter, char *domain, 1170Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 1180Sstevel@tonic-gate char **realfilter, const void *userdata), 1190Sstevel@tonic-gate const void *userdata) 1200Sstevel@tonic-gate { 1210Sstevel@tonic-gate int callbackstat = 0; 1220Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 1230Sstevel@tonic-gate int rc; 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate #ifdef DEBUG 1260Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_lookup]\n"); 1270Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter); 1280Sstevel@tonic-gate (void) fprintf(stdout, 1294953Smichen "\tuserdata: %s\n", userdata ? userdata : "NULL"); 1300Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database); 1310Sstevel@tonic-gate #endif /* DEBUG */ 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 1340Sstevel@tonic-gate 1350Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb, 1364953Smichen be->attrs, NULL, 0, &be->result, &error, NULL, 1374953Smichen userdata)) != NS_LDAP_SUCCESS) { 1380Sstevel@tonic-gate argp->returnval = 0; 1390Sstevel@tonic-gate rc = switch_err(rc, error); 1400Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 1412830Sdjl 1420Sstevel@tonic-gate return (rc); 1430Sstevel@tonic-gate } 1442830Sdjl (void) __ns_ldap_freeError(&error); 1450Sstevel@tonic-gate /* callback function */ 1460Sstevel@tonic-gate if ((callbackstat = 1474953Smichen be->ldapobj2str(be, argp)) != NSS_STR_PARSE_SUCCESS) { 1482830Sdjl goto error_out; 1492830Sdjl } 1502830Sdjl 1512830Sdjl /* 1522830Sdjl * publickey does not have a front end marshaller and expects 1532830Sdjl * a string to be returned in NSS. 1542830Sdjl * No need to convert file format -> struct. 1552830Sdjl * 1562830Sdjl */ 1572830Sdjl if (be->db_type == NSS_LDAP_DB_PUBLICKEY) { 1582830Sdjl argp->returnval = argp->buf.buffer; 1592830Sdjl argp->returnlen = strlen(argp->buf.buffer); 1602830Sdjl be->db_type = NSS_LDAP_DB_NONE; 1612830Sdjl return (NSS_SUCCESS); 1620Sstevel@tonic-gate } 1632830Sdjl /* 1642830Sdjl * Assume the switch engine wants the returned data in the file 1652830Sdjl * format when argp->buf.result == NULL. 1662830Sdjl * The front-end marshaller str2ether(ethers) uses 1672830Sdjl * ent (argp->buf.result) and buffer (argp->buf.buffer) 1682830Sdjl * for different purpose so ethers has to be treated differently. 1692830Sdjl */ 1702830Sdjl if (argp->buf.result != NULL || 1714953Smichen be->db_type == NSS_LDAP_DB_ETHERS) { 1722830Sdjl /* file format -> struct */ 1732830Sdjl if (argp->str2ent == NULL) { 1742830Sdjl callbackstat = NSS_STR_PARSE_PARSE; 1752830Sdjl goto error_out; 1762830Sdjl } 1770Sstevel@tonic-gate 1782830Sdjl callbackstat = (*argp->str2ent)(be->buffer, 1794953Smichen be->buflen, 1804953Smichen argp->buf.result, 1814953Smichen argp->buf.buffer, 1824953Smichen argp->buf.buflen); 1832830Sdjl if (callbackstat == NSS_STR_PARSE_SUCCESS) { 1842830Sdjl if (be->db_type == NSS_LDAP_DB_ETHERS && 1854953Smichen argp->buf.buffer != NULL) { 1862830Sdjl argp->returnval = argp->buf.buffer; 1872830Sdjl argp->returnlen = strlen(argp->buf.buffer); 1882830Sdjl } else { 1892830Sdjl argp->returnval = argp->buf.result; 1902830Sdjl argp->returnlen = 1; /* irrelevant */ 1912830Sdjl } 1922830Sdjl if (be->buffer != NULL) { 1932830Sdjl free(be->buffer); 1942830Sdjl be->buffer = NULL; 1952830Sdjl be->buflen = 0; 1962830Sdjl be->db_type = NSS_LDAP_DB_NONE; 1972830Sdjl } 1982830Sdjl return ((nss_status_t)NSS_SUCCESS); 1992830Sdjl } 2002830Sdjl } else { 2012830Sdjl /* return file format in argp->buf.buffer */ 2022830Sdjl argp->returnval = argp->buf.buffer; 2032830Sdjl argp->returnlen = strlen(argp->buf.buffer); 2042830Sdjl return ((nss_status_t)NSS_SUCCESS); 2052830Sdjl } 2062830Sdjl 2072830Sdjl error_out: 2082830Sdjl if (be->buffer != NULL) { 2092830Sdjl free(be->buffer); 2102830Sdjl be->buffer = NULL; 2112830Sdjl be->buflen = 0; 2122830Sdjl be->db_type = NSS_LDAP_DB_NONE; 2132830Sdjl } 2140Sstevel@tonic-gate /* error */ 2150Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_PARSE) { 2160Sstevel@tonic-gate argp->returnval = 0; 2170Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_ERANGE) { 2200Sstevel@tonic-gate argp->erange = 1; 2210Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate if (callbackstat == NSS_STR_PARSE_NO_ADDR) { 2240Sstevel@tonic-gate /* No IPV4 address is found */ 2250Sstevel@tonic-gate argp->h_errno = HOST_NOT_FOUND; 2260Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 2270Sstevel@tonic-gate } 2280Sstevel@tonic-gate return ((nss_status_t)NSS_UNAVAIL); 2290Sstevel@tonic-gate } 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate /* 2320Sstevel@tonic-gate * This function is similar to _nss_ldap_lookup except it does not 2330Sstevel@tonic-gate * do a callback. It is only used by getnetgrent.c 2340Sstevel@tonic-gate */ 2350Sstevel@tonic-gate 2362830Sdjl /* ARGSUSED */ 2370Sstevel@tonic-gate nss_status_t 2380Sstevel@tonic-gate _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, 2390Sstevel@tonic-gate char *database, char *searchfilter, char *domain, 2400Sstevel@tonic-gate int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, 2410Sstevel@tonic-gate char **realfilter, const void *userdata), 2420Sstevel@tonic-gate const void *userdata) 2430Sstevel@tonic-gate { 2440Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 2450Sstevel@tonic-gate int rc; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate #ifdef DEBUG 2480Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_nocb_lookup]\n"); 2490Sstevel@tonic-gate (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter); 2500Sstevel@tonic-gate (void) fprintf(stdout, "\tdatabase: %s\n", database); 2510Sstevel@tonic-gate (void) fprintf(stdout, 2524953Smichen "\tuserdata: %s\n", userdata ? userdata : "NULL"); 2530Sstevel@tonic-gate #endif /* DEBUG */ 2540Sstevel@tonic-gate 2550Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb, 2584953Smichen be->attrs, NULL, 0, &be->result, &error, NULL, 2594953Smichen userdata)) != NS_LDAP_SUCCESS) { 260*5362Smichen if (argp != NULL) 261*5362Smichen argp->returnval = 0; 2620Sstevel@tonic-gate rc = switch_err(rc, error); 2630Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 2640Sstevel@tonic-gate return (rc); 2650Sstevel@tonic-gate } 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 2680Sstevel@tonic-gate } 2690Sstevel@tonic-gate 2700Sstevel@tonic-gate 2710Sstevel@tonic-gate /* 2720Sstevel@tonic-gate * 2730Sstevel@tonic-gate */ 2740Sstevel@tonic-gate 2750Sstevel@tonic-gate void 2760Sstevel@tonic-gate _clean_ldap_backend(ldap_backend_ptr be) 2770Sstevel@tonic-gate { 2780Sstevel@tonic-gate ns_ldap_error_t *error; 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate #ifdef DEBUG 2810Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _clean_ldap_backend]\n"); 2820Sstevel@tonic-gate #endif /* DEBUG */ 2830Sstevel@tonic-gate 2840Sstevel@tonic-gate if (be->tablename != NULL) 2850Sstevel@tonic-gate free(be->tablename); 2860Sstevel@tonic-gate if (be->result != NULL) 2870Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 2880Sstevel@tonic-gate if (be->enumcookie != NULL) 2890Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error); 2900Sstevel@tonic-gate if (be->services_cookie != NULL) 2910Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie); 2920Sstevel@tonic-gate if (be->toglue != NULL) { 2930Sstevel@tonic-gate free(be->toglue); 2940Sstevel@tonic-gate be->toglue = NULL; 2950Sstevel@tonic-gate } 2962830Sdjl if (be->buffer != NULL) { 2972830Sdjl free(be->buffer); 2982830Sdjl be->buffer = NULL; 2992830Sdjl } 3000Sstevel@tonic-gate free(be); 3010Sstevel@tonic-gate } 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate /* 3050Sstevel@tonic-gate * _nss_ldap_destr will free all smalloc'ed variable strings and structures 3060Sstevel@tonic-gate * before exiting this nsswitch shared backend library. This function is 3070Sstevel@tonic-gate * called before returning control back to nsswitch. 3080Sstevel@tonic-gate */ 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate /*ARGSUSED1*/ 3110Sstevel@tonic-gate nss_status_t 3120Sstevel@tonic-gate _nss_ldap_destr(ldap_backend_ptr be, void *a) 3130Sstevel@tonic-gate { 3140Sstevel@tonic-gate 3150Sstevel@tonic-gate #ifdef DEBUG 3160Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_destr]\n"); 3170Sstevel@tonic-gate #endif /* DEBUG */ 3180Sstevel@tonic-gate 3190Sstevel@tonic-gate (void) _clean_ldap_backend(be); 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3220Sstevel@tonic-gate } 3230Sstevel@tonic-gate 3240Sstevel@tonic-gate 3250Sstevel@tonic-gate /* 3260Sstevel@tonic-gate * _nss_ldap_setent called before _nss_ldap_getent. This function is 3270Sstevel@tonic-gate * required by POSIX. 3280Sstevel@tonic-gate */ 3290Sstevel@tonic-gate 3300Sstevel@tonic-gate nss_status_t 3310Sstevel@tonic-gate _nss_ldap_setent(ldap_backend_ptr be, void *a) 3320Sstevel@tonic-gate { 3330Sstevel@tonic-gate struct gettablefilter *gtf; 3340Sstevel@tonic-gate 3350Sstevel@tonic-gate #ifdef DEBUG 3360Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_setent]\n"); 3370Sstevel@tonic-gate #endif /* DEBUG */ 3380Sstevel@tonic-gate 3390Sstevel@tonic-gate if (be->setcalled == 1) 3400Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 3410Sstevel@tonic-gate be->filter = NULL; 3420Sstevel@tonic-gate for (gtf = gettablefilterent; gtf->tablename != (char *)NULL; gtf++) { 3430Sstevel@tonic-gate if (strcmp(gtf->tablename, be->tablename)) 3440Sstevel@tonic-gate continue; 3450Sstevel@tonic-gate be->filter = (char *)gtf->tablefilter; 3460Sstevel@tonic-gate break; 3470Sstevel@tonic-gate } 3480Sstevel@tonic-gate 3490Sstevel@tonic-gate be->setcalled = 1; 3500Sstevel@tonic-gate be->enumcookie = NULL; 3510Sstevel@tonic-gate be->result = NULL; 3520Sstevel@tonic-gate be->services_cookie = NULL; 3532830Sdjl be->buffer = NULL; 3540Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate /* 3590Sstevel@tonic-gate * _nss_ldap_endent called after _nss_ldap_getent. This function is 3600Sstevel@tonic-gate * required by POSIX. 3610Sstevel@tonic-gate */ 3620Sstevel@tonic-gate 3630Sstevel@tonic-gate /*ARGSUSED1*/ 3640Sstevel@tonic-gate nss_status_t 3650Sstevel@tonic-gate _nss_ldap_endent(ldap_backend_ptr be, void *a) 3660Sstevel@tonic-gate { 3670Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate #ifdef DEBUG 3700Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_endent]\n"); 3710Sstevel@tonic-gate #endif /* DEBUG */ 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate be->setcalled = 0; 3740Sstevel@tonic-gate be->filter = NULL; 3750Sstevel@tonic-gate if (be->enumcookie != NULL) { 3760Sstevel@tonic-gate (void) __ns_ldap_endEntry(&be->enumcookie, &error); 3770Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 3780Sstevel@tonic-gate } 3790Sstevel@tonic-gate if (be->result != NULL) { 3800Sstevel@tonic-gate (void) __ns_ldap_freeResult(&be->result); 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate if (be->services_cookie != NULL) { 3830Sstevel@tonic-gate _nss_services_cookie_free((void **)&be->services_cookie); 3840Sstevel@tonic-gate } 3852830Sdjl if (be->buffer != NULL) { 3862830Sdjl free(be->buffer); 3872830Sdjl be->buffer = NULL; 3882830Sdjl } 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 3910Sstevel@tonic-gate } 3920Sstevel@tonic-gate 3930Sstevel@tonic-gate 3940Sstevel@tonic-gate /* 3950Sstevel@tonic-gate * 3960Sstevel@tonic-gate */ 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate nss_status_t 3990Sstevel@tonic-gate _nss_ldap_getent(ldap_backend_ptr be, void *a) 4000Sstevel@tonic-gate { 4010Sstevel@tonic-gate nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; 4020Sstevel@tonic-gate ns_ldap_error_t *error = NULL; 4030Sstevel@tonic-gate int parsestat = 0; 4040Sstevel@tonic-gate int retcode = 0; 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate #ifdef DEBUG 4070Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_getent]\n"); 4080Sstevel@tonic-gate #endif /* DEBUG */ 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate if (be->setcalled == 0) 4110Sstevel@tonic-gate (void) _nss_ldap_setent(be, a); 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate next_entry: 4140Sstevel@tonic-gate if (be->enumcookie == NULL) { 4150Sstevel@tonic-gate retcode = __ns_ldap_firstEntry(be->tablename, 4164953Smichen be->filter, _merge_SSD_filter, be->attrs, NULL, 4174953Smichen 0, &be->enumcookie, 4184953Smichen &be->result, &error, _F_GETENT_SSD); 4190Sstevel@tonic-gate } else { 4200Sstevel@tonic-gate if (be->services_cookie == NULL) { 4210Sstevel@tonic-gate retcode = __ns_ldap_nextEntry(be->enumcookie, 4224953Smichen &be->result, &error); 4230Sstevel@tonic-gate } 4240Sstevel@tonic-gate } 4250Sstevel@tonic-gate if (retcode != NS_LDAP_SUCCESS) { 4260Sstevel@tonic-gate retcode = switch_err(retcode, error); 4270Sstevel@tonic-gate (void) __ns_ldap_freeError(&error); 4280Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 4290Sstevel@tonic-gate return (retcode); 4300Sstevel@tonic-gate } else { 4312830Sdjl /* ns_ldap_entry_t -> file format */ 4322830Sdjl if ((parsestat = be->ldapobj2str(be, argp)) 4334953Smichen == NSS_STR_PARSE_SUCCESS) { 4342830Sdjl if (argp->buf.result != NULL) { 4352830Sdjl /* file format -> struct */ 4362830Sdjl if (argp->str2ent == NULL) { 4372830Sdjl parsestat = NSS_STR_PARSE_PARSE; 4382830Sdjl goto error_out; 4392830Sdjl } 4402830Sdjl parsestat = (*argp->str2ent)(be->buffer, 4414953Smichen be->buflen, 4424953Smichen argp->buf.result, 4434953Smichen argp->buf.buffer, 4444953Smichen argp->buf.buflen); 4452830Sdjl if (parsestat == NSS_STR_PARSE_SUCCESS) { 4462830Sdjl if (be->buffer != NULL) { 4472830Sdjl free(be->buffer); 4482830Sdjl be->buffer = NULL; 4492830Sdjl be->buflen = 0; 4502830Sdjl } 4512830Sdjl be->result = NULL; 4522830Sdjl argp->returnval = argp->buf.result; 4532830Sdjl argp->returnlen = 1; /* irrevelant */ 4542830Sdjl return ((nss_status_t)NSS_SUCCESS); 4552830Sdjl } 4562830Sdjl } else { 4572830Sdjl /* 4582830Sdjl * nscd is not caching the enumerated 4592830Sdjl * entries. This code path would be dormant. 4602830Sdjl * Keep this path for the future references. 4612830Sdjl */ 4622830Sdjl argp->returnval = argp->buf.buffer; 4632830Sdjl argp->returnlen = 4644953Smichen strlen(argp->buf.buffer) + 1; 4652830Sdjl } 4662830Sdjl } 4672830Sdjl error_out: 4682830Sdjl if (be->buffer != NULL) { 4692830Sdjl free(be->buffer); 4702830Sdjl be->buffer = NULL; 4712830Sdjl be->buflen = 0; 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate be->result = NULL; 4740Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_PARSE) { 4750Sstevel@tonic-gate argp->returnval = 0; 4760Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 4770Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 4780Sstevel@tonic-gate } 4790Sstevel@tonic-gate 4800Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_ERANGE) { 4810Sstevel@tonic-gate argp->erange = 1; 4820Sstevel@tonic-gate (void) _nss_ldap_endent(be, a); 4830Sstevel@tonic-gate return ((nss_status_t)NSS_NOTFOUND); 4840Sstevel@tonic-gate } 4850Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_NO_ADDR) 4860Sstevel@tonic-gate /* 4870Sstevel@tonic-gate * No IPV4 address is found in the current entry. 4880Sstevel@tonic-gate * It indicates that the entry contains IPV6 addresses 4890Sstevel@tonic-gate * only. Instead of calling _nss_ldap_endent to 4900Sstevel@tonic-gate * terminate, get next entry to continue enumeration. 4910Sstevel@tonic-gate * If it returned NSS_NOTFOUND here, 4920Sstevel@tonic-gate * gethostent() would return NULL 4930Sstevel@tonic-gate * and the enumeration would stop prematurely. 4940Sstevel@tonic-gate */ 4950Sstevel@tonic-gate goto next_entry; 4960Sstevel@tonic-gate } 4970Sstevel@tonic-gate 4980Sstevel@tonic-gate return ((nss_status_t)NSS_SUCCESS); 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate 5010Sstevel@tonic-gate 5020Sstevel@tonic-gate /* 5030Sstevel@tonic-gate * 5040Sstevel@tonic-gate */ 5050Sstevel@tonic-gate 5060Sstevel@tonic-gate nss_backend_t * 5070Sstevel@tonic-gate _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename, 5082830Sdjl const char **attrs, fnf ldapobj2str) 5090Sstevel@tonic-gate { 5100Sstevel@tonic-gate ldap_backend_ptr be; 5110Sstevel@tonic-gate 5120Sstevel@tonic-gate #ifdef DEBUG 5130Sstevel@tonic-gate (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_constr]\n"); 5140Sstevel@tonic-gate #endif /* DEBUG */ 5150Sstevel@tonic-gate 5162830Sdjl if ((be = (ldap_backend_ptr) calloc(1, sizeof (*be))) == 0) 5170Sstevel@tonic-gate return (0); 5180Sstevel@tonic-gate be->ops = ops; 5190Sstevel@tonic-gate be->nops = (nss_dbop_t)nops; 5200Sstevel@tonic-gate be->tablename = (char *)strdup(tablename); 5210Sstevel@tonic-gate be->attrs = attrs; 5222830Sdjl be->ldapobj2str = ldapobj2str; 5230Sstevel@tonic-gate 5240Sstevel@tonic-gate return ((nss_backend_t *)be); 5250Sstevel@tonic-gate } 5260Sstevel@tonic-gate 5270Sstevel@tonic-gate 5280Sstevel@tonic-gate /* 5290Sstevel@tonic-gate * 5300Sstevel@tonic-gate */ 5310Sstevel@tonic-gate int 5320Sstevel@tonic-gate chophostdomain(char *string, char *host, char *domain) 5330Sstevel@tonic-gate { 5340Sstevel@tonic-gate char *dot; 5350Sstevel@tonic-gate 5360Sstevel@tonic-gate if (string == NULL) 5370Sstevel@tonic-gate return (-1); 5380Sstevel@tonic-gate 5390Sstevel@tonic-gate if ((dot = strchr(string, '.')) == NULL) { 5400Sstevel@tonic-gate return (0); 5410Sstevel@tonic-gate } 5420Sstevel@tonic-gate *dot = '\0'; 5432830Sdjl (void) strcpy(host, string); 5442830Sdjl (void) strcpy(domain, ++dot); 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate return (0); 5470Sstevel@tonic-gate } 5480Sstevel@tonic-gate 5490Sstevel@tonic-gate 5500Sstevel@tonic-gate /* 5510Sstevel@tonic-gate * 5520Sstevel@tonic-gate */ 5530Sstevel@tonic-gate int 5540Sstevel@tonic-gate propersubdomain(char *domain, char *subdomain) 5550Sstevel@tonic-gate { 5560Sstevel@tonic-gate int domainlen, subdomainlen; 5570Sstevel@tonic-gate 5580Sstevel@tonic-gate /* sanity check */ 5590Sstevel@tonic-gate if (domain == NULL || subdomain == NULL) 5600Sstevel@tonic-gate return (-1); 5610Sstevel@tonic-gate 5620Sstevel@tonic-gate domainlen = strlen(domain); 5630Sstevel@tonic-gate subdomainlen = strlen(subdomain); 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate /* is afterdot a substring of domain? */ 5660Sstevel@tonic-gate if ((strncasecmp(domain, subdomain, subdomainlen)) != 0) 5670Sstevel@tonic-gate return (-1); 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate if (domainlen == subdomainlen) 5700Sstevel@tonic-gate return (1); 5710Sstevel@tonic-gate 5720Sstevel@tonic-gate if (subdomainlen > domainlen) 5730Sstevel@tonic-gate return (-1); 5740Sstevel@tonic-gate 5750Sstevel@tonic-gate if (*(domain + subdomainlen) != '.') 5760Sstevel@tonic-gate return (-1); 5770Sstevel@tonic-gate 5780Sstevel@tonic-gate return (1); 5790Sstevel@tonic-gate } 580