diff options
| author | Julian Pullen <Julian.Pullen@Sun.COM> | 2009-05-08 17:38:01 +0100 |
|---|---|---|
| committer | Julian Pullen <Julian.Pullen@Sun.COM> | 2009-05-08 17:38:01 +0100 |
| commit | b57459abfba36eb3068cfe44c6921168b4c4f774 (patch) | |
| tree | 5479f0844784d6b0929894abd0b14e3cee9135bd /usr/src/lib/libsldap/common | |
| parent | c9d66ba7a02565d1320b4a0780e249cfe8c02612 (diff) | |
| download | illumos-gate-b57459abfba36eb3068cfe44c6921168b4c4f774.tar.gz | |
4904603 disable ldaplist to not show userpassword attribute or just user logged in
Diffstat (limited to 'usr/src/lib/libsldap/common')
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_cache_door.h | 2 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_common.c | 39 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_config.c | 75 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_confmgr.c | 20 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_connect.c | 167 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_internal.h | 2 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_reads.c | 121 | ||||
| -rw-r--r-- | usr/src/lib/libsldap/common/ns_sldap.h | 7 |
8 files changed, 381 insertions, 52 deletions
diff --git a/usr/src/lib/libsldap/common/ns_cache_door.h b/usr/src/lib/libsldap/common/ns_cache_door.h index 52599534af..8e260c4f53 100644 --- a/usr/src/lib/libsldap/common/ns_cache_door.h +++ b/usr/src/lib/libsldap/common/ns_cache_door.h @@ -195,6 +195,8 @@ typedef union { #define GETSTATUSCHANGE 25 /* perform admin modify via ldap_cachemgr */ #define ADMINMODIFY 26 + /* get admin credentials for shadow lookups */ +#define GETADMINCRED 27 /* * GETLDAPSERVER request flags diff --git a/usr/src/lib/libsldap/common/ns_common.c b/usr/src/lib/libsldap/common/ns_common.c index 3518d1fe41..d800741f91 100644 --- a/usr/src/lib/libsldap/common/ns_common.c +++ b/usr/src/lib/libsldap/common/ns_common.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -252,11 +252,46 @@ __ns_ldap_dupAuth(const ns_cred_t *authp) } /* + * FUNCTION: __ns_ldap_freeUnixCred + * + * Frees all the memory associated with a UnixCred_t structure. + * + * RETURN VALUES: NS_LDAP_INVALID_PARAM, NS_LDAP_SUCCESS + * INPUT: UnixCred + */ +int +__ns_ldap_freeUnixCred(UnixCred_t ** credp) +{ + UnixCred_t *ap; + +#ifdef DEBUG + (void) fprintf(stderr, "__ns_ldap_freeUnixCred START\n"); +#endif + if (credp == NULL || *credp == NULL) + return (NS_LDAP_INVALID_PARAM); + + ap = *credp; + if (ap->userID) { + (void) memset(ap->userID, 0, strlen(ap->userID)); + free(ap->userID); + } + + if (ap->passwd) { + (void) memset(ap->passwd, 0, strlen(ap->passwd)); + free(ap->passwd); + } + + free(ap); + *credp = NULL; + return (NS_LDAP_SUCCESS); +} + +/* * FUNCTION: __ns_ldap_freeCred * * Frees all the memory associated with a ns_cred_t structure. * - * RETURN VALUES: NS_LDAP_INVALID_PARAM, NS_LDAP_SUCCESS, NS_LDAP_CONFIG + * RETURN VALUES: NS_LDAP_INVALID_PARAM, NS_LDAP_SUCCESS * INPUT: ns_cred_t */ int diff --git a/usr/src/lib/libsldap/common/ns_config.c b/usr/src/lib/libsldap/common/ns_config.c index 1a7a21bfee..96f3673428 100644 --- a/usr/src/lib/libsldap/common/ns_config.c +++ b/usr/src/lib/libsldap/common/ns_config.c @@ -3335,8 +3335,10 @@ __s_api_strValue(ns_config_t *cfg, char *str, return (buf); } -static int -__door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error) +/* shared by __door_getldapconfig() and __door_getadmincred() */ +int +__door_getconf(char **buffer, int *buflen, ns_ldap_error_t **error, + int callnumber) { typedef union { ldap_data_t s_d; @@ -3367,7 +3369,7 @@ __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error) adata = (sizeof (ldap_call_t) + strlen(domainname) +1); ndata = sizeof (space_t); - space->s_d.ldap_call.ldap_callnumber = GETLDAPCONFIGV1; + space->s_d.ldap_call.ldap_callnumber = callnumber; (void) strcpy(space->s_d.ldap_call.ldap_u.domainname, domainname); free(domainname); domainname = NULL; @@ -3410,6 +3412,73 @@ __door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error) return (retCode); } +static int +__door_getldapconfig(char **buffer, int *buflen, ns_ldap_error_t **error) +{ + return (__door_getconf(buffer, buflen, error, GETLDAPCONFIGV1)); +} + +/* + * SetDoorInfoToUnixCred parses ldapcachemgr configuration information + * for Admin credentials. + */ +int +SetDoorInfoToUnixCred(char *buffer, ns_ldap_error_t **errorp, + UnixCred_t **cred) +{ + UnixCred_t *ptr; + char errstr[MAXERROR]; + char *name, *value, valbuf[BUFSIZE]; + char *bufptr = buffer; + char *strptr; + char *rest; + ParamIndexType index = 0; + ldap_config_out_t *cfghdr; + + if (errorp == NULL || cred == NULL || *cred == NULL) + return (NS_LDAP_INVALID_PARAM); + *errorp = NULL; + + ptr = *cred; + + cfghdr = (ldap_config_out_t *)bufptr; + bufptr = (char *)cfghdr->config_str; + + strptr = (char *)strtok_r(bufptr, DOORLINESEP, &rest); + for (; ; ) { + if (strptr == NULL) + break; + (void) strlcpy(valbuf, strptr, sizeof (valbuf)); + __s_api_split_key_value(valbuf, &name, &value); + if (__ns_ldap_getParamType(name, &index) != 0) { + (void) snprintf(errstr, MAXERROR, + gettext("SetDoorInfoToUnixCred: " + "Unknown keyword encountered '%s'."), name); + MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX, + strdup(errstr), NULL); + return (NS_LDAP_CONFIG); + } + switch (index) { + case NS_LDAP_ADMIN_BINDDN_P: + ptr->userID = (char *)strdup(value); + break; + case NS_LDAP_ADMIN_BINDPASSWD_P: + ptr->passwd = (char *)strdup(value); + break; + default: + (void) snprintf(errstr, MAXERROR, + gettext("SetDoorInfoToUnixCred: " + "Unknown index encountered '%d'."), index); + MKERROR(LOG_ERR, *errorp, NS_CONFIG_SYNTAX, + strdup(errstr), NULL); + return (NS_LDAP_CONFIG); + } + strptr = (char *)strtok_r(NULL, DOORLINESEP, &rest); + } + + return (NS_LDAP_SUCCESS); +} + /* * SetDoorInfo parses ldapcachemgr configuration information * and verifies that the profile is version 1 or version 2 based. diff --git a/usr/src/lib/libsldap/common/ns_confmgr.c b/usr/src/lib/libsldap/common/ns_confmgr.c index a96f186ded..d6c9fcfaac 100644 --- a/usr/src/lib/libsldap/common/ns_confmgr.c +++ b/usr/src/lib/libsldap/common/ns_confmgr.c @@ -463,10 +463,13 @@ _print2buf(LineBuf *line, char *toprint, int addsep) * domainname is transmitted to ldapcachemgr and ldapcachemgr uses * it to select a configuration to transmit back. Otherwise it * is essentially unused in sldap. + * If cred_only is not 0, then only the credentials for shadow + * update are taken care of. */ ns_ldap_error_t * -__ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname, ns_config_t *new) +__ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname, + ns_config_t *new, int cred_only) { ns_config_t *ptr; char errstr[MAXERROR]; @@ -497,10 +500,17 @@ __ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname, ns_config_t *new) } (void) memset((char *)configinfo, 0, sizeof (LineBuf)); for (i = 0; i <= NS_LDAP_MAX_PIT_P; i++) { - /* the credential for shadow update is not to be exposed */ - if (i == NS_LDAP_ADMIN_BINDDN_P || - i == NS_LDAP_ADMIN_BINDPASSWD_P) - continue; + if (cred_only) { + /* only exposed credential for shadow update */ + if (i != NS_LDAP_ADMIN_BINDDN_P && + i != NS_LDAP_ADMIN_BINDPASSWD_P) + continue; + } else { + /* credential for shadow update is not to be exposed */ + if (i == NS_LDAP_ADMIN_BINDDN_P || + i == NS_LDAP_ADMIN_BINDPASSWD_P) + continue; + } str = __s_api_strValue(ptr, string, sizeof (string), i, NS_DOOR_FMT); if (str == NULL) diff --git a/usr/src/lib/libsldap/common/ns_connect.c b/usr/src/lib/libsldap/common/ns_connect.c index 67cdee702f..5be22acc27 100644 --- a/usr/src/lib/libsldap/common/ns_connect.c +++ b/usr/src/lib/libsldap/common/ns_connect.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdlib.h> #include <stdio.h> #include <errno.h> @@ -68,6 +66,13 @@ extern int ldap_sasl_cram_md5_bind_s(LDAP *, char *, struct berval *, LDAPControl **, LDAPControl **); extern int ldapssl_install_gethostbyaddr(LDAP *ld, const char *skip); +extern int __door_getconf(char **buffer, int *buflen, + ns_ldap_error_t **error, int callnumber); +extern int __ns_ldap_freeUnixCred(UnixCred_t **credp); +extern int SetDoorInfoToUnixCred(char *buffer, + ns_ldap_error_t **errorp, + UnixCred_t **cred); + static int openConnection(LDAP **, const char *, const ns_cred_t *, int, ns_ldap_error_t **, int, int, ns_conn_user_t *); static void @@ -135,6 +140,41 @@ getFirstFromConfig(ns_server_info_t *ret, ns_ldap_error_t **error) return (NS_LDAP_SUCCESS); } +/* very similar to __door_getldapconfig() in ns_config.c */ +static int +__door_getadmincred(char **buffer, int *buflen, ns_ldap_error_t **error) +{ + return (__door_getconf(buffer, buflen, error, GETADMINCRED)); +} + +/* + * This function requests Admin credentials from the cache manager through + * the door functionality + */ + +static int +requestAdminCred(UnixCred_t **cred, ns_ldap_error_t **error) +{ + char *buffer = NULL; + int buflen = 0; + int ret; + + *error = NULL; + ret = __door_getadmincred(&buffer, &buflen, error); + + if (ret != NS_LDAP_SUCCESS) { + if (*error != NULL && (*error)->message != NULL) + syslog(LOG_WARNING, "libsldap: %s", (*error)->message); + return (ret); + } + + /* now convert from door format */ + ret = SetDoorInfoToUnixCred(buffer, error, cred); + free(buffer); + + return (ret); +} + /* * This function requests a server from the cache manager through * the door functionality @@ -1418,6 +1458,8 @@ openConnection(LDAP **ldp, const char *serverAddr, const ns_cred_t *auth, * * aMethod Currently requested authentication method to be tried * + * getAdmin If non 0, get Admin -i.e., not proxyAgent- DN and password + * * OUTPUT: * * authp authentication method to use. @@ -1426,7 +1468,8 @@ static int __s_api_getDefaultAuth( int *cLevel, ns_auth_t *aMethod, - ns_cred_t **authp) + ns_cred_t **authp, + int getAdmin) { void **paramVal = NULL; char *modparamVal = NULL; @@ -1435,6 +1478,7 @@ __s_api_getDefaultAuth( int getCertpath = 0; int rc = 0; ns_ldap_error_t *errorp = NULL; + UnixCred_t *AdminCred = NULL; #ifdef DEBUG (void) fprintf(stderr, "__s_api_getDefaultAuth START\n"); @@ -1472,7 +1516,6 @@ __s_api_getDefaultAuth( getPasswd++; } else if (aMethod->saslmech != NS_LDAP_SASL_GSSAPI) { (void) __ns_ldap_freeCred(authp); - *authp = NULL; return (NS_LDAP_INVALID_PARAM); } break; @@ -1488,7 +1531,6 @@ __s_api_getDefaultAuth( getCertpath++; } else { (void) __ns_ldap_freeCred(authp); - *authp = NULL; return (NS_LDAP_INVALID_PARAM); } break; @@ -1496,51 +1538,99 @@ __s_api_getDefaultAuth( if (getUid) { paramVal = NULL; - if ((rc = __ns_ldap_getParam(NS_LDAP_BINDDN_P, - ¶mVal, &errorp)) != NS_LDAP_SUCCESS) { - (void) __ns_ldap_freeCred(authp); - (void) __ns_ldap_freeError(&errorp); - *authp = NULL; - return (rc); - } + if (getAdmin) { + /* + * Assume AdminCred has been retrieved from + * ldap_cachemgr already. It will not work + * without userID or password. Flags getUid + * and getPasswd should always be set + * together. + */ + AdminCred = calloc(1, sizeof (UnixCred_t)); + if (AdminCred == NULL) { + (void) __ns_ldap_freeCred(authp); + return (NS_LDAP_MEMORY); + } - if (paramVal == NULL || *paramVal == NULL) { - (void) __ns_ldap_freeCred(authp); - *authp = NULL; - return (NS_LDAP_INVALID_PARAM); - } + rc = requestAdminCred(&AdminCred, &errorp); + if (rc != NS_LDAP_SUCCESS) { + (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); + (void) __ns_ldap_freeError(&errorp); + return (rc); + } - (*authp)->cred.unix_cred.userID = strdup((char *)*paramVal); - (void) __ns_ldap_freeParam(¶mVal); + if (AdminCred->userID == NULL) { + (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); + return (NS_LDAP_INVALID_PARAM); + } + (*authp)->cred.unix_cred.userID = AdminCred->userID; + AdminCred->userID = NULL; + } else { + rc = __ns_ldap_getParam(NS_LDAP_BINDDN_P, + ¶mVal, &errorp); + if (rc != NS_LDAP_SUCCESS) { + (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeError(&errorp); + return (rc); + } + + if (paramVal == NULL || *paramVal == NULL) { + (void) __ns_ldap_freeCred(authp); + return (NS_LDAP_INVALID_PARAM); + } + + (*authp)->cred.unix_cred.userID = + strdup((char *)*paramVal); + (void) __ns_ldap_freeParam(¶mVal); + } if ((*authp)->cred.unix_cred.userID == NULL) { (void) __ns_ldap_freeCred(authp); - *authp = NULL; + (void) __ns_ldap_freeUnixCred(&AdminCred); return (NS_LDAP_MEMORY); } } if (getPasswd) { paramVal = NULL; - if ((rc = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P, - ¶mVal, &errorp)) != NS_LDAP_SUCCESS) { - (void) __ns_ldap_freeCred(authp); - (void) __ns_ldap_freeError(&errorp); - *authp = NULL; - return (rc); - } + if (getAdmin) { + /* + * Assume AdminCred has been retrieved from + * ldap_cachemgr already. It will not work + * without the userID anyway because for + * getting admin credential, flags getUid + * and getPasswd should always be set + * together. + */ + if (AdminCred == NULL || AdminCred->passwd == NULL) { + (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); + return (NS_LDAP_INVALID_PARAM); + } + modparamVal = dvalue(AdminCred->passwd); + } else { + rc = __ns_ldap_getParam(NS_LDAP_BINDPASSWD_P, + ¶mVal, &errorp); + if (rc != NS_LDAP_SUCCESS) { + (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeError(&errorp); + return (rc); + } - if (paramVal == NULL || *paramVal == NULL) { - (void) __ns_ldap_freeCred(authp); - *authp = NULL; - return (NS_LDAP_INVALID_PARAM); + if (paramVal == NULL || *paramVal == NULL) { + (void) __ns_ldap_freeCred(authp); + return (NS_LDAP_INVALID_PARAM); + } + + modparamVal = dvalue((char *)*paramVal); + (void) __ns_ldap_freeParam(¶mVal); } - modparamVal = dvalue((char *)*paramVal); - (void) __ns_ldap_freeParam(¶mVal); if (modparamVal == NULL || (strlen((char *)modparamVal) == 0)) { (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); if (modparamVal != NULL) free(modparamVal); - *authp = NULL; return (NS_LDAP_INVALID_PARAM); } @@ -1551,6 +1641,7 @@ __s_api_getDefaultAuth( if ((rc = __ns_ldap_getParam(NS_LDAP_HOST_CERTPATH_P, ¶mVal, &errorp)) != NS_LDAP_SUCCESS) { (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); (void) __ns_ldap_freeError(&errorp); *authp = NULL; return (rc); @@ -1558,6 +1649,7 @@ __s_api_getDefaultAuth( if (paramVal == NULL || *paramVal == NULL) { (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); *authp = NULL; return (NS_LDAP_INVALID_PARAM); } @@ -1566,10 +1658,12 @@ __s_api_getDefaultAuth( (void) __ns_ldap_freeParam(¶mVal); if ((*authp)->hostcertpath == NULL) { (void) __ns_ldap_freeCred(authp); + (void) __ns_ldap_freeUnixCred(&AdminCred); *authp = NULL; return (NS_LDAP_MEMORY); } } + (void) __ns_ldap_freeUnixCred(&AdminCred); return (NS_LDAP_SUCCESS); } @@ -1759,7 +1853,8 @@ getConnection( /* with default credentials */ authp = NULL; rc = __s_api_getDefaultAuth(*cNext, - *aNext, &authp); + *aNext, &authp, + flags & NS_LDAP_READ_SHADOW); if (rc != NS_LDAP_SUCCESS) { continue; } diff --git a/usr/src/lib/libsldap/common/ns_internal.h b/usr/src/lib/libsldap/common/ns_internal.h index a389ef0e28..3157e141ed 100644 --- a/usr/src/lib/libsldap/common/ns_internal.h +++ b/usr/src/lib/libsldap/common/ns_internal.h @@ -831,7 +831,7 @@ char **__ns_ldap_mapAttributeList(const char *service, void __ns_ldap_setServer(int set); ns_ldap_error_t *__ns_ldap_LoadConfiguration(); ns_ldap_error_t *__ns_ldap_LoadDoorInfo(LineBuf *configinfo, char *domainname, - ns_config_t *new); + ns_config_t *new, int cred_only); ns_ldap_error_t *__ns_ldap_DumpConfiguration(char *filename); ns_ldap_error_t *__ns_ldap_DumpLdif(char *filename); int __ns_ldap_cache_ping(); diff --git a/usr/src/lib/libsldap/common/ns_reads.c b/usr/src/lib/libsldap/common/ns_reads.c index a2d658252d..7b65cd986b 100644 --- a/usr/src/lib/libsldap/common/ns_reads.c +++ b/usr/src/lib/libsldap/common/ns_reads.c @@ -19,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <sys/types.h> #include <stdlib.h> @@ -36,6 +34,7 @@ #include <unistd.h> #include <string.h> #include <strings.h> +#include <priv.h> #include "ns_sldap.h" #include "ns_internal.h" @@ -2824,6 +2823,70 @@ search_state_machine(ns_ldap_cookie_t *cookie, ns_state_t state, int cycle) } /* + * For a lookup of shadow data, if shadow update is enabled, + * check the calling process' privilege to ensure it's + * allowed to perform such operation. + */ +static int +check_shadow(ns_ldap_cookie_t *cookie, const char *service) +{ + char errstr[MAXERROR]; + char *err; + boolean_t priv; + /* caller */ + priv_set_t *ps; + /* zone */ + priv_set_t *zs; + + /* + * If service is "shadow", we may need + * to use privilege credentials. + */ + if ((strcmp(service, "shadow") == 0) && + __ns_ldap_is_shadow_update_enabled()) { + /* + * Since we release admin credentials after + * connection is closed and we do not cache + * them, we allow any root or all zone + * privilege process to read shadow data. + */ + priv = (geteuid() == 0); + if (!priv) { + /* caller */ + ps = priv_allocset(); + + (void) getppriv(PRIV_EFFECTIVE, ps); + zs = priv_str_to_set("zone", ",", NULL); + priv = priv_isequalset(ps, zs); + priv_freeset(ps); + priv_freeset(zs); + } + if (!priv) { + (void) sprintf(errstr, + gettext("Permission denied")); + err = strdup(errstr); + if (err == NULL) + return (NS_LDAP_MEMORY); + MKERROR(LOG_INFO, cookie->errorp, NS_LDAP_INTERNAL, err, + NULL); + return (NS_LDAP_INTERNAL); + } + cookie->i_flags |= NS_LDAP_READ_SHADOW; + /* + * We do not want to reuse connection (hence + * keep it open) with admin credentials. + * If NS_LDAP_KEEP_CONN is set, reject the + * request. + */ + if (cookie->i_flags & NS_LDAP_KEEP_CONN) + return (NS_LDAP_INVALID_PARAM); + cookie->i_flags |= NS_LDAP_NEW_CONN; + } + + return (NS_LDAP_SUCCESS); +} + +/* * internal function for __ns_ldap_list */ static int @@ -2855,6 +2918,13 @@ ldap_list( *rResult = NULL; *rcp = NS_LDAP_SUCCESS; + /* + * Sanity check - NS_LDAP_READ_SHADOW is for our + * own internal use. + */ + if (flags & NS_LDAP_READ_SHADOW) + return (NS_LDAP_INVALID_PARAM); + /* Initialize State machine cookie */ cookie = init_search_state_machine(); if (cookie == NULL) { @@ -2947,6 +3017,9 @@ ldap_list( cookie->callback = callback; cookie->use_usercb = 1; } + + /* check_shadow() may add extra value to cookie->i_flags */ + cookie->i_flags = flags; if (service) { cookie->service = strdup(service); if (cookie->service == NULL) { @@ -2955,12 +3028,27 @@ ldap_list( *rcp = NS_LDAP_MEMORY; return (NS_LDAP_MEMORY); } + + /* + * If given, use the credential given by the caller, and + * skip the credential check required for shadow update. + */ + if (auth == NULL) { + rc = check_shadow(cookie, service); + if (rc != NS_LDAP_SUCCESS) { + *errorp = cookie->errorp; + cookie->errorp = NULL; + delete_search_cookie(cookie); + cookie = NULL; + *rcp = rc; + return (rc); + } + } } cookie->i_filter = strdup(filter); cookie->i_attr = attribute; cookie->i_auth = auth; - cookie->i_flags = flags; if (batch != NULL) { cookie->batch = batch; @@ -3450,6 +3538,13 @@ firstEntry( *errorp = NULL; *result = NULL; + /* + * Sanity check - NS_LDAP_READ_SHADOW is for our + * own internal use. + */ + if (flags & NS_LDAP_READ_SHADOW) + return (NS_LDAP_INVALID_PARAM); + /* get the service descriptor - or create a default one */ rc = __s_api_get_SSD_from_SSDtoUse_service(service, &sdlist, errorp); @@ -3545,18 +3640,34 @@ firstEntry( cookie->use_filtercb = 1; } cookie->use_usercb = 0; + /* check_shadow() may add extra value to cookie->i_flags */ + cookie->i_flags = flags; if (service) { cookie->service = strdup(service); if (cookie->service == NULL) { delete_search_cookie(cookie); return (NS_LDAP_MEMORY); } + + /* + * If given, use the credential given by the caller, and + * skip the credential check required for shadow update. + */ + if (auth == NULL) { + rc = check_shadow(cookie, service); + if (rc != NS_LDAP_SUCCESS) { + *errorp = cookie->errorp; + cookie->errorp = NULL; + delete_search_cookie(cookie); + cookie = NULL; + return (rc); + } + } } cookie->i_filter = strdup(filter); cookie->i_attr = attribute; cookie->i_auth = auth; - cookie->i_flags = flags; state = INIT; for (;;) { diff --git a/usr/src/lib/libsldap/common/ns_sldap.h b/usr/src/lib/libsldap/common/ns_sldap.h index f8bb420019..a540e7d2f1 100644 --- a/usr/src/lib/libsldap/common/ns_sldap.h +++ b/usr/src/lib/libsldap/common/ns_sldap.h @@ -91,6 +91,13 @@ typedef enum ScopeType { #define NS_LDAP_UPDATE_SHADOW 0x4000 /* + * NS_LDAP_READ_SHADOW is for a privileged caller of __ns_ldap_list() + * and __ns_ldap_firstEntry() to read the shadow database on the + * LDAP server. + */ +#define NS_LDAP_READ_SHADOW 0x8000 + +/* * Authentication Information */ typedef enum CredLevel { |
