/** * polkit_backend_session_monitor_get_session_for_subject: * @monitor: A #PolkitBackendSessionMonitor. * @subject: A #PolkitSubject. * @error: Return location for error. * * Gets the session corresponding to @subject or %NULL if no session exists. * * Returns: %NULL if @error is set otherwise a #PolkitUnixSession that should be freed with g_object_unref(). */ PolkitSubject * polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, PolkitSubject *subject, GError **error) { PolkitUnixProcess *tmp_process = NULL; PolkitUnixProcess *process = NULL; PolkitSubject *session = NULL; char *session_id = NULL; pid_t pid; #if HAVE_SD_UID_GET_DISPLAY uid_t uid; #endif if (POLKIT_IS_UNIX_PROCESS (subject)) process = POLKIT_UNIX_PROCESS (subject); /* We already have a process */ else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) { /* Convert bus name to process */ tmp_process = (PolkitUnixProcess*)polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); if (!tmp_process) goto out; process = tmp_process; } else { g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_NOT_SUPPORTED, "Cannot get session for subject of type %s", g_type_name (G_TYPE_FROM_INSTANCE (subject))); } /* Now do process -> pid -> same session */ g_assert (process != NULL); pid = polkit_unix_process_get_pid (process); if (sd_pid_get_session (pid, &session_id) >= 0) { session = polkit_unix_session_new (session_id); goto out; } #if HAVE_SD_UID_GET_DISPLAY /* Now do process -> uid -> graphical session (systemd version 213)*/ if (sd_pid_get_owner_uid (pid, &uid) < 0) goto out; if (sd_uid_get_display (uid, &session_id) >= 0) { session = polkit_unix_session_new (session_id); goto out; } #endif out: free (session_id); if (tmp_process) g_object_unref (tmp_process); return session; }
/** * pk_dbus_get_session_systemd: **/ static gchar * pk_dbus_get_session_systemd (guint pid) { g_autofree gchar *session_id = NULL; uid_t uid; /* do process -> pid -> same session */ if (sd_pid_get_session (pid, &session_id) >= 0) return pk_dbus_make_logind_session_id (session_id); /* do process -> uid -> graphical session */ if (sd_pid_get_owner_uid (pid, &uid) < 0) return NULL; if (sd_uid_get_display (uid, &session_id) >= 0) return pk_dbus_make_logind_session_id (session_id); return NULL; }
int main(int argc, char* argv[]) { /* The small core field we allocate on the stack, to keep things simple */ char *core_pid = NULL, *core_uid = NULL, *core_gid = NULL, *core_signal = NULL, *core_session = NULL, *core_exe = NULL, *core_comm = NULL, *core_cmdline = NULL, *core_cgroup = NULL, *core_cwd = NULL, *core_root = NULL, *core_unit = NULL, *core_slice = NULL; /* The larger ones we allocate on the heap */ _cleanup_free_ char *core_timestamp = NULL, *core_message = NULL, *coredump_data = NULL, *core_owner_uid = NULL, *core_open_fds = NULL, *core_proc_status = NULL, *core_proc_maps = NULL, *core_proc_limits = NULL, *core_proc_cgroup = NULL, *core_environ = NULL; _cleanup_free_ char *exe = NULL, *comm = NULL, *filename = NULL; const char *info[_INFO_LEN]; _cleanup_close_ int coredump_fd = -1; struct iovec iovec[26]; uint64_t coredump_size; int r, j = 0; uid_t uid, owner_uid; gid_t gid; pid_t pid; char *t; const char *p; /* Make sure we never enter a loop */ prctl(PR_SET_DUMPABLE, 0); /* First, log to a safe place, since we don't know what * crashed and it might be journald which we'd rather not log * to then. */ log_set_target(LOG_TARGET_KMSG); log_open(); if (argc < INFO_COMM + 1) { log_error("Not enough arguments passed from kernel (%d, expected %d).", argc - 1, INFO_COMM + 1 - 1); r = -EINVAL; goto finish; } /* Ignore all parse errors */ parse_config(); log_debug("Selected storage '%s'.", coredump_storage_to_string(arg_storage)); log_debug("Selected compression %s.", yes_no(arg_compress)); r = parse_uid(argv[INFO_UID + 1], &uid); if (r < 0) { log_error("Failed to parse UID."); goto finish; } r = parse_pid(argv[INFO_PID + 1], &pid); if (r < 0) { log_error("Failed to parse PID."); goto finish; } r = parse_gid(argv[INFO_GID + 1], &gid); if (r < 0) { log_error("Failed to parse GID."); goto finish; } if (get_process_comm(pid, &comm) < 0) { log_warning("Failed to get COMM, falling back to the command line."); comm = strv_join(argv + INFO_COMM + 1, " "); } if (get_process_exe(pid, &exe) < 0) log_warning("Failed to get EXE."); info[INFO_PID] = argv[INFO_PID + 1]; info[INFO_UID] = argv[INFO_UID + 1]; info[INFO_GID] = argv[INFO_GID + 1]; info[INFO_SIGNAL] = argv[INFO_SIGNAL + 1]; info[INFO_TIMESTAMP] = argv[INFO_TIMESTAMP + 1]; info[INFO_COMM] = comm; info[INFO_EXE] = exe; if (cg_pid_get_unit(pid, &t) >= 0) { if (streq(t, SPECIAL_JOURNALD_SERVICE)) { free(t); /* If we are journald, we cut things short, * don't write to the journal, but still * create a coredump. */ if (arg_storage != COREDUMP_STORAGE_NONE) arg_storage = COREDUMP_STORAGE_EXTERNAL; r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size); if (r < 0) goto finish; r = maybe_remove_external_coredump(filename, coredump_size); if (r < 0) goto finish; log_info("Detected coredump of the journal daemon itself, diverted to %s.", filename); goto finish; } core_unit = strjoina("COREDUMP_UNIT=", t); free(t); } else if (cg_pid_get_user_unit(pid, &t) >= 0) { core_unit = strjoina("COREDUMP_USER_UNIT=", t); free(t); } if (core_unit) IOVEC_SET_STRING(iovec[j++], core_unit); /* OK, now we know it's not the journal, hence we can make use * of it now. */ log_set_target(LOG_TARGET_JOURNAL_OR_KMSG); log_open(); core_pid = strjoina("COREDUMP_PID=", info[INFO_PID]); IOVEC_SET_STRING(iovec[j++], core_pid); core_uid = strjoina("COREDUMP_UID=", info[INFO_UID]); IOVEC_SET_STRING(iovec[j++], core_uid); core_gid = strjoina("COREDUMP_GID=", info[INFO_GID]); IOVEC_SET_STRING(iovec[j++], core_gid); core_signal = strjoina("COREDUMP_SIGNAL=", info[INFO_SIGNAL]); IOVEC_SET_STRING(iovec[j++], core_signal); if (sd_pid_get_session(pid, &t) >= 0) { core_session = strjoina("COREDUMP_SESSION=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_session); } if (sd_pid_get_owner_uid(pid, &owner_uid) >= 0) { r = asprintf(&core_owner_uid, "COREDUMP_OWNER_UID=" UID_FMT, owner_uid); if (r > 0) IOVEC_SET_STRING(iovec[j++], core_owner_uid); } if (sd_pid_get_slice(pid, &t) >= 0) { core_slice = strjoina("COREDUMP_SLICE=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_slice); } if (comm) { core_comm = strjoina("COREDUMP_COMM=", comm); IOVEC_SET_STRING(iovec[j++], core_comm); } if (exe) { core_exe = strjoina("COREDUMP_EXE=", exe); IOVEC_SET_STRING(iovec[j++], core_exe); } if (get_process_cmdline(pid, 0, false, &t) >= 0) { core_cmdline = strjoina("COREDUMP_CMDLINE=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cmdline); } if (cg_pid_get_path_shifted(pid, NULL, &t) >= 0) { core_cgroup = strjoina("COREDUMP_CGROUP=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cgroup); } if (compose_open_fds(pid, &t) >= 0) { core_open_fds = strappend("COREDUMP_OPEN_FDS=", t); free(t); if (core_open_fds) IOVEC_SET_STRING(iovec[j++], core_open_fds); } p = procfs_file_alloca(pid, "status"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_status = strappend("COREDUMP_PROC_STATUS=", t); free(t); if (core_proc_status) IOVEC_SET_STRING(iovec[j++], core_proc_status); } p = procfs_file_alloca(pid, "maps"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_maps = strappend("COREDUMP_PROC_MAPS=", t); free(t); if (core_proc_maps) IOVEC_SET_STRING(iovec[j++], core_proc_maps); } p = procfs_file_alloca(pid, "limits"); if (read_full_file(p, &t, NULL) >= 0) { core_proc_limits = strappend("COREDUMP_PROC_LIMITS=", t); free(t); if (core_proc_limits) IOVEC_SET_STRING(iovec[j++], core_proc_limits); } p = procfs_file_alloca(pid, "cgroup"); if (read_full_file(p, &t, NULL) >=0) { core_proc_cgroup = strappend("COREDUMP_PROC_CGROUP=", t); free(t); if (core_proc_cgroup) IOVEC_SET_STRING(iovec[j++], core_proc_cgroup); } if (get_process_cwd(pid, &t) >= 0) { core_cwd = strjoina("COREDUMP_CWD=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_cwd); } if (get_process_root(pid, &t) >= 0) { core_root = strjoina("COREDUMP_ROOT=", t); free(t); IOVEC_SET_STRING(iovec[j++], core_root); } if (get_process_environ(pid, &t) >= 0) { core_environ = strappend("COREDUMP_ENVIRON=", t); free(t); if (core_environ) IOVEC_SET_STRING(iovec[j++], core_environ); } core_timestamp = strjoin("COREDUMP_TIMESTAMP=", info[INFO_TIMESTAMP], "000000", NULL); if (core_timestamp) IOVEC_SET_STRING(iovec[j++], core_timestamp); IOVEC_SET_STRING(iovec[j++], "MESSAGE_ID=fc2e22bc6ee647b6b90729ab34a250b1"); IOVEC_SET_STRING(iovec[j++], "PRIORITY=2"); /* Vacuum before we write anything again */ coredump_vacuum(-1, arg_keep_free, arg_max_use); /* Always stream the coredump to disk, if that's possible */ r = save_external_coredump(info, uid, &filename, &coredump_fd, &coredump_size); if (r < 0) /* skip whole core dumping part */ goto log; /* If we don't want to keep the coredump on disk, remove it * now, as later on we will lack the privileges for * it. However, we keep the fd to it, so that we can still * process it and log it. */ r = maybe_remove_external_coredump(filename, coredump_size); if (r < 0) goto finish; if (r == 0) { const char *coredump_filename; coredump_filename = strjoina("COREDUMP_FILENAME=", filename); IOVEC_SET_STRING(iovec[j++], coredump_filename); } /* Vacuum again, but exclude the coredump we just created */ coredump_vacuum(coredump_fd, arg_keep_free, arg_max_use); /* Now, let's drop privileges to become the user who owns the * segfaulted process and allocate the coredump memory under * the user's uid. This also ensures that the credentials * journald will see are the ones of the coredumping user, * thus making sure the user gets access to the core * dump. Let's also get rid of all capabilities, if we run as * root, we won't need them anymore. */ r = drop_privileges(uid, gid, 0); if (r < 0) { log_error_errno(r, "Failed to drop privileges: %m"); goto finish; } #ifdef HAVE_ELFUTILS /* Try to get a strack trace if we can */ if (coredump_size <= arg_process_size_max) { _cleanup_free_ char *stacktrace = NULL; r = coredump_make_stack_trace(coredump_fd, exe, &stacktrace); if (r >= 0) core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.\n\n", stacktrace, NULL); else if (r == -EINVAL) log_warning("Failed to generate stack trace: %s", dwfl_errmsg(dwfl_errno())); else log_warning_errno(r, "Failed to generate stack trace: %m"); } if (!core_message) #endif log: core_message = strjoin("MESSAGE=Process ", info[INFO_PID], " (", comm, ") of user ", info[INFO_UID], " dumped core.", NULL); if (core_message) IOVEC_SET_STRING(iovec[j++], core_message); /* Optionally store the entire coredump in the journal */ if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) && coredump_size <= arg_journal_size_max) { size_t sz = 0; /* Store the coredump itself in the journal */ r = allocate_journal_field(coredump_fd, (size_t) coredump_size, &coredump_data, &sz); if (r >= 0) { iovec[j].iov_base = coredump_data; iovec[j].iov_len = sz; j++; } } r = sd_journal_sendv(iovec, j); if (r < 0) log_error_errno(r, "Failed to log coredump: %m"); finish: return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; }
static void test_login(void) { int r, k; uid_t u, u2; char *seat, *type, *class, *display; char *session; char *state; char *session2; char *t; char **seats, **sessions, **machines; uid_t *uids; unsigned n; struct pollfd pollfd; sd_login_monitor *m; assert_se(sd_pid_get_session(0, &session) == 0); printf("session = %s\n", session); assert_se(sd_pid_get_owner_uid(0, &u2) == 0); printf("user = %lu\n", (unsigned long) u2); r = sd_uid_get_sessions(u2, false, &sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); assert_se(r == sd_uid_get_sessions(u2, false, NULL)); r = sd_uid_get_seats(u2, false, &seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("seats = %s\n", t); free(t); assert_se(r == sd_uid_get_seats(u2, false, NULL)); r = sd_session_is_active(session); assert_se(r >= 0); printf("active = %s\n", yes_no(r)); r = sd_session_get_state(session, &state); assert_se(r >= 0); printf("state = %s\n", state); free(state); assert_se(sd_session_get_uid(session, &u) >= 0); printf("uid = %lu\n", (unsigned long) u); assert_se(u == u2); assert_se(sd_session_get_type(session, &type) >= 0); printf("type = %s\n", type); free(type); assert_se(sd_session_get_class(session, &class) >= 0); printf("class = %s\n", class); free(class); assert_se(sd_session_get_display(session, &display) >= 0); printf("display = %s\n", display); free(display); assert_se(sd_session_get_seat(session, &seat) >= 0); printf("seat = %s\n", seat); r = sd_seat_can_multi_session(seat); assert_se(r >= 0); printf("can do multi session = %s\n", yes_no(r)); r = sd_seat_can_tty(seat); assert_se(r >= 0); printf("can do tty = %s\n", yes_no(r)); r = sd_seat_can_graphical(seat); assert_se(r >= 0); printf("can do graphical = %s\n", yes_no(r)); assert_se(sd_uid_get_state(u, &state) >= 0); printf("state = %s\n", state); assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); k = sd_uid_is_on_seat(u, 1, seat); assert_se(k >= 0); assert_se(!!r == !!r); assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); printf("session2 = %s\n", session2); printf("uid2 = %lu\n", (unsigned long) u2); r = sd_seat_get_sessions(seat, &sessions, &uids, &n); assert_se(r >= 0); printf("n_sessions = %i\n", r); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); printf("uids ="); for (k = 0; k < (int) n; k++) printf(" %lu", (unsigned long) uids[k]); printf("\n"); free(uids); assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); free(session); free(state); free(session2); free(seat); r = sd_get_seats(&seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("n_seats = %i\n", r); printf("seats = %s\n", t); free(t); assert_se(sd_get_seats(NULL) == r); r = sd_seat_get_active(NULL, &t, NULL); assert_se(r >= 0); printf("active session on current seat = %s\n", t); free(t); r = sd_get_sessions(&sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("n_sessions = %i\n", r); printf("sessions = %s\n", t); free(t); assert_se(sd_get_sessions(NULL) == r); r = sd_get_uids(&uids); assert_se(r >= 0); printf("uids ="); for (k = 0; k < r; k++) printf(" %lu", (unsigned long) uids[k]); printf("\n"); free(uids); printf("n_uids = %i\n", r); assert_se(sd_get_uids(NULL) == r); r = sd_get_machine_names(&machines); assert_se(r >= 0); assert_se(r == (int) strv_length(machines)); assert_se(t = strv_join(machines, ", ")); strv_free(machines); printf("n_machines = %i\n", r); printf("machines = %s\n", t); free(t); r = sd_login_monitor_new("session", &m); assert_se(r >= 0); for (n = 0; n < 5; n++) { usec_t timeout, nw; zero(pollfd); assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0); assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0); assert_se(sd_login_monitor_get_timeout(m, &timeout) >= 0); nw = now(CLOCK_MONOTONIC); r = poll(&pollfd, 1, timeout == (uint64_t) -1 ? -1 : timeout > nw ? (int) ((timeout - nw) / 1000) : 0); assert_se(r >= 0); sd_login_monitor_flush(m); printf("Wake!\n"); } sd_login_monitor_unref(m); }
int main(int argc, char* argv[]) { int r, k; uid_t u, u2; char *seat, *type, *class, *display; char *session; char *state; char *session2; char *t; char **seats, **sessions; uid_t *uids; unsigned n; struct pollfd pollfd; sd_login_monitor *m; assert_se(sd_pid_get_session(0, &session) == 0); printf("session = %s\n", session); assert_se(sd_pid_get_owner_uid(0, &u2) == 0); printf("user = %lu\n", (unsigned long) u2); r = sd_uid_get_sessions(u2, false, &sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); assert_se(r == sd_uid_get_sessions(u2, false, NULL)); r = sd_uid_get_seats(u2, false, &seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("seats = %s\n", t); free(t); assert_se(r == sd_uid_get_seats(u2, false, NULL)); r = sd_session_is_active(session); assert_se(r >= 0); printf("active = %s\n", yes_no(r)); r = sd_session_get_state(session, &state); assert_se(r >= 0); printf("state = %s\n", state); free(state); assert_se(sd_session_get_uid(session, &u) >= 0); printf("uid = %lu\n", (unsigned long) u); assert_se(u == u2); assert_se(sd_session_get_type(session, &type) >= 0); printf("type = %s\n", type); free(type); assert_se(sd_session_get_class(session, &class) >= 0); printf("class = %s\n", class); free(class); assert_se(sd_session_get_display(session, &display) >= 0); printf("display = %s\n", display); free(display); assert_se(sd_session_get_seat(session, &seat) >= 0); printf("seat = %s\n", seat); r = sd_seat_can_multi_session(seat); assert_se(r >= 0); printf("can do multi session = %s\n", yes_no(r)); r = sd_seat_can_tty(seat); assert_se(r >= 0); printf("can do tty = %s\n", yes_no(r)); r = sd_seat_can_graphical(seat); assert_se(r >= 0); printf("can do graphical = %s\n", yes_no(r)); assert_se(sd_uid_get_state(u, &state) >= 0); printf("state = %s\n", state); assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); k = sd_uid_is_on_seat(u, 1, seat); assert_se(k >= 0); assert_se(!!r == !!r); assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); printf("session2 = %s\n", session2); printf("uid2 = %lu\n", (unsigned long) u2); r = sd_seat_get_sessions(seat, &sessions, &uids, &n); assert_se(r >= 0); printf("n_sessions = %i\n", r); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); printf("uids ="); for (k = 0; k < (int) n; k++) printf(" %lu", (unsigned long) uids[k]); printf("\n"); free(uids); assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); free(session); free(state); free(session2); free(seat); r = sd_get_seats(&seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("n_seats = %i\n", r); printf("seats = %s\n", t); free(t); assert_se(sd_get_seats(NULL) == r); r = sd_seat_get_active(NULL, &t, NULL); assert_se(r >= 0); printf("active session on current seat = %s\n", t); free(t); r = sd_get_sessions(&sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("n_sessions = %i\n", r); printf("sessions = %s\n", t); free(t); assert_se(sd_get_sessions(NULL) == r); r = sd_get_uids(&uids); assert_se(r >= 0); printf("uids ="); for (k = 0; k < r; k++) printf(" %lu", (unsigned long) uids[k]); printf("\n"); free(uids); printf("n_uids = %i\n", r); assert_se(sd_get_uids(NULL) == r); r = sd_login_monitor_new("session", &m); assert_se(r >= 0); zero(pollfd); pollfd.fd = sd_login_monitor_get_fd(m); pollfd.events = POLLIN; for (n = 0; n < 5; n++) { r = poll(&pollfd, 1, -1); assert_se(r >= 0); sd_login_monitor_flush(m); printf("Wake!\n"); } sd_login_monitor_unref(m); return 0; }
static void test_login(void) { _cleanup_close_pair_ int pair[2] = { -1, -1 }; _cleanup_free_ char *pp = NULL, *qq = NULL; int r, k; uid_t u, u2; char *seat, *type, *class, *display, *remote_user, *remote_host, *display_session; char *session; char *state; char *session2; char *t; char **seats, **sessions, **machines; uid_t *uids; unsigned n; struct pollfd pollfd; sd_login_monitor *m = NULL; assert_se(sd_pid_get_session(0, &session) == 0); printf("session = %s\n", session); assert_se(sd_pid_get_owner_uid(0, &u2) == 0); printf("user = "******"\n", u2); display_session = NULL; r = sd_uid_get_display(u2, &display_session); assert_se(r >= 0 || r == -ENXIO); printf("user's display session = %s\n", strna(display_session)); free(display_session); assert_se(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == 0); sd_peer_get_session(pair[0], &pp); sd_peer_get_session(pair[1], &qq); assert_se(streq_ptr(pp, qq)); r = sd_uid_get_sessions(u2, false, &sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); assert_se(r == sd_uid_get_sessions(u2, false, NULL)); r = sd_uid_get_seats(u2, false, &seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("seats = %s\n", t); free(t); assert_se(r == sd_uid_get_seats(u2, false, NULL)); r = sd_session_is_active(session); assert_se(r >= 0); printf("active = %s\n", yes_no(r)); r = sd_session_is_remote(session); assert_se(r >= 0); printf("remote = %s\n", yes_no(r)); r = sd_session_get_state(session, &state); assert_se(r >= 0); printf("state = %s\n", state); free(state); assert_se(sd_session_get_uid(session, &u) >= 0); printf("uid = "UID_FMT"\n", u); assert_se(u == u2); assert_se(sd_session_get_type(session, &type) >= 0); printf("type = %s\n", type); free(type); assert_se(sd_session_get_class(session, &class) >= 0); printf("class = %s\n", class); free(class); display = NULL; r = sd_session_get_display(session, &display); assert_se(r >= 0 || r == -ENXIO); printf("display = %s\n", strna(display)); free(display); remote_user = NULL; r = sd_session_get_remote_user(session, &remote_user); assert_se(r >= 0 || r == -ENXIO); printf("remote_user = %s\n", strna(remote_user)); free(remote_user); remote_host = NULL; r = sd_session_get_remote_host(session, &remote_host); assert_se(r >= 0 || r == -ENXIO); printf("remote_host = %s\n", strna(remote_host)); free(remote_host); assert_se(sd_session_get_seat(session, &seat) >= 0); printf("seat = %s\n", seat); r = sd_seat_can_multi_session(seat); assert_se(r >= 0); printf("can do multi session = %s\n", yes_no(r)); r = sd_seat_can_tty(seat); assert_se(r >= 0); printf("can do tty = %s\n", yes_no(r)); r = sd_seat_can_graphical(seat); assert_se(r >= 0); printf("can do graphical = %s\n", yes_no(r)); assert_se(sd_uid_get_state(u, &state) >= 0); printf("state = %s\n", state); assert_se(sd_uid_is_on_seat(u, 0, seat) > 0); k = sd_uid_is_on_seat(u, 1, seat); assert_se(k >= 0); assert_se(!!r == !!r); assert_se(sd_seat_get_active(seat, &session2, &u2) >= 0); printf("session2 = %s\n", session2); printf("uid2 = "UID_FMT"\n", u2); r = sd_seat_get_sessions(seat, &sessions, &uids, &n); assert_se(r >= 0); printf("n_sessions = %i\n", r); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("sessions = %s\n", t); free(t); printf("uids ="); for (k = 0; k < (int) n; k++) printf(" "UID_FMT, uids[k]); printf("\n"); free(uids); assert_se(sd_seat_get_sessions(seat, NULL, NULL, NULL) == r); free(session); free(state); free(session2); free(seat); r = sd_get_seats(&seats); assert_se(r >= 0); assert_se(r == (int) strv_length(seats)); assert_se(t = strv_join(seats, ", ")); strv_free(seats); printf("n_seats = %i\n", r); printf("seats = %s\n", t); free(t); assert_se(sd_get_seats(NULL) == r); r = sd_seat_get_active(NULL, &t, NULL); assert_se(r >= 0); printf("active session on current seat = %s\n", t); free(t); r = sd_get_sessions(&sessions); assert_se(r >= 0); assert_se(r == (int) strv_length(sessions)); assert_se(t = strv_join(sessions, ", ")); strv_free(sessions); printf("n_sessions = %i\n", r); printf("sessions = %s\n", t); free(t); assert_se(sd_get_sessions(NULL) == r); r = sd_get_uids(&uids); assert_se(r >= 0); printf("uids ="); for (k = 0; k < r; k++) printf(" "UID_FMT, uids[k]); printf("\n"); free(uids); printf("n_uids = %i\n", r); assert_se(sd_get_uids(NULL) == r); r = sd_get_machine_names(&machines); assert_se(r >= 0); assert_se(r == (int) strv_length(machines)); assert_se(t = strv_join(machines, ", ")); strv_free(machines); printf("n_machines = %i\n", r); printf("machines = %s\n", t); free(t); r = sd_login_monitor_new("session", &m); assert_se(r >= 0); for (n = 0; n < 5; n++) { usec_t timeout, nw; zero(pollfd); assert_se((pollfd.fd = sd_login_monitor_get_fd(m)) >= 0); assert_se((pollfd.events = sd_login_monitor_get_events(m)) >= 0); assert_se(sd_login_monitor_get_timeout(m, &timeout) >= 0); nw = now(CLOCK_MONOTONIC); r = poll(&pollfd, 1, timeout == (uint64_t) -1 ? -1 : timeout > nw ? (int) ((timeout - nw) / 1000) : 0); assert_se(r >= 0); sd_login_monitor_flush(m); printf("Wake!\n"); } sd_login_monitor_unref(m); }