Blame SOURCES/autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch

306fa1
autofs-5.1.4 - fix update_negative_cache() map source usage
306fa1
306fa1
From: Ian Kent <raven@themaw.net>
306fa1
306fa1
File map sources can be either plain text or executable.
306fa1
306fa1
When the map path is specified without a type (eg. when a
306fa1
full path is used) an instance map source is used and the
306fa1
original map is left unchanged.
306fa1
306fa1
But update_negative_cache() fails to take this into account
306fa1
causing it to update the wrong map cache.
306fa1
306fa1
When a map reload is done the map entry appears to not exist
306fa1
so the new map entry is added.
306fa1
306fa1
This could go unnoticed except that, after a map read, the
306fa1
map entry cache cleans stale map entries and the existence
306fa1
of this negative entry causes the new map entry to be deleted
306fa1
and map lookups continue to fail.
306fa1
306fa1
In hindsite the use of an instance map source for this is
306fa1
probably uneccessary but changing it will be risky so, for
306fa1
now, just make update_negative_cache() use the correct map.
306fa1
306fa1
Signed-off-by: Ian Kent <raven@themaw.net>
306fa1
---
306fa1
 CHANGELOG       |    1 +
306fa1
 daemon/lookup.c |   38 ++++++++++++++++++++++++++++++++++++--
306fa1
 2 files changed, 37 insertions(+), 2 deletions(-)
306fa1
306fa1
--- autofs-5.0.7.orig/CHANGELOG
306fa1
+++ autofs-5.0.7/CHANGELOG
306fa1
@@ -301,6 +301,7 @@
306fa1
 - add man page note about extra slashes in paths.
306fa1
 - add units After line to include statd service.
306fa1
 - use systemd sd_notify() at startup.
306fa1
+- fix update_negative_cache() map source usage.
306fa1
 
306fa1
 25/07/2012 autofs-5.0.7
306fa1
 =======================
306fa1
--- autofs-5.0.7.orig/daemon/lookup.c
306fa1
+++ autofs-5.0.7/daemon/lookup.c
306fa1
@@ -1097,6 +1097,37 @@ static enum nsswitch_status lookup_map_n
306fa1
 	return result;
306fa1
 }
306fa1
 
306fa1
+static struct map_source *lookup_get_map_source(struct master_mapent *entry)
306fa1
+{
306fa1
+	struct map_source *map = entry->maps;
306fa1
+	struct stat st;
306fa1
+	char *type;
306fa1
+
306fa1
+	if (map->type || *map->argv[0] != '/')
306fa1
+		return map;
306fa1
+
306fa1
+	if (*(map->argv[0] + 1) == '/')
306fa1
+		return map;
306fa1
+
306fa1
+	if (stat(map->argv[0], &st) == -1)
306fa1
+		return NULL;
306fa1
+
306fa1
+	if (!S_ISREG(st.st_mode))
306fa1
+		return NULL;
306fa1
+
306fa1
+	if (st.st_mode & __S_IEXEC)
306fa1
+		type = "program";
306fa1
+	else
306fa1
+		type = "file";
306fa1
+
306fa1
+	/* This is a file source with a path starting with "/".
306fa1
+	 * But file maps can be either plain text or executable
306fa1
+	 * so they use a map instance and the actual map source
306fa1
+	 * remains untouched.
306fa1
+	 */
306fa1
+	return master_find_source_instance(map, type, map->format, 0, NULL);
306fa1
+}
306fa1
+
306fa1
 static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
306fa1
 {
306fa1
 	struct master_mapent *entry = ap->entry;
306fa1
@@ -1130,11 +1161,14 @@ static void update_negative_cache(struct
306fa1
 			logmsg("key \"%s\" not found in map source(s).", name);
306fa1
 		}
306fa1
 
306fa1
-		/* Doesn't exist in any source, just add it somewhere */
306fa1
+		/* Doesn't exist in any source, just add it somewhere.
306fa1
+		 * Also take care to use the same map source used by
306fa1
+		 * map reads and key lookups for the update.
306fa1
+		 */
306fa1
 		if (source)
306fa1
 			map = source;
306fa1
 		else
306fa1
-			map = entry->maps;
306fa1
+			map = lookup_get_map_source(entry);
306fa1
 		if (map) {
306fa1
 			time_t now = time(NULL);
306fa1
 			int rv = CHE_FAIL;