Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[pam_systemd] Add timeout=<seconds> argument. JB#37881
If user@.service takes longer than 25 seconds to start up, the
CreateSession method call made from pam_systemd will timeout
and failure is assumed (even if the user service gets successfully
to started stage, the reply sent after timeout is ignored).

Add sd_bus_call_method_with_timeout() convenience method call function
that is otherwise similar to already existing sd_bus_call_method()
except it allows using custom reply timeouts.

Allow passing of timeout=<seconds> argument to pam_systemd plugin when
longer than default D-Bus method call timeouts are needed.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
  • Loading branch information
spiiroin committed Apr 18, 2017
1 parent e841e1e commit cbb1de1
Show file tree
Hide file tree
Showing 2 changed files with 153 additions and 0 deletions.
151 changes: 151 additions & 0 deletions rpm/systemd-225-add-pam-systemd-timeout-argument.patch
@@ -0,0 +1,151 @@
From 2936884c5d5705e6ebafec4669e79dc754574b6b Mon Sep 17 00:00:00 2001
From: Simo Piiroinen <simo.piiroinen@jollamobile.com>
Date: Thu, 13 Apr 2017 09:53:13 +0300
Subject: [PATCH] [pam_systemd] Add timeout=<seconds> argument. JB#37881

If user@.service takes longer than 25 seconds to start up, the
CreateSession method call made from pam_systemd will timeout
and failure is assumed (even if the user service gets successfully
to started stage, the reply sent after timeout is ignored).

Add sd_bus_call_method_with_timeout() convenience method call function
that is otherwise similar to already existing sd_bus_call_method()
except it allows using custom reply timeouts.

Allow passing of timeout=<seconds> argument to pam_systemd plugin when
longer than default D-Bus method call timeouts are needed.

Signed-off-by: Simo Piiroinen <simo.piiroinen@jollamobile.com>
---
src/libsystemd/sd-bus/bus-convenience.c | 42 +++++++++++++++++++++++++++++++++
src/login/pam_systemd.c | 16 ++++++++++---
src/systemd/sd-bus.h | 1 +
3 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/src/libsystemd/sd-bus/bus-convenience.c b/src/libsystemd/sd-bus/bus-convenience.c
index af5f7da..90d9034 100644
--- a/src/libsystemd/sd-bus/bus-convenience.c
+++ b/src/libsystemd/sd-bus/bus-convenience.c
@@ -136,6 +136,48 @@ fail:
return sd_bus_error_set_errno(error, r);
}

+_public_ int sd_bus_call_method_with_timeout(
+ sd_bus *bus,
+ const char *destination,
+ const char *path,
+ const char *interface,
+ const char *member,
+ uint64_t usec,
+ sd_bus_error *error,
+ sd_bus_message **reply,
+ const char *types, ...) {
+
+ _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
+ int r;
+
+ bus_assert_return(bus, -EINVAL, error);
+ bus_assert_return(!bus_pid_changed(bus), -ECHILD, error);
+
+ if (!BUS_IS_OPEN(bus->state)) {
+ r = -ENOTCONN;
+ goto fail;
+ }
+
+ r = sd_bus_message_new_method_call(bus, &m, destination, path, interface, member);
+ if (r < 0)
+ goto fail;
+
+ if (!isempty(types)) {
+ va_list ap;
+
+ va_start(ap, types);
+ r = bus_message_append_ap(m, types, ap);
+ va_end(ap);
+ if (r < 0)
+ goto fail;
+ }
+
+ return sd_bus_call(bus, m, usec, error, reply);
+
+fail:
+ return sd_bus_error_set_errno(error, r);
+}
+
_public_ int sd_bus_reply_method_return(
sd_bus_message *call,
const char *types, ...) {
diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c
index f83d18b..e85b640 100644
--- a/src/login/pam_systemd.c
+++ b/src/login/pam_systemd.c
@@ -50,7 +50,8 @@ static int parse_argv(
int argc, const char **argv,
const char **class,
const char **type,
- bool *debug) {
+ bool *debug,
+ unsigned *timeout) {

unsigned i;

@@ -79,6 +80,9 @@ static int parse_argv(
else if (debug)
*debug = k;

+ } else if (startswith(argv[i], "timeout=")) {
+ if (safe_atou(argv[i] + 8, timeout) != 0)
+ pam_syslog(handle, LOG_WARNING, "Failed to parse timeout= argument, ignoring.");
} else
pam_syslog(handle, LOG_WARNING, "Unknown parameter '%s', ignoring", argv[i]);
}
@@ -217,6 +221,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
_cleanup_bus_flush_close_unref_ sd_bus *bus = NULL;
int session_fd = -1, existing, r;
bool debug = false, remote;
+ unsigned timeout = 0;
struct passwd *pw;
uint32_t vtnr = 0;
uid_t original_uid;
@@ -231,7 +236,8 @@ _public_ PAM_EXTERN int pam_sm_open_session(
argc, argv,
&class_pam,
&type_pam,
- &debug) < 0)
+ &debug,
+ &timeout) < 0)
return PAM_SESSION_ERR;

if (debug)
@@ -377,11 +383,15 @@ _public_ PAM_EXTERN int pam_sm_open_session(
strempty(seat), vtnr, strempty(tty), strempty(display),
yes_no(remote), strempty(remote_user), strempty(remote_host));

- r = sd_bus_call_method(bus,
+ if (timeout)
+ pam_syslog(handle, LOG_DEBUG, "Using %us D-Bus method call timeout", timeout);
+
+ r = sd_bus_call_method_with_timeout(bus,
"org.freedesktop.login1",
"/org/freedesktop/login1",
"org.freedesktop.login1.Manager",
"CreateSession",
+ timeout * USEC_PER_SEC,
&error,
&reply,
"uusssssussbssa(sv)",
diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h
index 5439a19..a8f3d4f 100644
--- a/src/systemd/sd-bus.h
+++ b/src/systemd/sd-bus.h
@@ -300,6 +300,7 @@ int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machin
/* Convenience calls */

int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
+int sd_bus_call_method_with_timeout(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...);
int sd_bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...);
int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *type);
int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char type, void *ret_ptr);
--
2.7.4

2 changes: 2 additions & 0 deletions rpm/systemd.spec
Expand Up @@ -35,6 +35,7 @@ Patch23: systemd-backport-Revert-rules-remove-firmware-loading-rules.patc
# Workaround for JB#36605. Should be removed after implementing UDEV events
# handling in initramfs.
Patch24: systemd-udev-lvm-workaround.patch
Patch25: systemd-225-add-pam-systemd-timeout-argument.patch

BuildRequires: libcap-devel
BuildRequires: libmount-devel
Expand Down Expand Up @@ -194,6 +195,7 @@ This package includes tests for systemd.
%patch23 -p1
# JB#36605 LVM/UDEV workaround.
%patch24 -p1
%patch25 -p1

%build
./autogen.sh
Expand Down

0 comments on commit cbb1de1

Please sign in to comment.