[systemd-commits] 8 commits - Makefile.am man/systemd.xml src/dbus-manager.c src/execute.c src/install.c src/install.h src/loginctl.c src/logind.c src/manager.c src/pam-module.c src/path-lookup.c src/sd-login.c src/tmpfiles.c src/uaccess.c src/util.c src/util.h TODO

Lennart Poettering lennart at kemper.freedesktop.org
Fri Jul 22 19:16:32 PDT 2011


 Makefile.am        |    4 
 TODO               |   34 +-----
 man/systemd.xml    |   38 ++++++
 src/dbus-manager.c |  292 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/execute.c      |   42 +------
 src/install.c      |    9 +
 src/install.h      |    3 
 src/loginctl.c     |   86 ++++++---------
 src/logind.c       |   19 +--
 src/manager.c      |   31 +++++
 src/pam-module.c   |   20 +--
 src/path-lookup.c  |    6 -
 src/sd-login.c     |   10 -
 src/tmpfiles.c     |   30 +----
 src/uaccess.c      |   47 ++------
 src/util.c         |   72 ++++++++++---
 src/util.h         |    1 
 17 files changed, 533 insertions(+), 211 deletions(-)

New commits:
commit 253ee27a0c7a410d27d490bb79ea97caed6a2b68
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 04:15:38 2011 +0200

    manager: add log control via RT signals

diff --git a/TODO b/TODO
index 62bea41..82bc995 100644
--- a/TODO
+++ b/TODO
@@ -36,7 +36,7 @@ Features:
 
 * logind: non-local X11 server handling
 
-* logind: use sysfs path in device hash table instead of syname, as soon as fb driver is fixed
+* logind: use sysfs path in device hash table instead of sysname, as soon as fb driver is fixed
 
 * possibly apply systemd-sysctl per network device subtrees on hotplug
 
@@ -59,7 +59,9 @@ Features:
 
 * readahead: check whether a btrfs volume includes ssd by checking mount flag "ssd"
 
-* support sd_notify() style notificatio when reload is finished (RELOADED=1)
+* support sd_notify() style notification when reload is finished (RELOADED=1)
+
+* support sf_notify() style notification when shutting down, to make auto-exit bus services work
 
 * verify that the AF_UNIX sockets of a service in the fs still exist
   when we start a service in order to avoid confusion when a user
@@ -68,8 +70,6 @@ Features:
 * Make it possible to set the keymap independently from the font on
   the kernel cmdline. Right now setting one resets also the other.
 
-* add dbus call to convert snapshot into target
-
 * move nss-myhostname into systemd
 
 * figure out a standard place to configure timezone name, inform myllynen at redhat.com
@@ -84,14 +84,8 @@ Features:
 
 * allow list of paths in config_parse_condition_path()
 
-* introduce dbus calls for enabling/disabling a service
-
-* support notifications for services being enabled/disabled
-
 * show enablement status in systemctl status
 
-* consider services with any kind of link in /etc/systemd/system enabled
-
 * teach systemctl to enable unit files in arbitrary directories
 
 * In systemctl make sure both is-enabled and is-active print a string, or neither.
@@ -101,6 +95,8 @@ Features:
     systemctl unmask <unit>
   Also support --temp to make this temporary by placing mask links in /run.
 
+* perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable"
+
 * add support for /bin/mount -s
 
 * GC unreferenced jobs (such as .device jobs)
@@ -120,8 +116,8 @@ Features:
 * write blog stories about:
   - enabling dbus services
   - status update
-  - /etc/sysconfig and /etc/default
   - how to make changes to sysctl and sysfs attributes
+  - remote access
 
 * allow port=0 in .socket units
 
@@ -189,12 +185,8 @@ Features:
 
 * make sure timeouts are applied to Type=oneshot services.
 
-* detect LXC environment
-
 * investigate whether the gnome pty helper should be moved into systemd, to provide cgroup support.
 
-* perhaps add "systemctl reenable" as combination of "systemctl disable" and "systemctl enable"
-
 * need a way to apply mount options of api vfs from systemd unit files
   (or some other modern source?) instead of fstab?
 
@@ -218,16 +210,6 @@ Features:
 * systemd --user
   - get PR_SET_ANCHOR merged: http://lkml.org/lkml/2010/2/2/165
 
-* add VT tracking:
-  - provide CK functionality
-  - start getty only when actual vt switch happens (same model as
-    socket on-demand activation). allocate the next free tty and
-    start a getty there. this way, pressing alt-f[1-12] will switch
-    through running X and getty sessions, and any unallocated
-    activated tty will start a new getty. the hardcoding of
-    getty[1-6] will entirely go away.
-  - http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=fbc92a3455577ab17615cbcb91826399061bd789
-
 * implicitly import "defaults" settings file into all types
 
 * port over to LISTEN_FDS/LISTEN_PID:
diff --git a/man/systemd.xml b/man/systemd.xml
index 142c1d6..5129fbb 100644
--- a/man/systemd.xml
+++ b/man/systemd.xml
@@ -800,6 +800,44 @@
                                 on the kernel command
                                 line.</para></listitem>
                         </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+22</term>
+                                <term>SIGRTMIN+23</term>
+
+                                <listitem><para>Sets the log level to
+                                <literal>debug</literal>
+                                (resp. <literal>info</literal> on
+                                <literal>SIGRTMIN+32</literal>), as
+                                controlled via
+                                <varname>systemd.log_level=debug</varname>
+                                (resp. <varname>systemd.log_level=info</varname>
+                                on <literal>SIGRTMIN+23</literal>) on
+                                the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term>SIGRTMIN+27</term>
+                                <term>SIGRTMIN+28</term>
+                                <term>SIGRTMIN+29</term>
+
+                                <listitem><para>Sets the log level to
+                                <literal>console</literal>
+                                (resp. <literal>kmsg</literal> on
+                                <literal>SIGRTMIN+28</literal>;
+                                resp.<literal>syslog-or-kmsg</literal>
+                                on <literal>SIGRTMIN+29</literal>), as
+                                controlled via
+                                <varname>systemd.log_target=console</varname>
+                                (resp. <varname>systemd.log_target=kmsg</varname>
+                                on <literal>SIGRTMIN+28</literal>;
+                                resp
+                                <varname>systemd.log_target=syslog-or-kmsg</varname>
+                                on <literal>SIGRTMIN+29</literal>) on
+                                the kernel command
+                                line.</para></listitem>
+                        </varlistentry>
                 </variablelist>
         </refsect1>
 
diff --git a/src/manager.c b/src/manager.c
index c1242ae..cdd618e 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -186,6 +186,11 @@ static int manager_setup_signals(Manager *m) {
                         SIGRTMIN+16, /* systemd: Immediate kexec */
                         SIGRTMIN+20, /* systemd: enable status messages */
                         SIGRTMIN+21, /* systemd: disable status messages */
+                        SIGRTMIN+22, /* systemd: set log level to LOG_DEBUG */
+                        SIGRTMIN+23, /* systemd: set log level to LOG_INFO */
+                        SIGRTMIN+27, /* systemd: set log target to console */
+                        SIGRTMIN+28, /* systemd: set log target to kmsg */
+                        SIGRTMIN+29, /* systemd: set log target to syslog-or-kmsg */
                         -1);
         assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
 
@@ -2200,6 +2205,7 @@ static int manager_process_signal_fd(Manager *m) {
                         break;
 
                 default: {
+
                         /* Starting SIGRTMIN+0 */
                         static const char * const target_table[] = {
                                 [0] = SPECIAL_DEFAULT_TARGET,
@@ -2244,6 +2250,31 @@ static int manager_process_signal_fd(Manager *m) {
                                 m->show_status = false;
                                 break;
 
+                        case 22:
+                                log_set_max_level(LOG_DEBUG);
+                                log_notice("Setting log level to debug.");
+                                break;
+
+                        case 23:
+                                log_set_max_level(LOG_INFO);
+                                log_notice("Setting log level to info.");
+                                break;
+
+                        case 27:
+                                log_set_target(LOG_TARGET_CONSOLE);
+                                log_notice("Setting log target to console.");
+                                break;
+
+                        case 28:
+                                log_set_target(LOG_TARGET_KMSG);
+                                log_notice("Setting log target to kmsg.");
+                                break;
+
+                        case 29:
+                                log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
+                                log_notice("Setting log target to syslog-or-kmsg.");
+                                break;
+
                         default:
                                 log_warning("Got unhandled signal <%s>.", strna(signal_to_string(sfsi.ssi_signo)));
                         }

commit c0576cd6d61b81d3bab307e2deee10447de115db
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 03:44:47 2011 +0200

    bus: expose installer functions

diff --git a/Makefile.am b/Makefile.am
index af44b13..78c76d7 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -593,7 +593,8 @@ libsystemd_core_la_SOURCES = \
 	src/cgroup-util.c \
 	src/condition.c \
         src/dbus-common.c \
-        src/sd-daemon.c
+        src/sd-daemon.c \
+        src/install.c
 
 libsystemd_core_la_CFLAGS = \
 	$(AM_CFLAGS) \
@@ -991,6 +992,7 @@ systemd_uaccess_CFLAGS = \
 systemd_uaccess_LDADD = \
 	libsystemd-basic.la \
 	libsystemd-daemon.la \
+	libsystemd-login.la \
         $(UDEV_LIBS) \
         $(ACL_LIBS)
 
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index 4bed5c8..582de4b 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -29,6 +29,7 @@
 #include "bus-errors.h"
 #include "build.h"
 #include "dbus-common.h"
+#include "install.h"
 
 #define BUS_MANAGER_INTERFACE_BEGIN                                     \
         " <interface name=\"org.freedesktop.systemd1.Manager\">\n"
@@ -132,6 +133,53 @@
         "  <method name=\"UnsetAndSetEnvironment\">\n"                  \
         "   <arg name=\"unset\" type=\"as\" direction=\"in\"/>\n"       \
         "   <arg name=\"set\" type=\"as\" direction=\"in\"/>\n"         \
+        "  </method>\n"                                                 \
+        "  <method name=\"ListUnitFiles\">\n"                            \
+        "   <arg name=\"changes\" type=\"a(ss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"GetUnitFileState\">\n"                        \
+        "   <arg name=\"file\" type=\"s\" direction=\"in\"/>\n"         \
+        "   <arg name=\"state\" type=\"s\" direction=\"out\"/>\n"       \
+        "  </method>\n"                                                 \
+        "  <method name=\"EnableUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"DisableUnitFiles\">\n"                        \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"ReenableUnitFiles\">\n"                       \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"LinkUnitFiles\">\n"                           \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"PresetUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"MaskUnitFiles\">\n"                           \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"force\" type=\"b\" direction=\"in\"/>\n"        \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
+        "  </method>\n"                                                 \
+        "  <method name=\"UnmaskUnitFiles\">\n"                         \
+        "   <arg name=\"files\" type=\"as\" direction=\"in\"/>\n"       \
+        "   <arg name=\"runtime\" type=\"b\" direction=\"in\"/>\n"      \
+        "   <arg name=\"changes\" type=\"a(sss)\" direction=\"out\"/>\n" \
         "  </method>\n"
 
 #define BUS_MANAGER_INTERFACE_SIGNALS                                   \
@@ -157,7 +205,8 @@
         "   <arg name=\"initrd\" type=\"t\"/>\n"                        \
         "   <arg name=\"userspace\" type=\"t\"/>\n"                     \
         "   <arg name=\"total\" type=\"t\"/>\n"                         \
-        "  </signal>"
+        "  </signal>"                                                   \
+        "  <signal name=\"UnitFilesChanged\"/>\n"
 
 #define BUS_MANAGER_INTERFACE_PROPERTIES_GENERAL                        \
         "  <property name=\"Version\" type=\"s\" access=\"read\"/>\n"   \
@@ -373,6 +422,61 @@ static const char *message_get_sender_with_fallback(DBusMessage *m) {
         return ":no-sender";
 }
 
+static DBusMessage *message_from_file_changes(DBusMessage *m, UnitFileChange *changes, unsigned n_changes) {
+        DBusMessageIter iter, sub, sub2;
+        DBusMessage *reply;
+        unsigned i;
+
+        assert(changes);
+
+        reply = dbus_message_new_method_return(m);
+        if (!reply)
+                return NULL;
+
+        dbus_message_iter_init_append(reply, &iter);
+
+        if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(sss)", &sub))
+                goto oom;
+
+        for (i = 0; i < n_changes; i++) {
+                const char *type, *path, *source;
+
+                type = unit_file_change_type_to_string(changes[i].type);
+                path = strempty(changes[i].path);
+                source = strempty(changes[i].source);
+
+                if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                    !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &type) ||
+                    !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &path) ||
+                    !dbus_message_iter_append_basic(&sub, DBUS_TYPE_STRING, &source) ||
+                    !dbus_message_iter_close_container(&sub, &sub2))
+                        goto oom;
+        }
+
+        if (!dbus_message_iter_close_container(&iter, &sub))
+                goto oom;
+
+        return reply;
+
+oom:
+        dbus_message_unref(reply);
+        return NULL;
+}
+
+static int bus_manager_send_unit_files_changed(Manager *m) {
+        DBusMessage *s;
+        int r;
+
+        s = dbus_message_new_signal("/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager", "UnitFilesChanged");
+        if (!s)
+                return -ENOMEM;
+
+        r = bus_broadcast(m, s);
+        dbus_message_unref(s);
+
+        return r;
+}
+
 static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, DBusMessage *message, void *data) {
         Manager *m = data;
 
@@ -420,6 +524,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
         char * path = NULL;
         JobType job_type = _JOB_TYPE_INVALID;
         bool reload_if_possible = false;
+        const char *member;
 
         assert(connection);
         assert(message);
@@ -427,6 +532,8 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
 
         dbus_error_init(&error);
 
+        member = dbus_message_get_member(message);
+
         if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnit")) {
                 const char *name;
                 Unit *u;
@@ -1063,7 +1170,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                 DBusMessageIter iter;
 
                 if (!dbus_message_iter_init(message, &iter))
-                        return bus_send_error_reply(connection, message, NULL, -EINVAL);
+                        goto oom;
 
                 r = bus_parse_strv_iter(&iter, &l_unset);
                 if (r < 0) {
@@ -1109,6 +1216,187 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
 
                 strv_free(m->environment);
                 m->environment = f;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ListUnitFiles")) {
+                DBusMessageIter iter, sub, sub2;
+                Hashmap *h;
+                Iterator i;
+                UnitFileList *item;
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                h = hashmap_new(string_hash_func, string_compare_func);
+                if (!h)
+                        goto oom;
+
+                r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h);
+                if (r < 0) {
+                        unit_file_list_free(h);
+                        dbus_message_unref(reply);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                dbus_message_iter_init_append(reply, &iter);
+
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(ss)", &sub)) {
+                        unit_file_list_free(h);
+                        goto oom;
+                }
+
+                HASHMAP_FOREACH(item, h, i) {
+                        const char *state;
+
+                        state = unit_file_state_to_string(item->state);
+                        assert(state);
+
+                        if (!dbus_message_iter_open_container(&sub, DBUS_TYPE_STRUCT, NULL, &sub2) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &item->path) ||
+                            !dbus_message_iter_append_basic(&sub2, DBUS_TYPE_STRING, &state) ||
+                            !dbus_message_iter_close_container(&sub, &sub2)) {
+                                unit_file_list_free(h);
+                                goto oom;
+                        }
+                }
+
+                unit_file_list_free(h);
+
+                if (!dbus_message_iter_close_container(&iter, &sub))
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "GetUnitFileState")) {
+                const char *name;
+                UnitFileState state;
+                const char *s;
+
+                if (!dbus_message_get_args(
+                                    message,
+                                    &error,
+                                    DBUS_TYPE_STRING, &name,
+                                    DBUS_TYPE_INVALID))
+                        return bus_send_error_reply(connection, message, &error, -EINVAL);
+
+                state = unit_file_get_state(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, name);
+                if (state < 0)
+                        return bus_send_error_reply(connection, message, NULL, state);
+
+                s = unit_file_state_to_string(state);
+                assert(s);
+
+                reply = dbus_message_new_method_return(message);
+                if (!reply)
+                        goto oom;
+
+                if (!dbus_message_append_args(
+                                    reply,
+                                    DBUS_TYPE_STRING, &s,
+                                    DBUS_TYPE_INVALID))
+                        goto oom;
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "EnableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "ReenableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "LinkUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "PresetUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "MaskUnitFiles")) {
+
+                char **l = NULL;
+                DBusMessageIter iter;
+                UnitFileScope scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+                UnitFileChange *changes = NULL;
+                unsigned n_changes = 0;
+                dbus_bool_t runtime, force;
+
+                if (!dbus_message_iter_init(message, &iter))
+                        goto oom;
+
+                r = bus_parse_strv_iter(&iter, &l);
+                if (r < 0) {
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                if (!dbus_message_iter_next(&iter) ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, true) < 0 ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &force, false) < 0) {
+                        strv_free(l);
+                        return bus_send_error_reply(connection, message, NULL, -EIO);
+                }
+
+                if (streq(member, "EnableUnitFiles"))
+                        r = unit_file_enable(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "ReenableUnitFiles"))
+                        r = unit_file_reenable(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "LinkUnitFiles"))
+                        r = unit_file_link(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "PresetUnitFiles"))
+                        r = unit_file_preset(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else if (streq(member, "MaskUnitFiles"))
+                        r = unit_file_mask(scope, runtime, NULL, l, force, &changes, &n_changes);
+                else
+                        assert_not_reached("Uh? Wrong method");
+
+                strv_free(l);
+                bus_manager_send_unit_files_changed(m);
+
+                if (r < 0) {
+                        unit_file_changes_free(changes, n_changes);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                reply = message_from_file_changes(message, changes, n_changes);
+                unit_file_changes_free(changes, n_changes);
+
+                if (!reply)
+                        goto oom;
+
+        } else if (dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "DisableUnitFiles") ||
+                   dbus_message_is_method_call(message, "org.freedesktop.systemd1.Manager", "UnmaskUnitFiles")) {
+
+                char **l = NULL;
+                DBusMessageIter iter;
+                UnitFileScope scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER;
+                UnitFileChange *changes = NULL;
+                unsigned n_changes = 0;
+                dbus_bool_t runtime;
+
+                if (!dbus_message_iter_init(message, &iter))
+                        goto oom;
+
+                r = bus_parse_strv_iter(&iter, &l);
+                if (r < 0) {
+                        if (r == -ENOMEM)
+                                goto oom;
+
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                if (!dbus_message_iter_next(&iter) ||
+                    bus_iter_get_basic_and_next(&iter, DBUS_TYPE_BOOLEAN, &runtime, false) < 0) {
+                        strv_free(l);
+                        return bus_send_error_reply(connection, message, NULL, -EIO);
+                }
+
+                if (streq(member, "DisableUnitFiles"))
+                        r = unit_file_disable(scope, runtime, NULL, l, &changes, &n_changes);
+                else if (streq(member, "UnmaskUnitFiles"))
+                        r = unit_file_unmask(scope, runtime, NULL, l, &changes, &n_changes);
+                else
+                        assert_not_reached("Uh? Wrong method");
+
+                strv_free(l);
+                bus_manager_send_unit_files_changed(m);
+
+                if (r < 0) {
+                        unit_file_changes_free(changes, n_changes);
+                        return bus_send_error_reply(connection, message, NULL, r);
+                }
+
+                reply = message_from_file_changes(message, changes, n_changes);
+                unit_file_changes_free(changes, n_changes);
+
+                if (!reply)
+                        goto oom;
 
         } else
                 return bus_default_message_handler(connection, message, NULL, INTERFACES_LIST, properties);
diff --git a/src/install.c b/src/install.c
index e6bd578..b37bbbd 100644
--- a/src/install.c
+++ b/src/install.c
@@ -1942,3 +1942,10 @@ static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = {
 };
 
 DEFINE_STRING_TABLE_LOOKUP(unit_file_state, UnitFileState);
+
+static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX] = {
+        [UNIT_FILE_SYMLINK] = "symlink",
+        [UNIT_FILE_UNLINK] = "unlink",
+};
+
+DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, UnitFileChangeType);
diff --git a/src/install.h b/src/install.h
index a3eacf5..0505a82 100644
--- a/src/install.h
+++ b/src/install.h
@@ -83,4 +83,7 @@ int unit_file_query_preset(UnitFileScope scope, const char *name);
 const char *unit_file_state_to_string(UnitFileState s);
 UnitFileState unit_file_state_from_string(const char *s);
 
+const char *unit_file_change_type_to_string(UnitFileChangeType s);
+UnitFileChangeType unit_file_change_type_from_string(const char *s);
+
 #endif

commit 5780425ea7f4b649852991bc515fa8ce71ee43dd
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 01:18:20 2011 +0200

    login: drop unused variables

diff --git a/src/sd-login.c b/src/sd-login.c
index b7ae870..2c5b153 100644
--- a/src/sd-login.c
+++ b/src/sd-login.c
@@ -327,7 +327,6 @@ _public_ int sd_session_is_active(const char *session) {
 _public_ int sd_session_get_uid(const char *session, uid_t *uid) {
         int r;
         char *p, *s = NULL;
-        unsigned long ul;
 
         if (!session)
                 return -EINVAL;
@@ -610,7 +609,6 @@ static inline sd_login_monitor* FD_TO_MONITOR(int fd) {
 }
 
 _public_ int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
-        const char *path;
         int fd, k;
         bool good = false;
 

commit 4b67834e9f8a336dbc917f3bf212550e61cc98b4
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 01:17:59 2011 +0200

    util: make use of get_user_creds() and get_group_creds() wherever applicable

diff --git a/src/execute.c b/src/execute.c
index 40af7d6..7b25679 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -549,36 +549,6 @@ static int restore_confirm_stdio(const ExecContext *context,
         return 0;
 }
 
-static int get_group_creds(const char *groupname, gid_t *gid) {
-        struct group *g;
-        gid_t id;
-
-        assert(groupname);
-        assert(gid);
-
-        /* We enforce some special rules for gid=0: in order to avoid
-         * NSS lookups for root we hardcode its data. */
-
-        if (streq(groupname, "root") || streq(groupname, "0")) {
-                *gid = 0;
-                return 0;
-        }
-
-        if (parse_gid(groupname, &id) >= 0) {
-                errno = 0;
-                g = getgrgid(id);
-        } else {
-                errno = 0;
-                g = getgrnam(groupname);
-        }
-
-        if (!g)
-                return errno != 0 ? -errno : -ESRCH;
-
-        *gid = g->gr_gid;
-        return 0;
-}
-
 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
         bool keep_groups = false;
         int r;
@@ -590,9 +560,12 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
 
         if (context->group || username) {
 
-                if (context->group)
-                        if ((r = get_group_creds(context->group, &gid)) < 0)
+                if (context->group) {
+                        const char *g = context->group;
+
+                        if ((r = get_group_creds(&g, &gid)) < 0)
                                 return r;
+                }
 
                 /* First step, initialize groups from /etc/groups */
                 if (username && gid != 0) {
@@ -627,13 +600,16 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
                         k = 0;
 
                 STRV_FOREACH(i, context->supplementary_groups) {
+                        const char *g;
 
                         if (k >= ngroups_max) {
                                 free(gids);
                                 return -E2BIG;
                         }
 
-                        if ((r = get_group_creds(*i, gids+k)) < 0) {
+                        g = *i;
+                        r = get_group_creds(&g, gids+k);
+                        if (r < 0) {
                                 free(gids);
                                 return r;
                         }
diff --git a/src/loginctl.c b/src/loginctl.c
index 08ee804..53058d0 100644
--- a/src/loginctl.c
+++ b/src/loginctl.c
@@ -1061,17 +1061,11 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
                         uid_t uid;
                         uint32_t u;
 
-                        if (parse_uid(args[i], &uid) < 0) {
-                                struct passwd *pw;
-
-                                pw = getpwnam(args[i]);
-                                if (!pw) {
-                                        log_error("User %s unknown.", args[i]);
-                                        ret = -ENOENT;
-                                        goto finish;
-                                }
-
-                                uid = pw->pw_uid;
+                        r = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
+                        if (r < 0) {
+                                log_error("User %s unknown.", args[i]);
+                                r = -ENOENT;
+                                goto finish;
                         }
 
                         m = dbus_message_new_method_call(
@@ -1298,18 +1292,10 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (parse_uid(args[i], &uid) < 0) {
-                        struct passwd *pw;
-
-                        errno = 0;
-                        pw = getpwnam(args[i]);
-                        if (!pw) {
-                                ret = errno ? -errno : -ENOENT;
-                                log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
-                                goto finish;
-                        }
-
-                        uid = pw->pw_uid;
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to resolve user %s: %s", args[i], strerror(-ret));
+                        goto finish;
                 }
 
                 u = (uint32_t) uid;
@@ -1335,6 +1321,8 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
                 m = reply = NULL;
         }
 
+        ret = 0;
+
 finish:
         if (m)
                 dbus_message_unref(m);
@@ -1373,18 +1361,10 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (parse_uid(args[i], &uid) < 0) {
-                        struct passwd *pw;
-
-                        errno = 0;
-                        pw = getpwnam(args[i]);
-                        if (!pw) {
-                                ret = errno ? -errno : -ENOENT;
-                                log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
-                                goto finish;
-                        }
-
-                        uid = pw->pw_uid;
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
+                        goto finish;
                 }
 
                 u = (uint32_t) uid;
@@ -1408,6 +1388,8 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
                 m = reply = NULL;
         }
 
+        ret = 0;
+
 finish:
         if (m)
                 dbus_message_unref(m);
@@ -1449,18 +1431,10 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (parse_uid(args[i], &uid) < 0) {
-                        struct passwd *pw;
-
-                        errno = 0;
-                        pw = getpwnam(args[i]);
-                        if (!pw) {
-                                ret = errno ? -errno : -ENOENT;
-                                log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
-                                goto finish;
-                        }
-
-                        uid = pw->pw_uid;
+                ret = get_user_creds((const char**) (args+i), &uid, NULL, NULL);
+                if (ret < 0) {
+                        log_error("Failed to look up user %s: %s", args[i], strerror(-ret));
+                        goto finish;
                 }
 
                 u = (uint32_t) uid;
@@ -1485,6 +1459,8 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) {
                 m = reply = NULL;
         }
 
+        ret = 0;
+
 finish:
         if (m)
                 dbus_message_unref(m);
diff --git a/src/logind.c b/src/logind.c
index a081501..8b99065 100644
--- a/src/logind.c
+++ b/src/logind.c
@@ -239,17 +239,18 @@ int manager_add_user(Manager *m, uid_t uid, gid_t gid, const char *name, User **
 }
 
 int manager_add_user_by_name(Manager *m, const char *name, User **_user) {
-        struct passwd *p;
+        uid_t uid;
+        gid_t gid;
+        int r;
 
         assert(m);
         assert(name);
 
-        errno = 0;
-        p = getpwnam(name);
-        if (!p)
-                return errno ? -errno : -ENOENT;
+        r = get_user_creds(&name, &uid, &gid, NULL);
+        if (r < 0)
+                return r;
 
-        return manager_add_user(m, p->pw_uid, p->pw_gid, name, _user);
+        return manager_add_user(m, uid, gid, name, _user);
 }
 
 int manager_add_user_by_uid(Manager *m, uid_t uid, User **_user) {
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index a1b2f8b..3a1985a 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -757,18 +757,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (user && !streq(user, "-")) {
-                uid_t uid;
-                struct passwd *p;
-
-                if (streq(user, "root") || streq(user, "0"))
-                        i->uid = 0;
-                else if (parse_uid(user, &uid) >= 0)
-                        i->uid = uid;
-                else if ((p = getpwnam(user)))
-                        i->uid = p->pw_uid;
-                else {
+                const char *u = user;
+
+                r = get_user_creds(&u, &i->uid, NULL, NULL);
+                if (r < 0) {
                         log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
-                        r = -ENOENT;
                         goto finish;
                 }
 
@@ -776,18 +769,11 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (group && !streq(group, "-")) {
-                gid_t gid;
-                struct group *g;
-
-                if (streq(group, "root") || streq(group, "0"))
-                        i->gid = 0;
-                else if (parse_gid(group, &gid) >= 0)
-                        i->gid = gid;
-                else if ((g = getgrnam(group)))
-                        i->gid = g->gr_gid;
-                else {
+                const char *g = group;
+
+                r = get_group_creds(&g, &i->gid);
+                if (r < 0) {
                         log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
-                        r = -ENOENT;
                         goto finish;
                 }
 
diff --git a/src/util.c b/src/util.c
index 3a82ef7..45b578b 100644
--- a/src/util.c
+++ b/src/util.c
@@ -54,6 +54,7 @@
 #include <sys/time.h>
 #include <linux/rtc.h>
 #include <glob.h>
+#include <grp.h>
 
 #include "macro.h"
 #include "util.h"
@@ -5266,18 +5267,21 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h
 
         assert(username);
         assert(*username);
-        assert(uid);
-        assert(gid);
-        assert(home);
 
         /* We enforce some special rules for uid=0: in order to avoid
          * NSS lookups for root we hardcode its data. */
 
         if (streq(*username, "root") || streq(*username, "0")) {
                 *username = "root";
-                *uid = 0;
-                *gid = 0;
-                *home = "/root";
+
+                if (uid)
+                        *uid = 0;
+
+                if (gid)
+                        *gid = 0;
+
+                if (home)
+                        *home = "/root";
                 return 0;
         }
 
@@ -5300,9 +5304,53 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h
         if (!p)
                 return errno != 0 ? -errno : -ESRCH;
 
-        *uid = p->pw_uid;
-        *gid = p->pw_gid;
-        *home = p->pw_dir;
+        if (uid)
+                *uid = p->pw_uid;
+
+        if (gid)
+                *gid = p->pw_gid;
+
+        if (home)
+                *home = p->pw_dir;
+
+        return 0;
+}
+
+int get_group_creds(const char **groupname, gid_t *gid) {
+        struct group *g;
+        gid_t id;
+
+        assert(groupname);
+
+        /* We enforce some special rules for gid=0: in order to avoid
+         * NSS lookups for root we hardcode its data. */
+
+        if (streq(*groupname, "root") || streq(*groupname, "0")) {
+                *groupname = "root";
+
+                if (gid)
+                        *gid = 0;
+
+                return 0;
+        }
+
+        if (parse_gid(*groupname, &id) >= 0) {
+                errno = 0;
+                g = getgrgid(id);
+
+                if (g)
+                        *groupname = g->gr_name;
+        } else {
+                errno = 0;
+                g = getgrnam(*groupname);
+        }
+
+        if (!g)
+                return errno != 0 ? -errno : -ESRCH;
+
+        if (gid)
+                *gid = g->gr_gid;
+
         return 0;
 }
 
diff --git a/src/util.h b/src/util.h
index 9537d13..bf5703c 100644
--- a/src/util.h
+++ b/src/util.h
@@ -449,6 +449,7 @@ bool display_is_local(const char *display);
 int socket_from_display(const char *display, char **path);
 
 int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home);
+int get_group_creds(const char **groupname, gid_t *gid);
 
 int glob_exists(const char *path);
 

commit e6a6b406791a76ca979ff5e615fd4d9a986a14b8
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 00:49:32 2011 +0200

    install: don't choke on dead links

diff --git a/src/install.c b/src/install.c
index 9f415ed..e6bd578 100644
--- a/src/install.c
+++ b/src/install.c
@@ -1874,7 +1874,7 @@ int unit_file_get_list(
                         }
 
                         r = null_or_empty_path(f->path);
-                        if (r < 0) {
+                        if (r < 0 && r != -ENOENT) {
                                 free(f->path);
                                 free(f);
                                 goto finish;

commit 3d7d60c8225082a6ec036c794071cbfba52ee751
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 00:48:11 2011 +0200

    uaccess: port over to using sd-login

diff --git a/src/uaccess.c b/src/uaccess.c
index a9713a5..786f0ef 100644
--- a/src/uaccess.c
+++ b/src/uaccess.c
@@ -26,13 +26,13 @@
 #include "util.h"
 #include "log.h"
 #include "sd-daemon.h"
+#include "sd-login.h"
 
 int main(int argc, char *argv[]) {
         int r;
         const char *path = NULL, *seat;
-        char *p, *active_uid = NULL;
-        unsigned long ul;
         bool changed_acl = false;
+        uid_t uid;
 
         log_set_target(LOG_TARGET_AUTO);
         log_parse_environment();
@@ -52,44 +52,23 @@ int main(int argc, char *argv[]) {
         path = argv[1];
         seat = argc < 3 || isempty(argv[2]) ? "seat0" : argv[2];
 
-        p = strappend("/run/systemd/seats/", seat);
-        if (!p) {
-                log_error("Out of memory.");
-                r = -ENOMEM;
+        r = sd_seat_get_active(seat, NULL, &uid);
+        if (r == -ENOENT) {
+                /* No active session on this seat */
+                r = 0;
+                goto finish;
+        } else if (r < 0) {
+                log_error("Failed to determine active user on seat %s.", seat);
                 goto finish;
         }
 
-        r = parse_env_file(p, NEWLINE,
-                           "ACTIVE_UID", &active_uid,
-                           NULL);
-        free(p);
-
+        r = devnode_acl(path, true, false, 0, true, uid);
         if (r < 0) {
-                if (errno == ENOENT) {
-                        r = 0;
-                        goto finish;
-                }
-
-                log_error("Failed to read seat data for %s: %s", seat, strerror(-r));
+                log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
                 goto finish;
         }
 
-        if (active_uid) {
-                r = safe_atolu(active_uid, &ul);
-                if (r < 0) {
-                        log_error("Failed to parse active UID value %s: %s", active_uid, strerror(-r));
-                        goto finish;
-                }
-
-                r = devnode_acl(path, true, false, 0, true, (uid_t) ul);
-                if (r < 0) {
-                        log_error("Failed to apply ACL on %s: %s", path, strerror(-r));
-                        goto finish;
-                }
-
-                changed_acl = true;
-        }
-
+        changed_acl = true;
         r = 0;
 
 finish:
@@ -105,7 +84,5 @@ finish:
                 }
         }
 
-        free(active_uid);
-
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
 }

commit 4bf2bbb6fbfa745fa7e51f85dc59fc008207cb3e
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 00:47:50 2011 +0200

    lookup: fix NUL termination of search path array

diff --git a/src/path-lookup.c b/src/path-lookup.c
index e1925f1..bed9175 100644
--- a/src/path-lookup.c
+++ b/src/path-lookup.c
@@ -56,7 +56,8 @@ static char** user_dirs(void) {
         const char * const config_unit_paths[] = {
                 "/run/systemd/user",
                 USER_CONFIG_UNIT_PATH,
-                "/etc/systemd/user"
+                "/etc/systemd/user",
+                NULL
         };
 
         const char * const data_unit_paths[] = {
@@ -64,7 +65,8 @@ static char** user_dirs(void) {
                 "/usr/local/share/systemd/user",
                 USER_DATA_UNIT_PATH,
                 "/usr/lib/systemd/user",
-                "/usr/share/systemd/user"
+                "/usr/share/systemd/user",
+                NULL
         };
 
         const char *home, *e;

commit ddd88763921a1534081ed28e36f6712a85449005
Author: Lennart Poettering <lennart at poettering.net>
Date:   Sat Jul 23 00:47:17 2011 +0200

    util: user parse_uid() wherever applicable

diff --git a/TODO b/TODO
index ca8f1f1..62bea41 100644
--- a/TODO
+++ b/TODO
@@ -20,6 +20,8 @@ F15 External:
 
 Features:
 
+* fix CUPS .path unit for globbing
+
 * move PAM code into its own binary
 
 * logind: ensure ACLs are updated on login and logout
diff --git a/src/execute.c b/src/execute.c
index 92f4eaf..40af7d6 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -551,7 +551,7 @@ static int restore_confirm_stdio(const ExecContext *context,
 
 static int get_group_creds(const char *groupname, gid_t *gid) {
         struct group *g;
-        unsigned long lu;
+        gid_t id;
 
         assert(groupname);
         assert(gid);
@@ -564,9 +564,9 @@ static int get_group_creds(const char *groupname, gid_t *gid) {
                 return 0;
         }
 
-        if (safe_atolu(groupname, &lu) >= 0) {
+        if (parse_gid(groupname, &id) >= 0) {
                 errno = 0;
-                g = getgrgid((gid_t) lu);
+                g = getgrgid(id);
         } else {
                 errno = 0;
                 g = getgrnam(groupname);
diff --git a/src/loginctl.c b/src/loginctl.c
index 829213e..08ee804 100644
--- a/src/loginctl.c
+++ b/src/loginctl.c
@@ -1058,9 +1058,10 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
                         }
 
                 } else if (strstr(args[0], "user")) {
-                        uint32_t uid;
+                        uid_t uid;
+                        uint32_t u;
 
-                        if (safe_atou(args[i], &uid) < 0) {
+                        if (parse_uid(args[i], &uid) < 0) {
                                 struct passwd *pw;
 
                                 pw = getpwnam(args[i]);
@@ -1084,8 +1085,9 @@ static int show(DBusConnection *bus, char **args, unsigned n) {
                                 goto finish;
                         }
 
+                        u = (uint32_t) uid;
                         if (!dbus_message_append_args(m,
-                                                      DBUS_TYPE_UINT32, &uid,
+                                                      DBUS_TYPE_UINT32, &u,
                                                       DBUS_TYPE_INVALID)) {
                                 log_error("Could not append arguments to message.");
                                 ret = -ENOMEM;
@@ -1282,7 +1284,8 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
         b = streq(args[0], "enable-linger");
 
         for (i = 1; i < n; i++) {
-                uint32_t uid;
+                uint32_t u;
+                uid_t uid;
 
                 m = dbus_message_new_method_call(
                                 "org.freedesktop.login1",
@@ -1295,7 +1298,7 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (safe_atou32(args[i], &uid) < 0) {
+                if (parse_uid(args[i], &uid) < 0) {
                         struct passwd *pw;
 
                         errno = 0;
@@ -1309,8 +1312,9 @@ static int enable_linger(DBusConnection *bus, char **args, unsigned n) {
                         uid = pw->pw_uid;
                 }
 
+                u = (uint32_t) uid;
                 if (!dbus_message_append_args(m,
-                                              DBUS_TYPE_UINT32, &uid,
+                                              DBUS_TYPE_UINT32, &u,
                                               DBUS_TYPE_BOOLEAN, &b,
                                               DBUS_TYPE_BOOLEAN, &interactive,
                                               DBUS_TYPE_INVALID)) {
@@ -1356,6 +1360,7 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
 
         for (i = 1; i < n; i++) {
                 uint32_t u;
+                uid_t uid;
 
                 m = dbus_message_new_method_call(
                                 "org.freedesktop.login1",
@@ -1368,7 +1373,7 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (safe_atou32(args[i], &u) < 0) {
+                if (parse_uid(args[i], &uid) < 0) {
                         struct passwd *pw;
 
                         errno = 0;
@@ -1379,9 +1384,10 @@ static int terminate_user(DBusConnection *bus, char **args, unsigned n) {
                                 goto finish;
                         }
 
-                        u = pw->pw_uid;
+                        uid = pw->pw_uid;
                 }
 
+                u = (uint32_t) uid;
                 if (!dbus_message_append_args(m,
                                               DBUS_TYPE_UINT32, &u,
                                               DBUS_TYPE_INVALID)) {
@@ -1429,6 +1435,7 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) {
                 arg_kill_who = "all";
 
         for (i = 1; i < n; i++) {
+                uid_t uid;
                 uint32_t u;
 
                 m = dbus_message_new_method_call(
@@ -1442,7 +1449,7 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) {
                         goto finish;
                 }
 
-                if (safe_atou32(args[i], &u) < 0) {
+                if (parse_uid(args[i], &uid) < 0) {
                         struct passwd *pw;
 
                         errno = 0;
@@ -1453,9 +1460,10 @@ static int kill_user(DBusConnection *bus, char **args, unsigned n) {
                                 goto finish;
                         }
 
-                        u = pw->pw_uid;
+                        uid = pw->pw_uid;
                 }
 
+                u = (uint32_t) uid;
                 if (!dbus_message_append_args(m,
                                               DBUS_TYPE_UINT32, &u,
                                               DBUS_TYPE_INT32, arg_signal,
diff --git a/src/logind.c b/src/logind.c
index f96ace2..a081501 100644
--- a/src/logind.c
+++ b/src/logind.c
@@ -509,19 +509,19 @@ int manager_enumerate_users(Manager *m) {
         }
 
         while ((de = readdir(d))) {
-                unsigned long ul;
+                uid_t uid;
                 User *u;
 
                 if (!dirent_is_file(de))
                         continue;
 
-                k = safe_atolu(de->d_name, &ul);
+                k = parse_uid(de->d_name, &uid);
                 if (k < 0) {
                         log_error("Failed to parse file name %s: %s", de->d_name, strerror(-k));
                         continue;
                 }
 
-                u = hashmap_get(m->users, ULONG_TO_PTR(ul));
+                u = hashmap_get(m->users, ULONG_TO_PTR(uid));
                 if (!u) {
                         unlinkat(dirfd(d), de->d_name, 0);
                         continue;
diff --git a/src/pam-module.c b/src/pam-module.c
index dfeab97..a3ce246 100644
--- a/src/pam-module.c
+++ b/src/pam-module.c
@@ -180,14 +180,14 @@ static int get_user_data(
                  * it probably contains a uid of the host system. */
 
                 if (read_one_line_file("/proc/self/loginuid", &s) >= 0) {
-                        uint32_t u;
+                        uid_t uid;
 
-                        r = safe_atou32(s, &u);
+                        r = parse_uid(s, &uid);
                         free(s);
 
-                        if (r >= 0 && u != (uint32_t) -1 && u > 0) {
+                        if (r >= 0 && uid != (uint32_t) -1) {
                                 have_loginuid = true;
-                                pw = pam_modutil_getpwuid(handle, u);
+                                pw = pam_modutil_getpwuid(handle, uid);
                         }
                 }
         }
@@ -239,10 +239,10 @@ static bool check_user_lists(
         }
 
         STRV_FOREACH(l, kill_exclude_users) {
-                uint32_t id;
+                uid_t u;
 
-                if (safe_atou32(*l, &id) >= 0)
-                        if ((uid_t) id == uid)
+                if (parse_uid(*l, &u) >= 0)
+                        if (u == uid)
                                 return false;
 
                 if (name && streq(name, *l))
@@ -253,10 +253,10 @@ static bool check_user_lists(
                 return true;
 
         STRV_FOREACH(l, kill_only_users) {
-                uint32_t id;
+                uid_t u;
 
-                if (safe_atou32(*l, &id) >= 0)
-                        if ((uid_t) id == uid)
+                if (parse_uid(*l, &u) >= 0)
+                        if (u == uid)
                                 return true;
 
                 if (name && streq(name, *l))
diff --git a/src/sd-login.c b/src/sd-login.c
index 6dfc2d0..b7ae870 100644
--- a/src/sd-login.c
+++ b/src/sd-login.c
@@ -349,14 +349,10 @@ _public_ int sd_session_get_uid(const char *session, uid_t *uid) {
         if (!s)
                 return -EIO;
 
-        r = safe_atolu(s, &ul);
+        r = parse_uid(s, uid);
         free(s);
 
-        if (r < 0)
-                return r;
-
-        *uid = (uid_t) ul;
-        return 0;
+        return r;
 }
 
 _public_ int sd_session_get_seat(const char *session, char **seat) {
diff --git a/src/tmpfiles.c b/src/tmpfiles.c
index feb2a21..a1b2f8b 100644
--- a/src/tmpfiles.c
+++ b/src/tmpfiles.c
@@ -757,13 +757,13 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (user && !streq(user, "-")) {
-                unsigned long lu;
+                uid_t uid;
                 struct passwd *p;
 
                 if (streq(user, "root") || streq(user, "0"))
                         i->uid = 0;
-                else if (safe_atolu(user, &lu) >= 0)
-                        i->uid = (uid_t) lu;
+                else if (parse_uid(user, &uid) >= 0)
+                        i->uid = uid;
                 else if ((p = getpwnam(user)))
                         i->uid = p->pw_uid;
                 else {
@@ -776,13 +776,13 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
         }
 
         if (group && !streq(group, "-")) {
-                unsigned long lu;
+                gid_t gid;
                 struct group *g;
 
                 if (streq(group, "root") || streq(group, "0"))
                         i->gid = 0;
-                else if (safe_atolu(group, &lu) >= 0)
-                        i->gid = (gid_t) lu;
+                else if (parse_gid(group, &gid) >= 0)
+                        i->gid = gid;
                 else if ((g = getgrnam(group)))
                         i->gid = g->gr_gid;
                 else {
diff --git a/src/util.c b/src/util.c
index 2d4f229..3a82ef7 100644
--- a/src/util.c
+++ b/src/util.c
@@ -5262,7 +5262,7 @@ int socket_from_display(const char *display, char **path) {
 
 int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **home) {
         struct passwd *p;
-        unsigned long lu;
+        uid_t u;
 
         assert(username);
         assert(*username);
@@ -5281,9 +5281,9 @@ int get_user_creds(const char **username, uid_t *uid, gid_t *gid, const char **h
                 return 0;
         }
 
-        if (safe_atolu(*username, &lu) >= 0) {
+        if (parse_uid(*username, &u) >= 0) {
                 errno = 0;
-                p = getpwuid((uid_t) lu);
+                p = getpwuid(u);
 
                 /* If there are multiple users with the same id, make
                  * sure to leave $USER to the configured value instead



More information about the systemd-commits mailing list