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

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