chiark / gitweb /
logind: when generating session ids with a counter, retry if session is already allocated
[elogind.git] / src / logind-dbus.c
index 693906ef70e05cbd8d0a8b2b6ab7aa2c4b1451d3..2bad549fc528a60e49eda77ec1027cfda8d4e32e 100644 (file)
@@ -176,7 +176,7 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
         Seat *s;
         DBusMessageIter iter;
         int r;
-        char *id, *p;
+        char *id = NULL, *p;
         int vtnr = -1;
         int pipe_fds[2] = { -1, -1 };
         DBusMessage *reply = NULL;
@@ -306,19 +306,30 @@ static int bus_manager_create_session(Manager *m, DBusMessage *message, DBusMess
 
         audit_session_from_pid(leader, &audit_id);
 
-        if (audit_id > 0)
+        if (audit_id > 0) {
                 asprintf(&id, "%lu", (unsigned long) audit_id);
-        else
-                asprintf(&id, "c%lu", ++m->session_counter);
 
-        if (!id) {
-                r = -ENOMEM;
-                goto fail;
-        }
+                if (!id) {
+                        r = -ENOMEM;
+                        goto fail;
+                }
 
-        if (hashmap_get(m->sessions, id)) {
-                r = -EEXIST;
-                goto fail;
+                if (hashmap_get(m->sessions, id)) {
+                        r = -EEXIST;
+                        goto fail;
+                }
+
+        } else {
+                do {
+                        free(id);
+                        asprintf(&id, "c%lu", ++m->session_counter);
+
+                        if (!id) {
+                                r = -ENOMEM;
+                                goto fail;
+                        }
+
+                } while (hashmap_get(m->sessions, id));
         }
 
         r = manager_add_session(m, user, id, &session);
@@ -589,7 +600,7 @@ static DBusHandlerResult manager_message_handler(
 
                 dbus_message_iter_init_append(reply, &iter);
 
-                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "susso", &sub))
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(susso)", &sub))
                         goto oom;
 
                 HASHMAP_FOREACH(session, m->sessions, i) {
@@ -635,7 +646,7 @@ static DBusHandlerResult manager_message_handler(
 
                 dbus_message_iter_init_append(reply, &iter);
 
-                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "uso", &sub))
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(uso)", &sub))
                         goto oom;
 
                 HASHMAP_FOREACH(user, m->users, i) {
@@ -679,7 +690,7 @@ static DBusHandlerResult manager_message_handler(
 
                 dbus_message_iter_init_append(reply, &iter);
 
-                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "so", &sub))
+                if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "(so)", &sub))
                         goto oom;
 
                 HASHMAP_FOREACH(seat, m->seats, i) {
@@ -896,6 +907,36 @@ const DBusObjectPathVTable bus_manager_vtable = {
         .message_function = manager_message_handler
 };
 
+DBusHandlerResult bus_message_filter(
+                DBusConnection *connection,
+                DBusMessage *message,
+                void *userdata) {
+
+        Manager *m = userdata;
+        DBusError error;
+
+        assert(m);
+        assert(connection);
+        assert(message);
+
+        dbus_error_init(&error);
+
+        if (dbus_message_is_signal(message, "org.freedesktop.systemd1.Agent", "Released")) {
+                const char *cgroup;
+
+                if (!dbus_message_get_args(message, &error,
+                                           DBUS_TYPE_STRING, &cgroup,
+                                           DBUS_TYPE_INVALID))
+                        log_error("Failed to parse Released message: %s", bus_error_message(&error));
+                else
+                        manager_cgroup_notify_empty(m, cgroup);
+        }
+
+        dbus_error_free(&error);
+
+        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
+
 int manager_send_changed(Manager *manager, const char *properties) {
         DBusMessage *m;
         int r = -ENOMEM;