diff options
author | Julian Pullen <Julian.Pullen@Sun.COM> | 2010-07-30 14:57:39 +0100 |
---|---|---|
committer | Julian Pullen <Julian.Pullen@Sun.COM> | 2010-07-30 14:57:39 +0100 |
commit | 6ad9980e9a4cec174c968627f18eabe18c64db70 (patch) | |
tree | 645ac1f95ae47ed0cda4fd9add3a3d4aabf0a993 | |
parent | 0a9ca722160f34063063ed10026813f91e2937d8 (diff) | |
download | illumos-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.c | 20 | ||||
-rw-r--r-- | usr/src/lib/libsldap/common/ns_connect.c | 41 |
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; } |