]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/user-util.c
tree-wide: drop license boilerplate
[thirdparty/systemd.git] / src / basic / user-util.c
1 /* SPDX-License-Identifier: LGPL-2.1+ */
2 /***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6 ***/
7
8 #include <alloca.h>
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <grp.h>
12 #include <pwd.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 #include <stdio.h>
16 #include <stdlib.h>
17 #include <string.h>
18 #include <sys/stat.h>
19 #include <unistd.h>
20 #include <utmp.h>
21
22 #include "alloc-util.h"
23 #include "fd-util.h"
24 #include "fileio.h"
25 #include "format-util.h"
26 #include "macro.h"
27 #include "missing.h"
28 #include "parse-util.h"
29 #include "path-util.h"
30 #include "string-util.h"
31 #include "strv.h"
32 #include "user-util.h"
33 #include "utf8.h"
34
35 bool uid_is_valid(uid_t uid) {
36
37 /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.436. */
38
39 /* Some libc APIs use UID_INVALID as special placeholder */
40 if (uid == (uid_t) UINT32_C(0xFFFFFFFF))
41 return false;
42
43 /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
44 if (uid == (uid_t) UINT32_C(0xFFFF))
45 return false;
46
47 return true;
48 }
49
50 int parse_uid(const char *s, uid_t *ret) {
51 uint32_t uid = 0;
52 int r;
53
54 assert(s);
55
56 assert_cc(sizeof(uid_t) == sizeof(uint32_t));
57 r = safe_atou32(s, &uid);
58 if (r < 0)
59 return r;
60
61 if (!uid_is_valid(uid))
62 return -ENXIO; /* we return ENXIO instead of EINVAL
63 * here, to make it easy to distuingish
64 * invalid numeric uids from invalid
65 * strings. */
66
67 if (ret)
68 *ret = uid;
69
70 return 0;
71 }
72
73 char* getlogname_malloc(void) {
74 uid_t uid;
75 struct stat st;
76
77 if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
78 uid = st.st_uid;
79 else
80 uid = getuid();
81
82 return uid_to_name(uid);
83 }
84
85 char *getusername_malloc(void) {
86 const char *e;
87
88 e = getenv("USER");
89 if (e)
90 return strdup(e);
91
92 return uid_to_name(getuid());
93 }
94
95 int get_user_creds(
96 const char **username,
97 uid_t *uid, gid_t *gid,
98 const char **home,
99 const char **shell) {
100
101 struct passwd *p;
102 uid_t u;
103
104 assert(username);
105 assert(*username);
106
107 /* We enforce some special rules for uid=0 and uid=65534: in order to avoid NSS lookups for root we hardcode
108 * their user record data. */
109
110 if (STR_IN_SET(*username, "root", "0")) {
111 *username = "root";
112
113 if (uid)
114 *uid = 0;
115 if (gid)
116 *gid = 0;
117
118 if (home)
119 *home = "/root";
120
121 if (shell)
122 *shell = "/bin/sh";
123
124 return 0;
125 }
126
127 if (synthesize_nobody() &&
128 STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
129 *username = NOBODY_USER_NAME;
130
131 if (uid)
132 *uid = UID_NOBODY;
133 if (gid)
134 *gid = GID_NOBODY;
135
136 if (home)
137 *home = "/";
138
139 if (shell)
140 *shell = "/sbin/nologin";
141
142 return 0;
143 }
144
145 if (parse_uid(*username, &u) >= 0) {
146 errno = 0;
147 p = getpwuid(u);
148
149 /* If there are multiple users with the same id, make
150 * sure to leave $USER to the configured value instead
151 * of the first occurrence in the database. However if
152 * the uid was configured by a numeric uid, then let's
153 * pick the real username from /etc/passwd. */
154 if (p)
155 *username = p->pw_name;
156 } else {
157 errno = 0;
158 p = getpwnam(*username);
159 }
160
161 if (!p)
162 return errno > 0 ? -errno : -ESRCH;
163
164 if (uid) {
165 if (!uid_is_valid(p->pw_uid))
166 return -EBADMSG;
167
168 *uid = p->pw_uid;
169 }
170
171 if (gid) {
172 if (!gid_is_valid(p->pw_gid))
173 return -EBADMSG;
174
175 *gid = p->pw_gid;
176 }
177
178 if (home)
179 *home = p->pw_dir;
180
181 if (shell)
182 *shell = p->pw_shell;
183
184 return 0;
185 }
186
187 static inline bool is_nologin_shell(const char *shell) {
188
189 return PATH_IN_SET(shell,
190 /* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
191 * message and exits. Different distributions place the binary at different places though,
192 * hence let's list them all. */
193 "/bin/nologin",
194 "/sbin/nologin",
195 "/usr/bin/nologin",
196 "/usr/sbin/nologin",
197 /* 'true' and 'false' work too for the same purpose, but are less friendly as they don't do
198 * any message printing. Different distributions place the binary at various places but at
199 * least not in the 'sbin' directory. */
200 "/bin/false",
201 "/usr/bin/false",
202 "/bin/true",
203 "/usr/bin/true");
204 }
205
206 int get_user_creds_clean(
207 const char **username,
208 uid_t *uid, gid_t *gid,
209 const char **home,
210 const char **shell) {
211
212 int r;
213
214 /* Like get_user_creds(), but resets home/shell to NULL if they don't contain anything relevant. */
215
216 r = get_user_creds(username, uid, gid, home, shell);
217 if (r < 0)
218 return r;
219
220 if (shell &&
221 (isempty(*shell) || is_nologin_shell(*shell)))
222 *shell = NULL;
223
224 if (home &&
225 (isempty(*home) || path_equal(*home, "/")))
226 *home = NULL;
227
228 return 0;
229 }
230
231 int get_group_creds(const char **groupname, gid_t *gid) {
232 struct group *g;
233 gid_t id;
234
235 assert(groupname);
236
237 /* We enforce some special rules for gid=0: in order to avoid
238 * NSS lookups for root we hardcode its data. */
239
240 if (STR_IN_SET(*groupname, "root", "0")) {
241 *groupname = "root";
242
243 if (gid)
244 *gid = 0;
245
246 return 0;
247 }
248
249 if (synthesize_nobody() &&
250 STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
251 *groupname = NOBODY_GROUP_NAME;
252
253 if (gid)
254 *gid = GID_NOBODY;
255
256 return 0;
257 }
258
259 if (parse_gid(*groupname, &id) >= 0) {
260 errno = 0;
261 g = getgrgid(id);
262
263 if (g)
264 *groupname = g->gr_name;
265 } else {
266 errno = 0;
267 g = getgrnam(*groupname);
268 }
269
270 if (!g)
271 return errno > 0 ? -errno : -ESRCH;
272
273 if (gid) {
274 if (!gid_is_valid(g->gr_gid))
275 return -EBADMSG;
276
277 *gid = g->gr_gid;
278 }
279
280 return 0;
281 }
282
283 char* uid_to_name(uid_t uid) {
284 char *ret;
285 int r;
286
287 /* Shortcut things to avoid NSS lookups */
288 if (uid == 0)
289 return strdup("root");
290 if (synthesize_nobody() &&
291 uid == UID_NOBODY)
292 return strdup(NOBODY_USER_NAME);
293
294 if (uid_is_valid(uid)) {
295 long bufsize;
296
297 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
298 if (bufsize <= 0)
299 bufsize = 4096;
300
301 for (;;) {
302 struct passwd pwbuf, *pw = NULL;
303 _cleanup_free_ char *buf = NULL;
304
305 buf = malloc(bufsize);
306 if (!buf)
307 return NULL;
308
309 r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
310 if (r == 0 && pw)
311 return strdup(pw->pw_name);
312 if (r != ERANGE)
313 break;
314
315 bufsize *= 2;
316 }
317 }
318
319 if (asprintf(&ret, UID_FMT, uid) < 0)
320 return NULL;
321
322 return ret;
323 }
324
325 char* gid_to_name(gid_t gid) {
326 char *ret;
327 int r;
328
329 if (gid == 0)
330 return strdup("root");
331 if (synthesize_nobody() &&
332 gid == GID_NOBODY)
333 return strdup(NOBODY_GROUP_NAME);
334
335 if (gid_is_valid(gid)) {
336 long bufsize;
337
338 bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
339 if (bufsize <= 0)
340 bufsize = 4096;
341
342 for (;;) {
343 struct group grbuf, *gr = NULL;
344 _cleanup_free_ char *buf = NULL;
345
346 buf = malloc(bufsize);
347 if (!buf)
348 return NULL;
349
350 r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
351 if (r == 0 && gr)
352 return strdup(gr->gr_name);
353 if (r != ERANGE)
354 break;
355
356 bufsize *= 2;
357 }
358 }
359
360 if (asprintf(&ret, GID_FMT, gid) < 0)
361 return NULL;
362
363 return ret;
364 }
365
366 int in_gid(gid_t gid) {
367 long ngroups_max;
368 gid_t *gids;
369 int r, i;
370
371 if (getgid() == gid)
372 return 1;
373
374 if (getegid() == gid)
375 return 1;
376
377 if (!gid_is_valid(gid))
378 return -EINVAL;
379
380 ngroups_max = sysconf(_SC_NGROUPS_MAX);
381 assert(ngroups_max > 0);
382
383 gids = newa(gid_t, ngroups_max);
384
385 r = getgroups(ngroups_max, gids);
386 if (r < 0)
387 return -errno;
388
389 for (i = 0; i < r; i++)
390 if (gids[i] == gid)
391 return 1;
392
393 return 0;
394 }
395
396 int in_group(const char *name) {
397 int r;
398 gid_t gid;
399
400 r = get_group_creds(&name, &gid);
401 if (r < 0)
402 return r;
403
404 return in_gid(gid);
405 }
406
407 int get_home_dir(char **_h) {
408 struct passwd *p;
409 const char *e;
410 char *h;
411 uid_t u;
412
413 assert(_h);
414
415 /* Take the user specified one */
416 e = secure_getenv("HOME");
417 if (e && path_is_absolute(e)) {
418 h = strdup(e);
419 if (!h)
420 return -ENOMEM;
421
422 *_h = h;
423 return 0;
424 }
425
426 /* Hardcode home directory for root and nobody to avoid NSS */
427 u = getuid();
428 if (u == 0) {
429 h = strdup("/root");
430 if (!h)
431 return -ENOMEM;
432
433 *_h = h;
434 return 0;
435 }
436 if (synthesize_nobody() &&
437 u == UID_NOBODY) {
438 h = strdup("/");
439 if (!h)
440 return -ENOMEM;
441
442 *_h = h;
443 return 0;
444 }
445
446 /* Check the database... */
447 errno = 0;
448 p = getpwuid(u);
449 if (!p)
450 return errno > 0 ? -errno : -ESRCH;
451
452 if (!path_is_absolute(p->pw_dir))
453 return -EINVAL;
454
455 h = strdup(p->pw_dir);
456 if (!h)
457 return -ENOMEM;
458
459 *_h = h;
460 return 0;
461 }
462
463 int get_shell(char **_s) {
464 struct passwd *p;
465 const char *e;
466 char *s;
467 uid_t u;
468
469 assert(_s);
470
471 /* Take the user specified one */
472 e = getenv("SHELL");
473 if (e) {
474 s = strdup(e);
475 if (!s)
476 return -ENOMEM;
477
478 *_s = s;
479 return 0;
480 }
481
482 /* Hardcode shell for root and nobody to avoid NSS */
483 u = getuid();
484 if (u == 0) {
485 s = strdup("/bin/sh");
486 if (!s)
487 return -ENOMEM;
488
489 *_s = s;
490 return 0;
491 }
492 if (synthesize_nobody() &&
493 u == UID_NOBODY) {
494 s = strdup("/sbin/nologin");
495 if (!s)
496 return -ENOMEM;
497
498 *_s = s;
499 return 0;
500 }
501
502 /* Check the database... */
503 errno = 0;
504 p = getpwuid(u);
505 if (!p)
506 return errno > 0 ? -errno : -ESRCH;
507
508 if (!path_is_absolute(p->pw_shell))
509 return -EINVAL;
510
511 s = strdup(p->pw_shell);
512 if (!s)
513 return -ENOMEM;
514
515 *_s = s;
516 return 0;
517 }
518
519 int reset_uid_gid(void) {
520 int r;
521
522 r = maybe_setgroups(0, NULL);
523 if (r < 0)
524 return r;
525
526 if (setresgid(0, 0, 0) < 0)
527 return -errno;
528
529 if (setresuid(0, 0, 0) < 0)
530 return -errno;
531
532 return 0;
533 }
534
535 int take_etc_passwd_lock(const char *root) {
536
537 struct flock flock = {
538 .l_type = F_WRLCK,
539 .l_whence = SEEK_SET,
540 .l_start = 0,
541 .l_len = 0,
542 };
543
544 const char *path;
545 int fd, r;
546
547 /* This is roughly the same as lckpwdf(), but not as awful. We
548 * don't want to use alarm() and signals, hence we implement
549 * our own trivial version of this.
550 *
551 * Note that shadow-utils also takes per-database locks in
552 * addition to lckpwdf(). However, we don't given that they
553 * are redundant as they invoke lckpwdf() first and keep
554 * it during everything they do. The per-database locks are
555 * awfully racy, and thus we just won't do them. */
556
557 if (root)
558 path = prefix_roota(root, ETC_PASSWD_LOCK_PATH);
559 else
560 path = ETC_PASSWD_LOCK_PATH;
561
562 fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
563 if (fd < 0)
564 return log_debug_errno(errno, "Cannot open %s: %m", path);
565
566 r = fcntl(fd, F_SETLKW, &flock);
567 if (r < 0) {
568 safe_close(fd);
569 return log_debug_errno(errno, "Locking %s failed: %m", path);
570 }
571
572 return fd;
573 }
574
575 bool valid_user_group_name(const char *u) {
576 const char *i;
577 long sz;
578
579 /* Checks if the specified name is a valid user/group name. Also see POSIX IEEE Std 1003.1-2008, 2016 Edition,
580 * 3.437. We are a bit stricter here however. Specifically we deviate from POSIX rules:
581 *
582 * - We don't allow any dots (this would break chown syntax which permits dots as user/group name separator)
583 * - We require that names fit into the appropriate utmp field
584 * - We don't allow empty user names
585 *
586 * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
587 */
588
589 if (isempty(u))
590 return false;
591
592 if (!(u[0] >= 'a' && u[0] <= 'z') &&
593 !(u[0] >= 'A' && u[0] <= 'Z') &&
594 u[0] != '_')
595 return false;
596
597 for (i = u+1; *i; i++) {
598 if (!(*i >= 'a' && *i <= 'z') &&
599 !(*i >= 'A' && *i <= 'Z') &&
600 !(*i >= '0' && *i <= '9') &&
601 !IN_SET(*i, '_', '-'))
602 return false;
603 }
604
605 sz = sysconf(_SC_LOGIN_NAME_MAX);
606 assert_se(sz > 0);
607
608 if ((size_t) (i-u) > (size_t) sz)
609 return false;
610
611 if ((size_t) (i-u) > UT_NAMESIZE - 1)
612 return false;
613
614 return true;
615 }
616
617 bool valid_user_group_name_or_id(const char *u) {
618
619 /* Similar as above, but is also fine with numeric UID/GID specifications, as long as they are in the right
620 * range, and not the invalid user ids. */
621
622 if (isempty(u))
623 return false;
624
625 if (valid_user_group_name(u))
626 return true;
627
628 return parse_uid(u, NULL) >= 0;
629 }
630
631 bool valid_gecos(const char *d) {
632
633 if (!d)
634 return false;
635
636 if (!utf8_is_valid(d))
637 return false;
638
639 if (string_has_cc(d, NULL))
640 return false;
641
642 /* Colons are used as field separators, and hence not OK */
643 if (strchr(d, ':'))
644 return false;
645
646 return true;
647 }
648
649 bool valid_home(const char *p) {
650 /* Note that this function is also called by valid_shell(), any
651 * changes must account for that. */
652
653 if (isempty(p))
654 return false;
655
656 if (!utf8_is_valid(p))
657 return false;
658
659 if (string_has_cc(p, NULL))
660 return false;
661
662 if (!path_is_absolute(p))
663 return false;
664
665 if (!path_is_normalized(p))
666 return false;
667
668 /* Colons are used as field separators, and hence not OK */
669 if (strchr(p, ':'))
670 return false;
671
672 return true;
673 }
674
675 int maybe_setgroups(size_t size, const gid_t *list) {
676 int r;
677
678 /* Check if setgroups is allowed before we try to drop all the auxiliary groups */
679 if (size == 0) { /* Dropping all aux groups? */
680 _cleanup_free_ char *setgroups_content = NULL;
681 bool can_setgroups;
682
683 r = read_one_line_file("/proc/self/setgroups", &setgroups_content);
684 if (r == -ENOENT)
685 /* Old kernels don't have /proc/self/setgroups, so assume we can use setgroups */
686 can_setgroups = true;
687 else if (r < 0)
688 return r;
689 else
690 can_setgroups = streq(setgroups_content, "allow");
691
692 if (!can_setgroups) {
693 log_debug("Skipping setgroups(), /proc/self/setgroups is set to 'deny'");
694 return 0;
695 }
696 }
697
698 if (setgroups(size, list) < 0)
699 return -errno;
700
701 return 0;
702 }
703
704 bool synthesize_nobody(void) {
705
706 #ifdef NOLEGACY
707 return true;
708 #else
709 /* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by
710 * touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems
711 * that used the "nobody" user name and group name for other UIDs/GIDs than 65534.
712 *
713 * Note that we do not employ any kind of synchronization on the following caching variable. If the variable is
714 * accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that
715 * shouldn't matter as each initialization should come to the same result. */
716 static int cache = -1;
717
718 if (cache < 0)
719 cache = access("/etc/systemd/dont-synthesize-nobody", F_OK) < 0;
720
721 return cache;
722 #endif
723 }
724
725 int putpwent_sane(const struct passwd *pw, FILE *stream) {
726 assert(pw);
727 assert(stream);
728
729 errno = 0;
730 if (putpwent(pw, stream) != 0)
731 return errno > 0 ? -errno : -EIO;
732
733 return 0;
734 }
735
736 int putspent_sane(const struct spwd *sp, FILE *stream) {
737 assert(sp);
738 assert(stream);
739
740 errno = 0;
741 if (putspent(sp, stream) != 0)
742 return errno > 0 ? -errno : -EIO;
743
744 return 0;
745 }
746
747 int putgrent_sane(const struct group *gr, FILE *stream) {
748 assert(gr);
749 assert(stream);
750
751 errno = 0;
752 if (putgrent(gr, stream) != 0)
753 return errno > 0 ? -errno : -EIO;
754
755 return 0;
756 }
757
758 #if ENABLE_GSHADOW
759 int putsgent_sane(const struct sgrp *sg, FILE *stream) {
760 assert(sg);
761 assert(stream);
762
763 errno = 0;
764 if (putsgent(sg, stream) != 0)
765 return errno > 0 ? -errno : -EIO;
766
767 return 0;
768 }
769 #endif
770
771 int fgetpwent_sane(FILE *stream, struct passwd **pw) {
772 struct passwd *p;
773
774 assert(pw);
775 assert(stream);
776
777 errno = 0;
778 p = fgetpwent(stream);
779 if (p == NULL) {
780 if (errno == ENOENT)
781 return false;
782 return errno > 0 ? -errno : -EIO;
783 }
784
785 *pw = p;
786 return true;
787 }
788
789 int fgetspent_sane(FILE *stream, struct spwd **sp) {
790 struct spwd *s;
791
792 assert(sp);
793 assert(stream);
794
795 errno = 0;
796 s = fgetspent(stream);
797 if (s == NULL) {
798 if (errno == ENOENT)
799 return false;
800 return errno > 0 ? -errno : -EIO;
801 }
802
803 *sp = s;
804 return true;
805 }
806
807 int fgetgrent_sane(FILE *stream, struct group **gr) {
808 struct group *g;
809
810 assert(gr);
811 assert(stream);
812
813 errno = 0;
814 g = fgetgrent(stream);
815 if (g == NULL) {
816 if (errno == ENOENT)
817 return false;
818 return errno > 0 ? -errno : -EIO;
819 }
820
821 *gr = g;
822 return true;
823 }
824
825 #if ENABLE_GSHADOW
826 int fgetsgent_sane(FILE *stream, struct sgrp **sg) {
827 struct sgrp *s;
828
829 assert(sg);
830 assert(stream);
831
832 errno = 0;
833 s = fgetsgent(stream);
834 if (s == NULL) {
835 if (errno == ENOENT)
836 return false;
837 return errno > 0 ? -errno : -EIO;
838 }
839
840 *sg = s;
841 return true;
842 }
843 #endif