summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsldap/common
diff options
context:
space:
mode:
authorJulian Pullen <Julian.Pullen@Sun.COM>2009-05-08 17:38:01 +0100
committerJulian Pullen <Julian.Pullen@Sun.COM>2009-05-08 17:38:01 +0100
commitb57459abfba36eb3068cfe44c6921168b4c4f774 (patch)
tree5479f0844784d6b0929894abd0b14e3cee9135bd /usr/src/lib/libsldap/common
parentc9d66ba7a02565d1320b4a0780e249cfe8c02612 (diff)
downloadillumos-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.h2
-rw-r--r--usr/src/lib/libsldap/common/ns_common.c39
-rw-r--r--usr/src/lib/libsldap/common/ns_config.c75
-rw-r--r--usr/src/lib/libsldap/common/ns_confmgr.c20
-rw-r--r--usr/src/lib/libsldap/common/ns_connect.c167
-rw-r--r--usr/src/lib/libsldap/common/ns_internal.h2
-rw-r--r--usr/src/lib/libsldap/common/ns_reads.c121
-rw-r--r--usr/src/lib/libsldap/common/ns_sldap.h7
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,
- &paramVal, &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(&paramVal);
+ 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,
+ &paramVal, &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(&paramVal);
+ }
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,
- &paramVal, &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,
+ &paramVal, &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(&paramVal);
}
- modparamVal = dvalue((char *)*paramVal);
- (void) __ns_ldap_freeParam(&paramVal);
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,
&paramVal, &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(&paramVal);
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 {