Bug Summary

File:build-scan/../src/libsystemd/sd-login/sd-login.c
Warning:line 816, column 9
Potential leak of memory pointed to by 'l'

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name sd-login.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/libsystemd/libsystemd_static.a.p -I src/libsystemd -I ../src/libsystemd -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I src/core -I ../src/core -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility default -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/libsystemd/sd-login/sd-login.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2/***
3***/
4
5#include <errno(*__errno_location ()).h>
6#include <poll.h>
7#include <string.h>
8#include <sys/inotify.h>
9#include <unistd.h>
10
11#include "sd-login.h"
12
13#include "alloc-util.h"
14#include "cgroup-util.h"
15#include "dirent-util.h"
16#include "escape.h"
17#include "fd-util.h"
18#include "fileio.h"
19#include "format-util.h"
20#include "fs-util.h"
21#include "hostname-util.h"
22#include "io-util.h"
23#include "login-util.h"
24#include "macro.h"
25#include "parse-util.h"
26#include "path-util.h"
27#include "socket-util.h"
28#include "string-util.h"
29#include "strv.h"
30#include "user-util.h"
31#include "util.h"
32
33/* Error codes:
34 *
35 * invalid input parameters → -EINVAL
36 * invalid fd → -EBADF
37 * process does not exist → -ESRCH
38 * cgroup does not exist → -ENOENT
39 * machine, session does not exist → -ENXIO
40 * requested metadata on object is missing → -ENODATA
41 */
42
43_public___attribute__ ((visibility("default"))) int sd_pid_get_session(pid_t pid, char **session) {
44 int r;
45
46 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 46, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
47 assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("session"), "../src/libsystemd/sd-login/sd-login.c"
, 47, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
48
49 r = cg_pid_get_session(pid, session);
50 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
51}
52
53_public___attribute__ ((visibility("default"))) int sd_pid_get_unit(pid_t pid, char **unit) {
54 int r;
55
56 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 56, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
57 assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("unit"), "../src/libsystemd/sd-login/sd-login.c"
, 57, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
58
59 r = cg_pid_get_unit(pid, unit);
60 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
61}
62
63_public___attribute__ ((visibility("default"))) int sd_pid_get_user_unit(pid_t pid, char **unit) {
64 int r;
65
66 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 66, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
67 assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("unit"), "../src/libsystemd/sd-login/sd-login.c"
, 67, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
68
69 r = cg_pid_get_user_unit(pid, unit);
70 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
71}
72
73_public___attribute__ ((visibility("default"))) int sd_pid_get_machine_name(pid_t pid, char **name) {
74 int r;
75
76 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 76, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
77 assert_return(name, -EINVAL)do { if (!(((__builtin_expect(!!(name),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("name"), "../src/libsystemd/sd-login/sd-login.c"
, 77, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
78
79 r = cg_pid_get_machine_name(pid, name);
80 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
81}
82
83_public___attribute__ ((visibility("default"))) int sd_pid_get_slice(pid_t pid, char **slice) {
84 int r;
85
86 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 86, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
87 assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("slice"), "../src/libsystemd/sd-login/sd-login.c"
, 87, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
88
89 r = cg_pid_get_slice(pid, slice);
90 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
91}
92
93_public___attribute__ ((visibility("default"))) int sd_pid_get_user_slice(pid_t pid, char **slice) {
94 int r;
95
96 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 96, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
97 assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("slice"), "../src/libsystemd/sd-login/sd-login.c"
, 97, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
98
99 r = cg_pid_get_user_slice(pid, slice);
100 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
101}
102
103_public___attribute__ ((visibility("default"))) int sd_pid_get_owner_uid(pid_t pid, uid_t *uid) {
104 int r;
105
106 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 106, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
107 assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-login/sd-login.c"
, 107, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
108
109 r = cg_pid_get_owner_uid(pid, uid);
110 return IN_SET(r, -ENXIO, -ENOMEDIUM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-6, -123})/sizeof(int)]; switch(r) { case
-6: case -123: _found = 1; break; default: break; } _found; }
)
? -ENODATA61 : r;
111}
112
113_public___attribute__ ((visibility("default"))) int sd_pid_get_cgroup(pid_t pid, char **cgroup) {
114 char *c;
115 int r;
116
117 assert_return(pid >= 0, -EINVAL)do { if (!(((__builtin_expect(!!(pid >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 117, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
118 assert_return(cgroup, -EINVAL)do { if (!(((__builtin_expect(!!(cgroup),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("cgroup"), "../src/libsystemd/sd-login/sd-login.c"
, 118, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
119
120 r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER"_systemd", pid, &c);
121 if (r < 0)
122 return r;
123
124 /* The internal APIs return the empty string for the root
125 * cgroup, let's return the "/" in the public APIs instead, as
126 * that's easier and less ambiguous for people to grok. */
127 if (isempty(c)) {
128 free(c);
129 c = strdup("/");
130 if (!c)
131 return -ENOMEM12;
132
133 }
134
135 *cgroup = c;
136 return 0;
137}
138
139_public___attribute__ ((visibility("default"))) int sd_peer_get_session(int fd, char **session) {
140 struct ucred ucred = {};
141 int r;
142
143 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 143, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
144 assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("session"), "../src/libsystemd/sd-login/sd-login.c"
, 144, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
145
146 r = getpeercred(fd, &ucred);
147 if (r < 0)
148 return r;
149
150 return cg_pid_get_session(ucred.pid, session);
151}
152
153_public___attribute__ ((visibility("default"))) int sd_peer_get_owner_uid(int fd, uid_t *uid) {
154 struct ucred ucred;
155 int r;
156
157 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 157, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
158 assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-login/sd-login.c"
, 158, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
159
160 r = getpeercred(fd, &ucred);
161 if (r < 0)
162 return r;
163
164 return cg_pid_get_owner_uid(ucred.pid, uid);
165}
166
167_public___attribute__ ((visibility("default"))) int sd_peer_get_unit(int fd, char **unit) {
168 struct ucred ucred;
169 int r;
170
171 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 171, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
172 assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("unit"), "../src/libsystemd/sd-login/sd-login.c"
, 172, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
173
174 r = getpeercred(fd, &ucred);
175 if (r < 0)
176 return r;
177
178 return cg_pid_get_unit(ucred.pid, unit);
179}
180
181_public___attribute__ ((visibility("default"))) int sd_peer_get_user_unit(int fd, char **unit) {
182 struct ucred ucred;
183 int r;
184
185 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 185, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
186 assert_return(unit, -EINVAL)do { if (!(((__builtin_expect(!!(unit),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("unit"), "../src/libsystemd/sd-login/sd-login.c"
, 186, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
187
188 r = getpeercred(fd, &ucred);
189 if (r < 0)
190 return r;
191
192 return cg_pid_get_user_unit(ucred.pid, unit);
193}
194
195_public___attribute__ ((visibility("default"))) int sd_peer_get_machine_name(int fd, char **machine) {
196 struct ucred ucred;
197 int r;
198
199 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 199, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
200 assert_return(machine, -EINVAL)do { if (!(((__builtin_expect(!!(machine),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("machine"), "../src/libsystemd/sd-login/sd-login.c"
, 200, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
201
202 r = getpeercred(fd, &ucred);
203 if (r < 0)
204 return r;
205
206 return cg_pid_get_machine_name(ucred.pid, machine);
207}
208
209_public___attribute__ ((visibility("default"))) int sd_peer_get_slice(int fd, char **slice) {
210 struct ucred ucred;
211 int r;
212
213 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 213, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
214 assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("slice"), "../src/libsystemd/sd-login/sd-login.c"
, 214, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
215
216 r = getpeercred(fd, &ucred);
217 if (r < 0)
218 return r;
219
220 return cg_pid_get_slice(ucred.pid, slice);
221}
222
223_public___attribute__ ((visibility("default"))) int sd_peer_get_user_slice(int fd, char **slice) {
224 struct ucred ucred;
225 int r;
226
227 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 227, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
228 assert_return(slice, -EINVAL)do { if (!(((__builtin_expect(!!(slice),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("slice"), "../src/libsystemd/sd-login/sd-login.c"
, 228, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
229
230 r = getpeercred(fd, &ucred);
231 if (r < 0)
232 return r;
233
234 return cg_pid_get_user_slice(ucred.pid, slice);
235}
236
237_public___attribute__ ((visibility("default"))) int sd_peer_get_cgroup(int fd, char **cgroup) {
238 struct ucred ucred;
239 int r;
240
241 assert_return(fd >= 0, -EBADF)do { if (!(((__builtin_expect(!!(fd >= 0),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/libsystemd/sd-login/sd-login.c"
, 241, __PRETTY_FUNCTION__), 0))) return (-9); } while (0)
;
242 assert_return(cgroup, -EINVAL)do { if (!(((__builtin_expect(!!(cgroup),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("cgroup"), "../src/libsystemd/sd-login/sd-login.c"
, 242, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
243
244 r = getpeercred(fd, &ucred);
245 if (r < 0)
246 return r;
247
248 return sd_pid_get_cgroup(ucred.pid, cgroup);
249}
250
251static int file_of_uid(uid_t uid, char **p) {
252
253 assert_return(uid_is_valid(uid), -EINVAL)do { if (!(((__builtin_expect(!!(uid_is_valid(uid)),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("uid_is_valid(uid)"
), "../src/libsystemd/sd-login/sd-login.c", 253, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
254 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/libsystemd/sd-login/sd-login.c"
, 254, __PRETTY_FUNCTION__); } while (0)
;
255
256 if (asprintf(p, "/run/systemd/users/" UID_FMT"%" "u", uid) < 0)
257 return -ENOMEM12;
258
259 return 0;
260}
261
262_public___attribute__ ((visibility("default"))) int sd_uid_get_state(uid_t uid, char**state) {
263 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0);
264 char *s = NULL((void*)0);
265 int r;
266
267 assert_return(state, -EINVAL)do { if (!(((__builtin_expect(!!(state),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("state"), "../src/libsystemd/sd-login/sd-login.c"
, 267, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
268
269 r = file_of_uid(uid, &p);
270 if (r < 0)
271 return r;
272
273 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "STATE", &s, NULL((void*)0));
274 if (r == -ENOENT2) {
275 free(s);
276 s = strdup("offline");
277 if (!s)
278 return -ENOMEM12;
279
280 }
281 else if (r < 0) {
282 free(s);
283 return r;
284 }
285 if (isempty(s)) {
286 free(s);
287 return -EIO5;
288 }
289
290 *state = s;
291 return 0;
292}
293
294_public___attribute__ ((visibility("default"))) int sd_uid_get_display(uid_t uid, char **session) {
295 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
296 int r;
297
298 assert_return(session, -EINVAL)do { if (!(((__builtin_expect(!!(session),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("session"), "../src/libsystemd/sd-login/sd-login.c"
, 298, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
299
300 r = file_of_uid(uid, &p);
301 if (r < 0)
302 return r;
303
304 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "DISPLAY", &s, NULL((void*)0));
305 if (r == -ENOENT2)
306 return -ENODATA61;
307 if (r < 0)
308 return r;
309 if (isempty(s))
310 return -ENODATA61;
311
312 *session = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; });
313
314 return 0;
315}
316
317static int file_of_seat(const char *seat, char **_p) {
318 char *p;
319 int r;
320
321 assert(_p)do { if ((__builtin_expect(!!(!(_p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_p"), "../src/libsystemd/sd-login/sd-login.c"
, 321, __PRETTY_FUNCTION__); } while (0)
;
322
323 if (seat) {
324 if (!filename_is_valid(seat))
325 return -EINVAL22;
326
327 p = strappend("/run/systemd/seats/", seat);
328 } else {
329 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
330
331 r = sd_session_get_seat(NULL((void*)0), &buf);
332 if (r < 0)
333 return r;
334
335 p = strappend("/run/systemd/seats/", buf);
336 }
337
338 if (!p)
339 return -ENOMEM12;
340
341 *_p = TAKE_PTR(p)({ typeof(p) _ptr_ = (p); (p) = ((void*)0); _ptr_; });
342 return 0;
343}
344
345_public___attribute__ ((visibility("default"))) int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat) {
346 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0), *s = NULL((void*)0), *p = NULL((void*)0);
347 size_t l;
348 int r;
349 const char *word, *variable, *state;
350
351 assert_return(uid_is_valid(uid), -EINVAL)do { if (!(((__builtin_expect(!!(uid_is_valid(uid)),1))) ? (1
) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("uid_is_valid(uid)"
), "../src/libsystemd/sd-login/sd-login.c", 351, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
352
353 r = file_of_seat(seat, &p);
354 if (r < 0)
355 return r;
356
357 variable = require_active ? "ACTIVE_UID" : "UIDS";
358
359 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", variable, &s, NULL((void*)0));
360 if (r == -ENOENT2)
361 return 0;
362 if (r < 0)
363 return r;
364 if (isempty(s))
365 return 0;
366
367 if (asprintf(&t, UID_FMT"%" "u", uid) < 0)
368 return -ENOMEM12;
369
370 FOREACH_WORD(word, l, s, state)for ((state) = (s), (word) = split(&(state), &(l), (" \t\n\r"
), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r"
), (0)))
371 if (strneq(t, word, l)(strncmp((t), (word), (l)) == 0))
372 return 1;
373
374 return 0;
375}
376
377static int uid_get_array(uid_t uid, const char *variable, char ***array) {
378 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
379 char **a;
380 int r;
381
382 assert(variable)do { if ((__builtin_expect(!!(!(variable)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("variable"), "../src/libsystemd/sd-login/sd-login.c"
, 382, __PRETTY_FUNCTION__); } while (0)
;
383
384 r = file_of_uid(uid, &p);
385 if (r < 0)
386 return r;
387
388 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", variable, &s, NULL((void*)0));
389 if (r == -ENOENT2 || (r >= 0 && isempty(s))) {
390 if (array)
391 *array = NULL((void*)0);
392 return 0;
393 }
394 if (r < 0)
395 return r;
396
397 a = strv_split(s, " ");
398 if (!a)
399 return -ENOMEM12;
400
401 strv_uniq(a);
402 r = (int) strv_length(a);
403
404 if (array)
405 *array = a;
406 else
407 strv_free(a);
408
409 return r;
410}
411
412_public___attribute__ ((visibility("default"))) int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions) {
413 return uid_get_array(
414 uid,
415 require_active == 0 ? "ONLINE_SESSIONS" :
416 require_active > 0 ? "ACTIVE_SESSIONS" :
417 "SESSIONS",
418 sessions);
419}
420
421_public___attribute__ ((visibility("default"))) int sd_uid_get_seats(uid_t uid, int require_active, char ***seats) {
422 return uid_get_array(
423 uid,
424 require_active == 0 ? "ONLINE_SEATS" :
425 require_active > 0 ? "ACTIVE_SEATS" :
426 "SEATS",
427 seats);
428}
429
430static int file_of_session(const char *session, char **_p) {
431 char *p;
432 int r;
433
434 assert(_p)do { if ((__builtin_expect(!!(!(_p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_p"), "../src/libsystemd/sd-login/sd-login.c"
, 434, __PRETTY_FUNCTION__); } while (0)
;
435
436 if (session) {
437 if (!session_id_valid(session))
438 return -EINVAL22;
439
440 p = strappend("/run/systemd/sessions/", session);
441 } else {
442 _cleanup_free___attribute__((cleanup(freep))) char *buf = NULL((void*)0);
443
444 r = sd_pid_get_session(0, &buf);
445 if (r < 0)
446 return r;
447
448 p = strappend("/run/systemd/sessions/", buf);
449 }
450
451 if (!p)
452 return -ENOMEM12;
453
454 *_p = p;
455 return 0;
456}
457
458_public___attribute__ ((visibility("default"))) int sd_session_is_active(const char *session) {
459 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
460 int r;
461
462 r = file_of_session(session, &p);
463 if (r < 0)
464 return r;
465
466 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "ACTIVE", &s, NULL((void*)0));
467 if (r == -ENOENT2)
468 return -ENXIO6;
469 if (r < 0)
470 return r;
471 if (isempty(s))
472 return -EIO5;
473
474 return parse_boolean(s);
475}
476
477_public___attribute__ ((visibility("default"))) int sd_session_is_remote(const char *session) {
478 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
479 int r;
480
481 r = file_of_session(session, &p);
482 if (r < 0)
483 return r;
484
485 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "REMOTE", &s, NULL((void*)0));
486 if (r == -ENOENT2)
487 return -ENXIO6;
488 if (r < 0)
489 return r;
490 if (isempty(s))
491 return -ENODATA61;
492
493 return parse_boolean(s);
494}
495
496_public___attribute__ ((visibility("default"))) int sd_session_get_state(const char *session, char **state) {
497 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
498 int r;
499
500 assert_return(state, -EINVAL)do { if (!(((__builtin_expect(!!(state),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("state"), "../src/libsystemd/sd-login/sd-login.c"
, 500, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
501
502 r = file_of_session(session, &p);
503 if (r < 0)
504 return r;
505
506 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "STATE", &s, NULL((void*)0));
507 if (r == -ENOENT2)
508 return -ENXIO6;
509 if (r < 0)
510 return r;
511 if (isempty(s))
512 return -EIO5;
513
514 *state = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; });
515
516 return 0;
517}
518
519_public___attribute__ ((visibility("default"))) int sd_session_get_uid(const char *session, uid_t *uid) {
520 int r;
521 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
522
523 assert_return(uid, -EINVAL)do { if (!(((__builtin_expect(!!(uid),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("uid"), "../src/libsystemd/sd-login/sd-login.c"
, 523, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
524
525 r = file_of_session(session, &p);
526 if (r < 0)
527 return r;
528
529 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "UID", &s, NULL((void*)0));
530 if (r == -ENOENT2)
531 return -ENXIO6;
532 if (r < 0)
533 return r;
534 if (isempty(s))
535 return -EIO5;
536
537 return parse_uid(s, uid);
538}
539
540static int session_get_string(const char *session, const char *field, char **value) {
541 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
542 int r;
543
544 assert_return(value, -EINVAL)do { if (!(((__builtin_expect(!!(value),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("value"), "../src/libsystemd/sd-login/sd-login.c"
, 544, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
545 assert(field)do { if ((__builtin_expect(!!(!(field)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("field"), "../src/libsystemd/sd-login/sd-login.c"
, 545, __PRETTY_FUNCTION__); } while (0)
;
546
547 r = file_of_session(session, &p);
548 if (r < 0)
549 return r;
550
551 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", field, &s, NULL((void*)0));
552 if (r == -ENOENT2)
553 return -ENXIO6;
554 if (r < 0)
555 return r;
556 if (isempty(s))
557 return -ENODATA61;
558
559 *value = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; });
560 return 0;
561}
562
563_public___attribute__ ((visibility("default"))) int sd_session_get_seat(const char *session, char **seat) {
564 return session_get_string(session, "SEAT", seat);
565}
566
567_public___attribute__ ((visibility("default"))) int sd_session_get_tty(const char *session, char **tty) {
568 return session_get_string(session, "TTY", tty);
569}
570
571_public___attribute__ ((visibility("default"))) int sd_session_get_vt(const char *session, unsigned *vtnr) {
572 _cleanup_free___attribute__((cleanup(freep))) char *vtnr_string = NULL((void*)0);
573 unsigned u;
574 int r;
575
576 assert_return(vtnr, -EINVAL)do { if (!(((__builtin_expect(!!(vtnr),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("vtnr"), "../src/libsystemd/sd-login/sd-login.c"
, 576, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
577
578 r = session_get_string(session, "VTNR", &vtnr_string);
579 if (r < 0)
580 return r;
581
582 r = safe_atou(vtnr_string, &u);
583 if (r < 0)
584 return r;
585
586 *vtnr = u;
587 return 0;
588}
589
590_public___attribute__ ((visibility("default"))) int sd_session_get_service(const char *session, char **service) {
591 return session_get_string(session, "SERVICE", service);
592}
593
594_public___attribute__ ((visibility("default"))) int sd_session_get_type(const char *session, char **type) {
595 return session_get_string(session, "TYPE", type);
596}
597
598_public___attribute__ ((visibility("default"))) int sd_session_get_class(const char *session, char **class) {
599 return session_get_string(session, "CLASS", class);
600}
601
602_public___attribute__ ((visibility("default"))) int sd_session_get_desktop(const char *session, char **desktop) {
603 _cleanup_free___attribute__((cleanup(freep))) char *escaped = NULL((void*)0);
604 char *t;
605 int r;
606
607 assert_return(desktop, -EINVAL)do { if (!(((__builtin_expect(!!(desktop),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("desktop"), "../src/libsystemd/sd-login/sd-login.c"
, 607, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
608
609 r = session_get_string(session, "DESKTOP", &escaped);
610 if (r < 0)
611 return r;
612
613 r = cunescape(escaped, 0, &t);
614 if (r < 0)
615 return r;
616
617 *desktop = t;
618 return 0;
619}
620
621_public___attribute__ ((visibility("default"))) int sd_session_get_display(const char *session, char **display) {
622 return session_get_string(session, "DISPLAY", display);
623}
624
625_public___attribute__ ((visibility("default"))) int sd_session_get_remote_user(const char *session, char **remote_user) {
626 return session_get_string(session, "REMOTE_USER", remote_user);
627}
628
629_public___attribute__ ((visibility("default"))) int sd_session_get_remote_host(const char *session, char **remote_host) {
630 return session_get_string(session, "REMOTE_HOST", remote_host);
631}
632
633_public___attribute__ ((visibility("default"))) int sd_seat_get_active(const char *seat, char **session, uid_t *uid) {
634 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0), *t = NULL((void*)0);
635 int r;
636
637 assert_return(session || uid, -EINVAL)do { if (!(((__builtin_expect(!!(session || uid),1))) ? (1) :
(log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("session || uid"
), "../src/libsystemd/sd-login/sd-login.c", 637, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
638
639 r = file_of_seat(seat, &p);
640 if (r < 0)
641 return r;
642
643 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r",
644 "ACTIVE", &s,
645 "ACTIVE_UID", &t,
646 NULL((void*)0));
647 if (r == -ENOENT2)
648 return -ENXIO6;
649 if (r < 0)
650 return r;
651
652 if (session && !s)
653 return -ENODATA61;
654
655 if (uid && !t)
656 return -ENODATA61;
657
658 if (uid && t) {
659 r = parse_uid(t, uid);
660 if (r < 0)
661 return r;
662 }
663
664 if (session && s)
665 *session = TAKE_PTR(s)({ typeof(s) _ptr_ = (s); (s) = ((void*)0); _ptr_; });
666
667 return 0;
668}
669
670_public___attribute__ ((visibility("default"))) int sd_seat_get_sessions(const char *seat, char ***sessions, uid_t **uids, unsigned *n_uids) {
671 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0), *t = NULL((void*)0);
672 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **a = NULL((void*)0);
673 _cleanup_free___attribute__((cleanup(freep))) uid_t *b = NULL((void*)0);
674 unsigned n = 0;
675 int r;
676
677 r = file_of_seat(seat, &p);
678 if (r < 0)
679 return r;
680
681 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r",
682 "SESSIONS", &s,
683 "UIDS", &t,
684 NULL((void*)0));
685 if (r == -ENOENT2)
686 return -ENXIO6;
687 if (r < 0)
688 return r;
689
690 if (s) {
691 a = strv_split(s, " ");
692 if (!a)
693 return -ENOMEM12;
694 }
695
696 if (uids && t) {
697 const char *word, *state;
698 size_t l;
699
700 FOREACH_WORD(word, l, t, state)for ((state) = (t), (word) = split(&(state), &(l), (" \t\n\r"
), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r"
), (0)))
701 n++;
702
703 if (n > 0) {
704 unsigned i = 0;
705
706 b = new(uid_t, n)((uid_t*) malloc_multiply(sizeof(uid_t), (n)));
707 if (!b)
708 return -ENOMEM12;
709
710 FOREACH_WORD(word, l, t, state)for ((state) = (t), (word) = split(&(state), &(l), (" \t\n\r"
), (0)); (word); (word) = split(&(state), &(l), (" \t\n\r"
), (0)))
{
711 _cleanup_free___attribute__((cleanup(freep))) char *k = NULL((void*)0);
712
713 k = strndup(word, l);
714 if (!k)
715 return -ENOMEM12;
716
717 r = parse_uid(k, b + i);
718 if (r < 0)
719 return r;
720
721 i++;
722 }
723 }
724 }
725
726 r = (int) strv_length(a);
727
728 if (sessions)
729 *sessions = TAKE_PTR(a)({ typeof(a) _ptr_ = (a); (a) = ((void*)0); _ptr_; });
730
731 if (uids)
732 *uids = TAKE_PTR(b)({ typeof(b) _ptr_ = (b); (b) = ((void*)0); _ptr_; });
733
734 if (n_uids)
735 *n_uids = n;
736
737 return r;
738}
739
740static int seat_get_can(const char *seat, const char *variable) {
741 _cleanup_free___attribute__((cleanup(freep))) char *p = NULL((void*)0), *s = NULL((void*)0);
742 int r;
743
744 assert(variable)do { if ((__builtin_expect(!!(!(variable)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("variable"), "../src/libsystemd/sd-login/sd-login.c"
, 744, __PRETTY_FUNCTION__); } while (0)
;
745
746 r = file_of_seat(seat, &p);
747 if (r < 0)
748 return r;
749
750 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r",
751 variable, &s,
752 NULL((void*)0));
753 if (r == -ENOENT2)
754 return -ENXIO6;
755 if (r < 0)
756 return r;
757 if (isempty(s))
758 return -ENODATA61;
759
760 return parse_boolean(s);
761}
762
763_public___attribute__ ((visibility("default"))) int sd_seat_can_multi_session(const char *seat) {
764 return seat_get_can(seat, "CAN_MULTI_SESSION");
765}
766
767_public___attribute__ ((visibility("default"))) int sd_seat_can_tty(const char *seat) {
768 return seat_get_can(seat, "CAN_TTY");
769}
770
771_public___attribute__ ((visibility("default"))) int sd_seat_can_graphical(const char *seat) {
772 return seat_get_can(seat, "CAN_GRAPHICAL");
773}
774
775_public___attribute__ ((visibility("default"))) int sd_get_seats(char ***seats) {
776 int r;
777
778 r = get_files_in_directory("/run/systemd/seats/", seats);
779 if (r == -ENOENT2) {
780 if (seats)
781 *seats = NULL((void*)0);
782 return 0;
783 }
784 return r;
785}
786
787_public___attribute__ ((visibility("default"))) int sd_get_sessions(char ***sessions) {
788 int r;
789
790 r = get_files_in_directory("/run/systemd/sessions/", sessions);
791 if (r == -ENOENT2) {
792 if (sessions)
793 *sessions = NULL((void*)0);
794 return 0;
795 }
796 return r;
797}
798
799_public___attribute__ ((visibility("default"))) int sd_get_uids(uid_t **users) {
800 _cleanup_closedir___attribute__((cleanup(closedirp))) DIR *d;
801 struct dirent *de;
802 int r = 0;
803 unsigned n = 0;
804 _cleanup_free___attribute__((cleanup(freep))) uid_t *l = NULL((void*)0);
805
806 d = opendir("/run/systemd/users/");
807 if (!d) {
1
Assuming 'd' is non-null
2
Taking false branch
808 if (errno(*__errno_location ()) == ENOENT2) {
809 if (users)
810 *users = NULL((void*)0);
811 return 0;
812 }
813 return -errno(*__errno_location ());
814 }
815
816 FOREACH_DIRENT_ALL(de, d, return -errno)for ((*__errno_location ()) = 0, de = readdir(d);; (*__errno_location
()) = 0, de = readdir(d)) if (!de) { if ((*__errno_location (
)) > 0) { return -(*__errno_location ()); } break; } else
{
3
Loop condition is true. Entering loop body
4
Assuming 'de' is non-null
5
Taking false branch
19
Loop condition is true. Entering loop body
20
Assuming 'de' is null
21
Taking true branch
22
Assuming the condition is true
23
Taking true branch
24
Potential leak of memory pointed to by 'l'
817 int k;
818 uid_t uid;
819
820 dirent_ensure_type(d, de);
821
822 if (!dirent_is_file(de))
6
Assuming the condition is false
7
Taking false branch
823 continue;
824
825 k = parse_uid(de->d_name, &uid);
826 if (k < 0)
8
Assuming 'k' is >= 0
9
Taking false branch
827 continue;
828
829 if (users) {
10
Assuming 'users' is non-null
11
Taking true branch
830 if ((unsigned) r
11.1
'r' is >= 'n'
>= n) {
12
Taking true branch
831 uid_t *t;
832
833 n = MAX(16, 2*r)__extension__ ({ const typeof((16)) __unique_prefix_A16 = ((16
)); const typeof((2*r)) __unique_prefix_B17 = ((2*r)); __unique_prefix_A16
> __unique_prefix_B17 ? __unique_prefix_A16 : __unique_prefix_B17
; })
;
13
'?' condition is true
834 t = realloc(l, sizeof(uid_t) * n);
14
Memory is allocated
835 if (!t)
15
Assuming 't' is non-null
16
Taking false branch
836 return -ENOMEM12;
837
838 l = t;
839 }
840
841 assert((unsigned) r < n)do { if ((__builtin_expect(!!(!((unsigned) r < n)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("(unsigned) r < n"), "../src/libsystemd/sd-login/sd-login.c"
, 841, __PRETTY_FUNCTION__); } while (0)
;
17
Taking false branch
18
Loop condition is false. Exiting loop
842 l[r++] = uid;
843 } else
844 r++;
845 }
846
847 if (users)
848 *users = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
849
850 return r;
851}
852
853_public___attribute__ ((visibility("default"))) int sd_get_machine_names(char ***machines) {
854 _cleanup_strv_free___attribute__((cleanup(strv_freep))) char **l = NULL((void*)0);
855 char **a, **b;
856 int r;
857
858 r = get_files_in_directory("/run/systemd/machines/", &l);
859 if (r == -ENOENT2) {
860 if (machines)
861 *machines = NULL((void*)0);
862 return 0;
863 }
864 if (r < 0)
865 return r;
866
867 if (l) {
868 r = 0;
869
870 /* Filter out the unit: symlinks */
871 for (a = b = l; *a; a++) {
872 if (startswith(*a, "unit:") || !machine_name_is_valid(*a)hostname_is_valid(*a, 0))
873 free(*a);
874 else {
875 *b = *a;
876 b++;
877 r++;
878 }
879 }
880
881 *b = NULL((void*)0);
882 }
883
884 if (machines)
885 *machines = TAKE_PTR(l)({ typeof(l) _ptr_ = (l); (l) = ((void*)0); _ptr_; });
886
887 return r;
888}
889
890_public___attribute__ ((visibility("default"))) int sd_machine_get_class(const char *machine, char **class) {
891 _cleanup_free___attribute__((cleanup(freep))) char *c = NULL((void*)0);
892 const char *p;
893 int r;
894
895 assert_return(class, -EINVAL)do { if (!(((__builtin_expect(!!(class),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("class"), "../src/libsystemd/sd-login/sd-login.c"
, 895, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
896
897 if (streq(machine, ".host")(strcmp((machine),(".host")) == 0)) {
898 c = strdup("host");
899 if (!c)
900 return -ENOMEM12;
901 } else {
902 if (!machine_name_is_valid(machine)hostname_is_valid(machine, 0))
903 return -EINVAL22;
904
905 p = strjoina("/run/systemd/machines/", machine)({ const char *_appendees_[] = { "/run/systemd/machines/", machine
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
906 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "CLASS", &c, NULL((void*)0));
907 if (r == -ENOENT2)
908 return -ENXIO6;
909 if (r < 0)
910 return r;
911 if (!c)
912 return -EIO5;
913 }
914
915 *class = TAKE_PTR(c)({ typeof(c) _ptr_ = (c); (c) = ((void*)0); _ptr_; });
916 return 0;
917}
918
919_public___attribute__ ((visibility("default"))) int sd_machine_get_ifindices(const char *machine, int **ifindices) {
920 _cleanup_free___attribute__((cleanup(freep))) char *netif = NULL((void*)0);
921 size_t l, allocated = 0, nr = 0;
922 int *ni = NULL((void*)0);
923 const char *p, *word, *state;
924 int r;
925
926 assert_return(machine_name_is_valid(machine), -EINVAL)do { if (!(((__builtin_expect(!!(hostname_is_valid(machine, 0
)),1))) ? (1) : (log_assert_failed_return_realm(LOG_REALM_SYSTEMD
, ("machine_name_is_valid(machine)"), "../src/libsystemd/sd-login/sd-login.c"
, 926, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
927 assert_return(ifindices, -EINVAL)do { if (!(((__builtin_expect(!!(ifindices),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("ifindices"), "../src/libsystemd/sd-login/sd-login.c"
, 927, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
928
929 p = strjoina("/run/systemd/machines/", machine)({ const char *_appendees_[] = { "/run/systemd/machines/", machine
}; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ =
0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
930 r = parse_env_file(NULL((void*)0), p, NEWLINE"\n\r", "NETIF", &netif, NULL((void*)0));
931 if (r == -ENOENT2)
932 return -ENXIO6;
933 if (r < 0)
934 return r;
935 if (!netif) {
936 *ifindices = NULL((void*)0);
937 return 0;
938 }
939
940 FOREACH_WORD(word, l, netif, state)for ((state) = (netif), (word) = split(&(state), &(l)
, (" \t\n\r"), (0)); (word); (word) = split(&(state), &
(l), (" \t\n\r"), (0)))
{
941 char buf[l+1];
942 int ifi;
943
944 *(char*) (mempcpy(buf, word, l)) = 0;
945
946 if (parse_ifindex(buf, &ifi) < 0)
947 continue;
948
949 if (!GREEDY_REALLOC(ni, allocated, nr+1)greedy_realloc((void**) &(ni), &(allocated), (nr+1), sizeof
((ni)[0]))
) {
950 free(ni);
951 return -ENOMEM12;
952 }
953
954 ni[nr++] = ifi;
955 }
956
957 *ifindices = ni;
958 return nr;
959}
960
961static inline int MONITOR_TO_FD(sd_login_monitor *m) {
962 return (int) (unsigned long) m - 1;
963}
964
965static inline sd_login_monitor* FD_TO_MONITOR(int fd) {
966 return (sd_login_monitor*) (unsigned long) (fd + 1);
967}
968
969_public___attribute__ ((visibility("default"))) int sd_login_monitor_new(const char *category, sd_login_monitor **m) {
970 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
971 bool_Bool good = false0;
972 int k;
973
974 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-login/sd-login.c"
, 974, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
975
976 fd = inotify_init1(IN_NONBLOCKIN_NONBLOCK|IN_CLOEXECIN_CLOEXEC);
977 if (fd < 0)
978 return -errno(*__errno_location ());
979
980 if (!category || streq(category, "seat")(strcmp((category),("seat")) == 0)) {
981 k = inotify_add_watch(fd, "/run/systemd/seats/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200);
982 if (k < 0)
983 return -errno(*__errno_location ());
984
985 good = true1;
986 }
987
988 if (!category || streq(category, "session")(strcmp((category),("session")) == 0)) {
989 k = inotify_add_watch(fd, "/run/systemd/sessions/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200);
990 if (k < 0)
991 return -errno(*__errno_location ());
992
993 good = true1;
994 }
995
996 if (!category || streq(category, "uid")(strcmp((category),("uid")) == 0)) {
997 k = inotify_add_watch(fd, "/run/systemd/users/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200);
998 if (k < 0)
999 return -errno(*__errno_location ());
1000
1001 good = true1;
1002 }
1003
1004 if (!category || streq(category, "machine")(strcmp((category),("machine")) == 0)) {
1005 k = inotify_add_watch(fd, "/run/systemd/machines/", IN_MOVED_TO0x00000080|IN_DELETE0x00000200);
1006 if (k < 0)
1007 return -errno(*__errno_location ());
1008
1009 good = true1;
1010 }
1011
1012 if (!good)
1013 return -EINVAL22;
1014
1015 *m = FD_TO_MONITOR(fd);
1016 fd = -1;
1017
1018 return 0;
1019}
1020
1021_public___attribute__ ((visibility("default"))) sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m) {
1022 int fd;
1023
1024 if (!m)
1025 return NULL((void*)0);
1026
1027 fd = MONITOR_TO_FD(m);
1028 close_nointr(fd);
1029
1030 return NULL((void*)0);
1031}
1032
1033_public___attribute__ ((visibility("default"))) int sd_login_monitor_flush(sd_login_monitor *m) {
1034 int r;
1035
1036 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-login/sd-login.c"
, 1036, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1037
1038 r = flush_fd(MONITOR_TO_FD(m));
1039 if (r < 0)
1040 return r;
1041
1042 return 0;
1043}
1044
1045_public___attribute__ ((visibility("default"))) int sd_login_monitor_get_fd(sd_login_monitor *m) {
1046
1047 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-login/sd-login.c"
, 1047, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1048
1049 return MONITOR_TO_FD(m);
1050}
1051
1052_public___attribute__ ((visibility("default"))) int sd_login_monitor_get_events(sd_login_monitor *m) {
1053
1054 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-login/sd-login.c"
, 1054, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1055
1056 /* For now we will only return POLLIN here, since we don't
1057 * need anything else ever for inotify. However, let's have
1058 * this API to keep our options open should we later on need
1059 * it. */
1060 return POLLIN0x001;
1061}
1062
1063_public___attribute__ ((visibility("default"))) int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec) {
1064
1065 assert_return(m, -EINVAL)do { if (!(((__builtin_expect(!!(m),1))) ? (1) : (log_assert_failed_return_realm
(LOG_REALM_SYSTEMD, ("m"), "../src/libsystemd/sd-login/sd-login.c"
, 1065, __PRETTY_FUNCTION__), 0))) return (-22); } while (0)
;
1066 assert_return(timeout_usec, -EINVAL)do { if (!(((__builtin_expect(!!(timeout_usec),1))) ? (1) : (
log_assert_failed_return_realm(LOG_REALM_SYSTEMD, ("timeout_usec"
), "../src/libsystemd/sd-login/sd-login.c", 1066, __PRETTY_FUNCTION__
), 0))) return (-22); } while (0)
;
1067
1068 /* For now we will only return (uint64_t) -1, since we don't
1069 * need any timeout. However, let's have this API to keep our
1070 * options open should we later on need it. */
1071 *timeout_usec = (uint64_t) -1;
1072 return 0;
1073}