|
Ian Kent |
36ee82 |
diff --git a/include/defaults.h b/include/defaults.h
|
|
Ian Kent |
36ee82 |
index 0984b1c..46393d9 100644
|
|
Ian Kent |
36ee82 |
--- a/include/defaults.h
|
|
Ian Kent |
36ee82 |
+++ b/include/defaults.h
|
|
Ian Kent |
36ee82 |
@@ -26,7 +26,8 @@
|
|
Ian Kent |
36ee82 |
#define DEFAULT_BROWSE_MODE 1
|
|
Ian Kent |
36ee82 |
#define DEFAULT_LOGGING 0
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-#define DEFAULT_LDAP_SERVER NULL
|
|
Ian Kent |
36ee82 |
+#define DEFAULT_LDAP_TIMEOUT -1
|
|
Ian Kent |
36ee82 |
+#define DEFAULT_LDAP_NETWORK_TIMEOUT 8
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
#define DEFAULT_MAP_OBJ_CLASS "nisMap"
|
|
Ian Kent |
36ee82 |
#define DEFAULT_ENTRY_OBJ_CLASS "nisObject"
|
|
Ian Kent |
36ee82 |
@@ -46,6 +47,10 @@ unsigned int defaults_get_timeout(void);
|
|
Ian Kent |
36ee82 |
unsigned int defaults_get_browse_mode(void);
|
|
Ian Kent |
36ee82 |
unsigned int defaults_get_logging(void);
|
|
Ian Kent |
36ee82 |
const char *defaults_get_ldap_server(void);
|
|
Ian Kent |
36ee82 |
+unsigned int defaults_get_ldap_timeout(void);
|
|
Ian Kent |
36ee82 |
+unsigned int defaults_get_ldap_network_timeout(void);
|
|
Ian Kent |
36ee82 |
+struct list_head *defaults_get_uris(void);
|
|
Ian Kent |
36ee82 |
+void defaults_free_uris(struct list_head *);
|
|
Ian Kent |
36ee82 |
struct ldap_schema *defaults_get_default_schema(void);
|
|
Ian Kent |
36ee82 |
struct ldap_schema *defaults_get_schema(void);
|
|
Ian Kent |
36ee82 |
struct ldap_searchdn *defaults_get_searchdns(void);
|
|
Ian Kent |
36ee82 |
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
|
Ian Kent |
36ee82 |
index 1a924be..ca8d658 100644
|
|
Ian Kent |
36ee82 |
--- a/include/lookup_ldap.h
|
|
Ian Kent |
36ee82 |
+++ b/include/lookup_ldap.h
|
|
Ian Kent |
36ee82 |
@@ -18,6 +18,11 @@ struct ldap_schema {
|
|
Ian Kent |
36ee82 |
char *value_attr;
|
|
Ian Kent |
36ee82 |
};
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
+struct ldap_uri {
|
|
Ian Kent |
36ee82 |
+ char *uri;
|
|
Ian Kent |
36ee82 |
+ struct list_head list;
|
|
Ian Kent |
36ee82 |
+};
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
struct ldap_searchdn {
|
|
Ian Kent |
36ee82 |
char *basedn;
|
|
Ian Kent |
36ee82 |
struct ldap_searchdn *next;
|
|
Ian Kent |
36ee82 |
@@ -30,6 +35,8 @@ struct lookup_context {
|
|
Ian Kent |
36ee82 |
int port;
|
|
Ian Kent |
36ee82 |
char *base;
|
|
Ian Kent |
36ee82 |
char *qdn;
|
|
Ian Kent |
36ee82 |
+ unsigned int timeout;
|
|
Ian Kent |
36ee82 |
+ unsigned int network_timeout;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* LDAP version 2 or 3 */
|
|
Ian Kent |
36ee82 |
int version;
|
|
Ian Kent |
36ee82 |
@@ -37,7 +44,17 @@ struct lookup_context {
|
|
Ian Kent |
36ee82 |
/* LDAP lookup configuration */
|
|
Ian Kent |
36ee82 |
struct ldap_schema *schema;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- /* List of base dns for searching */
|
|
Ian Kent |
36ee82 |
+ /*
|
|
Ian Kent |
36ee82 |
+ * List of servers and base dns for searching.
|
|
Ian Kent |
36ee82 |
+ * uri is the list of servers to attempt connection to and is
|
|
Ian Kent |
36ee82 |
+ * used only if server, above, is NULL. The head of the list
|
|
Ian Kent |
36ee82 |
+ * is the server which we are currently connected to.
|
|
Ian Kent |
36ee82 |
+ * cur_host tracks chnages to connected server, triggering
|
|
Ian Kent |
36ee82 |
+ * a scan of basedns when it changes.
|
|
Ian Kent |
36ee82 |
+ * sdns is the list of basdns to check, done in the order
|
|
Ian Kent |
36ee82 |
+ * given in configuration.
|
|
Ian Kent |
36ee82 |
+ */
|
|
Ian Kent |
36ee82 |
+ struct list_head *uri;
|
|
Ian Kent |
36ee82 |
char *cur_host;
|
|
Ian Kent |
36ee82 |
struct ldap_searchdn *sdns;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -77,7 +94,7 @@ struct lookup_context {
|
|
Ian Kent |
36ee82 |
#define LDAP_AUTH_AUTODETECT 0x0004
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* lookup_ldap.c */
|
|
Ian Kent |
36ee82 |
-LDAP *init_ldap_connection(struct lookup_context *ctxt);
|
|
Ian Kent |
36ee82 |
+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt);
|
|
Ian Kent |
36ee82 |
int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt);
|
|
Ian Kent |
36ee82 |
int authtype_requires_creds(const char *authtype);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
diff --git a/lib/defaults.c b/lib/defaults.c
|
|
Ian Kent |
36ee82 |
index 7da4631..bf1ceed 100644
|
|
Ian Kent |
36ee82 |
--- a/lib/defaults.c
|
|
Ian Kent |
36ee82 |
+++ b/lib/defaults.c
|
|
Ian Kent |
36ee82 |
@@ -17,6 +17,7 @@
|
|
Ian Kent |
36ee82 |
#include <ctype.h>
|
|
Ian Kent |
36ee82 |
#include <string.h>
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
+#include "list.h"
|
|
Ian Kent |
36ee82 |
#include "defaults.h"
|
|
Ian Kent |
36ee82 |
#include "lookup_ldap.h"
|
|
Ian Kent |
36ee82 |
#include "log.h"
|
|
Ian Kent |
36ee82 |
@@ -30,7 +31,9 @@
|
|
Ian Kent |
36ee82 |
#define ENV_NAME_BROWSE_MODE "BROWSE_MODE"
|
|
Ian Kent |
36ee82 |
#define ENV_NAME_LOGGING "LOGGING"
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-#define ENV_LDAP_SERVER "LDAP_SERVER"
|
|
Ian Kent |
36ee82 |
+#define LDAP_URI "LDAP_URI"
|
|
Ian Kent |
36ee82 |
+#define ENV_LDAP_TIMEOUT "LDAP_TIMEOUT"
|
|
Ian Kent |
36ee82 |
+#define ENV_LDAP_NETWORK_TIMEOUT "LDAP_NETWORK_TIMEOUT"
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
#define SEARCH_BASE "SEARCH_BASE"
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -44,7 +47,6 @@
|
|
Ian Kent |
36ee82 |
#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE"
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME;
|
|
Ian Kent |
36ee82 |
-static const char *default_ldap_server = DEFAULT_LDAP_SERVER;
|
|
Ian Kent |
36ee82 |
static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
static char *get_env_string(const char *name)
|
|
Ian Kent |
36ee82 |
@@ -178,6 +180,99 @@ static int parse_line(char *line, char **res, char **value)
|
|
Ian Kent |
36ee82 |
return 1;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
+void defaults_free_uris(struct list_head *list)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ struct list_head *next;
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *uri;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (list_empty(list)) {
|
|
Ian Kent |
36ee82 |
+ free(list);
|
|
Ian Kent |
36ee82 |
+ return;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ next = list->next;
|
|
Ian Kent |
36ee82 |
+ while (next != list) {
|
|
Ian Kent |
36ee82 |
+ uri = list_entry(next, struct ldap_uri, list);
|
|
Ian Kent |
36ee82 |
+ next = next->next;
|
|
Ian Kent |
36ee82 |
+ list_del(&uri->list);
|
|
Ian Kent |
36ee82 |
+ free(uri->uri);
|
|
Ian Kent |
36ee82 |
+ free(uri);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ free(list);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+static unsigned int add_uris(char *value, struct list_head *list)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ char *str, *tok, *ptr = NULL;
|
|
Ian Kent |
36ee82 |
+ size_t len = strlen(value);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ str = alloca(len);
|
|
Ian Kent |
36ee82 |
+ if (!str)
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
+ strcpy(str, value);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ tok = strtok_r(str, " ", &ptr);
|
|
Ian Kent |
36ee82 |
+ while (tok) {
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *new;
|
|
Ian Kent |
36ee82 |
+ char *uri;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ new = malloc(sizeof(struct ldap_uri));
|
|
Ian Kent |
36ee82 |
+ if (!new)
|
|
Ian Kent |
36ee82 |
+ continue;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ uri = strdup(tok);
|
|
Ian Kent |
36ee82 |
+ if (!uri)
|
|
Ian Kent |
36ee82 |
+ free(new);
|
|
Ian Kent |
36ee82 |
+ else {
|
|
Ian Kent |
36ee82 |
+ new->uri = uri;
|
|
Ian Kent |
36ee82 |
+ list_add_tail(&new->list, list);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ tok = strtok_r(NULL, " ", &ptr);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return 1;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+struct list_head *defaults_get_uris(void)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ FILE *f;
|
|
Ian Kent |
36ee82 |
+ char buf[MAX_LINE_LEN];
|
|
Ian Kent |
36ee82 |
+ char *res;
|
|
Ian Kent |
36ee82 |
+ struct list_head *list;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ f = fopen(DEFAULTS_CONFIG_FILE, "r");
|
|
Ian Kent |
36ee82 |
+ if (!f)
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ list = malloc(sizeof(struct list_head));
|
|
Ian Kent |
36ee82 |
+ if (!list) {
|
|
Ian Kent |
36ee82 |
+ fclose(f);
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ INIT_LIST_HEAD(list);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ while ((res = fgets(buf, MAX_LINE_LEN, f))) {
|
|
Ian Kent |
36ee82 |
+ char *key, *value;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (!parse_line(res, &key, &value))
|
|
Ian Kent |
36ee82 |
+ continue;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (!strcasecmp(res, LDAP_URI))
|
|
Ian Kent |
36ee82 |
+ add_uris(value, list);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (list_empty(list)) {
|
|
Ian Kent |
36ee82 |
+ free(list);
|
|
Ian Kent |
36ee82 |
+ list = NULL;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ fclose(f);
|
|
Ian Kent |
36ee82 |
+ return list;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
/*
|
|
Ian Kent |
36ee82 |
* Read config env variables and check they have been set.
|
|
Ian Kent |
36ee82 |
*
|
|
Ian Kent |
36ee82 |
@@ -205,7 +300,8 @@ unsigned int defaults_read_config(void)
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_TIMEOUT, value) ||
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_BROWSE_MODE, value) ||
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_LOGGING, value) ||
|
|
Ian Kent |
36ee82 |
- check_set_config_value(key, ENV_LDAP_SERVER, value) ||
|
|
Ian Kent |
36ee82 |
+ check_set_config_value(key, ENV_LDAP_TIMEOUT, value) ||
|
|
Ian Kent |
36ee82 |
+ check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value) ||
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value) ||
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value) ||
|
|
Ian Kent |
36ee82 |
check_set_config_value(key, ENV_NAME_MAP_ATTR, value) ||
|
|
Ian Kent |
36ee82 |
@@ -284,15 +380,26 @@ unsigned int defaults_get_logging(void)
|
|
Ian Kent |
36ee82 |
return logging;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-const char *defaults_get_ldap_server(void)
|
|
Ian Kent |
36ee82 |
+unsigned int defaults_get_ldap_timeout(void)
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
- char *server;
|
|
Ian Kent |
36ee82 |
+ int res;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- server = get_env_string(ENV_LDAP_SERVER);
|
|
Ian Kent |
36ee82 |
- if (!server)
|
|
Ian Kent |
36ee82 |
- return default_ldap_server;
|
|
Ian Kent |
36ee82 |
+ res = get_env_number(ENV_LDAP_TIMEOUT);
|
|
Ian Kent |
36ee82 |
+ if (res < 0)
|
|
Ian Kent |
36ee82 |
+ res = DEFAULT_LDAP_TIMEOUT;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- return (const char *) server;
|
|
Ian Kent |
36ee82 |
+ return res;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+unsigned int defaults_get_ldap_network_timeout(void)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ int res;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT);
|
|
Ian Kent |
36ee82 |
+ if (res < 0)
|
|
Ian Kent |
36ee82 |
+ res = DEFAULT_LDAP_NETWORK_TIMEOUT;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return res;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
struct ldap_schema *defaults_get_default_schema(void)
|
|
Ian Kent |
36ee82 |
diff --git a/man/auto.master.5.in b/man/auto.master.5.in
|
|
Ian Kent |
36ee82 |
index 0cb2f07..68447e0 100644
|
|
Ian Kent |
36ee82 |
--- a/man/auto.master.5.in
|
|
Ian Kent |
36ee82 |
+++ b/man/auto.master.5.in
|
|
Ian Kent |
36ee82 |
@@ -230,10 +230,27 @@ values must be set, any partial schema specification will be ignored.
|
|
Ian Kent |
36ee82 |
.P
|
|
Ian Kent |
36ee82 |
The configuration settings available are:
|
|
Ian Kent |
36ee82 |
.TP
|
|
Ian Kent |
36ee82 |
+.B LDAP_TIMEOUT
|
|
Ian Kent |
36ee82 |
+Set the network response timeout (default 8).
|
|
Ian Kent |
36ee82 |
+Set timeout value for the synchronous API calls. The default is the LDAP
|
|
Ian Kent |
36ee82 |
+library default of an infinite timeout.
|
|
Ian Kent |
36ee82 |
+.TP
|
|
Ian Kent |
36ee82 |
+.B LDAP_NETWORK_TIMEOUT
|
|
Ian Kent |
36ee82 |
+Set the network response timeout (default 8).
|
|
Ian Kent |
36ee82 |
+.TP
|
|
Ian Kent |
36ee82 |
+.B LDAP_URI
|
|
Ian Kent |
36ee82 |
+A space seperated list of server uris of the form <proto>://<server>[/]
|
|
Ian Kent |
36ee82 |
+where <proto> can be ldap or ldaps. The option can be given multiple times.
|
|
Ian Kent |
36ee82 |
+Map entries that include a server name override this option and it is then
|
|
Ian Kent |
36ee82 |
+not used. Default is an empty list in which case either the server given
|
|
Ian Kent |
36ee82 |
+in a map entry or the LDAP configured default is used. This uri list is read at
|
|
Ian Kent |
36ee82 |
+startup and whenever the daemon receives a HUP signal.
|
|
Ian Kent |
36ee82 |
+.TP
|
|
Ian Kent |
36ee82 |
.B SEARCH_BASE
|
|
Ian Kent |
36ee82 |
The base dn to use when searching for amap base dn. This entry may be
|
|
Ian Kent |
36ee82 |
given multiple times and each will be checked for a map base dn in
|
|
Ian Kent |
36ee82 |
-the order they occur in the configuration.
|
|
Ian Kent |
36ee82 |
+the order they occur in the configuration. The search base list is read
|
|
Ian Kent |
36ee82 |
+at startup and whenever the daemon recieves a HUP signal.
|
|
Ian Kent |
36ee82 |
.TP
|
|
Ian Kent |
36ee82 |
.B MAP_OBJECT_CLASS
|
|
Ian Kent |
36ee82 |
The map object class. In the \fBnisMap\fP schema this corresponds to the class
|
|
Ian Kent |
36ee82 |
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
|
Ian Kent |
36ee82 |
index 2baf8b8..4068561 100644
|
|
Ian Kent |
36ee82 |
--- a/modules/lookup_ldap.c
|
|
Ian Kent |
36ee82 |
+++ b/modules/lookup_ldap.c
|
|
Ian Kent |
36ee82 |
@@ -49,6 +49,8 @@ static struct ldap_schema common_schema[] = {
|
|
Ian Kent |
36ee82 |
};
|
|
Ian Kent |
36ee82 |
static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
+static LDAP *auth_init(const char *, struct lookup_context *);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
int rv;
|
|
Ian Kent |
36ee82 |
@@ -59,10 +61,18 @@ int bind_ldap_anonymous(LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
rv = ldap_simple_bind_s(ldap, NULL, NULL);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_SUCCESS) {
|
|
Ian Kent |
36ee82 |
- crit(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
- MODPREFIX "Unable to bind to the LDAP server: "
|
|
Ian Kent |
36ee82 |
- "%s, error %s", ctxt->server ? "" : "(default)",
|
|
Ian Kent |
36ee82 |
- ldap_err2string(rv));
|
|
Ian Kent |
36ee82 |
+ if (!ctxt->uri) {
|
|
Ian Kent |
36ee82 |
+ crit(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
+ MODPREFIX "Unable to bind to the LDAP server: "
|
|
Ian Kent |
36ee82 |
+ "%s, error %s", ctxt->server ? "" : "(default)",
|
|
Ian Kent |
36ee82 |
+ ldap_err2string(rv));
|
|
Ian Kent |
36ee82 |
+ } else {
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *uri;
|
|
Ian Kent |
36ee82 |
+ uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
Ian Kent |
36ee82 |
+ warn(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
+ MODPREFIX "Unable to bind to the LDAP server: "
|
|
Ian Kent |
36ee82 |
+ "%s, error %s", uri->uri, ldap_err2string(rv));
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
return -1;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -98,20 +108,21 @@ int unbind_ldap_connection(LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
return rv;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+LDAP *init_ldap_connection(const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
LDAP *ldap = NULL;
|
|
Ian Kent |
36ee82 |
- int timeout = 8;
|
|
Ian Kent |
36ee82 |
+ struct timeval timeout = { ctxt->timeout, 0 };
|
|
Ian Kent |
36ee82 |
+ struct timeval net_timeout = { ctxt->network_timeout, 0 };
|
|
Ian Kent |
36ee82 |
int rv;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
ctxt->version = 3;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* Initialize the LDAP context. */
|
|
Ian Kent |
36ee82 |
- rv = ldap_initialize(&ldap, ctxt->server);
|
|
Ian Kent |
36ee82 |
+ rv = ldap_initialize(&ldap, uri);
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_OPT_SUCCESS) {
|
|
Ian Kent |
36ee82 |
crit(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
MODPREFIX "couldn't initialize LDAP connection to %s",
|
|
Ian Kent |
36ee82 |
- ctxt->server ? ctxt->server : "default server");
|
|
Ian Kent |
36ee82 |
+ uri ? uri : "default server");
|
|
Ian Kent |
36ee82 |
return NULL;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -120,7 +131,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_OPT_SUCCESS) {
|
|
Ian Kent |
36ee82 |
/* fall back to LDAPv2 */
|
|
Ian Kent |
36ee82 |
ldap_unbind_ext(ldap, NULL, NULL);
|
|
Ian Kent |
36ee82 |
- rv = ldap_initialize(&ldap, ctxt->server);
|
|
Ian Kent |
36ee82 |
+ rv = ldap_initialize(&ldap, uri);
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_OPT_SUCCESS) {
|
|
Ian Kent |
36ee82 |
crit(LOGOPT_ANY, MODPREFIX "couldn't initialize LDAP");
|
|
Ian Kent |
36ee82 |
return NULL;
|
|
Ian Kent |
36ee82 |
@@ -128,12 +139,22 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
ctxt->version = 2;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- /* Sane network connection timeout */
|
|
Ian Kent |
36ee82 |
- rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &timeout);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (ctxt->timeout != -1) {
|
|
Ian Kent |
36ee82 |
+ /* Set synchronous call timeout */
|
|
Ian Kent |
36ee82 |
+ rv = ldap_set_option(ldap, LDAP_OPT_TIMEOUT, &timeout);
|
|
Ian Kent |
36ee82 |
+ if (rv != LDAP_OPT_SUCCESS)
|
|
Ian Kent |
36ee82 |
+ info(LOGOPT_ANY, MODPREFIX
|
|
Ian Kent |
36ee82 |
+ "failed to set synchronous call timeout to %d",
|
|
Ian Kent |
36ee82 |
+ timeout.tv_sec);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ /* Sane network timeout */
|
|
Ian Kent |
36ee82 |
+ rv = ldap_set_option(ldap, LDAP_OPT_NETWORK_TIMEOUT, &net_timeout);
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_OPT_SUCCESS)
|
|
Ian Kent |
36ee82 |
info(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
MODPREFIX "failed to set connection timeout to %d",
|
|
Ian Kent |
36ee82 |
- timeout);
|
|
Ian Kent |
36ee82 |
+ net_timeout.tv_sec);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
#ifdef WITH_SASL
|
|
Ian Kent |
36ee82 |
if (ctxt->use_tls) {
|
|
Ian Kent |
36ee82 |
@@ -159,7 +180,7 @@ LDAP *init_ldap_connection(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
return NULL;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
ctxt->use_tls = LDAP_TLS_DONT_USE;
|
|
Ian Kent |
36ee82 |
- ldap = init_ldap_connection(ctxt);
|
|
Ian Kent |
36ee82 |
+ ldap = init_ldap_connection(uri, ctxt);
|
|
Ian Kent |
36ee82 |
if (ldap)
|
|
Ian Kent |
36ee82 |
ctxt->use_tls = LDAP_TLS_INIT;
|
|
Ian Kent |
36ee82 |
return ldap;
|
|
Ian Kent |
36ee82 |
@@ -271,7 +292,7 @@ static int get_query_dn(LDAP *ldap, struct lookup_context *ctxt, const char *cla
|
|
Ian Kent |
36ee82 |
e = ldap_first_entry(ldap, result);
|
|
Ian Kent |
36ee82 |
if (e) {
|
|
Ian Kent |
36ee82 |
dn = ldap_get_dn(ldap, e);
|
|
Ian Kent |
36ee82 |
- debug(LOGOPT_NONE, MODPREFIX "query dn %s", dn);
|
|
Ian Kent |
36ee82 |
+ debug(LOGOPT_NONE, MODPREFIX "found query dn %s", dn);
|
|
Ian Kent |
36ee82 |
} else {
|
|
Ian Kent |
36ee82 |
debug(LOGOPT_NONE,
|
|
Ian Kent |
36ee82 |
MODPREFIX "query succeeded, no matches for %s",
|
|
Ian Kent |
36ee82 |
@@ -378,16 +399,11 @@ static int find_query_dn(LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
return 0;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-static LDAP *do_connect(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+static int do_bind(LDAP *ldap, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
- LDAP *ldap;
|
|
Ian Kent |
36ee82 |
char *host = NULL, *nhost;
|
|
Ian Kent |
36ee82 |
int rv, need_base = 1;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- ldap = init_ldap_connection(ctxt);
|
|
Ian Kent |
36ee82 |
- if (!ldap)
|
|
Ian Kent |
36ee82 |
- return NULL;
|
|
Ian Kent |
36ee82 |
-
|
|
Ian Kent |
36ee82 |
#ifdef WITH_SASL
|
|
Ian Kent |
36ee82 |
debug(LOGOPT_NONE, "auth_required: %d, sasl_mech %s",
|
|
Ian Kent |
36ee82 |
ctxt->auth_required, ctxt->sasl_mech);
|
|
Ian Kent |
36ee82 |
@@ -407,23 +423,19 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
debug(LOGOPT_NONE, MODPREFIX "ldap anonymous bind returned %d", rv);
|
|
Ian Kent |
36ee82 |
#endif
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- if (rv != 0) {
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
- return NULL;
|
|
Ian Kent |
36ee82 |
- }
|
|
Ian Kent |
36ee82 |
+ if (rv != 0)
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host);
|
|
Ian Kent |
36ee82 |
if (rv != LDAP_SUCCESS || !host) {
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
debug(LOGOPT_ANY, "failed to get hostname for connection");
|
|
Ian Kent |
36ee82 |
- return NULL;
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
nhost = strdup(host);
|
|
Ian Kent |
36ee82 |
if (!nhost) {
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
debug(LOGOPT_ANY, "failed to alloc context for hostname");
|
|
Ian Kent |
36ee82 |
- return NULL;
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
ldap_memfree(host);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -443,7 +455,7 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
if (!need_base)
|
|
Ian Kent |
36ee82 |
- return ldap;
|
|
Ian Kent |
36ee82 |
+ return 1;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/*
|
|
Ian Kent |
36ee82 |
* If the schema isn't defined in the configuration then check for
|
|
Ian Kent |
36ee82 |
@@ -452,20 +464,134 @@ static LDAP *do_connect(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
*/
|
|
Ian Kent |
36ee82 |
if (!ctxt->schema) {
|
|
Ian Kent |
36ee82 |
if (!find_query_dn(ldap, ctxt)) {
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
error(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
MODPREFIX "failed to find valid query dn");
|
|
Ian Kent |
36ee82 |
- return NULL;
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
} else {
|
|
Ian Kent |
36ee82 |
const char *class = ctxt->schema->map_class;
|
|
Ian Kent |
36ee82 |
const char *key = ctxt->schema->map_attr;
|
|
Ian Kent |
36ee82 |
if (!get_query_dn(ldap, ctxt, class, key)) {
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
error(LOGOPT_ANY, MODPREFIX "failed to get query dn");
|
|
Ian Kent |
36ee82 |
+ return 0;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return 1;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+static LDAP *do_connect(const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ LDAP *ldap;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ ldap = init_ldap_connection(uri, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap)
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (!do_bind(ldap, ctxt)) {
|
|
Ian Kent |
36ee82 |
+ unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+static LDAP *connect_to_server(const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ LDAP *ldap;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+#ifdef WITH_SASL
|
|
Ian Kent |
36ee82 |
+ /*
|
|
Ian Kent |
36ee82 |
+ * Determine which authentication mechanism to use if we require
|
|
Ian Kent |
36ee82 |
+ * authentication.
|
|
Ian Kent |
36ee82 |
+ */
|
|
Ian Kent |
36ee82 |
+ if (ctxt->auth_required & LDAP_AUTH_REQUIRED) {
|
|
Ian Kent |
36ee82 |
+ ldap = auth_init(uri, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap && ctxt->auth_required & LDAP_AUTH_AUTODETECT)
|
|
Ian Kent |
36ee82 |
+ warn(LOGOPT_NONE,
|
|
Ian Kent |
36ee82 |
+ "no authentication mechanisms auto detected.");
|
|
Ian Kent |
36ee82 |
+ if (!ldap) {
|
|
Ian Kent |
36ee82 |
+ error(LOGOPT_ANY, MODPREFIX
|
|
Ian Kent |
36ee82 |
+ "cannot initialize authentication setup");
|
|
Ian Kent |
36ee82 |
return NULL;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (!do_bind(ldap, ctxt)) {
|
|
Ian Kent |
36ee82 |
+ unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
+ error(LOGOPT_ANY, MODPREFIX "cannot bind to server");
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+#endif
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ ldap = do_connect(uri, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap) {
|
|
Ian Kent |
36ee82 |
+ error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+static LDAP *find_server(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ LDAP *ldap = NULL;
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *this;
|
|
Ian Kent |
36ee82 |
+ struct list_head *p;
|
|
Ian Kent |
36ee82 |
+ LIST_HEAD(tmp);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ /* Try each uri in list, add connect fails to tmp list */
|
|
Ian Kent |
36ee82 |
+ p = ctxt->uri->next;
|
|
Ian Kent |
36ee82 |
+ while(p != ctxt->uri) {
|
|
Ian Kent |
36ee82 |
+ this = list_entry(p, struct ldap_uri, list);
|
|
Ian Kent |
36ee82 |
+ p = p->next;
|
|
Ian Kent |
36ee82 |
+ debug(LOGOPT_ANY, "check uri %s", this->uri);
|
|
Ian Kent |
36ee82 |
+ ldap = connect_to_server(this->uri, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (ldap) {
|
|
Ian Kent |
36ee82 |
+ debug(LOGOPT_ANY, "connexted to uri %s", this->uri);
|
|
Ian Kent |
36ee82 |
+ break;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ list_del_init(&this->list);
|
|
Ian Kent |
36ee82 |
+ list_add_tail(&this->list, &tmp);
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
+ /*
|
|
Ian Kent |
36ee82 |
+ * Successfuly connected uri (head of list) and untried uris are
|
|
Ian Kent |
36ee82 |
+ * in ctxt->uri list. Make list of remainder and failed uris with
|
|
Ian Kent |
36ee82 |
+ * failed uris at end and assign back to ctxt-uri.
|
|
Ian Kent |
36ee82 |
+ */
|
|
Ian Kent |
36ee82 |
+ list_splice(ctxt->uri, &tmp);
|
|
Ian Kent |
36ee82 |
+ INIT_LIST_HEAD(ctxt->uri);
|
|
Ian Kent |
36ee82 |
+ list_splice(&tmp, ctxt->uri);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+static LDAP *do_reconnect(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ LDAP *ldap;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (ctxt->server || !ctxt->uri) {
|
|
Ian Kent |
36ee82 |
+ ldap = do_connect(ctxt->server, ctxt);
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+ } else {
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *this;
|
|
Ian Kent |
36ee82 |
+ this = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
|
Ian Kent |
36ee82 |
+ ldap = do_connect(this->uri, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (ldap)
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
+ /* Failed to connect, put at end of list */
|
|
Ian Kent |
36ee82 |
+ list_del_init(&this->list);
|
|
Ian Kent |
36ee82 |
+ list_add_tail(&this->list, ctxt->uri);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ autofs_sasl_done(ctxt);
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ /* Current server failed connect, try the rest */
|
|
Ian Kent |
36ee82 |
+ ldap = find_server(ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap)
|
|
Ian Kent |
36ee82 |
+ error(LOGOPT_ANY, MODPREFIX "failed to find available server");
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
return ldap;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
@@ -760,10 +886,10 @@ out:
|
|
Ian Kent |
36ee82 |
* information. If there is no configuration file, then we fall back to
|
|
Ian Kent |
36ee82 |
* trying all supported authentication mechanisms until one works.
|
|
Ian Kent |
36ee82 |
*
|
|
Ian Kent |
36ee82 |
- * Returns 0 on success, with authtype, user and secret filled in as
|
|
Ian Kent |
36ee82 |
- * appropriate. Returns -1 on failre.
|
|
Ian Kent |
36ee82 |
+ * Returns ldap connection on success, with authtype, user and secret
|
|
Ian Kent |
36ee82 |
+ * filled in as appropriate. Returns NULL on failre.
|
|
Ian Kent |
36ee82 |
*/
|
|
Ian Kent |
36ee82 |
-int auth_init(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
+static LDAP *auth_init(const char *uri, struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
int ret;
|
|
Ian Kent |
36ee82 |
LDAP *ldap;
|
|
Ian Kent |
36ee82 |
@@ -776,14 +902,11 @@ int auth_init(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
*/
|
|
Ian Kent |
36ee82 |
ret = parse_ldap_config(ctxt);
|
|
Ian Kent |
36ee82 |
if (ret)
|
|
Ian Kent |
36ee82 |
- return -1;
|
|
Ian Kent |
36ee82 |
-
|
|
Ian Kent |
36ee82 |
- if (ctxt->auth_required & LDAP_AUTH_NOTREQUIRED)
|
|
Ian Kent |
36ee82 |
- return 0;
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- ldap = init_ldap_connection(ctxt);
|
|
Ian Kent |
36ee82 |
+ ldap = init_ldap_connection(uri, ctxt);
|
|
Ian Kent |
36ee82 |
if (!ldap)
|
|
Ian Kent |
36ee82 |
- return -1;
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/*
|
|
Ian Kent |
36ee82 |
* Initialize the sasl library. It is okay if user and secret
|
|
Ian Kent |
36ee82 |
@@ -794,18 +917,12 @@ int auth_init(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
* the credential cache and the client and service principals.
|
|
Ian Kent |
36ee82 |
*/
|
|
Ian Kent |
36ee82 |
ret = autofs_sasl_init(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
- unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
if (ret) {
|
|
Ian Kent |
36ee82 |
ctxt->sasl_mech = NULL;
|
|
Ian Kent |
36ee82 |
- if (ctxt->auth_required & LDAP_AUTH_AUTODETECT) {
|
|
Ian Kent |
36ee82 |
- warn(LOGOPT_NONE,
|
|
Ian Kent |
36ee82 |
- "no authentication mechanisms auto detected.");
|
|
Ian Kent |
36ee82 |
- return 0;
|
|
Ian Kent |
36ee82 |
- }
|
|
Ian Kent |
36ee82 |
- return -1;
|
|
Ian Kent |
36ee82 |
+ return NULL;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- return 0;
|
|
Ian Kent |
36ee82 |
+ return ldap;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
#endif
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -1036,6 +1153,8 @@ static void free_context(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
free(ctxt->cur_host);
|
|
Ian Kent |
36ee82 |
if (ctxt->base)
|
|
Ian Kent |
36ee82 |
free(ctxt->base);
|
|
Ian Kent |
36ee82 |
+ if (ctxt->uri)
|
|
Ian Kent |
36ee82 |
+ defaults_free_uris(ctxt->uri);
|
|
Ian Kent |
36ee82 |
if (ctxt->sdns)
|
|
Ian Kent |
36ee82 |
defaults_free_searchdns(ctxt->sdns);
|
|
Ian Kent |
36ee82 |
free(ctxt);
|
|
Ian Kent |
36ee82 |
@@ -1043,6 +1162,30 @@ static void free_context(struct lookup_context *ctxt)
|
|
Ian Kent |
36ee82 |
return;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
+static void validate_uris(struct list_head *list)
|
|
Ian Kent |
36ee82 |
+{
|
|
Ian Kent |
36ee82 |
+ struct list_head *next;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ next = list->next;
|
|
Ian Kent |
36ee82 |
+ while (next != list) {
|
|
Ian Kent |
36ee82 |
+ struct ldap_uri *this;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ this = list_entry(next, struct ldap_uri, list);
|
|
Ian Kent |
36ee82 |
+ next = next->next;
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ /* At least we get some basic validation */
|
|
Ian Kent |
36ee82 |
+ if (!ldap_is_ldap_url(this->uri)) {
|
|
Ian Kent |
36ee82 |
+ warn(LOGOPT_ANY,
|
|
Ian Kent |
36ee82 |
+ "removed invalid uri from list, %s", this->uri);
|
|
Ian Kent |
36ee82 |
+ list_del(&this->list);
|
|
Ian Kent |
36ee82 |
+ free(this->uri);
|
|
Ian Kent |
36ee82 |
+ free(this);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ return;
|
|
Ian Kent |
36ee82 |
+}
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
/*
|
|
Ian Kent |
36ee82 |
* This initializes a context (persistent non-global data) for queries to
|
|
Ian Kent |
36ee82 |
* this module. Return zero if we succeed.
|
|
Ian Kent |
36ee82 |
@@ -1051,7 +1194,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
36ee82 |
{
|
|
Ian Kent |
36ee82 |
struct lookup_context *ctxt;
|
|
Ian Kent |
36ee82 |
char buf[MAX_ERR_BUF];
|
|
Ian Kent |
36ee82 |
- int ret;
|
|
Ian Kent |
36ee82 |
LDAP *ldap = NULL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
*context = NULL;
|
|
Ian Kent |
36ee82 |
@@ -1079,33 +1221,42 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
|
Ian Kent |
36ee82 |
return 1;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
-#ifdef WITH_SASL
|
|
Ian Kent |
36ee82 |
- /*
|
|
Ian Kent |
36ee82 |
- * Determine which authentication mechanism to use. We sanity-
|
|
Ian Kent |
36ee82 |
- * check by binding to the server temporarily.
|
|
Ian Kent |
36ee82 |
- */
|
|
Ian Kent |
36ee82 |
- ret = auth_init(ctxt);
|
|
Ian Kent |
36ee82 |
- if (ret && (ctxt->auth_required & LDAP_AUTH_REQUIRED)) {
|
|
Ian Kent |
36ee82 |
- error(LOGOPT_ANY, MODPREFIX
|
|
Ian Kent |
36ee82 |
- "cannot initialize authentication setup");
|
|
Ian Kent |
36ee82 |
- free_context(ctxt);
|
|
Ian Kent |
36ee82 |
- return 1;
|
|
Ian Kent |
36ee82 |
+ ctxt->timeout = defaults_get_ldap_timeout();
|
|
Ian Kent |
36ee82 |
+ ctxt->network_timeout = defaults_get_ldap_network_timeout();
|
|
Ian Kent |
36ee82 |
+
|
|
Ian Kent |
36ee82 |
+ if (!ctxt->server) {
|
|
Ian Kent |
36ee82 |
+ struct list_head *uris = defaults_get_uris();
|
|
Ian Kent |
36ee82 |
+ if (uris) {
|
|
Ian Kent |
36ee82 |
+ validate_uris(uris);
|
|
Ian Kent |
36ee82 |
+ if (!list_empty(uris))
|
|
Ian Kent |
36ee82 |
+ ctxt->uri = uris;
|
|
Ian Kent |
36ee82 |
+ else
|
|
Ian Kent |
36ee82 |
+ free(uris);
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
-#endif
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
- ldap = do_connect(ctxt);
|
|
Ian Kent |
36ee82 |
- if (!ldap) {
|
|
Ian Kent |
36ee82 |
- error(LOGOPT_ANY, MODPREFIX "cannot connect to server");
|
|
Ian Kent |
36ee82 |
- free_context(ctxt);
|
|
Ian Kent |
36ee82 |
- return 1;
|
|
Ian Kent |
36ee82 |
+ if (ctxt->server || !ctxt->uri) {
|
|
Ian Kent |
36ee82 |
+ ldap = connect_to_server(ctxt->server, ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap) {
|
|
Ian Kent |
36ee82 |
+ free_context(ctxt);
|
|
Ian Kent |
36ee82 |
+ return 1;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
+ } else {
|
|
Ian Kent |
36ee82 |
+ ldap = find_server(ctxt);
|
|
Ian Kent |
36ee82 |
+ if (!ldap) {
|
|
Ian Kent |
36ee82 |
+ free_context(ctxt);
|
|
Ian Kent |
36ee82 |
+ error(LOGOPT_ANY, MODPREFIX
|
|
Ian Kent |
36ee82 |
+ "failed to find available server");
|
|
Ian Kent |
36ee82 |
+ return 1;
|
|
Ian Kent |
36ee82 |
+ }
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
unbind_ldap_connection(ldap, ctxt);
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* Open the parser, if we can. */
|
|
Ian Kent |
36ee82 |
ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
|
|
Ian Kent |
36ee82 |
if (!ctxt->parse) {
|
|
Ian Kent |
36ee82 |
- crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
|
|
Ian Kent |
36ee82 |
free_context(ctxt);
|
|
Ian Kent |
36ee82 |
+ crit(LOGOPT_ANY, MODPREFIX "failed to open parse context");
|
|
Ian Kent |
36ee82 |
return 1;
|
|
Ian Kent |
36ee82 |
}
|
|
Ian Kent |
36ee82 |
*context = ctxt;
|
|
Ian Kent |
36ee82 |
@@ -1153,7 +1304,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
|
Ian Kent |
36ee82 |
query[l] = '\0';
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* Initialize the LDAP context. */
|
|
Ian Kent |
36ee82 |
- ldap = do_connect(ctxt);
|
|
Ian Kent |
36ee82 |
+ ldap = do_reconnect(ctxt);
|
|
Ian Kent |
36ee82 |
if (!ldap)
|
|
Ian Kent |
36ee82 |
return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -1305,7 +1456,7 @@ static int read_one_map(struct autofs_point *ap,
|
|
Ian Kent |
36ee82 |
query[l] = '\0';
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* Initialize the LDAP context. */
|
|
Ian Kent |
36ee82 |
- ldap = do_connect(ctxt);
|
|
Ian Kent |
36ee82 |
+ ldap = do_reconnect(ctxt);
|
|
Ian Kent |
36ee82 |
if (!ldap)
|
|
Ian Kent |
36ee82 |
return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
@@ -1536,6 +1687,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
|
Ian Kent |
36ee82 |
if (ret != NSS_STATUS_SUCCESS) {
|
|
Ian Kent |
36ee82 |
switch (rv) {
|
|
Ian Kent |
36ee82 |
case LDAP_SIZELIMIT_EXCEEDED:
|
|
Ian Kent |
36ee82 |
+ crit(ap->logopt, MODPREFIX
|
|
Ian Kent |
36ee82 |
+ "Unable to download entire LDAP map for: %s",
|
|
Ian Kent |
36ee82 |
+ ap->path);
|
|
Ian Kent |
36ee82 |
case LDAP_UNWILLING_TO_PERFORM:
|
|
Ian Kent |
36ee82 |
pthread_setcancelstate(cur_state, NULL);
|
|
Ian Kent |
36ee82 |
return NSS_STATUS_UNAVAIL;
|
|
Ian Kent |
36ee82 |
@@ -1612,7 +1766,7 @@ static int lookup_one(struct autofs_point *ap,
|
|
Ian Kent |
36ee82 |
query[ql] = '\0';
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
/* Initialize the LDAP context. */
|
|
Ian Kent |
36ee82 |
- ldap = do_connect(ctxt);
|
|
Ian Kent |
36ee82 |
+ ldap = do_reconnect(ctxt);
|
|
Ian Kent |
36ee82 |
if (!ldap)
|
|
Ian Kent |
36ee82 |
return CHE_FAIL;
|
|
Ian Kent |
36ee82 |
|
|
Ian Kent |
36ee82 |
diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in
|
|
Ian Kent |
36ee82 |
index 2b1e20a..f01ee5f 100644
|
|
Ian Kent |
36ee82 |
--- a/redhat/autofs.sysconfig.in
|
|
Ian Kent |
36ee82 |
+++ b/redhat/autofs.sysconfig.in
|
|
Ian Kent |
36ee82 |
@@ -23,6 +23,25 @@ BROWSE_MODE="no"
|
|
Ian Kent |
36ee82 |
#
|
|
Ian Kent |
36ee82 |
# Define base dn for map dn lookup.
|
|
Ian Kent |
36ee82 |
#
|
|
Ian Kent |
36ee82 |
+# Define server URIs
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP_URI - space seperated list of server uris of the form
|
|
Ian Kent |
36ee82 |
+# <proto>://<server>[/] where <proto> can be ldap
|
|
Ian Kent |
36ee82 |
+# or ldaps. The option can be given multiple times.
|
|
Ian Kent |
36ee82 |
+# Map entries that include a server name override
|
|
Ian Kent |
36ee82 |
+# this option.
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_URI=""
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP__TIMEOUT - timeout value for the synchronous API calls
|
|
Ian Kent |
36ee82 |
+# (default is LDAP library default).
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_TIMEOUT=-1
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_NETWORK_TIMEOUT=8
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
# SEARCH_BASE - base dn to use for searching for map search dn.
|
|
Ian Kent |
36ee82 |
# Multiple entries can be given and they are checked
|
|
Ian Kent |
36ee82 |
# in the order they occur here.
|
|
Ian Kent |
36ee82 |
diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in
|
|
Ian Kent |
36ee82 |
index 2b1e20a..028341c 100644
|
|
Ian Kent |
36ee82 |
--- a/samples/autofs.conf.default.in
|
|
Ian Kent |
36ee82 |
+++ b/samples/autofs.conf.default.in
|
|
Ian Kent |
36ee82 |
@@ -21,6 +21,25 @@ BROWSE_MODE="no"
|
|
Ian Kent |
36ee82 |
#
|
|
Ian Kent |
36ee82 |
#LOGGING="none"
|
|
Ian Kent |
36ee82 |
#
|
|
Ian Kent |
36ee82 |
+# Define server URIs
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP_URI - space seperated list of server uris of the form
|
|
Ian Kent |
36ee82 |
+# <proto>://<server>[/] where <proto> can be ldap
|
|
Ian Kent |
36ee82 |
+# or ldaps. The option can be given multiple times.
|
|
Ian Kent |
36ee82 |
+# Map entries that include a server name override
|
|
Ian Kent |
36ee82 |
+# this option.
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_URI=""
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP__TIMEOUT - timeout value for the synchronous API calls
|
|
Ian Kent |
36ee82 |
+# (default is LDAP library default).
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_TIMEOUT=-1
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
+#LDAP_NETWORK_TIMEOUT=8
|
|
Ian Kent |
36ee82 |
+#
|
|
Ian Kent |
36ee82 |
# Define base dn for map dn lookup.
|
|
Ian Kent |
36ee82 |
#
|
|
Ian Kent |
36ee82 |
# SEARCH_BASE - base dn to use for searching for map search dn.
|