diff --git a/man/NetworkManager-dispatcher.xml b/man/NetworkManager-dispatcher.xml
index f6e1d22d76..e0c9b572d7 100644
--- a/man/NetworkManager-dispatcher.xml
+++ b/man/NetworkManager-dispatcher.xml
@@ -308,6 +308,33 @@
In case of VPN, VPN_IP_IFACE is set, and IP4_*, IP6_* variables with VPN prefix are
exported too, like VPN_IP4_ADDRESS_0, VPN_IP4_NUM_ADDRESSES.
+
+ The content of the user setting for the connection
+ being activated is also passed via environment variables. Each key is
+ stored in a variable with name CONNECTION_USER_
+ concatenated with the encoding of the key name. The encoding works as
+ follows:
+
+
+ lowercase letters become uppercase
+
+
+ uppercase letters are prefixed with an underscore
+
+
+ numbers do not change
+
+
+ a dot is replaced with a double underscore
+
+
+ any other character is encoded with an underscore followed by
+ its 3-digit octal representation
+
+
+ For example, key test.foo-Bar2 is stored in a variable named
+ CONNECTION_USER_TEST__FOO_055_BAR2.
+
Dispatcher scripts are run one at a time, but asynchronously from the main
NetworkManager process, and will be killed if they run for too long. If your script
diff --git a/src/nm-dispatcher/nm-dispatcher-utils.c b/src/nm-dispatcher/nm-dispatcher-utils.c
index f8a4c28000..6659936f48 100644
--- a/src/nm-dispatcher/nm-dispatcher-utils.c
+++ b/src/nm-dispatcher/nm-dispatcher-utils.c
@@ -540,6 +540,36 @@ nm_dispatcher_utils_construct_envp(const char *action,
_items_add_key0(items, NULL, "DEVICE_IP_IFACE", ip_iface);
}
+ {
+ gs_unref_variant GVariant *user_setting = NULL;
+
+ user_setting = g_variant_lookup_value(connection_dict,
+ NM_SETTING_USER_SETTING_NAME,
+ NM_VARIANT_TYPE_SETTING);
+ if (user_setting) {
+ gs_unref_variant GVariant *data = NULL;
+ nm_auto_free_gstring GString *string = NULL;
+ GVariantIter iter;
+ const char *key;
+ const char *val;
+
+ data =
+ g_variant_lookup_value(user_setting, NM_SETTING_USER_DATA, G_VARIANT_TYPE("a{ss}"));
+ if (data) {
+ g_variant_iter_init(&iter, data);
+ while (g_variant_iter_next(&iter, "{&s&s}", &key, &val)) {
+ if (key) {
+ if (!string)
+ string = g_string_sized_new(64);
+ g_string_assign(string, "CONNECTION_USER_");
+ nm_utils_env_var_encode_name(key, string);
+ _items_add_key0(items, NULL, string->str, val);
+ }
+ }
+ }
+ }
+ }
+
/* Device items aren't valid if the device isn't activated */
if (iface && dev_state == NM_DEVICE_STATE_ACTIVATED) {
construct_proxy_items(items, device_proxy_props, NULL);