autofs-5.0.3 - multi-map doesn't pickup NIS updates automatically

From: Ian Kent <raven@themaw.net>

In a multi-map configuration, autofs doesn't pick up NIS updates
automatically. This is caused by the lookup not checking alternate
sources for the given key (or wildcard) when doing a key lookup.
---

 CHANGELOG                |    1 +
 lib/cache.c              |    2 ++
 modules/lookup_file.c    |   11 ++++++++---
 modules/lookup_ldap.c    |   11 ++++++++---
 modules/lookup_nisplus.c |   11 ++++++++---
 modules/lookup_yp.c      |   11 ++++++++---
 6 files changed, 35 insertions(+), 12 deletions(-)


diff --git a/CHANGELOG b/CHANGELOG
index 268fca6..3ed84d3 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,7 @@
 - fix incorrect pthreads condition handling for mount requests.
 - add check for exports automatically mounted by NFS kernel client.
 - update nsswitch parser to ignore nsswitch sources that aren't supported.
+- check for map key in (possible) alternate map sources when doing lookup.
  
 14/01/2008 autofs-5.0.3
 -----------------------
diff --git a/lib/cache.c b/lib/cache.c
index 55586a3..d5abab0 100644
--- a/lib/cache.c
+++ b/lib/cache.c
@@ -700,6 +700,8 @@ int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key
 	int ret = CHE_OK;
 
 	me = cache_lookup(mc, key);
+	while (me && me->source != ms)
+		me = cache_lookup_key_next(me);
 	if (!me || (*me->key == '*' && *key != '*')) {
 		ret = cache_add(mc, ms, key, mapent, age);
 		if (!ret) {
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 466690a..894f6fd 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -1116,9 +1116,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		pthread_cleanup_push(cache_lock_cleanup, mc);
 		mapent_len = strlen(me->mapent);
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
index ded26f7..5cc2148 100644
--- a/modules/lookup_ldap.c
+++ b/modules/lookup_ldap.c
@@ -2596,9 +2596,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c
index 628ffcf..3c19fd3 100644
--- a/modules/lookup_nisplus.c
+++ b/modules/lookup_nisplus.c
@@ -530,9 +530,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c
index 0fc84f8..14f981c 100644
--- a/modules/lookup_yp.c
+++ b/modules/lookup_yp.c
@@ -636,9 +636,14 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
 
 	cache_readlock(mc);
 	me = cache_lookup(mc, key);
-	/* Stale mapent => check for wildcard */
-	if (me && !me->mapent)
-		me = cache_lookup_distinct(mc, "*");
+	/* Stale mapent => check for entry in alternate source or wildcard */
+	if (me && !me->mapent) {
+		while ((me = cache_lookup_key_next(me)))
+			if (me->source == source)
+				break;
+		if (!me)
+			me = cache_lookup_distinct(mc, "*");
+	}
 	if (me && (me->source == source || *me->key == '/')) {
 		mapent_len = strlen(me->mapent);
 		mapent = alloca(mapent_len + 1);
