diff options
author | Lennart Poettering <lennart@poettering.net> | 2011-02-04 12:46:38 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2011-02-04 12:46:38 +0100 |
commit | b20c6be697ded108e3c3bd5b8812fee13326eefc (patch) | |
tree | 2c8be1fc5eb7c60e1c1ece7e93368bb903229731 | |
parent | 7115593375de5c84d44df9aafb011da4a1385569 (diff) |
pam: optionally reset cgroup memberships for login sessions
-rw-r--r-- | man/pam_systemd.xml | 38 | ||||
-rw-r--r-- | src/load-fragment.c | 1 | ||||
-rw-r--r-- | src/pam-module.c | 60 |
3 files changed, 72 insertions, 27 deletions
diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index eddd8e003f..6fe6981011 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -222,17 +222,30 @@ separated list of cgroup controllers in which hierarchies a user/session cgroup will be created by default for - each user logging in. If ommited, - defaults to 'cpu', meaning that in - addition to creating per-user and - per-session cgroups in systemd's own - hierarchy, groups are created in the - 'cpu' hierarchy, on order to ensure - that every use and every sessions gets - an equal amount of CPU time, - regardless how many processes a user - or session might - own.</para></listitem> + each user logging in, in addition to + the cgroup in the named 'name=systemd' + hierarchy. If ommited, defaults to an + empty list. This may be used to move + user sessions into their own groups in + the 'cpu' hierarchy which ensures that + every logged in user gets an equal + amount of CPU time regardless how many + processes he has + started.</para></listitem> + </varlistentry> + + <varlistentry> + <term><option>reset-controllers=</option></term> + + <listitem><para>Takes a comma + separated list of cgroup controllers + in which hierarchies the logged in + processes will be reset to the root + cgroup. If ommited, defaults to 'cpu', + meaning that a 'cpu' cgroup grouping + inherited from the login manager will + be reset for the processes of the + logged in user.</para></listitem> </varlistentry> </variablelist> @@ -245,7 +258,8 @@ <option>create-session=1</option>, <option>kill-session=0</option>, <option>kill-user=0</option>, - <option>keep-root=1</option>.</para> + <option>keep-root=1</option>, + <option>reset-controllers=cpu</option>.</para> </refsect1> <refsect1> diff --git a/src/load-fragment.c b/src/load-fragment.c index fc64ddd5a0..ab2bcd2d2f 100644 --- a/src/load-fragment.c +++ b/src/load-fragment.c @@ -918,7 +918,6 @@ static int config_parse_limit( struct rlimit **rl = data; unsigned long long u; - int r; assert(filename); assert(lvalue); diff --git a/src/pam-module.c b/src/pam-module.c index fc3aac185d..117df05181 100644 --- a/src/pam-module.c +++ b/src/pam-module.c @@ -43,12 +43,11 @@ static int parse_argv(pam_handle_t *handle, bool *kill_session, bool *kill_user, bool *keep_root, - char ***controllers) { + char ***controllers, + char ***reset_controllers) { unsigned i; -#if 0 - bool controller_set = false; -#endif + bool reset_controller_set = false; assert(argc >= 0); assert(argc == 0 || argv); @@ -106,9 +105,21 @@ static int parse_argv(pam_handle_t *handle, *controllers = l; } -#if 0 - controller_set = true; -#endif + } else if (startswith(argv[i], "reset-controllers=")) { + + if (reset_controllers) { + char **l; + + if (!(l = strv_split(argv[i] + 18, ","))) { + pam_syslog(handle, LOG_ERR, "Out of memory."); + return -ENOMEM; + } + + strv_free(*reset_controllers); + *reset_controllers = l; + } + + reset_controller_set = true; } else { pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]); @@ -116,8 +127,7 @@ static int parse_argv(pam_handle_t *handle, } } -#if 0 - if (!controller_set && controllers) { + if (!reset_controller_set && reset_controllers) { char **l; if (!(l = strv_new("cpu", NULL))) { @@ -125,13 +135,15 @@ static int parse_argv(pam_handle_t *handle, return -ENOMEM; } - *controllers = l; + *reset_controllers = l; } -#endif if (controllers) strv_remove(*controllers, "name=systemd"); + if (reset_controllers) + strv_remove(*reset_controllers, "name=systemd"); + if (kill_session && *kill_session && kill_user) *kill_user = true; @@ -320,6 +332,22 @@ static int create_user_group( return PAM_SUCCESS; } +static int reset_group( + pam_handle_t *handle, + const char *controller) { + + int r; + + assert(handle); + + if ((r = cg_attach(controller, "/", 0)) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to reset cgroup for controller %s: %s", controller, strerror(-r)); + return PAM_SESSION_ERR; + } + + return PAM_SUCCESS; +} + _public_ PAM_EXTERN int pam_sm_open_session( pam_handle_t *handle, int flags, @@ -331,7 +359,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( char *buf = NULL; int lock_fd = -1; bool create_session = true; - char **controllers = NULL, **c; + char **controllers = NULL, **reset_controllers = NULL, **c; assert(handle); @@ -341,7 +369,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (sd_booted() <= 0) return PAM_SUCCESS; - if (parse_argv(handle, argc, argv, &create_session, NULL, NULL, NULL, &controllers) < 0) + if (parse_argv(handle, argc, argv, &create_session, NULL, NULL, NULL, &controllers, &reset_controllers) < 0) return PAM_SESSION_ERR; if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) @@ -429,6 +457,9 @@ _public_ PAM_EXTERN int pam_sm_open_session( STRV_FOREACH(c, controllers) create_user_group(handle, *c, buf, pw, true, false); + STRV_FOREACH(c, reset_controllers) + reset_group(handle, *c); + r = PAM_SUCCESS; finish: @@ -438,6 +469,7 @@ finish: close_nointr_nofail(lock_fd); strv_free(controllers); + strv_free(reset_controllers); return r; } @@ -490,7 +522,7 @@ _public_ PAM_EXTERN int pam_sm_close_session( if (sd_booted() <= 0) return PAM_SUCCESS; - if (parse_argv(handle, argc, argv, NULL, &kill_session, &kill_user, &keep_root, &controllers) < 0) + if (parse_argv(handle, argc, argv, NULL, &kill_session, &kill_user, &keep_root, &controllers, NULL) < 0) return PAM_SESSION_ERR; if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) |