- add upstream fixes and fix for bug 1086887.
This commit is contained in:
parent
492919dcab
commit
86506c6a39
@ -0,0 +1,423 @@
|
||||
autofs-5.0.8 - amd lookup update lookup hesiod to handle amd keys
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Warning, this is completely untested.
|
||||
|
||||
I don't have a hesiod test environment so I can't test this at all.
|
||||
If we do in fact have hesiod users then I'll need to work with them
|
||||
to fix any reported problems.
|
||||
---
|
||||
CHANGELOG | 3
|
||||
modules/lookup_hesiod.c | 330 ++++++++++++++++++++++++++++++++++++++---------
|
||||
2 files changed, 272 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 16a8ab4..f44f6f5 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -4,7 +4,8 @@
|
||||
- add amd map format parser.
|
||||
- amd lookup update lookup ldap to handle amd keys
|
||||
- inadvertantly drop from initial series.
|
||||
-
|
||||
+- amd lookup update lookup hesiod to handle amd keys
|
||||
+ - inadvertantly drop from initial series.
|
||||
|
||||
28/03/2014 autofs-5.0.9
|
||||
=======================
|
||||
diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c
|
||||
index c4f3558..526f294 100644
|
||||
--- a/modules/lookup_hesiod.c
|
||||
+++ b/modules/lookup_hesiod.c
|
||||
@@ -20,12 +20,15 @@
|
||||
#include "automount.h"
|
||||
#include "nsswitch.h"
|
||||
|
||||
-#define MAPFMT_DEFAULT "hesiod"
|
||||
+#define MAPFMT_DEFAULT "hesiod"
|
||||
+#define AMD_MAP_PREFIX "hesiod."
|
||||
+#define AMD_MAP_PREFIX_LEN 7
|
||||
|
||||
#define MODPREFIX "lookup(hesiod): "
|
||||
#define HESIOD_LEN 512
|
||||
|
||||
struct lookup_context {
|
||||
+ const char *mapname;
|
||||
struct parse_mod *parser;
|
||||
void *hesiod_context;
|
||||
};
|
||||
@@ -50,6 +53,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
return 1;
|
||||
}
|
||||
+ memset(ctxt, 0, sizeof(struct lookup_context));
|
||||
|
||||
/* Initialize the resolver. */
|
||||
res_init();
|
||||
@@ -66,6 +70,20 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
if (!mapfmt)
|
||||
mapfmt = MAPFMT_DEFAULT;
|
||||
|
||||
+ if (!strcmp(mapfmt, "amd")) {
|
||||
+ /* amd formated hesiod maps have a map name */
|
||||
+ const char *mapname = argv[0];
|
||||
+ if (strncmp(mapname, AMD_MAP_PREFIX, AMD_MAP_PREFIX_LEN)) {
|
||||
+ logerr(MODPREFIX
|
||||
+ "incorrect prefix for hesiod map %s", mapname);
|
||||
+ free(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ ctxt->mapname = mapname;
|
||||
+ argc--;
|
||||
+ argv++;
|
||||
+ }
|
||||
+
|
||||
/* Open the parser, if we can. */
|
||||
ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
|
||||
if (!ctxt->parser) {
|
||||
@@ -97,16 +115,203 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
||||
* it's an ERR filesystem, it's an error message we should log. Otherwise,
|
||||
* assume it's something we know how to deal with already (generic).
|
||||
*/
|
||||
+static int lookup_one(struct autofs_point *ap,
|
||||
+ struct map_source *source,
|
||||
+ const char *key, int key_len,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ struct mapent_cache *mc;
|
||||
+ char **hes_result;
|
||||
+ char **record, *best_record = NULL, *p;
|
||||
+ int priority, lowest_priority = INT_MAX;
|
||||
+ int ret, status;
|
||||
+
|
||||
+ mc = source->mc;
|
||||
+
|
||||
+ status = pthread_mutex_lock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
+ hes_result = hesiod_resolve(ctxt->hesiod_context, key, "filsys");
|
||||
+ if (!hes_result || !hes_result[0]) {
|
||||
+ int err = errno;
|
||||
+ error(ap->logopt,
|
||||
+ MODPREFIX "key \"%s\" not found in map", key);
|
||||
+ status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+ if (err == HES_ER_NOTFOUND)
|
||||
+ return CHE_MISSING;
|
||||
+ else
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* autofs doesn't support falling back to alternate records, so just
|
||||
+ find the record with the lowest priority and hope it works.
|
||||
+ -- Aaron Ucko <amu@alum.mit.edu> 2002-03-11 */
|
||||
+ for (record = hes_result; *record; ++record) {
|
||||
+ p = strrchr(*record, ' ');
|
||||
+ if ( p && isdigit(p[1]) ) {
|
||||
+ priority = atoi(p+1);
|
||||
+ } else {
|
||||
+ priority = INT_MAX - 1;
|
||||
+ }
|
||||
+ if (priority < lowest_priority) {
|
||||
+ lowest_priority = priority;
|
||||
+ best_record = *record;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cache_writelock(mc);
|
||||
+ ret = cache_update(mc, source, key, best_record, time(NULL));
|
||||
+ cache_unlock(mc);
|
||||
+ if (ret == CHE_FAIL) {
|
||||
+ hesiod_free_list(ctxt->hesiod_context, hes_result);
|
||||
+ status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "lookup for \"%s\" gave \"%s\"",
|
||||
+ key, best_record);
|
||||
+
|
||||
+ hesiod_free_list(ctxt->hesiod_context, hes_result);
|
||||
+
|
||||
+ status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int lookup_one_amd(struct autofs_point *ap,
|
||||
+ struct map_source *source,
|
||||
+ const char *key, int key_len,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ struct mapent_cache *mc;
|
||||
+ char *hesiod_base;
|
||||
+ char **hes_result;
|
||||
+ char *lkp_key;
|
||||
+ int status, ret;
|
||||
+
|
||||
+ mc = source->mc;
|
||||
+
|
||||
+ hesiod_base = conf_amd_get_hesiod_base();
|
||||
+ if (!hesiod_base)
|
||||
+ return CHE_FAIL;
|
||||
+
|
||||
+ lkp_key = malloc(key_len + strlen(ctxt->mapname) - 7 + 2);
|
||||
+ if (!lkp_key) {
|
||||
+ free(hesiod_base);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ strcpy(lkp_key, key);
|
||||
+ strcat(lkp_key, ".");
|
||||
+ strcat(lkp_key, ctxt->mapname + AMD_MAP_PREFIX_LEN);
|
||||
+
|
||||
+ status = pthread_mutex_lock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
+ hes_result = hesiod_resolve(ctxt->hesiod_context, lkp_key, hesiod_base);
|
||||
+ if (!hes_result || !hes_result[0]) {
|
||||
+ int err = errno;
|
||||
+ if (err == HES_ER_NOTFOUND)
|
||||
+ ret = CHE_MISSING;
|
||||
+ else
|
||||
+ ret = CHE_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ cache_writelock(mc);
|
||||
+ ret = cache_update(mc, source, lkp_key, *hes_result, time(NULL));
|
||||
+ cache_unlock(mc);
|
||||
+
|
||||
+ if (hes_result)
|
||||
+ hesiod_free_list(ctxt->hesiod_context, hes_result);
|
||||
+done:
|
||||
+ free(lkp_key);
|
||||
+
|
||||
+ status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
+ if (status)
|
||||
+ fatal(status);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int match_amd_key(struct autofs_point *ap,
|
||||
+ struct map_source *source,
|
||||
+ const char *key, int key_len,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ char *lkp_key;
|
||||
+ char *prefix;
|
||||
+ int ret;
|
||||
+
|
||||
+ ret = lookup_one_amd(ap, source, key, key_len, ctxt);
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ return ret;
|
||||
+
|
||||
+ lkp_key = strdup(key);
|
||||
+ if (!lkp_key) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "strdup: %s", estr);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ ret = CHE_MISSING;
|
||||
+
|
||||
+ /*
|
||||
+ * Now strip successive directory components and try a
|
||||
+ * match against map entries ending with a wildcard and
|
||||
+ * finally try the wilcard entry itself.
|
||||
+ */
|
||||
+ while ((prefix = strrchr(lkp_key, '/'))) {
|
||||
+ char *match;
|
||||
+ size_t len;
|
||||
+ *prefix = '\0';
|
||||
+ len = strlen(lkp_key) + 3;
|
||||
+ match = malloc(len);
|
||||
+ if (!match) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
+ ret = CHE_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ len--;
|
||||
+ strcpy(match, lkp_key);
|
||||
+ strcat(match, "/*");
|
||||
+ ret = lookup_one_amd(ap, source, match, len, ctxt);
|
||||
+ free(match);
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ /* Lastly try the wildcard */
|
||||
+ ret = lookup_one_amd(ap, source, "*", 1, ctxt);
|
||||
+done:
|
||||
+ free(lkp_key);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context)
|
||||
{
|
||||
struct lookup_context *ctxt = (struct lookup_context *) context;
|
||||
- struct map_source *source;
|
||||
struct mapent_cache *mc;
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ struct map_source *source;
|
||||
struct mapent *me;
|
||||
- char **hes_result;
|
||||
- int status, rv;
|
||||
- char **record, *best_record = NULL, *p;
|
||||
- int priority, lowest_priority = INT_MAX;
|
||||
+ char key[KEY_MAX_LEN + 1];
|
||||
+ size_t key_len;
|
||||
+ char *lkp_key;
|
||||
+ size_t len;
|
||||
+ char *mapent;
|
||||
+ int rv;
|
||||
|
||||
source = ap->entry->current;
|
||||
ap->entry->current = NULL;
|
||||
@@ -118,6 +323,19 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
MODPREFIX "looking up root=\"%s\", name=\"%s\"",
|
||||
ap->path, name);
|
||||
|
||||
+ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
|
||||
+ if (key_len > KEY_MAX_LEN)
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ } else {
|
||||
+ key_len = expandamdent(name, NULL, NULL);
|
||||
+ if (key_len > KEY_MAX_LEN)
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ expandamdent(name, key, NULL);
|
||||
+ key[key_len] = '\0';
|
||||
+ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key);
|
||||
+ }
|
||||
+
|
||||
/* Check if we recorded a mount fail for this key anywhere */
|
||||
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
|
||||
if (me) {
|
||||
@@ -144,69 +362,61 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
}
|
||||
}
|
||||
|
||||
- chdir("/"); /* If this is not here the filesystem stays
|
||||
- busy, for some reason... */
|
||||
-
|
||||
- status = pthread_mutex_lock(&hesiod_mutex);
|
||||
- if (status)
|
||||
- fatal(status);
|
||||
-
|
||||
- hes_result = hesiod_resolve(ctxt->hesiod_context, name, "filsys");
|
||||
- if (!hes_result || !hes_result[0]) {
|
||||
- /* Note: it is not clear to me how to distinguish between
|
||||
- * the "no search results" case and other failures. --JM */
|
||||
- error(ap->logopt,
|
||||
- MODPREFIX "key \"%s\" not found in map", name);
|
||||
- status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
- if (status)
|
||||
- fatal(status);
|
||||
- return NSS_STATUS_NOTFOUND;
|
||||
+ /* If this is not here the filesystem stays busy, for some reason... */
|
||||
+ if (chdir("/"))
|
||||
+ warn(ap->logopt,
|
||||
+ MODPREFIX "failed to set working directory to \"/\"");
|
||||
+
|
||||
+ len = key_len;
|
||||
+ if (!(source->flags & MAP_FLAG_FORMAT_AMD))
|
||||
+ lkp_key = strdup(key);
|
||||
+ else {
|
||||
+ rv = lookup_one_amd(ap, source, "/defaults", 9, ctxt);
|
||||
+ if (rv == CHE_FAIL)
|
||||
+ warn(ap->logopt,
|
||||
+ MODPREFIX "failed to lookup \"/defaults\" entry");
|
||||
+
|
||||
+ if (!ap->pref)
|
||||
+ lkp_key = strdup(key);
|
||||
+ else {
|
||||
+ len += strlen(ap->pref);
|
||||
+ lkp_key = malloc(len + 1);
|
||||
+ if (lkp_key) {
|
||||
+ strcpy(lkp_key, ap->pref);
|
||||
+ strcat(lkp_key, name);
|
||||
+ }
|
||||
+ }
|
||||
}
|
||||
|
||||
- /* autofs doesn't support falling back to alternate records, so just
|
||||
- find the record with the lowest priority and hope it works.
|
||||
- -- Aaron Ucko <amu@alum.mit.edu> 2002-03-11 */
|
||||
- for (record = hes_result; *record; ++record) {
|
||||
- p = strrchr(*record, ' ');
|
||||
- if ( p && isdigit(p[1]) ) {
|
||||
- priority = atoi(p+1);
|
||||
- } else {
|
||||
- priority = INT_MAX - 1;
|
||||
- }
|
||||
- if (priority < lowest_priority) {
|
||||
- lowest_priority = priority;
|
||||
- best_record = *record;
|
||||
- }
|
||||
+ if (!lkp_key) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, "malloc: %s", estr);
|
||||
+ return NSS_STATUS_UNKNOWN;
|
||||
}
|
||||
|
||||
- cache_writelock(mc);
|
||||
- rv = cache_update(mc, source, name, best_record, time(NULL));
|
||||
- cache_unlock(mc);
|
||||
- if (rv == CHE_FAIL)
|
||||
- return NSS_STATUS_UNAVAIL;
|
||||
+ if (source->flags & MAP_FLAG_FORMAT_AMD)
|
||||
+ rv = match_amd_key(ap, source, lkp_key, len, ctxt);
|
||||
+ else
|
||||
+ rv = lookup_one(ap, source, lkp_key, len, ctxt);
|
||||
|
||||
- debug(ap->logopt,
|
||||
- MODPREFIX "lookup for \"%s\" gave \"%s\"",
|
||||
- name, best_record);
|
||||
+ if (rv == CHE_FAIL) {
|
||||
+ free(lkp_key);
|
||||
+ return NSS_STATUS_UNAVAIL;
|
||||
+ }
|
||||
|
||||
- rv = ctxt->parser->parse_mount(ap, name, name_len, best_record,
|
||||
- ctxt->parser->context);
|
||||
+ me = match_cached_key(ap, MODPREFIX, source, lkp_key);
|
||||
+ free(lkp_key);
|
||||
+ if (!me)
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
|
||||
- hesiod_free_list(ctxt->hesiod_context, hes_result);
|
||||
+ if (!me->mapent)
|
||||
+ return NSS_STATUS_UNAVAIL;
|
||||
|
||||
- status = pthread_mutex_unlock(&hesiod_mutex);
|
||||
- if (status)
|
||||
- fatal(status);
|
||||
+ mapent = strdup(me->mapent);
|
||||
|
||||
- if (rv) {
|
||||
- /* Don't update negative cache when re-connecting */
|
||||
- if (ap->flags & MOUNT_FLAG_REMOUNT)
|
||||
- return NSS_STATUS_TRYAGAIN;
|
||||
- cache_writelock(mc);
|
||||
- cache_update_negative(mc, source, name, ap->negative_timeout);
|
||||
- cache_unlock(mc);
|
||||
- return NSS_STATUS_TRYAGAIN;
|
||||
- }
|
||||
+ rv = ctxt->parser->parse_mount(ap, key, key_len,
|
||||
+ mapent, ctxt->parser->context);
|
||||
+ free(mapent);
|
||||
|
||||
/*
|
||||
* Unavailable due to error such as module load fail
|
@ -0,0 +1,954 @@
|
||||
autofs-5.0.8 - amd lookup update lookup ldap to handle amd keys
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
|
||||
---
|
||||
CHANGELOG | 3
|
||||
include/lookup_ldap.h | 3
|
||||
modules/lookup_ldap.c | 707 +++++++++++++++++++++++++++++++++++++++++++++----
|
||||
3 files changed, 654 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 5cc1506..16a8ab4 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -2,6 +2,9 @@
|
||||
=======================
|
||||
- fix mistake in assignment.
|
||||
- add amd map format parser.
|
||||
+- amd lookup update lookup ldap to handle amd keys
|
||||
+ - inadvertantly drop from initial series.
|
||||
+
|
||||
|
||||
28/03/2014 autofs-5.0.9
|
||||
=======================
|
||||
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
||||
index f34c029..ba817aa 100644
|
||||
--- a/include/lookup_ldap.h
|
||||
+++ b/include/lookup_ldap.h
|
||||
@@ -36,6 +36,7 @@ struct ldap_searchdn {
|
||||
|
||||
struct lookup_context {
|
||||
char *mapname;
|
||||
+ unsigned int format;
|
||||
|
||||
char *server;
|
||||
int port;
|
||||
@@ -43,6 +44,8 @@ struct lookup_context {
|
||||
char *qdn;
|
||||
unsigned int timeout;
|
||||
unsigned int network_timeout;
|
||||
+ unsigned long timestamp;
|
||||
+ unsigned int check_defaults;
|
||||
|
||||
/* LDAP version 2 or 3 */
|
||||
int version;
|
||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
||||
index c22d100..833cb86 100644
|
||||
--- a/modules/lookup_ldap.c
|
||||
+++ b/modules/lookup_ldap.c
|
||||
@@ -29,6 +29,7 @@
|
||||
#include <resolv.h>
|
||||
#include <lber.h>
|
||||
#include <libxml/tree.h>
|
||||
+#include <stdlib.h>
|
||||
|
||||
#define MODULE_LOOKUP
|
||||
#include "automount.h"
|
||||
@@ -52,6 +53,14 @@ static struct ldap_schema common_schema[] = {
|
||||
};
|
||||
static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema);
|
||||
|
||||
+static struct ldap_schema amd_timestamp = {
|
||||
+ "madmap", "amdmapName", "amdmapTimestamp", NULL, "amdmapTimestamp"
|
||||
+};
|
||||
+
|
||||
+static struct ldap_schema amd_schema = {
|
||||
+ "amdmap", "amdmapName", "amdmap", "amdmapKey", "amdmapValue"
|
||||
+};
|
||||
+
|
||||
/*
|
||||
* Initialization and de-initialization of LDAP and OpenSSL must be
|
||||
* always serialized to avoid corruption of context structures inside
|
||||
@@ -62,6 +71,7 @@ pthread_mutex_t ldapinit_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
struct ldap_search_params {
|
||||
struct autofs_point *ap;
|
||||
LDAP *ldap;
|
||||
+ char *base;
|
||||
char *query, **attrs;
|
||||
struct berval *cookie;
|
||||
ber_int_t pageSize;
|
||||
@@ -531,6 +541,16 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
|
||||
if (ctxt->schema)
|
||||
return 0;
|
||||
|
||||
+ if (ctxt->format & MAP_FLAG_FORMAT_AMD) {
|
||||
+ schema = alloc_common_schema(&amd_schema);
|
||||
+ if (!schema) {
|
||||
+ error(logopt, MODPREFIX "failed to allocate schema");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ ctxt->schema = schema;
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < common_schema_count; i++) {
|
||||
const char *class = common_schema[i].map_class;
|
||||
const char *key = common_schema[i].map_attr;
|
||||
@@ -587,8 +607,10 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
|
||||
|
||||
if (!ctxt->cur_host) {
|
||||
ctxt->cur_host = nhost;
|
||||
- /* Check if schema defined in conf first time only */
|
||||
- ctxt->schema = defaults_get_schema();
|
||||
+ if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ /* Check if schema defined in conf first time only */
|
||||
+ ctxt->schema = defaults_get_schema();
|
||||
+ }
|
||||
} else {
|
||||
/* If connection host has changed update */
|
||||
if (strcmp(ctxt->cur_host, nhost)) {
|
||||
@@ -614,7 +636,7 @@ static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_c
|
||||
MODPREFIX "failed to find valid query dn");
|
||||
return 0;
|
||||
}
|
||||
- } else {
|
||||
+ } else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
|
||||
const char *class = ctxt->schema->map_class;
|
||||
const char *key = ctxt->schema->map_attr;
|
||||
if (!get_query_dn(logopt, ldap, ctxt, class, key)) {
|
||||
@@ -648,6 +670,126 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
|
||||
return ldap;
|
||||
}
|
||||
|
||||
+static unsigned long get_amd_timestamp(struct lookup_context *ctxt)
|
||||
+{
|
||||
+ LDAP *ldap;
|
||||
+ LDAPMessage *result = NULL, *e;
|
||||
+ char *query;
|
||||
+ int scope = LDAP_SCOPE_SUBTREE;
|
||||
+ char *map, *class, *value;
|
||||
+ char *attrs[2];
|
||||
+ struct berval **bvValues;
|
||||
+ unsigned long timestamp = 0;
|
||||
+ int rv, l, ql;
|
||||
+
|
||||
+ ldap = do_connect(LOGOPT_ANY, ctxt->server, ctxt);
|
||||
+ if (!ldap)
|
||||
+ return 0;
|
||||
+
|
||||
+ map = amd_timestamp.map_attr;
|
||||
+ class = amd_timestamp.entry_class;
|
||||
+ value = amd_timestamp.value_attr;
|
||||
+
|
||||
+ attrs[0] = value;
|
||||
+ attrs[1] = NULL;
|
||||
+
|
||||
+ /* Build a query string. */
|
||||
+ l = strlen(class) +
|
||||
+ strlen(map) + strlen(ctxt->mapname) + 21;
|
||||
+
|
||||
+ query = malloc(l);
|
||||
+ if (query == NULL) {
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
+ crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Look for an entry in class under ctxt-base
|
||||
+ * whose entry is equal to qKey.
|
||||
+ */
|
||||
+ ql = sprintf(query, "(&(objectclass=%s)(%s=%s))",
|
||||
+ class, map, ctxt->mapname);
|
||||
+ if (ql >= l) {
|
||||
+ error(LOGOPT_ANY,
|
||||
+ MODPREFIX "error forming query string");
|
||||
+ free(query);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
|
||||
+ if ((rv != LDAP_SUCCESS) || !result) {
|
||||
+ crit(LOGOPT_ANY, MODPREFIX "timestamp query failed %s", query);
|
||||
+ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
|
||||
+ if (result)
|
||||
+ ldap_msgfree(result);
|
||||
+ free(query);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ e = ldap_first_entry(ldap, result);
|
||||
+ if (!e) {
|
||||
+ debug(LOGOPT_ANY,
|
||||
+ MODPREFIX "got answer, but no entry for timestamp");
|
||||
+ ldap_msgfree(result);
|
||||
+ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
|
||||
+ free(query);
|
||||
+ return CHE_MISSING;
|
||||
+ }
|
||||
+
|
||||
+ while (e) {
|
||||
+ char *v_val;
|
||||
+ char *endptr;
|
||||
+
|
||||
+ bvValues = ldap_get_values_len(ldap, e, value);
|
||||
+ if (!bvValues || !*bvValues) {
|
||||
+ debug(LOGOPT_ANY,
|
||||
+ MODPREFIX "no value found in timestamp");
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ /* There should be one value for a timestamp */
|
||||
+ v_val = bvValues[0]->bv_val;
|
||||
+
|
||||
+ timestamp = strtol(v_val, &endptr, 0);
|
||||
+ if ((errno == ERANGE &&
|
||||
+ (timestamp == LONG_MAX || timestamp == LONG_MIN)) ||
|
||||
+ (errno != 0 && timestamp == 0)) {
|
||||
+ debug(LOGOPT_ANY,
|
||||
+ MODPREFIX "invalid value in timestamp");
|
||||
+ free(query);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (endptr == v_val) {
|
||||
+ debug(LOGOPT_ANY,
|
||||
+ MODPREFIX "no digits found in timestamp");
|
||||
+ free(query);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (*endptr != '\0') {
|
||||
+ warn(LOGOPT_ANY, MODPREFIX
|
||||
+ "characters found after number: %s", endptr);
|
||||
+ warn(LOGOPT_ANY,
|
||||
+ MODPREFIX "timestamp may be invalid");
|
||||
+ }
|
||||
+
|
||||
+ ldap_value_free_len(bvValues);
|
||||
+ break;
|
||||
+next:
|
||||
+ ldap_value_free_len(bvValues);
|
||||
+ e = ldap_next_entry(ldap, e);
|
||||
+ }
|
||||
+
|
||||
+ ldap_msgfree(result);
|
||||
+ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt);
|
||||
+ free(query);
|
||||
+
|
||||
+ return timestamp;
|
||||
+}
|
||||
+
|
||||
static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt)
|
||||
{
|
||||
LDAP *ldap;
|
||||
@@ -1215,7 +1357,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
const char *q = NULL;
|
||||
|
||||
/* Isolate the server(s). */
|
||||
- if ((q = strchr(s, '/'))) {
|
||||
+ if ((q = strchr(s, '/')) || (q = strchr(s, '\0'))) {
|
||||
l = q - s;
|
||||
if (*proto) {
|
||||
al_len = l + strlen(proto) + 2;
|
||||
@@ -1318,8 +1460,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
ptr += l + 1;
|
||||
}
|
||||
|
||||
- /* TODO: why did I do this - how can the map name "and" base dn be missing? */
|
||||
- if (!ptr)
|
||||
+ if (!ptr || ctxt->format & MAP_FLAG_FORMAT_AMD)
|
||||
goto done;
|
||||
|
||||
/*
|
||||
@@ -1505,36 +1646,83 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
/* If a map type isn't explicitly given, parse it like sun entries. */
|
||||
if (mapfmt == NULL)
|
||||
mapfmt = MAPFMT_DEFAULT;
|
||||
-
|
||||
- /*
|
||||
- * Parse out the server name and base dn, and fill them
|
||||
- * into the proper places in the lookup context structure.
|
||||
- */
|
||||
- if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) {
|
||||
- error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
|
||||
- free_context(ctxt);
|
||||
- return 1;
|
||||
+ if (!strcmp(mapfmt, "amd")) {
|
||||
+ ctxt->format = MAP_FLAG_FORMAT_AMD;
|
||||
+ ctxt->check_defaults = 1;
|
||||
}
|
||||
|
||||
- if (!ctxt->base)
|
||||
- ctxt->sdns = defaults_get_searchdns();
|
||||
-
|
||||
ctxt->timeout = defaults_get_ldap_timeout();
|
||||
ctxt->network_timeout = defaults_get_ldap_network_timeout();
|
||||
|
||||
- if (!ctxt->server) {
|
||||
- struct list_head *uris = defaults_get_uris();
|
||||
- if (uris) {
|
||||
- validate_uris(uris);
|
||||
- if (!list_empty(uris))
|
||||
- ctxt->uris = uris;
|
||||
- else {
|
||||
- error(LOGOPT_ANY,
|
||||
- "no valid uris found in config list"
|
||||
- ", using default system config");
|
||||
- free(uris);
|
||||
+ if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ /*
|
||||
+ * Parse out the server name and base dn, and fill them
|
||||
+ * into the proper places in the lookup context structure.
|
||||
+ */
|
||||
+ if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) {
|
||||
+ error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ if (!ctxt->base)
|
||||
+ ctxt->sdns = defaults_get_searchdns();
|
||||
+
|
||||
+ if (!ctxt->server) {
|
||||
+ struct list_head *uris = defaults_get_uris();
|
||||
+ if (uris) {
|
||||
+ validate_uris(uris);
|
||||
+ if (!list_empty(uris))
|
||||
+ ctxt->uris = uris;
|
||||
+ else {
|
||||
+ error(LOGOPT_ANY, MODPREFIX
|
||||
+ "no valid uris found in config list"
|
||||
+ ", using default system config");
|
||||
+ free(uris);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
+ } else {
|
||||
+ char *tmp = conf_amd_get_ldap_base();
|
||||
+ if (!tmp) {
|
||||
+ error(LOGOPT_ANY, MODPREFIX "failed to get base dn");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ ctxt->base = tmp;
|
||||
+
|
||||
+ tmp = conf_amd_get_ldap_hostports();
|
||||
+ if (!tmp) {
|
||||
+ error(LOGOPT_ANY,
|
||||
+ MODPREFIX "failed to get ldap_hostports");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Parse out the server name and port, and save them in
|
||||
+ * the proper places in the lookup context structure.
|
||||
+ */
|
||||
+ if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) {
|
||||
+ error(LOGOPT_ANY, MODPREFIX "cannot parse server string");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ free(tmp);
|
||||
+
|
||||
+ if (!ctxt->server) {
|
||||
+ error(LOGOPT_ANY, MODPREFIX "ldap_hostports not valid");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ tmp = strdup(argv[0]);
|
||||
+ if (!tmp) {
|
||||
+ error(LOGOPT_ANY, MODPREFIX "failed to set mapname");
|
||||
+ free_context(ctxt);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ ctxt->mapname = tmp;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1558,6 +1746,8 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
}
|
||||
#endif
|
||||
|
||||
+ ctxt->timestamp = get_amd_timestamp(ctxt);
|
||||
+
|
||||
/* Open the parser, if we can. */
|
||||
ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1);
|
||||
if (!ctxt->parse) {
|
||||
@@ -2029,7 +2219,7 @@ static int do_paged_query(struct ldap_search_params *sp, struct lookup_context *
|
||||
if (sp->morePages == TRUE)
|
||||
goto do_paged;
|
||||
|
||||
- rv = ldap_search_s(sp->ldap, ctxt->qdn, scope, sp->query, sp->attrs, 0, &sp->result);
|
||||
+ rv = ldap_search_s(sp->ldap, sp->base, scope, sp->query, sp->attrs, 0, &sp->result);
|
||||
if ((rv != LDAP_SUCCESS) || !sp->result) {
|
||||
/*
|
||||
* Check for Size Limit exceeded and force run through loop
|
||||
@@ -2063,7 +2253,7 @@ do_paged:
|
||||
|
||||
/* Search for entries in the directory using the parmeters. */
|
||||
rv = ldap_search_ext_s(sp->ldap,
|
||||
- ctxt->qdn, scope, sp->query, sp->attrs,
|
||||
+ sp->base, scope, sp->query, sp->attrs,
|
||||
0, controls, NULL, NULL, 0, &sp->result);
|
||||
if ((rv != LDAP_SUCCESS) && (rv != LDAP_PARTIAL_RESULTS)) {
|
||||
ldap_control_free(pageControl);
|
||||
@@ -2364,6 +2554,115 @@ next:
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
+static int do_get_amd_entries(struct ldap_search_params *sp,
|
||||
+ struct map_source *source,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ struct autofs_point *ap = sp->ap;
|
||||
+ struct mapent_cache *mc = source->mc;
|
||||
+ struct berval **bvKey;
|
||||
+ struct berval **bvValues;
|
||||
+ LDAPMessage *e;
|
||||
+ char *entry, *value;
|
||||
+ int rv, ret, count;
|
||||
+
|
||||
+ entry = ctxt->schema->entry_attr;
|
||||
+ value = ctxt->schema->value_attr;
|
||||
+
|
||||
+ e = ldap_first_entry(sp->ldap, sp->result);
|
||||
+ if (!e) {
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "query succeeded, no matches for %s",
|
||||
+ sp->query);
|
||||
+ ret = ldap_parse_result(sp->ldap, sp->result,
|
||||
+ &rv, NULL, NULL, NULL, NULL, 0);
|
||||
+ if (ret == LDAP_SUCCESS)
|
||||
+ return rv;
|
||||
+ else
|
||||
+ return LDAP_OPERATIONS_ERROR;
|
||||
+ } else
|
||||
+ debug(ap->logopt, MODPREFIX "examining entries");
|
||||
+
|
||||
+ while (e) {
|
||||
+ char *k_val, *v_val;
|
||||
+ ber_len_t k_len;
|
||||
+ char *s_key;
|
||||
+
|
||||
+ bvKey = ldap_get_values_len(sp->ldap, e, entry);
|
||||
+ if (!bvKey || !*bvKey) {
|
||||
+ e = ldap_next_entry(sp->ldap, e);
|
||||
+ if (!e) {
|
||||
+ debug(ap->logopt, MODPREFIX
|
||||
+ "failed to get next entry for query %s",
|
||||
+ sp->query);
|
||||
+ ret = ldap_parse_result(sp->ldap,
|
||||
+ sp->result, &rv,
|
||||
+ NULL, NULL, NULL, NULL, 0);
|
||||
+ if (ret == LDAP_SUCCESS)
|
||||
+ return rv;
|
||||
+ else
|
||||
+ return LDAP_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* By definition keys should be unique within each map entry */
|
||||
+ k_val = NULL;
|
||||
+ k_len = 0;
|
||||
+
|
||||
+ count = ldap_count_values_len(bvKey);
|
||||
+ if (count > 1)
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "more than one %s, using first", entry);
|
||||
+
|
||||
+ k_val = bvKey[0]->bv_val;
|
||||
+ k_len = bvKey[0]->bv_len;
|
||||
+
|
||||
+ bvValues = ldap_get_values_len(sp->ldap, e, value);
|
||||
+ if (!bvValues || !*bvValues) {
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "no %s defined for %s",
|
||||
+ value, sp->query);
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ count = ldap_count_values_len(bvValues);
|
||||
+ if (count > 1)
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "more than one %s, using first", value);
|
||||
+
|
||||
+ v_val = bvValues[0]->bv_val;
|
||||
+
|
||||
+ /* Don't fail on "/" in key => type == 0 */
|
||||
+ s_key = sanitize_path(k_val, k_len, 0, ap->logopt);
|
||||
+ if (!s_key)
|
||||
+ goto next;
|
||||
+
|
||||
+ cache_writelock(mc);
|
||||
+ cache_update(mc, source, s_key, v_val, sp->age);
|
||||
+ cache_unlock(mc);
|
||||
+
|
||||
+ free(s_key);
|
||||
+next:
|
||||
+ ldap_value_free_len(bvValues);
|
||||
+ ldap_value_free_len(bvKey);
|
||||
+ e = ldap_next_entry(sp->ldap, e);
|
||||
+ if (!e) {
|
||||
+ debug(ap->logopt, MODPREFIX
|
||||
+ "failed to get next entry for query %s",
|
||||
+ sp->query);
|
||||
+ ret = ldap_parse_result(sp->ldap,
|
||||
+ sp->result, &rv,
|
||||
+ NULL, NULL, NULL, NULL, 0);
|
||||
+ if (ret == LDAP_SUCCESS)
|
||||
+ return rv;
|
||||
+ else
|
||||
+ return LDAP_OPERATIONS_ERROR;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return LDAP_SUCCESS;
|
||||
+}
|
||||
|
||||
static int read_one_map(struct autofs_point *ap,
|
||||
struct map_source *source,
|
||||
@@ -2419,9 +2718,14 @@ static int read_one_map(struct autofs_point *ap,
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
+ if (ctxt->format & MAP_FLAG_FORMAT_AMD)
|
||||
+ sp.base = ctxt->base;
|
||||
+ else
|
||||
+ sp.base = ctxt->qdn;
|
||||
+
|
||||
/* Look around. */
|
||||
debug(ap->logopt,
|
||||
- MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, ctxt->qdn);
|
||||
+ MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, sp.base);
|
||||
|
||||
sp.cookie = NULL;
|
||||
sp.pageSize = 2000;
|
||||
@@ -2465,7 +2769,10 @@ static int read_one_map(struct autofs_point *ap,
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
- rv = do_get_entries(&sp, source, ctxt);
|
||||
+ if (source->flags & MAP_FLAG_FORMAT_AMD)
|
||||
+ rv = do_get_amd_entries(&sp, source, ctxt);
|
||||
+ else
|
||||
+ rv = do_get_entries(&sp, source, ctxt);
|
||||
if (rv != LDAP_SUCCESS) {
|
||||
ldap_msgfree(sp.result);
|
||||
unbind_ldap_connection(ap->logopt, sp.ldap, ctxt);
|
||||
@@ -2874,6 +3181,219 @@ next:
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static int lookup_one_amd(struct autofs_point *ap,
|
||||
+ struct map_source *source,
|
||||
+ char *qKey, int qKey_len,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ struct mapent_cache *mc = source->mc;
|
||||
+ LDAP *ldap;
|
||||
+ LDAPMessage *result = NULL, *e;
|
||||
+ char *query;
|
||||
+ int scope = LDAP_SCOPE_SUBTREE;
|
||||
+ char *map, *class, *entry, *value;
|
||||
+ char *attrs[3];
|
||||
+ struct berval **bvKey;
|
||||
+ struct berval **bvValues;
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ time_t age = time(NULL);
|
||||
+ int rv, l, ql, count;
|
||||
+ int ret = CHE_MISSING;
|
||||
+
|
||||
+ if (ctxt == NULL) {
|
||||
+ crit(ap->logopt, MODPREFIX "context was NULL");
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /* Initialize the LDAP context. */
|
||||
+ ldap = do_reconnect(ap->logopt, ctxt);
|
||||
+ if (!ldap)
|
||||
+ return CHE_UNAVAIL;
|
||||
+
|
||||
+ map = ctxt->schema->map_attr;
|
||||
+ class = ctxt->schema->entry_class;
|
||||
+ entry = ctxt->schema->entry_attr;
|
||||
+ value = ctxt->schema->value_attr;
|
||||
+
|
||||
+ attrs[0] = entry;
|
||||
+ attrs[1] = value;
|
||||
+ attrs[2] = NULL;
|
||||
+
|
||||
+ /* Build a query string. */
|
||||
+ l = strlen(class) +
|
||||
+ strlen(map) + strlen(ctxt->mapname) +
|
||||
+ strlen(entry) + strlen(qKey) + 24;
|
||||
+
|
||||
+ query = malloc(l);
|
||||
+ if (query == NULL) {
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
+ crit(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Look for an entry in class under ctxt-base
|
||||
+ * whose entry is equal to qKey.
|
||||
+ */
|
||||
+ ql = sprintf(query, "(&(objectclass=%s)(%s=%s)(%s=%s))",
|
||||
+ class, map, ctxt->mapname, entry, qKey);
|
||||
+ if (ql >= l) {
|
||||
+ error(ap->logopt,
|
||||
+ MODPREFIX "error forming query string");
|
||||
+ free(query);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->base);
|
||||
+
|
||||
+ rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result);
|
||||
+ if ((rv != LDAP_SUCCESS) || !result) {
|
||||
+ crit(ap->logopt, MODPREFIX "query failed for %s", query);
|
||||
+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
|
||||
+ if (result)
|
||||
+ ldap_msgfree(result);
|
||||
+ free(query);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "getting first entry for %s=\"%s\"", entry, qKey);
|
||||
+
|
||||
+ e = ldap_first_entry(ldap, result);
|
||||
+ if (!e) {
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "got answer, but no entry for %s", query);
|
||||
+ ldap_msgfree(result);
|
||||
+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
|
||||
+ free(query);
|
||||
+ return CHE_MISSING;
|
||||
+ }
|
||||
+
|
||||
+ while (e) {
|
||||
+ char *k_val, *v_val;
|
||||
+ ber_len_t k_len;
|
||||
+ char *s_key;
|
||||
+
|
||||
+ bvKey = ldap_get_values_len(ldap, e, entry);
|
||||
+ if (!bvKey || !*bvKey) {
|
||||
+ e = ldap_next_entry(ldap, e);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /* By definition keys should be unique within each map entry */
|
||||
+ k_val = NULL;
|
||||
+ k_len = 0;
|
||||
+
|
||||
+ count = ldap_count_values_len(bvKey);
|
||||
+ if (count > 1)
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "more than one %s, using first", entry);
|
||||
+
|
||||
+ k_val = bvKey[0]->bv_val;
|
||||
+ k_len = bvKey[0]->bv_len;
|
||||
+
|
||||
+ debug(ap->logopt, MODPREFIX "examining first entry");
|
||||
+
|
||||
+ bvValues = ldap_get_values_len(ldap, e, value);
|
||||
+ if (!bvValues || !*bvValues) {
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "no %s defined for %s", value, query);
|
||||
+ goto next;
|
||||
+ }
|
||||
+
|
||||
+ count = ldap_count_values_len(bvValues);
|
||||
+ if (count > 1)
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "more than one %s, using first", value);
|
||||
+
|
||||
+ /* There should be one value for a key, use first value */
|
||||
+ v_val = bvValues[0]->bv_val;
|
||||
+
|
||||
+ /* Don't fail on "/" in key => type == 0 */
|
||||
+ s_key = sanitize_path(k_val, k_len, 0, ap->logopt);
|
||||
+ if (!s_key)
|
||||
+ goto next;
|
||||
+
|
||||
+ cache_writelock(mc);
|
||||
+ ret = cache_update(mc, source, s_key, v_val, age);
|
||||
+ cache_unlock(mc);
|
||||
+
|
||||
+ free(s_key);
|
||||
+next:
|
||||
+ ldap_value_free_len(bvValues);
|
||||
+ ldap_value_free_len(bvKey);
|
||||
+ e = ldap_next_entry(ldap, e);
|
||||
+ }
|
||||
+
|
||||
+ ldap_msgfree(result);
|
||||
+ unbind_ldap_connection(ap->logopt, ldap, ctxt);
|
||||
+ free(query);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static int match_key(struct autofs_point *ap,
|
||||
+ struct map_source *source,
|
||||
+ char *key, int key_len,
|
||||
+ struct lookup_context *ctxt)
|
||||
+{
|
||||
+ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ char *lkp_key;
|
||||
+ char *prefix;
|
||||
+ int ret;
|
||||
+
|
||||
+ if (is_amd_format)
|
||||
+ ret = lookup_one_amd(ap, source, key, key_len, ctxt);
|
||||
+ else
|
||||
+ ret = lookup_one(ap, source, key, key_len, ctxt);
|
||||
+
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ return ret;
|
||||
+
|
||||
+ if (!is_amd_format)
|
||||
+ return CHE_FAIL;
|
||||
+
|
||||
+ lkp_key = strdup(key);
|
||||
+ if (!lkp_key) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "strdup: %s", estr);
|
||||
+ return CHE_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ ret = CHE_MISSING;
|
||||
+
|
||||
+ /*
|
||||
+ * Now strip successive directory components and try a
|
||||
+ * match against map entries ending with a wildcard and
|
||||
+ * finally try the wilcard entry itself.
|
||||
+ */
|
||||
+ while ((prefix = strrchr(lkp_key, '/'))) {
|
||||
+ char *match;
|
||||
+ size_t len;
|
||||
+ *prefix = '\0';
|
||||
+ len = strlen(lkp_key + 3);
|
||||
+ match = malloc(len);
|
||||
+ if (!match) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
+ ret = CHE_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+ len--;
|
||||
+ strcpy(match, lkp_key);
|
||||
+ strcat(match, "/*");
|
||||
+ ret = lookup_one_amd(ap, source, match, len, ctxt);
|
||||
+ free(match);
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ goto done;
|
||||
+ }
|
||||
+done:
|
||||
+ free(lkp_key);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int check_map_indirect(struct autofs_point *ap,
|
||||
struct map_source *source,
|
||||
char *key, int key_len,
|
||||
@@ -2888,16 +3408,43 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
mc = source->mc;
|
||||
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
||||
- ret = lookup_one(ap, source, key, key_len, ctxt);
|
||||
+
|
||||
+ pthread_mutex_lock(&ap->entry->current_mutex);
|
||||
+ if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
||||
+ unsigned long timestamp = get_amd_timestamp(ctxt);
|
||||
+ if (timestamp > ctxt->timestamp) {
|
||||
+ ctxt->timestamp = timestamp;
|
||||
+ source->stale = 1;
|
||||
+ ctxt->check_defaults = 1;
|
||||
+ }
|
||||
+
|
||||
+ if (ctxt->check_defaults) {
|
||||
+ /* Check for a /defaults entry */
|
||||
+ ret = lookup_one_amd(ap, source, "/defaults", 9, ctxt);
|
||||
+ if (ret == CHE_FAIL) {
|
||||
+ warn(ap->logopt, MODPREFIX
|
||||
+ "error getting /defaults from map %s",
|
||||
+ ctxt->mapname);
|
||||
+ } else
|
||||
+ ctxt->check_defaults = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ pthread_mutex_unlock(&ap->entry->current_mutex);
|
||||
+
|
||||
+ ret = match_key(ap, source, key, key_len, ctxt);
|
||||
if (ret == CHE_FAIL) {
|
||||
pthread_setcancelstate(cur_state, NULL);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
} else if (ret == CHE_UNAVAIL) {
|
||||
+ struct mapent *exists;
|
||||
/*
|
||||
* If the server is down and the entry exists in the cache
|
||||
* and belongs to this map return success and use the entry.
|
||||
*/
|
||||
- struct mapent *exists = cache_lookup(mc, key);
|
||||
+ if (source->flags & MAP_FLAG_FORMAT_AMD)
|
||||
+ exists = match_cached_key(ap, MODPREFIX, source, key);
|
||||
+ else
|
||||
+ exists = cache_lookup(mc, key);
|
||||
if (exists && exists->source == source) {
|
||||
pthread_setcancelstate(cur_state, NULL);
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@@ -2910,24 +3457,28 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
}
|
||||
pthread_setcancelstate(cur_state, NULL);
|
||||
|
||||
- /*
|
||||
- * Check for map change and update as needed for
|
||||
- * following cache lookup.
|
||||
- */
|
||||
- cache_readlock(mc);
|
||||
- t_last_read = ap->exp_runfreq + 1;
|
||||
- me = cache_lookup_first(mc);
|
||||
- while (me) {
|
||||
- if (me->source == source) {
|
||||
- t_last_read = now - me->age;
|
||||
- break;
|
||||
+ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ /*
|
||||
+ * Check for map change and update as needed for
|
||||
+ * following cache lookup.
|
||||
+ */
|
||||
+ cache_readlock(mc);
|
||||
+ t_last_read = ap->exp_runfreq + 1;
|
||||
+ me = cache_lookup_first(mc);
|
||||
+ while (me) {
|
||||
+ if (me->source == source) {
|
||||
+ t_last_read = now - me->age;
|
||||
+ break;
|
||||
+ }
|
||||
+ me = cache_lookup_next(mc, me);
|
||||
}
|
||||
- me = cache_lookup_next(mc, me);
|
||||
- }
|
||||
- cache_unlock(mc);
|
||||
+ cache_unlock(mc);
|
||||
|
||||
- if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
|
||||
- source->stale = 1;
|
||||
+ pthread_mutex_lock(&ap->entry->current_mutex);
|
||||
+ if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED)
|
||||
+ source->stale = 1;
|
||||
+ pthread_mutex_unlock(&ap->entry->current_mutex);
|
||||
+ }
|
||||
|
||||
cache_readlock(mc);
|
||||
me = cache_lookup_distinct(mc, "*");
|
||||
@@ -2948,8 +3499,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
struct mapent *me;
|
||||
char key[KEY_MAX_LEN + 1];
|
||||
int key_len;
|
||||
+ char *lkp_key;
|
||||
char *mapent = NULL;
|
||||
char mapent_buf[MAPENT_MAX_LEN + 1];
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
int status = 0;
|
||||
int ret = 1;
|
||||
|
||||
@@ -2961,9 +3514,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
|
||||
debug(ap->logopt, MODPREFIX "looking up %s", name);
|
||||
|
||||
- key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
|
||||
- if (key_len > KEY_MAX_LEN)
|
||||
- return NSS_STATUS_NOTFOUND;
|
||||
+ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name);
|
||||
+ if (key_len > KEY_MAX_LEN)
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ } else {
|
||||
+ key_len = expandamdent(name, NULL, NULL);
|
||||
+ if (key_len > KEY_MAX_LEN)
|
||||
+ return NSS_STATUS_NOTFOUND;
|
||||
+ expandamdent(name, key, NULL);
|
||||
+ key[key_len] = '\0';
|
||||
+ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key);
|
||||
+ }
|
||||
|
||||
/* Check if we recorded a mount fail for this key anywhere */
|
||||
me = lookup_source_mapent(ap, key, LKP_DISTINCT);
|
||||
@@ -2997,18 +3559,26 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
* we never know about it.
|
||||
*/
|
||||
if (ap->type == LKP_INDIRECT && *key != '/') {
|
||||
- char *lkp_key;
|
||||
-
|
||||
cache_readlock(mc);
|
||||
me = cache_lookup_distinct(mc, key);
|
||||
if (me && me->multi)
|
||||
lkp_key = strdup(me->multi->key);
|
||||
- else
|
||||
+ else if (!ap->pref)
|
||||
lkp_key = strdup(key);
|
||||
+ else {
|
||||
+ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1);
|
||||
+ if (lkp_key) {
|
||||
+ strcpy(lkp_key, ap->pref);
|
||||
+ strcat(lkp_key, key);
|
||||
+ }
|
||||
+ }
|
||||
cache_unlock(mc);
|
||||
|
||||
- if (!lkp_key)
|
||||
+ if (!lkp_key) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
return NSS_STATUS_UNKNOWN;
|
||||
+ }
|
||||
|
||||
status = check_map_indirect(ap, source,
|
||||
lkp_key, strlen(lkp_key), ctxt);
|
||||
@@ -3029,7 +3599,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
cache_readlock(mc);
|
||||
else
|
||||
cache_writelock(mc);
|
||||
- me = cache_lookup(mc, key);
|
||||
+
|
||||
+ if (!ap->pref)
|
||||
+ lkp_key = strdup(key);
|
||||
+ else {
|
||||
+ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1);
|
||||
+ if (lkp_key) {
|
||||
+ strcpy(lkp_key, ap->pref);
|
||||
+ strcat(lkp_key, key);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!lkp_key) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
+ cache_unlock(mc);
|
||||
+ return NSS_STATUS_UNKNOWN;
|
||||
+ }
|
||||
+
|
||||
+ me = match_cached_key(ap, MODPREFIX, source, lkp_key);
|
||||
/* Stale mapent => check for entry in alternate source or wildcard */
|
||||
if (me && !me->mapent) {
|
||||
while ((me = cache_lookup_key_next(me)))
|
||||
@@ -3055,6 +3643,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
}
|
||||
}
|
||||
cache_unlock(mc);
|
||||
+ free(lkp_key);
|
||||
|
||||
if (!mapent)
|
||||
return NSS_STATUS_TRYAGAIN;
|
@ -0,0 +1,64 @@
|
||||
autofs-5.0.9 - check for non existent negative entries in lookup_ghost()
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Map entries that have been created in the cache due to a negative lookup
|
||||
but don't exist in the map source shouldn't have directories created.
|
||||
|
||||
This can be detected by checking me->status.
|
||||
|
||||
For negative entries that are present in the map source me->status will
|
||||
have been set to 0 in lookup_prune_one_cache() and negavive entries that
|
||||
have been created in the same second as the map read will always have
|
||||
me->status > 0 and so will also be skipped by lookup_ghost().
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 16 +++++++++++++++-
|
||||
2 files changed, 16 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 8c1da44..113dfb8 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -7,6 +7,7 @@
|
||||
- amd lookup update lookup hesiod to handle amd keys
|
||||
- inadvertantly drop from initial series.
|
||||
- fix wildcard key lookup.
|
||||
+- check for non existent negative entries in lookup_ghost().
|
||||
|
||||
28/03/2014 autofs-5.0.9
|
||||
=======================
|
||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
||||
index 999be9d..b4cdcce 100644
|
||||
--- a/daemon/lookup.c
|
||||
+++ b/daemon/lookup.c
|
||||
@@ -716,6 +716,17 @@ int lookup_ghost(struct autofs_point *ap, const char *root)
|
||||
cache_readlock(mc);
|
||||
me = cache_enumerate(mc, NULL);
|
||||
while (me) {
|
||||
+ /*
|
||||
+ * Map entries that have been created in the cache
|
||||
+ * due to a negative lookup but don't exist in the
|
||||
+ * map source shouldn't have directories created.
|
||||
+ * me->status of negative entries that are present
|
||||
+ * in the map source will have me->status set to 0
|
||||
+ * in lookup_prune_one_cache().
|
||||
+ */
|
||||
+ if (me->status && !me->mapent)
|
||||
+ goto next;
|
||||
+
|
||||
if (!strcmp(me->key, "*"))
|
||||
goto next;
|
||||
|
||||
@@ -1339,7 +1350,10 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti
|
||||
|
||||
if (valid)
|
||||
cache_delete(mc, key);
|
||||
- else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
|
||||
+ else if (this->status) {
|
||||
+ cache_unlock(mc);
|
||||
+ goto next;
|
||||
+ } else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) {
|
||||
dev_t devid = ap->dev;
|
||||
status = CHE_FAIL;
|
||||
if (ap->type == LKP_DIRECT)
|
170
autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch
Normal file
170
autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch
Normal file
@ -0,0 +1,170 @@
|
||||
autofs-5.1.0-beta1 - fix wildcard key lookup
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The changes to key matching caused wildcard key lookups for autofs
|
||||
format maps to fail.
|
||||
---
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_ldap.c | 10 ++++------
|
||||
modules/lookup_nisplus.c | 11 +++++------
|
||||
modules/lookup_program.c | 4 ++--
|
||||
modules/lookup_yp.c | 6 ++----
|
||||
5 files changed, 14 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index f44f6f5..8c1da44 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -6,6 +6,7 @@
|
||||
- inadvertantly drop from initial series.
|
||||
- amd lookup update lookup hesiod to handle amd keys
|
||||
- inadvertantly drop from initial series.
|
||||
+- fix wildcard key lookup.
|
||||
|
||||
28/03/2014 autofs-5.0.9
|
||||
=======================
|
||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
||||
index 833cb86..dac346c 100644
|
||||
--- a/modules/lookup_ldap.c
|
||||
+++ b/modules/lookup_ldap.c
|
||||
@@ -3349,12 +3349,9 @@ static int match_key(struct autofs_point *ap,
|
||||
else
|
||||
ret = lookup_one(ap, source, key, key_len, ctxt);
|
||||
|
||||
- if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED || !is_amd_format)
|
||||
return ret;
|
||||
|
||||
- if (!is_amd_format)
|
||||
- return CHE_FAIL;
|
||||
-
|
||||
lkp_key = strdup(key);
|
||||
if (!lkp_key) {
|
||||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
@@ -3399,6 +3396,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
char *key, int key_len,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
|
||||
struct mapent_cache *mc;
|
||||
struct mapent *me;
|
||||
time_t now = time(NULL);
|
||||
@@ -3410,7 +3408,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state);
|
||||
|
||||
pthread_mutex_lock(&ap->entry->current_mutex);
|
||||
- if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
||||
+ if (is_amd_format) {
|
||||
unsigned long timestamp = get_amd_timestamp(ctxt);
|
||||
if (timestamp > ctxt->timestamp) {
|
||||
ctxt->timestamp = timestamp;
|
||||
@@ -3457,7 +3455,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
}
|
||||
pthread_setcancelstate(cur_state, NULL);
|
||||
|
||||
- if (!(source->flags & MAP_FLAG_FORMAT_AMD)) {
|
||||
+ if (!is_amd_format) {
|
||||
/*
|
||||
* Check for map change and update as needed for
|
||||
* following cache lookup.
|
||||
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
|
||||
index e9444c9..db1b162 100644
|
||||
--- a/modules/lookup_nisplus.c
|
||||
+++ b/modules/lookup_nisplus.c
|
||||
@@ -339,6 +339,7 @@ static int match_key(struct autofs_point *ap,
|
||||
const char *key, int key_len,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
|
||||
char buf[MAX_ERR_BUF];
|
||||
char *lkp_key;
|
||||
char *prefix;
|
||||
@@ -347,12 +348,9 @@ static int match_key(struct autofs_point *ap,
|
||||
ret = lookup_one(ap, source, key, key_len, ctxt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
- if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED || is_amd_format)
|
||||
return ret;
|
||||
|
||||
- if (!(source->flags & MAP_FLAG_FORMAT_AMD))
|
||||
- return CHE_FAIL;
|
||||
-
|
||||
lkp_key = strdup(key);
|
||||
if (!lkp_key) {
|
||||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
@@ -504,6 +502,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
char *key, int key_len,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
|
||||
struct mapent_cache *mc;
|
||||
struct mapent *me, *exists;
|
||||
time_t now = time(NULL);
|
||||
@@ -512,7 +511,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
|
||||
mc = source->mc;
|
||||
|
||||
- if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
||||
+ if (is_amd_format) {
|
||||
/* Check for a /defaults entry to update the map source */
|
||||
if (lookup_amd_defaults(ap, source, ctxt) == CHE_FAIL) {
|
||||
warn(ap->logopt, MODPREFIX
|
||||
@@ -559,7 +558,7 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
}
|
||||
me = cache_lookup_next(mc, me);
|
||||
}
|
||||
- if (source->flags & MAP_FLAG_FORMAT_AMD)
|
||||
+ if (is_amd_format)
|
||||
exists = match_cached_key(ap, MODPREFIX, source, key);
|
||||
else
|
||||
exists = cache_lookup_distinct(mc, key);
|
||||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
||||
index 08d14ff..aae0ec0 100644
|
||||
--- a/modules/lookup_program.c
|
||||
+++ b/modules/lookup_program.c
|
||||
@@ -382,7 +382,7 @@ static int match_key(struct autofs_point *ap,
|
||||
char *prefix;
|
||||
int ret;
|
||||
|
||||
- if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
||||
+ if (is_amd_format) {
|
||||
ret = lookup_amd_defaults(ap, source, ctxt);
|
||||
if (ret != NSS_STATUS_SUCCESS) {
|
||||
warn(ap->logopt,
|
||||
@@ -420,7 +420,7 @@ static int match_key(struct autofs_point *ap,
|
||||
ment = lookup_one(ap, lkp_key, lkp_len, ctxt);
|
||||
if (ment) {
|
||||
char *start = ment;
|
||||
- if (source->flags & MAP_FLAG_FORMAT_AMD) {
|
||||
+ if (is_amd_format) {
|
||||
start = ment + lkp_len;
|
||||
while (isblank(*start))
|
||||
start++;
|
||||
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
|
||||
index 146e39e..fcf470a 100644
|
||||
--- a/modules/lookup_yp.c
|
||||
+++ b/modules/lookup_yp.c
|
||||
@@ -457,6 +457,7 @@ static int match_key(struct autofs_point *ap,
|
||||
const char *key, int key_len,
|
||||
struct lookup_context *ctxt)
|
||||
{
|
||||
+ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD;
|
||||
char buf[MAX_ERR_BUF];
|
||||
char *lkp_key;
|
||||
char *prefix;
|
||||
@@ -465,12 +466,9 @@ static int match_key(struct autofs_point *ap,
|
||||
ret = lookup_one(ap, source, key, strlen(key), ctxt);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
- if (ret == CHE_OK || ret == CHE_UPDATED)
|
||||
+ if (ret == CHE_OK || ret == CHE_UPDATED || !is_amd_format)
|
||||
return ret;
|
||||
|
||||
- if (!(source->flags & MAP_FLAG_FORMAT_AMD))
|
||||
- return CHE_FAIL;
|
||||
-
|
||||
lkp_key = strdup(key);
|
||||
if (!lkp_key) {
|
||||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
18
autofs.spec
18
autofs.spec
@ -8,11 +8,15 @@
|
||||
Summary: A tool for automatically mounting and unmounting filesystems
|
||||
Name: autofs
|
||||
Version: 5.1.0
|
||||
Release: 0.beta1%{?dist}
|
||||
Release: 0.beta1.1%{?dist}
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
Group: System Environment/Daemons
|
||||
Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}-beta1.tar.gz
|
||||
Patch1: autofs-5.0.8-amd-lookup-update-lookup-ldap-to-handle-amd-keys.patch
|
||||
Patch2: autofs-5.0.8-amd-lookup-update-lookup-hesiod-to-handle-amd-keys.patch
|
||||
Patch3: autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch
|
||||
Patch4: autofs-5.0.9-check-for-non-existent-negative-entries-in-lookup_ghost.patch
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
%if %{with_systemd}
|
||||
BuildRequires: systemd-units
|
||||
@ -70,6 +74,10 @@ echo %{version}-%{release} > .version
|
||||
%define unitdir %{?_unitdir:/usr/lib/systemd/system}
|
||||
%define systemd_configure_arg --with-systemd
|
||||
%endif
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
|
||||
%build
|
||||
LDFLAGS=-Wl,-z,now
|
||||
@ -162,6 +170,14 @@ fi
|
||||
%dir /etc/auto.master.d
|
||||
|
||||
%changelog
|
||||
* Sun Apr 13 2014 Ian Kent <ikent@redhat.com> - 1:5.1.0-0.beta1.1
|
||||
- amd lookup update lookup ldap to handle amd keys
|
||||
- inadvertantly drop from initial series.
|
||||
- amd lookup update lookup hesiod to handle amd keys
|
||||
- inadvertantly drop from initial series.
|
||||
- fix wildcard key lookup.
|
||||
- check for non existent negative entries in lookup_ghost().
|
||||
|
||||
* Wed Apr 2 2014 Ian Kent <ikent@redhat.com> - 1:5.1.0-0.beta1
|
||||
- Update to autofs-5.0.1-beta1.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user