Description:  add config option to force use of program map stdvars
 Enabling the extended environment (including $HOME, for example) for
 program maps opens automount(8) to a privilege escalation.
 .
 Rather than just removing the entended environment a configuration
 option is added to disable it by default so that those who wish to
 use it can do so if they wish.
Origin: vendor
Author: Ian Kent <ikent@redhat.com>
Author: Salvatore Bonaccorso <carnil@debian.org>
Last-Update: 2015-02-28
---
--- a/include/defaults.h
+++ b/include/defaults.h
@@ -27,8 +27,9 @@
 #define DEFAULT_MOUNT_WAIT		-1
 #define DEFAULT_UMOUNT_WAIT		12
 #define DEFAULT_BROWSE_MODE		1
 #define DEFAULT_LOGGING			0
+#define DEFAULT_FORCE_STD_PROG_MAP_ENV  0
 
 #define DEFAULT_LDAP_TIMEOUT		-1
 #define DEFAULT_LDAP_NETWORK_TIMEOUT	8
 
@@ -61,8 +62,9 @@
 unsigned int defaults_get_timeout(void);
 unsigned int defaults_get_negative_timeout(void);
 unsigned int defaults_get_browse_mode(void);
 unsigned int defaults_get_logging(void);
+unsigned int defaults_force_std_prog_map_env(void);
 const char *defaults_get_ldap_server(void);
 unsigned int defaults_get_ldap_timeout(void);
 unsigned int defaults_get_ldap_network_timeout(void);
 unsigned int defaults_get_mount_nfs_default_proto(void);
--- a/lib/defaults.c
+++ b/lib/defaults.c
@@ -34,8 +34,9 @@
 #define ENV_NAME_TIMEOUT		"TIMEOUT"
 #define ENV_NAME_NEGATIVE_TIMEOUT	"NEGATIVE_TIMEOUT"
 #define ENV_NAME_BROWSE_MODE		"BROWSE_MODE"
 #define ENV_NAME_LOGGING		"LOGGING"
+#define ENV_NAME_FORCE_STD_PROG_MAP_ENV "FORCE_STANDARD_PROGRAM_MAP_ENV"
 
 #define LDAP_URI			"LDAP_URI"
 #define ENV_LDAP_TIMEOUT		"LDAP_TIMEOUT"
 #define ENV_LDAP_NETWORK_TIMEOUT	"LDAP_NETWORK_TIMEOUT"
@@ -518,8 +519,9 @@
 		    check_set_config_value(key, ENV_NAME_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) ||
+		    check_set_config_value(key, ENV_NAME_FORCE_STD_PROG_MAP_ENV, value, to_syslog) ||
 		    check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) ||
 		    check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value, to_syslog) ||
@@ -628,8 +630,19 @@
 
 	return logging;
 }
 
+unsigned int defaults_force_std_prog_map_env(void)
+{
+	int res;
+
+	res = get_env_yesno(ENV_NAME_FORCE_STD_PROG_MAP_ENV);
+	if (res < 0)
+		res = DEFAULT_FORCE_STD_PROG_MAP_ENV;
+
+	return res;
+}
+
 unsigned int defaults_get_ldap_timeout(void)
 {
 	int res;
 
--- a/man/autofs.5
+++ b/man/autofs.5
@@ -173,8 +173,13 @@
 SHOST	Short hostname (domain part removed if present)
 .fi
 .RE
 .sp
+If a program map is used these standard environment variables will have
+a prefix of "AUTOFS_" to prevent interpreted languages like python from
+being able to load and execute arbitray code from a user home directory.
+.RE
+.sp
 Additional entries can be defined with the -Dvariable=Value map-option to
 .BR automount (8).
 .SS Executable Maps
 A map can be marked as executable. A
--- a/modules/lookup_program.c
+++ b/modules/lookup_program.c
@@ -131,8 +131,9 @@
 	int quoted = 0;
 	int ret = 1;
 	int distance;
 	int alloci = 1;
+	char *prefix;
 
 	source = ap->entry->current;
 	ap->entry->current = NULL;
 	master_source_current_signal(ap->entry);
@@ -264,16 +265,27 @@
 		if (chdir(ap->path))
 			warn(ap->logopt,
 			     MODPREFIX "failed to set PWD to %s for map %s",
 			     ap->path, ctxt->mapname);
+
+		/*
+		 * By default use a prefix with standard environment
+		 * variables to prevent system subversion by interpreted
+		 * languages.
+		 */
+		if (defaults_force_std_prog_map_env())
+			prefix = NULL;
+		else
+			prefix = "AUTOFS_";
+
 		/*
 		 * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup
 		 * the macro table.
 		 */
 		if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) {
 			struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context;
 			/* Add standard environment as seen by sun map parser */
-			pctxt->subst = addstdenv(pctxt->subst, "AUTOFS_");
+			pctxt->subst = addstdenv(pctxt->subst, prefix);
 			macro_setenv(pctxt->subst);
 		}
 		execl(ctxt->mapname, ctxt->mapname, name, NULL);
 		_exit(255);	/* execl() failed */
--- a/samples/autofs.conf.default.in
+++ b/samples/autofs.conf.default.in
@@ -79,8 +79,19 @@
 # LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8).
 #
 #LDAP_NETWORK_TIMEOUT=8
 #
+# FORCE_STANDARD_PROGRAM_MAP_ENV - disable the use of the "AUTOFS_"
+#			prefix for standard environment variables when
+#			executing a program map. Since program maps
+#			are run as the privileded user this opens
+#			automount(8) to potential user privilege
+#			escalation when the program map is written
+#			in a language that  can load components from,
+#			for example, a user home directory.
+#
+#FORCE_STANDARD_PROGRAM_MAP_ENV="no"
+#
 # Define base dn for map dn lookup.
 #
 # SEARCH_BASE - base dn to use for searching for map search dn.
 # 		Multiple entries can be given and they are checked
--- a/man/auto.master.5.in
+++ b/man/auto.master.5.in
@@ -249,8 +249,16 @@
 options replace the global options (program default "yes", append options).
 .TP
 .B LOGGING
 set default log level "none", "verbose" or "debug" (program default "none").
+.TP
+.B FORCE_STANDARD_PROGRAM_MAP_ENV
+override the use of a prefix with standard environment variables when a
+program map is executed. Since program maps are run as the privileded
+user setting these standard environment variables opens automount(8) to
+potential user privilege escalation when the program map is written in a
+language that can load components from, for example, a user home directory
+(program default "no").
 .SH BUILTIN MAP -hosts
 If "-hosts" is given as the map then accessing a key under the mount point
 which corresponds to a hostname will allow access to the exports of that
 host. The hosts map cannot be dynamically updated and requires a HUP signal
