summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am6
-rw-r--r--NEWS31
-rw-r--r--configure.ac215
-rw-r--r--man/loginctl.xml36
-rw-r--r--man/logind.conf.xml50
-rw-r--r--man/systemd-run.xml93
-rw-r--r--src/core/selinux-access.c5
-rw-r--r--src/login/.gitignore1
-rw-r--r--src/login/loginctl.c14
-rw-r--r--src/login/logind-core.c8
-rw-r--r--src/login/logind-dbus.c8
-rw-r--r--src/login/logind.c82
-rw-r--r--src/login/logind.conf.in (renamed from src/login/logind.conf)2
-rw-r--r--src/login/org.freedesktop.login1.policy.in8
-rw-r--r--src/shared/logs-show.c2
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)|' \
diff --git a/NEWS b/NEWS
index 58a0f032a8..f697599a8f 100644
--- a/NEWS
+++ b/NEWS
@@ -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)(