1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-28 03:25:31 +03:00

pam: optionally reset cgroup memberships for login sessions

This commit is contained in:
Lennart Poettering 2011-02-04 12:46:38 +01:00
parent 7115593375
commit b20c6be697
3 changed files with 72 additions and 27 deletions

View File

@ -222,17 +222,30 @@
separated list of cgroup controllers separated list of cgroup controllers
in which hierarchies a user/session in which hierarchies a user/session
cgroup will be created by default for cgroup will be created by default for
each user logging in. If ommited, each user logging in, in addition to
defaults to 'cpu', meaning that in the cgroup in the named 'name=systemd'
addition to creating per-user and hierarchy. If ommited, defaults to an
per-session cgroups in systemd's own empty list. This may be used to move
hierarchy, groups are created in the user sessions into their own groups in
'cpu' hierarchy, on order to ensure the 'cpu' hierarchy which ensures that
that every use and every sessions gets every logged in user gets an equal
an equal amount of CPU time, amount of CPU time regardless how many
regardless how many processes a user processes he has
or session might started.</para></listitem>
own.</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> </varlistentry>
</variablelist> </variablelist>
@ -245,7 +258,8 @@
<option>create-session=1</option>, <option>create-session=1</option>,
<option>kill-session=0</option>, <option>kill-session=0</option>,
<option>kill-user=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>
<refsect1> <refsect1>

View File

@ -918,7 +918,6 @@ static int config_parse_limit(
struct rlimit **rl = data; struct rlimit **rl = data;
unsigned long long u; unsigned long long u;
int r;
assert(filename); assert(filename);
assert(lvalue); assert(lvalue);

View File

@ -43,12 +43,11 @@ static int parse_argv(pam_handle_t *handle,
bool *kill_session, bool *kill_session,
bool *kill_user, bool *kill_user,
bool *keep_root, bool *keep_root,
char ***controllers) { char ***controllers,
char ***reset_controllers) {
unsigned i; unsigned i;
#if 0 bool reset_controller_set = false;
bool controller_set = false;
#endif
assert(argc >= 0); assert(argc >= 0);
assert(argc == 0 || argv); assert(argc == 0 || argv);
@ -106,9 +105,21 @@ static int parse_argv(pam_handle_t *handle,
*controllers = l; *controllers = l;
} }
#if 0 } else if (startswith(argv[i], "reset-controllers=")) {
controller_set = true;
#endif 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 { } else {
pam_syslog(handle, LOG_ERR, "Unknown parameter '%s'.", argv[i]); 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 (!reset_controller_set && reset_controllers) {
if (!controller_set && controllers) {
char **l; char **l;
if (!(l = strv_new("cpu", NULL))) { if (!(l = strv_new("cpu", NULL))) {
@ -125,13 +135,15 @@ static int parse_argv(pam_handle_t *handle,
return -ENOMEM; return -ENOMEM;
} }
*controllers = l; *reset_controllers = l;
} }
#endif
if (controllers) if (controllers)
strv_remove(*controllers, "name=systemd"); strv_remove(*controllers, "name=systemd");
if (reset_controllers)
strv_remove(*reset_controllers, "name=systemd");
if (kill_session && *kill_session && kill_user) if (kill_session && *kill_session && kill_user)
*kill_user = true; *kill_user = true;
@ -320,6 +332,22 @@ static int create_user_group(
return PAM_SUCCESS; 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( _public_ PAM_EXTERN int pam_sm_open_session(
pam_handle_t *handle, pam_handle_t *handle,
int flags, int flags,
@ -331,7 +359,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
char *buf = NULL; char *buf = NULL;
int lock_fd = -1; int lock_fd = -1;
bool create_session = true; bool create_session = true;
char **controllers = NULL, **c; char **controllers = NULL, **reset_controllers = NULL, **c;
assert(handle); assert(handle);
@ -341,7 +369,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
if (sd_booted() <= 0) if (sd_booted() <= 0)
return PAM_SUCCESS; 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; return PAM_SESSION_ERR;
if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) 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) STRV_FOREACH(c, controllers)
create_user_group(handle, *c, buf, pw, true, false); create_user_group(handle, *c, buf, pw, true, false);
STRV_FOREACH(c, reset_controllers)
reset_group(handle, *c);
r = PAM_SUCCESS; r = PAM_SUCCESS;
finish: finish:
@ -438,6 +469,7 @@ finish:
close_nointr_nofail(lock_fd); close_nointr_nofail(lock_fd);
strv_free(controllers); strv_free(controllers);
strv_free(reset_controllers);
return r; return r;
} }
@ -490,7 +522,7 @@ _public_ PAM_EXTERN int pam_sm_close_session(
if (sd_booted() <= 0) if (sd_booted() <= 0)
return PAM_SUCCESS; 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; return PAM_SESSION_ERR;
if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS) if ((r = get_user_data(handle, &username, &pw)) != PAM_SUCCESS)