]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-login/test-login.c
a4ab2659b21e290f25d007c6e741d2b06b2ce79d
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
4 #include <sys/socket.h>
8 #include "alloc-util.h"
10 #include "errno-list.h"
12 #include "format-util.h"
14 #include "pidfd-util.h"
15 #include "process-util.h"
16 #include "string-util.h"
19 #include "time-util.h"
20 #include "user-util.h"
22 static char* format_uids(char **buf
, uid_t
* uids
, int count
) {
24 size_t size
= (DECIMAL_STR_MAX(uid_t
) + 1) * count
+ 1;
26 assert_se(*buf
= malloc(size
));
28 for (int k
= 0; k
< count
; k
++) {
29 sprintf(*buf
+ pos
, "%s"UID_FMT
"%n", k
> 0 ? " " : "", uids
[k
], &inc
);
33 assert_se(pos
< (ssize_t
)size
);
39 static const char *e(int r
) {
40 return r
== 0 ? "OK" : errno_to_name(r
);
44 _cleanup_close_pair_
int pair
[2] = EBADF_PAIR
;
45 _cleanup_free_
char *pp
= NULL
, *qq
= NULL
,
46 *display_session
= NULL
, *cgroup
= NULL
,
47 *display
= NULL
, *remote_user
= NULL
, *remote_host
= NULL
,
48 *type
= NULL
, *class = NULL
, *state
= NULL
, *state2
= NULL
,
49 *seat
= NULL
, *session
= NULL
,
50 *unit
= NULL
, *user_unit
= NULL
, *slice
= NULL
;
51 _cleanup_close_
int pidfd
= -EBADF
;
53 uid_t u
, u2
= UID_INVALID
;
54 char *t
, **seats
= NULL
, **sessions
= NULL
;
56 r
= sd_pid_get_unit(0, &unit
);
57 log_info("sd_pid_get_unit(0, …) → %s / \"%s\"", e(r
), strnull(unit
));
58 assert_se(IN_SET(r
, 0, -ENODATA
));
60 r
= sd_pid_get_user_unit(0, &user_unit
);
61 log_info("sd_pid_get_user_unit(0, …) → %s / \"%s\"", e(r
), strnull(user_unit
));
62 assert_se(IN_SET(r
, 0, -ENODATA
));
64 r
= sd_pid_get_slice(0, &slice
);
65 log_info("sd_pid_get_slice(0, …) → %s / \"%s\"", e(r
), strnull(slice
));
66 assert_se(IN_SET(r
, 0, -ENODATA
));
68 r
= sd_pid_get_owner_uid(0, &u2
);
69 log_info("sd_pid_get_owner_uid(0, …) → %s / "UID_FMT
, e(r
), u2
);
70 assert_se(IN_SET(r
, 0, -ENODATA
));
72 r
= sd_pid_get_session(0, &session
);
73 log_info("sd_pid_get_session(0, …) → %s / \"%s\"", e(r
), strnull(session
));
75 r
= sd_pid_get_cgroup(0, &cgroup
);
76 log_info("sd_pid_get_cgroup(0, …) → %s / \"%s\"", e(r
), strnull(cgroup
));
77 assert_se(IN_SET(r
, 0, -ENOMEDIUM
));
79 pidfd
= pidfd_open(getpid_cached(), 0);
81 _cleanup_free_
char *cgroup2
= NULL
, *session2
= NULL
,
82 *unit2
= NULL
, *user_unit2
= NULL
, *slice2
= NULL
;
84 r
= sd_pidfd_get_unit(pidfd
, &unit2
);
85 log_info("sd_pidfd_get_unit(pidfd, …) → %s / \"%s\"", e(r
), strnull(unit2
));
86 assert_se(IN_SET(r
, 0, -ENODATA
));
88 r
= sd_pidfd_get_user_unit(pidfd
, &user_unit2
);
89 log_info("sd_pidfd_get_user_unit(pidfd, …) → %s / \"%s\"", e(r
), strnull(user_unit2
));
90 assert_se(IN_SET(r
, 0, -ENODATA
));
92 r
= sd_pidfd_get_slice(pidfd
, &slice2
);
93 log_info("sd_pidfd_get_slice(pidfd, …) → %s / \"%s\"", e(r
), strnull(slice2
));
94 assert_se(IN_SET(r
, 0, -ENODATA
));
96 r
= sd_pidfd_get_owner_uid(pidfd
, &u2
);
97 log_info("sd_pidfd_get_owner_uid(pidfd, …) → %s / "UID_FMT
, e(r
), u2
);
98 assert_se(IN_SET(r
, 0, -ENODATA
));
100 r
= sd_pidfd_get_session(pidfd
, &session2
);
101 log_info("sd_pidfd_get_session(pidfd, …) → %s / \"%s\"", e(r
), strnull(session2
));
103 r
= sd_pidfd_get_cgroup(pidfd
, &cgroup2
);
104 log_info("sd_pidfd_get_cgroup(pidfd, …) → %s / \"%s\"", e(r
), strnull(cgroup2
));
105 assert_se(IN_SET(r
, 0, -ENOMEDIUM
));
108 r
= ASSERT_RETURN_IS_CRITICAL(uid_is_valid(u2
), sd_uid_get_display(u2
, &display_session
));
109 log_info("sd_uid_get_display("UID_FMT
", …) → %s / \"%s\"", u2
, e(r
), strnull(display_session
));
110 if (u2
== UID_INVALID
)
111 assert_se(r
== -EINVAL
);
113 assert_se(IN_SET(r
, 0, -ENODATA
));
115 assert_se(socketpair(AF_UNIX
, SOCK_STREAM
, 0, pair
) == 0);
116 sd_peer_get_session(pair
[0], &pp
);
117 sd_peer_get_session(pair
[1], &qq
);
118 assert_se(streq_ptr(pp
, qq
));
120 r
= ASSERT_RETURN_IS_CRITICAL(uid_is_valid(u2
), sd_uid_get_sessions(u2
, false, &sessions
));
121 assert_se(t
= strv_join(sessions
, " "));
122 log_info("sd_uid_get_sessions("UID_FMT
", …) → %s \"%s\"", u2
, e(r
), t
);
123 if (u2
== UID_INVALID
)
124 assert_se(r
== -EINVAL
);
127 assert_se(r
== (int) strv_length(sessions
));
129 sessions
= strv_free(sessions
);
132 assert_se(r
== ASSERT_RETURN_IS_CRITICAL(uid_is_valid(u2
), sd_uid_get_sessions(u2
, false, NULL
)));
134 r
= ASSERT_RETURN_IS_CRITICAL(uid_is_valid(u2
), sd_uid_get_seats(u2
, false, &seats
));
135 assert_se(t
= strv_join(seats
, " "));
136 log_info("sd_uid_get_seats("UID_FMT
", …) → %s \"%s\"", u2
, e(r
), t
);
137 if (u2
== UID_INVALID
)
138 assert_se(r
== -EINVAL
);
141 assert_se(r
== (int) strv_length(seats
));
143 seats
= strv_free(seats
);
146 assert_se(r
== ASSERT_RETURN_IS_CRITICAL(uid_is_valid(u2
), sd_uid_get_seats(u2
, false, NULL
)));
149 r
= sd_session_is_active(session
);
151 log_notice("sd_session_is_active() failed with ENXIO, it seems logind is not running.");
153 /* All those tests will fail with ENXIO, so let's skip them. */
156 log_info("sd_session_is_active(\"%s\") → %s", session
, yes_no(r
));
158 r
= sd_session_is_remote(session
);
160 log_info("sd_session_is_remote(\"%s\") → %s", session
, yes_no(r
));
162 r
= sd_session_get_state(session
, &state
);
164 log_info("sd_session_get_state(\"%s\") → \"%s\"", session
, state
);
166 assert_se(sd_session_get_uid(session
, &u
) >= 0);
167 log_info("sd_session_get_uid(\"%s\") → "UID_FMT
, session
, u
);
170 assert_se(sd_session_get_type(session
, &type
) >= 0);
171 log_info("sd_session_get_type(\"%s\") → \"%s\"", session
, type
);
173 assert_se(sd_session_get_class(session
, &class) >= 0);
174 log_info("sd_session_get_class(\"%s\") → \"%s\"", session
, class);
176 r
= sd_session_get_display(session
, &display
);
177 assert_se(IN_SET(r
, 0, -ENODATA
));
178 log_info("sd_session_get_display(\"%s\") → \"%s\"", session
, strna(display
));
180 r
= sd_session_get_remote_user(session
, &remote_user
);
181 assert_se(IN_SET(r
, 0, -ENODATA
));
182 log_info("sd_session_get_remote_user(\"%s\") → \"%s\"",
183 session
, strna(remote_user
));
185 r
= sd_session_get_remote_host(session
, &remote_host
);
186 assert_se(IN_SET(r
, 0, -ENODATA
));
187 log_info("sd_session_get_remote_host(\"%s\") → \"%s\"",
188 session
, strna(remote_host
));
190 r
= sd_session_get_seat(session
, &seat
);
194 log_info("sd_session_get_seat(\"%s\") → \"%s\"", session
, seat
);
196 #pragma GCC diagnostic push
197 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
198 r
= sd_seat_can_multi_session(seat
);
199 #pragma GCC diagnostic pop
201 log_info("sd_session_can_multi_seat(\"%s\") → %s", seat
, yes_no(r
));
203 r
= sd_seat_can_tty(seat
);
205 log_info("sd_session_can_tty(\"%s\") → %s", seat
, yes_no(r
));
207 r
= sd_seat_can_graphical(seat
);
209 log_info("sd_session_can_graphical(\"%s\") → %s", seat
, yes_no(r
));
211 log_info_errno(r
, "sd_session_get_seat(\"%s\"): %m", session
);
212 assert_se(r
== -ENODATA
);
215 assert_se(sd_uid_get_state(u
, &state2
) == 0);
216 log_info("sd_uid_get_state("UID_FMT
", …) → %s", u
, state2
);
221 _cleanup_free_
char *session2
= NULL
, *buf
= NULL
;
222 _cleanup_free_ uid_t
*uids
= NULL
;
225 assert_se(sd_uid_is_on_seat(u
, 0, seat
) > 0);
227 r
= sd_seat_get_active(seat
, &session2
, &u2
);
229 log_info("sd_seat_get_active(\"%s\", …) → \"%s\", "UID_FMT
, seat
, session2
, u2
);
231 r
= sd_uid_is_on_seat(u
, 1, seat
);
232 assert_se(IN_SET(r
, 0, 1));
233 assert_se(!!r
== streq(session
, session2
));
235 r
= sd_seat_get_sessions(seat
, &sessions
, &uids
, &n
);
237 assert_se(r
== (int) strv_length(sessions
));
238 assert_se(t
= strv_join(sessions
, " "));
240 log_info("sd_seat_get_sessions(\"%s\", …) → %s, \"%s\", [%u] {%s}",
241 seat
, e(r
), t
, n
, format_uids(&buf
, uids
, n
));
244 assert_se(sd_seat_get_sessions(seat
, NULL
, NULL
, NULL
) == r
);
247 r
= sd_get_seats(&seats
);
249 assert_se(r
== (int) strv_length(seats
));
250 assert_se(t
= strv_join(seats
, ", "));
252 log_info("sd_get_seats(…) → [%i] \"%s\"", r
, t
);
255 assert_se(sd_get_seats(NULL
) == r
);
257 r
= sd_seat_get_active(NULL
, &t
, NULL
);
258 assert_se(IN_SET(r
, 0, -ENODATA
, -ENXIO
));
259 log_info("sd_seat_get_active(NULL, …) (active session on current seat) → %s / \"%s\"", e(r
), strnull(t
));
262 r
= sd_get_sessions(&sessions
);
264 assert_se(r
== (int) strv_length(sessions
));
265 assert_se(t
= strv_join(sessions
, ", "));
267 log_info("sd_get_sessions(…) → [%i] \"%s\"", r
, t
);
270 assert_se(sd_get_sessions(NULL
) == r
);
273 _cleanup_free_ uid_t
*uids
= NULL
;
274 _cleanup_free_
char *buf
= NULL
;
276 r
= sd_get_uids(&uids
);
278 log_info("sd_get_uids(…) → [%i] {%s}", r
, format_uids(&buf
, uids
, r
));
280 assert_se(sd_get_uids(NULL
) == r
);
284 _cleanup_strv_free_
char **machines
= NULL
;
285 _cleanup_free_
char *buf
= NULL
;
287 r
= sd_get_machine_names(&machines
);
289 assert_se(r
== (int) strv_length(machines
));
290 assert_se(buf
= strv_join(machines
, " "));
291 log_info("sd_get_machines(…) → [%i] \"%s\"", r
, buf
);
293 assert_se(sd_get_machine_names(NULL
) == r
);
298 sd_login_monitor
*m
= NULL
;
301 if (!streq_ptr(saved_argv
[1], "-m"))
304 assert_se(sd_login_monitor_new("session", &m
) == 0);
306 for (unsigned n
= 0; n
< 5; n
++) {
307 struct pollfd pollfd
= {};
310 assert_se((pollfd
.fd
= sd_login_monitor_get_fd(m
)) >= 0);
311 assert_se((pollfd
.events
= sd_login_monitor_get_events(m
)) >= 0);
313 assert_se(sd_login_monitor_get_timeout(m
, &timeout
) >= 0);
315 nw
= now(CLOCK_MONOTONIC
);
318 timeout
== UINT64_MAX
? -1 :
319 timeout
> nw
? (int) ((timeout
- nw
) / 1000) :
324 sd_login_monitor_flush(m
);
328 sd_login_monitor_unref(m
);
331 static int intro(void) {
332 if (IN_SET(cg_unified(), -ENOENT
, -ENOMEDIUM
))
333 return log_tests_skipped("cgroupfs is not mounted");
335 log_info("/* Information printed is from the live system */");
339 DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO
, intro
);