diff options
author | Lennart Poettering <lennart@poettering.net> | 2016-04-21 12:29:36 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2016-04-21 12:29:36 +0200 |
commit | 52b9b66b7d7045a0b0a25150dc8ee0c7b815e414 (patch) | |
tree | 699d1bfe78dfb009624ba9e783e3b562609380fa | |
parent | 48062f072c7ba679667a309a76f71d595f0287e7 (diff) | |
parent | 42fbdf45864b46f3eb62a3738b81e687685eb9bd (diff) |
Merge pull request #3005 from keszybz/kill-user-proceses
Kill user session scope by default
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | NEWS | 31 | ||||
-rw-r--r-- | configure.ac | 215 | ||||
-rw-r--r-- | man/loginctl.xml | 36 | ||||
-rw-r--r-- | man/logind.conf.xml | 50 | ||||
-rw-r--r-- | man/systemd-run.xml | 93 | ||||
-rw-r--r-- | src/core/selinux-access.c | 5 | ||||
-rw-r--r-- | src/login/.gitignore | 1 | ||||
-rw-r--r-- | src/login/loginctl.c | 14 | ||||
-rw-r--r-- | src/login/logind-core.c | 8 | ||||
-rw-r--r-- | src/login/logind-dbus.c | 8 | ||||
-rw-r--r-- | src/login/logind.c | 82 | ||||
-rw-r--r-- | src/login/logind.conf.in (renamed from src/login/logind.conf) | 2 | ||||
-rw-r--r-- | src/login/org.freedesktop.login1.policy.in | 8 | ||||
-rw-r--r-- | src/shared/logs-show.c | 2 |
15 files changed, 375 insertions, 186 deletions
diff --git a/Makefile.am b/Makefile.am index 198265f48d..f2ef83b0c7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -5720,7 +5720,7 @@ dist_dbussystemservice_DATA += \ dist_dbuspolicy_DATA += \ src/login/org.freedesktop.login1.conf -dist_pkgsysconf_DATA += \ +nodist_pkgsysconf_DATA += \ src/login/logind.conf polkitpolicy_files += \ @@ -5757,7 +5757,8 @@ gperf_gperf_sources += \ EXTRA_DIST += \ src/login/71-seat.rules.in \ src/login/73-seat-late.rules.in \ - units/systemd-logind.service.in + units/systemd-logind.service.in \ + src/login/logind.conf.in # ------------------------------------------------------------------------------ if HAVE_PAM @@ -5874,6 +5875,7 @@ substitutions = \ '|NTP_SERVERS=$(NTP_SERVERS)|' \ '|DNS_SERVERS=$(DNS_SERVERS)|' \ '|DEFAULT_DNSSEC_MODE=$(DEFAULT_DNSSEC_MODE)|' \ + '|KILL_USER_PROCESSES=$(KILL_USER_PROCESSES)|' \ '|systemuidmax=$(SYSTEM_UID_MAX)|' \ '|systemgidmax=$(SYSTEM_GID_MAX)|' \ '|TTY_GID=$(TTY_GID)|' \ @@ -22,9 +22,30 @@ CHANGES WITH 230 in spe: * systemd-resolve conveniently resolves DANE records with the --tlsa option and OPENPGPKEY records with the --openpgp option. - * Testing tool /usr/lib/systemd/systemd-activate is renamed to - systemd-socket-activate and installed into /usr/bin. It is now fully - supported. + * systemd-logind will now by default terminate user processes that are + part of the user session scope unit (session-XX.scope) when the user + logs out. This behaviour is controlled by the + KillUserProcesses=yes|no setting in logind.conf, and previous default + of "no" is now changed to "yes". This means that user sessions will + be properly cleaned up after, but additional steps are necessary to + allow intentionally long-running processes to survive logout. + + While the user is logged in at least once, user@.service is running, + and any service that should survive the end of any individual login + session can be started at a user service or scope using systemd-run. + systemd-run(1) man page has been extended with an example which + shows how to run screen in a scope unit underneath user@.service. + The same command works for tmux. + + After the user logs out of all sessions, user@.service will be + terminated too, by default, unless the user has "lingering" enabled. + To effectively allow users to run long-term tasks even if they are + logged out, lingering must be enabled for them. See loginctl(1) for + details. The default polkit policy was modified to allow users to + set lingering for themselves without authentication. + + Previous defaults can be restored at compile time by the + --without-kill-user-processes option. * The unified cgroup hierarchy added in Linux 4.5 is now supported. Use systemd.unified_cgroup_hierarchy=1 on the kernel command line @@ -45,6 +66,10 @@ CHANGES WITH 230 in spe: * The Unique Identifier sent in DHCP requests can be configured. + * Testing tool /usr/lib/systemd/systemd-activate is renamed to + systemd-socket-activate and installed into /usr/bin. It is now fully + supported. + * systemd-journald now uses separate threads to flush changes to disk when closing journal files. diff --git a/configure.ac b/configure.ac index 7b9e64a0f6..d4e8ab6664 100644 --- a/configure.ac +++ b/configure.ac @@ -1014,6 +1014,16 @@ fi AM_CONDITIONAL(ENABLE_LOGIND, [test "$have_logind" = "yes"]) AS_IF([test "$have_logind" = "yes"], [ AC_DEFINE(HAVE_LOGIND, [1], [Logind support available]) ]) +AC_ARG_WITH([kill-user-processes], + [AS_HELP_STRING([--without-kill-user-processes], [Set logind's KillUserProcesses=no by default])]) +AS_IF([test "$with_kill_user_processes" != "no"], + [kill_user_processes=true + KILL_USER_PROCESSES=yes], + [kill_user_processes=false + KILL_USER_PROCESSES=no]) +AC_DEFINE_UNQUOTED(KILL_USER_PROCESSES, [$kill_user_processes], [Default KillUserProcesses setting]) +AC_SUBST(KILL_USER_PROCESSES) + # ------------------------------------------------------------------------------ have_machined=no AC_ARG_ENABLE(machined, AS_HELP_STRING([--disable-machined], [disable machine daemon])) @@ -1554,106 +1564,107 @@ AC_OUTPUT AC_MSG_RESULT([ $PACKAGE_NAME $VERSION - libcryptsetup: ${have_libcryptsetup} - PAM: ${have_pam} - AUDIT: ${have_audit} - IMA: ${have_ima} - AppArmor: ${have_apparmor} - SELinux: ${have_selinux} - SECCOMP: ${have_seccomp} - SMACK: ${have_smack} - ZLIB: ${have_zlib} - XZ: ${have_xz} - LZ4: ${have_lz4} - BZIP2: ${have_bzip2} - ACL: ${have_acl} - GCRYPT: ${have_gcrypt} - QRENCODE: ${have_qrencode} - MICROHTTPD: ${have_microhttpd} - GNUTLS: ${have_gnutls} - libcurl: ${have_libcurl} - libidn: ${have_libidn} - libiptc: ${have_libiptc} - ELFUTILS: ${have_elfutils} - binfmt: ${have_binfmt} - vconsole: ${have_vconsole} - quotacheck: ${have_quotacheck} - tmpfiles: ${have_tmpfiles} - sysusers: ${have_sysusers} - firstboot: ${have_firstboot} - randomseed: ${have_randomseed} - backlight: ${have_backlight} - rfkill: ${have_rfkill} - logind: ${have_logind} - machined: ${have_machined} - importd: ${have_importd} - hostnamed: ${have_hostnamed} - timedated: ${have_timedated} - timesyncd: ${have_timesyncd} - Default NTP servers: ${NTP_SERVERS} - time epoch: ${TIME_EPOCH} - localed: ${have_localed} - networkd: ${have_networkd} - resolved: ${have_resolved} - Default DNS servers: ${DNS_SERVERS} - Default DNSSEC mode: ${DEFAULT_DNSSEC_MODE} - coredump: ${have_coredump} - polkit: ${have_polkit} - efi: ${have_efi} - gnuefi: ${have_gnuefi} - efi arch: ${EFI_ARCH} - EFI machine type: ${EFI_MACHINE_TYPE_NAME} - EFI CC ${EFI_CC} - EFI libdir: ${EFI_LIB_DIR} - EFI ldsdir: ${EFI_LDS_DIR} - EFI includedir: ${EFI_INC_DIR} - kmod: ${have_kmod} - xkbcommon: ${have_xkbcommon} - blkid: ${have_blkid} - libmount: ${have_libmount} - dbus: ${have_dbus} - nss-myhostname: ${have_myhostname} - hwdb: ${enable_hwdb} - tpm: ${have_tpm} - kdbus: ${have_kdbus} - Python: ${have_python} - man pages: ${have_manpages} - test coverage: ${have_coverage} - Split /usr: ${enable_split_usr} - SysV compatibility: ${SYSTEM_SYSV_COMPAT} - utmp/wtmp support: ${have_utmp} - ldconfig support: ${enable_ldconfig} - hibernate support: ${enable_hibernate} - extra debugging: ${enable_debug} - tests: ${enable_tests} - - prefix: ${prefix} - rootprefix: ${with_rootprefix} - sysconf dir: ${sysconfdir} - datarootdir: ${datarootdir} - includedir: ${includedir} - lib dir: ${libdir} - rootlib dir: ${with_rootlibdir} - SysV init scripts: ${SYSTEM_SYSVINIT_PATH} - SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} - Build Python: ${PYTHON} - PAM modules dir: ${with_pamlibdir} - PAM configuration dir: ${with_pamconfdir} - D-Bus policy dir: ${with_dbuspolicydir} - D-Bus session dir: ${with_dbussessionservicedir} - D-Bus system dir: ${with_dbussystemservicedir} - Bash completions dir: ${with_bashcompletiondir} - Zsh completions dir: ${with_zshcompletiondir} - Extra start script: ${RC_LOCAL_SCRIPT_PATH_START} - Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP} - Wheel group: ${have_wheel_group} - Debug shell: ${SUSHELL} @ ${DEBUGTTY} - TTY GID: ${TTY_GID} - Maximum System UID: ${SYSTEM_UID_MAX} - Maximum System GID: ${SYSTEM_GID_MAX} - Certificate root: ${CERTIFICATEROOT} - - CFLAGS: ${OUR_CFLAGS} ${CFLAGS} - CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} - LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} + libcryptsetup: ${have_libcryptsetup} + PAM: ${have_pam} + AUDIT: ${have_audit} + IMA: ${have_ima} + AppArmor: ${have_apparmor} + SELinux: ${have_selinux} + SECCOMP: ${have_seccomp} + SMACK: ${have_smack} + ZLIB: ${have_zlib} + XZ: ${have_xz} + LZ4: ${have_lz4} + BZIP2: ${have_bzip2} + ACL: ${have_acl} + GCRYPT: ${have_gcrypt} + QRENCODE: ${have_qrencode} + MICROHTTPD: ${have_microhttpd} + GNUTLS: ${have_gnutls} + libcurl: ${have_libcurl} + libidn: ${have_libidn} + libiptc: ${have_libiptc} + ELFUTILS: ${have_elfutils} + binfmt: ${have_binfmt} + vconsole: ${have_vconsole} + quotacheck: ${have_quotacheck} + tmpfiles: ${have_tmpfiles} + sysusers: ${have_sysusers} + firstboot: ${have_firstboot} + randomseed: ${have_randomseed} + backlight: ${have_backlight} + rfkill: ${have_rfkill} + logind: ${have_logind} + Default KillUserProcesses setting: ${KILL_USER_PROCESSES} + machined: ${have_machined} + importd: ${have_importd} + hostnamed: ${have_hostnamed} + timedated: ${have_timedated} + timesyncd: ${have_timesyncd} + Default NTP servers: ${NTP_SERVERS} + time epoch: ${TIME_EPOCH} + localed: ${have_localed} + networkd: ${have_networkd} + resolved: ${have_resolved} + Default DNS servers: ${DNS_SERVERS} + Default DNSSEC mode: ${DEFAULT_DNSSEC_MODE} + coredump: ${have_coredump} + polkit: ${have_polkit} + efi: ${have_efi} + gnuefi: ${have_gnuefi} + efi arch: ${EFI_ARCH} + EFI machine type: ${EFI_MACHINE_TYPE_NAME} + EFI CC ${EFI_CC} + EFI libdir: ${EFI_LIB_DIR} + EFI ldsdir: ${EFI_LDS_DIR} + EFI includedir: ${EFI_INC_DIR} + kmod: ${have_kmod} + xkbcommon: ${have_xkbcommon} + blkid: ${have_blkid} + libmount: ${have_libmount} + dbus: ${have_dbus} + nss-myhostname: ${have_myhostname} + hwdb: ${enable_hwdb} + tpm: ${have_tpm} + kdbus: ${have_kdbus} + Python: ${have_python} + man pages: ${have_manpages} + test coverage: ${have_coverage} + Split /usr: ${enable_split_usr} + SysV compatibility: ${SYSTEM_SYSV_COMPAT} + utmp/wtmp support: ${have_utmp} + ldconfig support: ${enable_ldconfig} + hibernate support: ${enable_hibernate} + extra debugging: ${enable_debug} + tests: ${enable_tests} + + prefix: ${prefix} + rootprefix: ${with_rootprefix} + sysconf dir: ${sysconfdir} + datarootdir: ${datarootdir} + includedir: ${includedir} + lib dir: ${libdir} + rootlib dir: ${with_rootlibdir} + SysV init scripts: ${SYSTEM_SYSVINIT_PATH} + SysV rc?.d directories: ${SYSTEM_SYSVRCND_PATH} + Build Python: ${PYTHON} + PAM modules dir: ${with_pamlibdir} + PAM configuration dir: ${with_pamconfdir} + D-Bus policy dir: ${with_dbuspolicydir} + D-Bus session dir: ${with_dbussessionservicedir} + D-Bus system dir: ${with_dbussystemservicedir} + Bash completions dir: ${with_bashcompletiondir} + Zsh completions dir: ${with_zshcompletiondir} + Extra start script: ${RC_LOCAL_SCRIPT_PATH_START} + Extra stop script: ${RC_LOCAL_SCRIPT_PATH_STOP} + Wheel group: ${have_wheel_group} + Debug shell: ${SUSHELL} @ ${DEBUGTTY} + TTY GID: ${TTY_GID} + Maximum System UID: ${SYSTEM_UID_MAX} + Maximum System GID: ${SYSTEM_GID_MAX} + Certificate root: ${CERTIFICATEROOT} + + CFLAGS: ${OUR_CFLAGS} ${CFLAGS} + CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} + LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} ]) diff --git a/man/loginctl.xml b/man/loginctl.xml index 7f7252a5d9..fb51740503 100644 --- a/man/loginctl.xml +++ b/man/loginctl.xml @@ -312,7 +312,10 @@ This allows users who are not logged in to run long-running services. Takes one or more user names or numeric UIDs as argument. If no argument is specified, enables/disables - lingering for the user of the session of the caller. + lingering for the user of the session of the caller.</para> + + <para>See also <varname>KillUserProcesses=</varname> setting in + <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>. </para></listitem> </varlistentry> @@ -410,6 +413,37 @@ otherwise.</para> </refsect1> + <refsect1> + <title>Examples</title> + + <example> + <title>Querying user status</title> + + <programlisting>$ loginctl user-status +fatima (1005) + Since: Sat 2016-04-09 14:23:31 EDT; 54min ago + State: active + Sessions: 5 *3 + Unit: user-1005.slice + ├─user@1005.service + ... + ├─session-3.scope + ... + └─session-5.scope + ├─3473 login -- fatima + └─3515 -zsh + +Apr 09 14:40:30 laptop login[2325]: pam_unix(login:session): + session opened for user fatima by LOGIN(uid=0) +Apr 09 14:40:30 laptop login[2325]: LOGIN ON tty3 BY fatima +</programlisting> + + <para>There are two sessions, 3 and 5. Session 3 is a graphical session, + marked with a star. The tree of processing including the two corresponding + scope units and the user manager unit are shown.</para> + </example> + </refsect1> + <xi:include href="less-variables.xml" /> <refsect1> diff --git a/man/logind.conf.xml b/man/logind.conf.xml index 597759e33a..3217ece21a 100644 --- a/man/logind.conf.xml +++ b/man/logind.conf.xml @@ -119,30 +119,46 @@ <varlistentry> <term><varname>KillUserProcesses=</varname></term> - <listitem><para>Takes a boolean argument. Configures whether - the processes of a user should be killed when the user - completely logs out (i.e. after the user's last session - ended). Defaults to <literal>no</literal>.</para> - - <para>Note that setting <varname>KillUserProcesses=1</varname> + <listitem><para>Takes a boolean argument. Configures whether the processes of a + user should be killed when the user logs out. If true, the scope unit + corresponding to the session and all processes inside that scope will be + terminated. If false, the scope is "abandonded", see + <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + and processes are not killed. Defaults to <literal>yes</literal>, + but see the options <varname>KillOnlyUsers=</varname> and + <varname>KillExcludeUsers=</varname> below.</para> + + <para>In addition to session processes, user process may run under the user + manager unit <filename>user@.service</filename>. Depending on the linger + settings, this may allow users to run processes independent of their login + sessions. See the description of <command>enable-linger</command> in + <citerefentry><refentrytitle>loginctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>. + </para> + + <para>Note that setting <varname>KillUserProcesses=yes</varname> will break tools like - <citerefentry project='die-net'><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry>.</para></listitem> + <citerefentry project='die-net'><refentrytitle>screen</refentrytitle><manvolnum>1</manvolnum></citerefentry> + and + <citerefentry project='die-net'><refentrytitle>tmux</refentrytitle><manvolnum>1</manvolnum></citerefentry>, + unless they are moved out of the session scope. See example in + <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>. + </para></listitem> </varlistentry> <varlistentry> <term><varname>KillOnlyUsers=</varname></term> <term><varname>KillExcludeUsers=</varname></term> - <listitem><para>These settings take space-separated lists of - usernames that influence the effect of - <varname>KillUserProcesses=</varname>. If not empty, only - processes of users listed in <varname>KillOnlyUsers=</varname> - will be killed when they log out entirely. Processes of users - listed in <varname>KillExcludeUsers=</varname> are excluded - from being killed. <varname>KillExcludeUsers=</varname> - defaults to <literal>root</literal> and takes precedence over - <varname>KillOnlyUsers=</varname>, which defaults to the empty - list.</para></listitem> + <listitem><para>These settings take space-separated lists of usernames that override + the <varname>KillUserProcesses=</varname> setting. A user name may be added to + <varname>KillExcludeUsers=</varname> to exclude the processes in the session scopes of + that user from being killed even if <varname>KillUserProcesses=yes</varname> is set. If + <varname>KillExcludeUsers=</varname> is not set, the <literal>root</literal> user is + excluded by default. <varname>KillExcludeUsers=</varname> may be set to an empty value + to override this default. If a user is not excluded, <varname>KillOnlyUsers=</varname> + is checked next. If this setting is specified, only the session scopes of those users + will be killed. Otherwise, users are subject to the + <varname>KillUserProcesses=yes</varname> setting.</para></listitem> </varlistentry> <varlistentry> diff --git a/man/systemd-run.xml b/man/systemd-run.xml index 245daae946..9c1a29218e 100644 --- a/man/systemd-run.xml +++ b/man/systemd-run.xml @@ -341,10 +341,10 @@ <refsect1> <title>Examples</title> - <para>The following command will log the environment variables - provided by systemd to services:</para> + <example> + <title>Logging environment variables provided by systemd to services</title> - <programlisting># systemd-run env + <programlisting># systemd-run env Running as unit: run-19945.service # journalctl -u run-19945.service Sep 08 07:37:21 bupkis systemd[1]: Starting /usr/bin/env... @@ -352,19 +352,27 @@ Sep 08 07:37:21 bupkis systemd[1]: Started /usr/bin/env. Sep 08 07:37:21 bupkis env[19948]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin Sep 08 07:37:21 bupkis env[19948]: LANG=en_US.UTF-8 Sep 08 07:37:21 bupkis env[19948]: BOOT_IMAGE=/vmlinuz-3.11.0-0.rc5.git6.2.fc20.x86_64</programlisting> + </example> - <para>The following command invokes the - <citerefentry project='man-pages'><refentrytitle>updatedb</refentrytitle><manvolnum>8</manvolnum></citerefentry> - tool, but lowers the block I/O weight for it to 10. See - <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry> - for more information on the <varname>BlockIOWeight=</varname> - property.</para> + <example> + <title>Limiting resources available to a command</title> - <programlisting># systemd-run -p BlockIOWeight=10 updatedb</programlisting> + <programlisting># systemd-run -p BlockIOWeight=10 updatedb</programlisting> - <para>The following command will touch a file after 30 seconds.</para> + <para>This command invokes the + <citerefentry project='man-pages'><refentrytitle>updatedb</refentrytitle><manvolnum>8</manvolnum></citerefentry> + tool, but lowers the block I/O weight for it to 10. See + <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry> + for more information on the <varname>BlockIOWeight=</varname> + property.</para> + </example> - <programlisting># date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo + <example> + <title>Running commands at a specified time</title> + + <para>The following command will touch a file after 30 seconds.</para> + + <programlisting># date; systemd-run --on-active=30 --timer-property=AccuracySec=100ms /bin/touch /tmp/foo Mon Dec 8 20:44:24 KST 2014 Running as unit: run-71.timer Will run service as unit: run-71.service @@ -376,13 +384,60 @@ Dec 08 20:44:38 container systemd[1]: Started /bin/touch /tmp/foo. -- Logs begin at Fri 2014-12-05 19:09:21 KST, end at Mon 2014-12-08 20:44:54 KST. -- Dec 08 20:44:48 container systemd[1]: Starting /bin/touch /tmp/foo... Dec 08 20:44:48 container systemd[1]: Started /bin/touch /tmp/foo.</programlisting> - - <para>The following command invokes <filename>/bin/bash</filename> - as a service passing its standard input, output and error to - the calling TTY.</para> - - <programlisting># systemd-run -t --send-sighup /bin/bash</programlisting> - + </example> + + <example> + <title>Allowing access to the tty</title> + + <para>The following command invokes <filename>/bin/bash</filename> as a service + passing its standard input, output and error to the calling TTY.</para> + + <programlisting># systemd-run -t --send-sighup /bin/bash</programlisting> + </example> + + <example> + <title>Start <command>screen</command> as a user service</title> + + <programlisting>$ systemd-run --scope --user screen +Running scope as unit run-r14b0047ab6df45bfb45e7786cc839e76.scope. + +$ screen -ls +There is a screen on: + 492..laptop (Detached) +1 Socket in /var/run/screen/S-fatima. +</programlisting> + + <para>This starts the <command>screen</command> process as a child of the + <command>systemd --user</command> process that was started by + <filename>user@.service</filename>, in a scope unit. A + <citerefentry><refentrytitle>systemd.scope</refentrytitle><manvolnum>5</manvolnum></citerefentry> + unit is used instead of a + <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> + unit, because <command>screen</command> will exit when detaching from the terminal, + and a service unit would be terminated. Running <command>screen</command> + as a user unit has the advantage that it is not part of the session scope. + If <varname>KillUserProcesses=yes</varname> is configured in + <citerefentry><refentrytitle>logind.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, + the default, the session scope will be terminated when the user logs + out of that session.</para> + + <para>The <filename>user@.service</filename> is started automatically + when the user first logs in, and stays around as long as at least one + login session is open. After the user logs out of the last session, + <filename>user@.service</filename> and all services underneath it + are terminated. This behaviour is the default, when "lingering" is + not enabled for that user. Enabling lingering means that + <filename>user@.service</filename> is started automatically during + boot, even if the user is not logged in, and that the service is + not terminated when the user logs out.</para> + + <para>Enabling lingering allows the user to run processes without being logged in, + for example to allow <command>screen</command> to persist after the user logs out, + even if the session scope is terminated. In the default configuration, users can + enable lingering for themselves:</para> + + <programlisting>$ loginctl enable-linger</programlisting> + </example> </refsect1> <refsect1> diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 2cdfcf7b5d..cc287d602d 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -110,6 +110,7 @@ static int callback_type_to_priority(int type) { */ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) { va_list ap; + const char *fmt2; #ifdef HAVE_AUDIT int fd; @@ -131,8 +132,10 @@ _printf_(2, 3) static int log_callback(int type, const char *fmt, ...) { } #endif + fmt2 = strjoina("selinux: ", fmt); + va_start(ap, fmt); - log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt, ap); + log_internalv(LOG_AUTH | callback_type_to_priority(type), 0, __FILE__, __LINE__, __FUNCTION__, fmt2, ap); va_end(ap); return 0; diff --git a/src/login/.gitignore b/src/login/.gitignore index 39088ec252..3a8ba497c1 100644 --- a/src/login/.gitignore +++ b/src/login/.gitignore @@ -1,4 +1,5 @@ /logind-gperf.c +/logind.conf /org.freedesktop.login1.policy /71-seat.rules /73-seat-late.rules diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 01f6fa5db0..8b23135edd 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -293,6 +293,7 @@ typedef struct SessionStatusInfo { typedef struct UserStatusInfo { uid_t uid; + bool linger; char *name; struct dual_timestamp timestamp; char *state; @@ -551,6 +552,7 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) static const struct bus_properties_map map[] = { { "Name", "s", NULL, offsetof(UserStatusInfo, name) }, + { "Linger", "b", NULL, offsetof(UserStatusInfo, linger) }, { "Slice", "s", NULL, offsetof(UserStatusInfo, slice) }, { "State", "s", NULL, offsetof(UserStatusInfo, state) }, { "UID", "u", NULL, offsetof(UserStatusInfo, uid) }, @@ -595,16 +597,16 @@ static int print_user_status_info(sd_bus *bus, const char *path, bool *new_line) char **l; printf("\tSessions:"); - STRV_FOREACH(l, i.sessions) { - if (streq_ptr(*l, i.display)) - printf(" *%s", *l); - else - printf(" %s", *l); - } + STRV_FOREACH(l, i.sessions) + printf(" %s%s", + streq_ptr(*l, i.display) ? "*" : "", + *l); printf("\n"); } + printf("\t Linger: %s\n", yes_no(i.linger)); + if (i.slice) { printf("\t Unit: %s\n", i.slice); show_unit_cgroup(bus, "org.freedesktop.systemd1.Slice", i.slice, 0); diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 8bdb3a9a38..cbf8d757fe 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -364,16 +364,16 @@ bool manager_shall_kill(Manager *m, const char *user) { assert(m); assert(user); - if (!m->kill_user_processes) + if (!m->kill_exclude_users && streq(user, "root")) return false; if (strv_contains(m->kill_exclude_users, user)) return false; - if (strv_isempty(m->kill_only_users)) - return true; + if (!strv_isempty(m->kill_only_users)) + return strv_contains(m->kill_only_users, user); - return strv_contains(m->kill_only_users, user); + return m->kill_user_processes; } static int vt_is_busy(unsigned int vtnr) { diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 1d3133ee25..a281f99a34 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -1077,11 +1077,11 @@ static int method_terminate_seat(sd_bus_message *message, void *userdata, sd_bus static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_free_ char *cc = NULL; Manager *m = userdata; - int b, r; + int r, b, interactive; struct passwd *pw; const char *path; uint32_t uid; - int interactive; + bool self = false; assert(message); assert(m); @@ -1102,6 +1102,8 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu if (r < 0) return r; + self = true; + } else if (!uid_is_valid(uid)) return -EINVAL; @@ -1113,7 +1115,7 @@ static int method_set_user_linger(sd_bus_message *message, void *userdata, sd_bu r = bus_verify_polkit_async( message, CAP_SYS_ADMIN, - "org.freedesktop.login1.set-user-linger", + self ? "org.freedesktop.login1.set-self-linger" : "org.freedesktop.login1.set-user-linger", NULL, interactive, UID_INVALID, diff --git a/src/login/logind.c b/src/login/logind.c index d5f6757bd3..a48e2fc61e 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -41,17 +41,7 @@ static void manager_free(Manager *m); -static Manager *manager_new(void) { - Manager *m; - int r; - - m = new0(Manager, 1); - if (!m) - return NULL; - - m->console_active_fd = -1; - m->reserve_vt_fd = -1; - +static void manager_reset_config(Manager *m) { m->n_autovts = 6; m->reserve_vt = 6; m->remove_ipc = true; @@ -61,16 +51,38 @@ static Manager *manager_new(void) { m->handle_hibernate_key = HANDLE_HIBERNATE; m->handle_lid_switch = HANDLE_SUSPEND; m->handle_lid_switch_docked = HANDLE_IGNORE; + m->power_key_ignore_inhibited = false; + m->suspend_key_ignore_inhibited = false; + m->hibernate_key_ignore_inhibited = false; m->lid_switch_ignore_inhibited = true; + m->holdoff_timeout_usec = 30 * USEC_PER_SEC; m->idle_action_usec = 30 * USEC_PER_MINUTE; m->idle_action = HANDLE_IGNORE; - m->idle_action_not_before_usec = now(CLOCK_MONOTONIC); m->runtime_dir_size = PAGE_ALIGN((size_t) (physical_memory() / 10)); /* 10% */ m->user_tasks_max = UINT64_C(12288); + m->kill_user_processes = KILL_USER_PROCESSES; + + m->kill_only_users = strv_free(m->kill_only_users); + m->kill_exclude_users = strv_free(m->kill_exclude_users); +} + +static Manager *manager_new(void) { + Manager *m; + int r; + + m = new0(Manager, 1); + if (!m) + return NULL; + + m->console_active_fd = -1; + m->reserve_vt_fd = -1; + + m->idle_action_not_before_usec = now(CLOCK_MONOTONIC); + m->devices = hashmap_new(&string_hash_ops); m->seats = hashmap_new(&string_hash_ops); m->sessions = hashmap_new(&string_hash_ops); @@ -84,10 +96,6 @@ static Manager *manager_new(void) { if (!m->devices || !m->seats || !m->sessions || !m->users || !m->inhibitors || !m->buttons || !m->user_units || !m->session_units) goto fail; - m->kill_exclude_users = strv_new("root", NULL); - if (!m->kill_exclude_users) - goto fail; - m->udev = udev_new(); if (!m->udev) goto fail; @@ -98,6 +106,8 @@ static Manager *manager_new(void) { sd_event_set_watchdog(m->event, true); + manager_reset_config(m); + return m; fail: @@ -986,6 +996,30 @@ static int manager_dispatch_idle_action(sd_event_source *s, uint64_t t, void *us return 0; } +static int manager_parse_config_file(Manager *m) { + assert(m); + + return config_parse_many(PKGSYSCONFDIR "/logind.conf", + CONF_PATHS_NULSTR("systemd/logind.conf.d"), + "Login\0", + config_item_perf_lookup, logind_gperf_lookup, + false, m); +} + +static int manager_dispatch_reload_signal(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) { + Manager *m = userdata; + int r; + + manager_reset_config(m); + r = manager_parse_config_file(m); + if (r < 0) + log_warning_errno(r, "Failed to parse config file, using defaults: %m"); + else + log_info("Config file reloaded."); + + return 0; +} + static int manager_startup(Manager *m) { int r; Seat *seat; @@ -997,6 +1031,12 @@ static int manager_startup(Manager *m) { assert(m); + assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGHUP, -1) >= 0); + + r = sd_event_add_signal(m->event, NULL, SIGHUP, manager_dispatch_reload_signal, m); + if (r < 0) + return log_error_errno(r, "Failed to register SIGHUP handler: %m"); + /* Connect to console */ r = manager_connect_console(m); if (r < 0) @@ -1099,16 +1139,6 @@ static int manager_run(Manager *m) { } } -static int manager_parse_config_file(Manager *m) { - assert(m); - - return config_parse_many(PKGSYSCONFDIR "/logind.conf", - CONF_PATHS_NULSTR("systemd/logind.conf.d"), - "Login\0", - config_item_perf_lookup, logind_gperf_lookup, - false, m); -} - int main(int argc, char *argv[]) { Manager *m = NULL; int r; diff --git a/src/login/logind.conf b/src/login/logind.conf.in index 6095e482ac..3c96def45d 100644 --- a/src/login/logind.conf +++ b/src/login/logind.conf.in @@ -14,7 +14,7 @@ [Login] #NAutoVTs=6 #ReserveVT=6 -#KillUserProcesses=no +#KillUserProcesses=@KILL_USER_PROCESSES@ #KillOnlyUsers= #KillExcludeUsers=root #InhibitDelayMaxSec=5 diff --git a/src/login/org.freedesktop.login1.policy.in b/src/login/org.freedesktop.login1.policy.in index 23326bb79f..1fa6441629 100644 --- a/src/login/org.freedesktop.login1.policy.in +++ b/src/login/org.freedesktop.login1.policy.in @@ -111,6 +111,14 @@ </defaults> </action> + <action id="org.freedesktop.login1.set-self-linger"> + <_description>Allow non-logged-in user to run programs</_description> + <_message>Explicit request is required to run programs as a non-logged-in user.</_message> + <defaults> + <allow_any>yes</allow_any> + </defaults> + </action> + <action id="org.freedesktop.login1.set-user-linger"> <_description>Allow non-logged-in users to run programs</_description> <_message>Authentication is required to run programs as a non-logged-in user.</_message> diff --git a/src/shared/logs-show.c b/src/shared/logs-show.c index e2d2931c51..38a55525c0 100644 --- a/src/shared/logs-show.c +++ b/src/shared/logs-show.c @@ -1073,7 +1073,7 @@ int add_matches_for_unit(sd_journal *j, const char *unit) { ); if (r == 0 && endswith(unit, ".slice")) { - char *m5 = strappend("_SYSTEMD_SLICE=", unit); + const char *m5 = strjoina("_SYSTEMD_SLICE=", unit); /* Show all messages belonging to a slice */ (void)( |