summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Pullen <Julian.Pullen@Sun.COM>2010-07-30 14:57:39 +0100
committerJulian Pullen <Julian.Pullen@Sun.COM>2010-07-30 14:57:39 +0100
commit6ad9980e9a4cec174c968627f18eabe18c64db70 (patch)
tree645ac1f95ae47ed0cda4fd9add3a3d4aabf0a993
parent0a9ca722160f34063063ed10026813f91e2937d8 (diff)
downloadillumos-joyent-6ad9980e9a4cec174c968627f18eabe18c64db70.tar.gz
6959739 libsldap does not follow referrals correctly
6943753 Pam_ldap bind does not follow referrals during a login
-rw-r--r--usr/src/lib/libsldap/common/ns_common.c20
-rw-r--r--usr/src/lib/libsldap/common/ns_connect.c41
2 files changed, 47 insertions, 14 deletions
diff --git a/usr/src/lib/libsldap/common/ns_common.c b/usr/src/lib/libsldap/common/ns_common.c
index d800741f91..cd5de8d257 100644
--- a/usr/src/lib/libsldap/common/ns_common.c
+++ b/usr/src/lib/libsldap/common/ns_common.c
@@ -19,8 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
@@ -1495,8 +1494,23 @@ __s_api_addRefInfo(ns_referral_info_t **head, char *url,
return (NS_LDAP_MEMORY);
}
- if (scope)
+ /*
+ * If the scope is specified in the URL use it.
+ * Note if the scope is missing in the URL, ldap_url_parse_nodn()
+ * returns the scope BASE. We need to check that the scope of BASE
+ * is actually present in the URL.
+ * If the scope is missing in the URL then use the passed-in
+ * scope.
+ * If there is no passed-in scope, then use the scope SUBTREE.
+ */
+ if (ludp->lud_dn && ludp->lud_scope != LDAP_SCOPE_BASE)
+ ref->refScope = ludp->lud_scope;
+ else if (ludp->lud_dn && strstr(url, "?base"))
+ ref->refScope = LDAP_SCOPE_BASE;
+ else if (scope)
ref->refScope = *scope;
+ else
+ ref->refScope = LDAP_SCOPE_SUBTREE;
ref->next = NULL;
diff --git a/usr/src/lib/libsldap/common/ns_connect.c b/usr/src/lib/libsldap/common/ns_connect.c
index aa7a7a5e19..68387eaa52 100644
--- a/usr/src/lib/libsldap/common/ns_connect.c
+++ b/usr/src/lib/libsldap/common/ns_connect.c
@@ -74,7 +74,7 @@ extern int SetDoorInfoToUnixCred(char *buffer,
UnixCred_t **cred);
static int openConnection(LDAP **, const char *, const ns_cred_t *,
- int, ns_ldap_error_t **, int, int, ns_conn_user_t *);
+ int, ns_ldap_error_t **, int, int, ns_conn_user_t *, int);
static void
_DropConnection(ConnectionID cID, int flag, int fini);
@@ -779,7 +779,7 @@ makeConnection(Connection **conp, const char *serverAddr,
}
}
rc = openConnection(&ld, *bindHost, auth, timeoutSec, errorp,
- fail_if_new_pwd_reqd, passwd_mgmt, conn_user);
+ fail_if_new_pwd_reqd, passwd_mgmt, conn_user, flags);
if (rc == NS_LDAP_SUCCESS || rc ==
NS_LDAP_SUCCESS_WITH_INFO) {
exit_rc = rc;
@@ -851,7 +851,7 @@ makeConnection(Connection **conp, const char *serverAddr,
}
/* make the connection */
rc = openConnection(&ld, *bindHost, auth, timeoutSec, errorp,
- fail_if_new_pwd_reqd, passwd_mgmt, conn_user);
+ fail_if_new_pwd_reqd, passwd_mgmt, conn_user, flags);
/* if success, go to create connection structure */
if (rc == NS_LDAP_SUCCESS ||
rc == NS_LDAP_SUCCESS_WITH_INFO) {
@@ -1342,7 +1342,7 @@ static int
openConnection(LDAP **ldp, const char *serverAddr, const ns_cred_t *auth,
int timeoutSec, ns_ldap_error_t **errorp,
int fail_if_new_pwd_reqd, int passwd_mgmt,
- ns_conn_user_t *conn_user)
+ ns_conn_user_t *conn_user, int flags)
{
LDAP *ld = NULL;
int ldapVersion = LDAP_VERSION3;
@@ -1352,6 +1352,7 @@ openConnection(LDAP **ldp, const char *serverAddr, const ns_cred_t *auth,
uint16_t port = USE_DEFAULT_PORT;
char *s;
char errstr[MAXERROR];
+ int followRef;
ns_ldap_return_code ret_code = NS_LDAP_SUCCESS;
@@ -1406,14 +1407,27 @@ openConnection(LDAP **ldp, const char *serverAddr, const ns_cred_t *auth,
(void) ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &ldapVersion);
(void) ldap_set_option(ld, LDAP_OPT_DEREF, &derefOption);
/*
- * set LDAP_OPT_REFERRALS to OFF.
- * This library will handle the referral itself
- * based on API flags or configuration file
- * specification. If this option is not set
- * to OFF, libldap will never pass the
- * referral info up to this library
+ * This library will handle the referral itself based on API flags or
+ * configuration file specification. The LDAP bind operation is an
+ * exception where we rely on the LDAP library to follow the referal.
+ *
+ * The LDAP follow referral option must be set to OFF for the libldap5
+ * to pass the referral info up to this library. This option MUST be
+ * set to OFF after we have performed a sucessful bind. If we are not
+ * to follow referrals we MUST also set the LDAP follow referral option
+ * to OFF before we perform an LDAP bind.
*/
- (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+ ret_code = __s_api_toFollowReferrals(flags, &followRef, errorp);
+ if (ret_code != NS_LDAP_SUCCESS) {
+ (void) ldap_unbind(ld);
+ return (ret_code);
+ }
+
+ if (followRef)
+ (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_ON);
+ else
+ (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
+
(void) ldap_set_option(ld, LDAP_OPT_TIMELIMIT, &zero);
(void) ldap_set_option(ld, LDAP_OPT_SIZELIMIT, &zero);
/* setup TCP/IP connect timeout */
@@ -1431,6 +1445,11 @@ openConnection(LDAP **ldp, const char *serverAddr, const ns_cred_t *auth,
if (ret_code == NS_LDAP_SUCCESS ||
ret_code == NS_LDAP_SUCCESS_WITH_INFO) {
+ /*
+ * Turn off LDAP referral following so that this library can
+ * process referrals.
+ */
+ (void) ldap_set_option(ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF);
*ldp = ld;
}