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

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