Mercurial > illumos > illumos-gate
changeset 12981:9fda0aeb1cb6
6959739 libsldap does not follow referrals correctly
6943753 Pam_ldap bind does not follow referrals during a login
author | Julian Pullen <Julian.Pullen@Sun.COM> |
---|---|
date | Fri, 30 Jul 2010 14:57:39 +0100 |
parents | 4de81c4d427e |
children | 5d7f2db1e620 |
files | usr/src/lib/libsldap/common/ns_common.c usr/src/lib/libsldap/common/ns_connect.c |
diffstat | 2 files changed, 47 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/lib/libsldap/common/ns_common.c Fri Jul 30 14:28:01 2010 +0100 +++ b/usr/src/lib/libsldap/common/ns_common.c Fri Jul 30 14:57:39 2010 +0100 @@ -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 @@ 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;
--- a/usr/src/lib/libsldap/common/ns_connect.c Fri Jul 30 14:28:01 2010 +0100 +++ b/usr/src/lib/libsldap/common/ns_connect.c Fri Jul 30 14:57:39 2010 +0100 @@ -74,7 +74,7 @@ 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 @@ } } 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 @@ } /* 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 @@ 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 @@ 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 @@ (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 @@ 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; }