autofs-5.0.9 - add config option to force use of program map stdvars From: Ian Kent 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. --- CHANGELOG | 1 + include/defaults.h | 2 ++ lib/defaults.c | 13 +++++++++++++ man/auto.master.5.in | 8 ++++++++ man/autofs.5 | 5 +++++ modules/lookup_program.c | 14 +++++++++++++- redhat/autofs.sysconfig.in | 11 +++++++++++ samples/autofs.conf.default.in | 11 +++++++++++ 8 files changed, 64 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index a382b5e..1b55a14 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -24,6 +24,7 @@ - ensure negative cache isn't updated on remount. - dont add wildcard to negative cache. - add a prefix to program map stdvars. +- add config option to force use of program map stdvars. 28/03/2014 autofs-5.0.9 ======================= diff --git a/include/defaults.h b/include/defaults.h index 1181d25..fe57914 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -29,6 +29,7 @@ #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 @@ -64,6 +65,7 @@ int defaults_get_master_wait(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); diff --git a/lib/defaults.c b/lib/defaults.c index 41945f5..a678fc7 100644 --- a/lib/defaults.c +++ b/lib/defaults.c @@ -36,6 +36,7 @@ #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" @@ -521,6 +522,7 @@ unsigned int defaults_read_config(unsigned int 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) || @@ -642,6 +644,17 @@ unsigned int defaults_get_logging(void) 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; diff --git a/man/auto.master.5.in b/man/auto.master.5.in index 08ea1dc..bbf6a74 100644 --- a/man/auto.master.5.in +++ b/man/auto.master.5.in @@ -258,6 +258,14 @@ 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 diff --git a/man/autofs.5 b/man/autofs.5 index 46f3eb4..f8f0b8f 100644 --- a/man/autofs.5 +++ b/man/autofs.5 @@ -189,6 +189,11 @@ 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 diff --git a/modules/lookup_program.c b/modules/lookup_program.c index 865b881..d1f0ef7 100644 --- a/modules/lookup_program.c +++ b/modules/lookup_program.c @@ -132,6 +132,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * int ret = 1; int distance; int alloci = 1; + char *prefix; source = ap->entry->current; ap->entry->current = NULL; @@ -267,6 +268,17 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * 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. @@ -274,7 +286,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * 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); diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in index 1902ade..0154632 100644 --- a/redhat/autofs.sysconfig.in +++ b/redhat/autofs.sysconfig.in @@ -58,6 +58,17 @@ MOUNT_NFS_DEFAULT_PROTOCOL=4 # #LOGGING="none" # +# FORCE_STANDARD_PROGRAM_MAP_ENV - disable the use of the "AUTOFS_" +# prefix for standard environemt 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. # # Define server URIs diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in index 5fa030a..71ce6b1 100644 --- a/samples/autofs.conf.default.in +++ b/samples/autofs.conf.default.in @@ -57,6 +57,17 @@ BROWSE_MODE="no" # #LOGGING="none" # +# FORCE_STANDARD_PROGRAM_MAP_ENV - disable the use of the "AUTOFS_" +# prefix for standard environemt 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 server URIs # # LDAP_URI - space seperated list of server uris of the form