summaryrefslogtreecommitdiff
path: root/usr/src/lib/libsldap/common/ns_connect.c
diff options
context:
space:
mode:
authorjanga <none@none>2006-03-27 14:23:17 -0800
committerjanga <none@none>2006-03-27 14:23:17 -0800
commit689c2bf45cbd08f8feb29c8c945a57f48267abd9 (patch)
treeb3ae06636913888b4884c3277dcfed3c2bef0382 /usr/src/lib/libsldap/common/ns_connect.c
parent215de5951bb4495ba8c9cab0ccc0757dd7df69f0 (diff)
downloadillumos-gate-689c2bf45cbd08f8feb29c8c945a57f48267abd9.tar.gz
6237466 Solaris 10 LDAP Client using multiple authentication methods do not fail to second method listed
Diffstat (limited to 'usr/src/lib/libsldap/common/ns_connect.c')
-rw-r--r--usr/src/lib/libsldap/common/ns_connect.c106
1 files changed, 89 insertions, 17 deletions
diff --git a/usr/src/lib/libsldap/common/ns_connect.c b/usr/src/lib/libsldap/common/ns_connect.c
index 4108b687a3..bbe2dead54 100644
--- a/usr/src/lib/libsldap/common/ns_connect.c
+++ b/usr/src/lib/libsldap/common/ns_connect.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -66,6 +65,9 @@ static int nscdChecked = 0;
static pid_t checkedPid = -1;
static int isNscd = 0;
+/* Number of hostnames to allocate memory for */
+#define NUMTOMALLOC 32
+
/*
* Check /proc/PID/psinfo to see if this process is nscd
@@ -599,11 +601,12 @@ freeConnection(Connection *con)
* Success: returns the pointer to the Connection structure
* Failure: returns NULL, error code and message should be in errorp
*/
+
static int
makeConnection(Connection **conp, const char *serverAddr,
const ns_cred_t *auth, ConnectionID *cID, int timeoutSec,
ns_ldap_error_t **errorp, int fail_if_new_pwd_reqd,
- int nopasswd_acct_mgmt)
+ int nopasswd_acct_mgmt, char ***badsrvrs)
{
Connection *con = NULL;
ConnectionID id;
@@ -613,6 +616,8 @@ makeConnection(Connection **conp, const char *serverAddr,
char *hReq, *host = NULL;
LDAP *ld = NULL;
int passwd_mgmt = 0;
+ int totalbad = 0; /* Number of servers contacted unsuccessfully */
+ short memerr = 0; /* Variable for tracking memory allocation errors */
if (conp == NULL || errorp == NULL || auth == NULL)
return (NS_LDAP_INVALID_PARAM);
@@ -729,15 +734,49 @@ makeConnection(Connection **conp, const char *serverAddr,
if (rc == NS_LDAP_INTERNAL && *errorp != NULL) {
if ((*errorp)->status == LDAP_CONNECT_ERROR ||
(*errorp)->status == LDAP_SERVER_DOWN) {
- if (__s_api_removeServer(host) < 0) {
- /*
- * Couldn't remove server from
- * server list. Log a warning.
- */
- syslog(LOG_WARNING, "libsldap: could "
- "not remove %s from servers list",
- host);
+ /* Reset memory allocation error */
+ memerr = 0;
+ /*
+ * We contacted a server that we could
+ * not either authenticate to or contact.
+ * If it is due to authentication, then
+ * we need to try the server again. So,
+ * do not remove the server yet, but
+ * add it to the bad server list.
+ * The caller routine will remove
+ * the servers if:
+ * a). A good server is found or
+ * b). All the possible methods
+ * are tried without finding
+ * a good server
+ */
+ if (*badsrvrs == NULL) {
+ if (!(*badsrvrs = (char **)malloc
+ (sizeof (char *) * NUMTOMALLOC))) {
+ memerr = 1;
+ }
+ /* Allocate memory in chunks of NUMTOMALLOC */
+ } else if ((totalbad % NUMTOMALLOC) ==
+ NUMTOMALLOC - 1) {
+ char **tmpptr;
+ if (!(tmpptr = (char **)realloc(*badsrvrs,
+ (sizeof (char *) * NUMTOMALLOC *
+ ((totalbad/NUMTOMALLOC) + 2))))) {
+ memerr = 1;
+ } else {
+ *badsrvrs = tmpptr;
+ }
}
+ /*
+ * Store host only if there were no unsuccessful
+ * memory allocations above
+ */
+ if (!memerr &&
+ !((*badsrvrs)[totalbad++] = strdup(host))) {
+ memerr = 1;
+ totalbad--;
+ }
+ (*badsrvrs)[totalbad] = NULL;
}
}
@@ -750,6 +789,9 @@ makeConnection(Connection **conp, const char *serverAddr,
sinfo.saslMechanisms = NULL;
__s_api_free2dArray(sinfo.controls);
sinfo.controls = NULL;
+ /* Return if we had memory allocation errors */
+ if (memerr)
+ return (NS_LDAP_MEMORY);
if (*errorp) {
/*
* If openConnection() failed due to
@@ -1792,6 +1834,7 @@ __s_api_getConnection(
ns_cred_t anon;
int version = NS_LDAP_V2;
void **paramVal = NULL;
+ char **badSrvrs = NULL; /* List of problem hostnames */
if ((session == NULL) || (sessionId == NULL)) {
return (NS_LDAP_INVALID_PARAM);
@@ -1885,7 +1928,8 @@ __s_api_getConnection(
/* using specified auth method */
rc = makeConnection(&con, server, cred,
sessionId, timeoutSec, errorp,
- fail_if_new_pwd_reqd, nopasswd_acct_mgmt);
+ fail_if_new_pwd_reqd, nopasswd_acct_mgmt,
+ &badSrvrs);
if (rc == NS_LDAP_SUCCESS ||
rc == NS_LDAP_SUCCESS_WITH_INFO) {
*session = con;
@@ -1895,11 +1939,19 @@ __s_api_getConnection(
/* for every cred level */
for (cNext = cLevel; *cNext != NULL; cNext++) {
if (**cNext == NS_LDAP_CRED_ANON) {
- /* make connection anonymously */
+ /*
+ * make connection anonymously
+ * Free the down server list before
+ * looping through
+ */
+ if (badSrvrs && *badSrvrs) {
+ __s_api_free2dArray(badSrvrs);
+ badSrvrs = NULL;
+ }
rc = makeConnection(&con, server, &anon,
sessionId, timeoutSec, errorp,
fail_if_new_pwd_reqd,
- nopasswd_acct_mgmt);
+ nopasswd_acct_mgmt, &badSrvrs);
if (rc == NS_LDAP_SUCCESS ||
rc ==
NS_LDAP_SUCCESS_WITH_INFO) {
@@ -1918,10 +1970,18 @@ __s_api_getConnection(
if (rc != NS_LDAP_SUCCESS) {
continue;
}
+ /*
+ * Free the down server list before
+ * looping through
+ */
+ if (badSrvrs && *badSrvrs) {
+ __s_api_free2dArray(badSrvrs);
+ badSrvrs = NULL;
+ }
rc = makeConnection(&con, server, authp,
sessionId, timeoutSec, errorp,
fail_if_new_pwd_reqd,
- nopasswd_acct_mgmt);
+ nopasswd_acct_mgmt, &badSrvrs);
(void) __ns_ldap_freeCred(&authp);
if (rc == NS_LDAP_SUCCESS ||
rc ==
@@ -1944,6 +2004,18 @@ __s_api_getConnection(
done:
(void) __ns_ldap_freeParam((void ***)&aMethod);
(void) __ns_ldap_freeParam((void ***)&cLevel);
+
+ if (badSrvrs && *badSrvrs) {
+ /*
+ * At this point, either we have a successful
+ * connection or exhausted all the possible auths.
+ * and creds. Mark the problem servers as down
+ * so that the problem servers are not contacted
+ * again until the refresh_ttl expires.
+ */
+ (void) __s_api_removeBadServers(badSrvrs);
+ __s_api_free2dArray(badSrvrs);
+ }
return (rc);
}