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

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