1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <stddef.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sys/stat.h>
10 #include <unistd.h>
11 #include <utmp.h>
12 
13 #include "sd-messages.h"
14 
15 #include "alloc-util.h"
16 #include "errno-util.h"
17 #include "fd-util.h"
18 #include "fileio.h"
19 #include "format-util.h"
20 #include "macro.h"
21 #include "parse-util.h"
22 #include "path-util.h"
23 #include "path-util.h"
24 #include "random-util.h"
25 #include "string-util.h"
26 #include "strv.h"
27 #include "user-util.h"
28 #include "utf8.h"
29 
uid_is_valid(uid_t uid)30 bool uid_is_valid(uid_t uid) {
31 
32         /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.436. */
33 
34         /* Some libc APIs use UID_INVALID as special placeholder */
35         if (uid == (uid_t) UINT32_C(0xFFFFFFFF))
36                 return false;
37 
38         /* A long time ago UIDs where 16bit, hence explicitly avoid the 16bit -1 too */
39         if (uid == (uid_t) UINT32_C(0xFFFF))
40                 return false;
41 
42         return true;
43 }
44 
parse_uid(const char * s,uid_t * ret)45 int parse_uid(const char *s, uid_t *ret) {
46         uint32_t uid = 0;
47         int r;
48 
49         assert(s);
50 
51         assert_cc(sizeof(uid_t) == sizeof(uint32_t));
52 
53         /* We are very strict when parsing UIDs, and prohibit +/- as prefix, leading zero as prefix, and
54          * whitespace. We do this, since this call is often used in a context where we parse things as UID
55          * first, and if that doesn't work we fall back to NSS. Thus we really want to make sure that UIDs
56          * are parsed as UIDs only if they really really look like UIDs. */
57         r = safe_atou32_full(s, 10
58                              | SAFE_ATO_REFUSE_PLUS_MINUS
59                              | SAFE_ATO_REFUSE_LEADING_ZERO
60                              | SAFE_ATO_REFUSE_LEADING_WHITESPACE, &uid);
61         if (r < 0)
62                 return r;
63 
64         if (!uid_is_valid(uid))
65                 return -ENXIO; /* we return ENXIO instead of EINVAL
66                                 * here, to make it easy to distinguish
67                                 * invalid numeric uids from invalid
68                                 * strings. */
69 
70         if (ret)
71                 *ret = uid;
72 
73         return 0;
74 }
75 
parse_uid_range(const char * s,uid_t * ret_lower,uid_t * ret_upper)76 int parse_uid_range(const char *s, uid_t *ret_lower, uid_t *ret_upper) {
77         _cleanup_free_ char *word = NULL;
78         uid_t l, u;
79         int r;
80 
81         assert(s);
82         assert(ret_lower);
83         assert(ret_upper);
84 
85         r = extract_first_word(&s, &word, "-", EXTRACT_DONT_COALESCE_SEPARATORS);
86         if (r < 0)
87                 return r;
88         if (r == 0)
89                 return -EINVAL;
90 
91         r = parse_uid(word, &l);
92         if (r < 0)
93                 return r;
94 
95         /* Check for the upper bound and extract it if needed */
96         if (!s)
97                 /* Single number with no dash. */
98                 u = l;
99         else if (!*s)
100                 /* Trailing dash is an error. */
101                 return -EINVAL;
102         else {
103                 r = parse_uid(s, &u);
104                 if (r < 0)
105                         return r;
106 
107                 if (l > u)
108                         return -EINVAL;
109         }
110 
111         *ret_lower = l;
112         *ret_upper = u;
113         return 0;
114 }
115 
getlogname_malloc(void)116 char* getlogname_malloc(void) {
117         uid_t uid;
118         struct stat st;
119 
120         if (isatty(STDIN_FILENO) && fstat(STDIN_FILENO, &st) >= 0)
121                 uid = st.st_uid;
122         else
123                 uid = getuid();
124 
125         return uid_to_name(uid);
126 }
127 
getusername_malloc(void)128 char *getusername_malloc(void) {
129         const char *e;
130 
131         e = secure_getenv("USER");
132         if (e)
133                 return strdup(e);
134 
135         return uid_to_name(getuid());
136 }
137 
is_nologin_shell(const char * shell)138 bool is_nologin_shell(const char *shell) {
139 
140         return PATH_IN_SET(shell,
141                            /* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
142                             * message and exits. Different distributions place the binary at different places though,
143                             * hence let's list them all. */
144                            "/bin/nologin",
145                            "/sbin/nologin",
146                            "/usr/bin/nologin",
147                            "/usr/sbin/nologin",
148                            /* 'true' and 'false' work too for the same purpose, but are less friendly as they don't do
149                             * any message printing. Different distributions place the binary at various places but at
150                             * least not in the 'sbin' directory. */
151                            "/bin/false",
152                            "/usr/bin/false",
153                            "/bin/true",
154                            "/usr/bin/true");
155 }
156 
synthesize_user_creds(const char ** username,uid_t * uid,gid_t * gid,const char ** home,const char ** shell,UserCredsFlags flags)157 static int synthesize_user_creds(
158                 const char **username,
159                 uid_t *uid, gid_t *gid,
160                 const char **home,
161                 const char **shell,
162                 UserCredsFlags flags) {
163 
164         /* We enforce some special rules for uid=0 and uid=65534: in order to avoid NSS lookups for root we hardcode
165          * their user record data. */
166 
167         if (STR_IN_SET(*username, "root", "0")) {
168                 *username = "root";
169 
170                 if (uid)
171                         *uid = 0;
172                 if (gid)
173                         *gid = 0;
174 
175                 if (home)
176                         *home = "/root";
177 
178                 if (shell)
179                         *shell = "/bin/sh";
180 
181                 return 0;
182         }
183 
184         if (synthesize_nobody() &&
185             STR_IN_SET(*username, NOBODY_USER_NAME, "65534")) {
186                 *username = NOBODY_USER_NAME;
187 
188                 if (uid)
189                         *uid = UID_NOBODY;
190                 if (gid)
191                         *gid = GID_NOBODY;
192 
193                 if (home)
194                         *home = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : "/";
195 
196                 if (shell)
197                         *shell = FLAGS_SET(flags, USER_CREDS_CLEAN) ? NULL : NOLOGIN;
198 
199                 return 0;
200         }
201 
202         return -ENOMEDIUM;
203 }
204 
get_user_creds(const char ** username,uid_t * uid,gid_t * gid,const char ** home,const char ** shell,UserCredsFlags flags)205 int get_user_creds(
206                 const char **username,
207                 uid_t *uid, gid_t *gid,
208                 const char **home,
209                 const char **shell,
210                 UserCredsFlags flags) {
211 
212         uid_t u = UID_INVALID;
213         struct passwd *p;
214         int r;
215 
216         assert(username);
217         assert(*username);
218 
219         if (!FLAGS_SET(flags, USER_CREDS_PREFER_NSS) ||
220             (!home && !shell)) {
221 
222                 /* So here's the deal: normally, we'll try to synthesize all records we can synthesize, and override
223                  * the user database with that. However, if the user specifies USER_CREDS_PREFER_NSS then the
224                  * user database will override the synthetic records instead — except if the user is only interested in
225                  * the UID and/or GID (but not the home directory, or the shell), in which case we'll always override
226                  * the user database (i.e. the USER_CREDS_PREFER_NSS flag has no effect in this case). Why?
227                  * Simply because there are valid usecase where the user might change the home directory or the shell
228                  * of the relevant users, but changing the UID/GID mappings for them is something we explicitly don't
229                  * support. */
230 
231                 r = synthesize_user_creds(username, uid, gid, home, shell, flags);
232                 if (r >= 0)
233                         return 0;
234                 if (r != -ENOMEDIUM) /* not a username we can synthesize */
235                         return r;
236         }
237 
238         if (parse_uid(*username, &u) >= 0) {
239                 errno = 0;
240                 p = getpwuid(u);
241 
242                 /* If there are multiple users with the same id, make sure to leave $USER to the configured value
243                  * instead of the first occurrence in the database. However if the uid was configured by a numeric uid,
244                  * then let's pick the real username from /etc/passwd. */
245                 if (p)
246                         *username = p->pw_name;
247                 else if (FLAGS_SET(flags, USER_CREDS_ALLOW_MISSING) && !gid && !home && !shell) {
248 
249                         /* If the specified user is a numeric UID and it isn't in the user database, and the caller
250                          * passed USER_CREDS_ALLOW_MISSING and was only interested in the UID, then just return that
251                          * and don't complain. */
252 
253                         if (uid)
254                                 *uid = u;
255 
256                         return 0;
257                 }
258         } else {
259                 errno = 0;
260                 p = getpwnam(*username);
261         }
262         if (!p) {
263                 r = errno_or_else(ESRCH);
264 
265                 /* If the user requested that we only synthesize as fallback, do so now */
266                 if (FLAGS_SET(flags, USER_CREDS_PREFER_NSS)) {
267                         if (synthesize_user_creds(username, uid, gid, home, shell, flags) >= 0)
268                                 return 0;
269                 }
270 
271                 return r;
272         }
273 
274         if (uid) {
275                 if (!uid_is_valid(p->pw_uid))
276                         return -EBADMSG;
277 
278                 *uid = p->pw_uid;
279         }
280 
281         if (gid) {
282                 if (!gid_is_valid(p->pw_gid))
283                         return -EBADMSG;
284 
285                 *gid = p->pw_gid;
286         }
287 
288         if (home) {
289                 if (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
290                     (empty_or_root(p->pw_dir) ||
291                      !path_is_valid(p->pw_dir) ||
292                      !path_is_absolute(p->pw_dir)))
293                         *home = NULL; /* Note: we don't insist on normalized paths, since there are setups that have /./ in the path */
294                 else
295                         *home = p->pw_dir;
296         }
297 
298         if (shell) {
299                 if (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
300                     (isempty(p->pw_shell) ||
301                      !path_is_valid(p->pw_dir) ||
302                      !path_is_absolute(p->pw_shell) ||
303                      is_nologin_shell(p->pw_shell)))
304                         *shell = NULL;
305                 else
306                         *shell = p->pw_shell;
307         }
308 
309         return 0;
310 }
311 
get_group_creds(const char ** groupname,gid_t * gid,UserCredsFlags flags)312 int get_group_creds(const char **groupname, gid_t *gid, UserCredsFlags flags) {
313         struct group *g;
314         gid_t id;
315 
316         assert(groupname);
317 
318         /* We enforce some special rules for gid=0: in order to avoid NSS lookups for root we hardcode its data. */
319 
320         if (STR_IN_SET(*groupname, "root", "0")) {
321                 *groupname = "root";
322 
323                 if (gid)
324                         *gid = 0;
325 
326                 return 0;
327         }
328 
329         if (synthesize_nobody() &&
330             STR_IN_SET(*groupname, NOBODY_GROUP_NAME, "65534")) {
331                 *groupname = NOBODY_GROUP_NAME;
332 
333                 if (gid)
334                         *gid = GID_NOBODY;
335 
336                 return 0;
337         }
338 
339         if (parse_gid(*groupname, &id) >= 0) {
340                 errno = 0;
341                 g = getgrgid(id);
342 
343                 if (g)
344                         *groupname = g->gr_name;
345                 else if (FLAGS_SET(flags, USER_CREDS_ALLOW_MISSING)) {
346                         if (gid)
347                                 *gid = id;
348 
349                         return 0;
350                 }
351         } else {
352                 errno = 0;
353                 g = getgrnam(*groupname);
354         }
355 
356         if (!g)
357                 return errno_or_else(ESRCH);
358 
359         if (gid) {
360                 if (!gid_is_valid(g->gr_gid))
361                         return -EBADMSG;
362 
363                 *gid = g->gr_gid;
364         }
365 
366         return 0;
367 }
368 
uid_to_name(uid_t uid)369 char* uid_to_name(uid_t uid) {
370         char *ret;
371         int r;
372 
373         /* Shortcut things to avoid NSS lookups */
374         if (uid == 0)
375                 return strdup("root");
376         if (synthesize_nobody() &&
377             uid == UID_NOBODY)
378                 return strdup(NOBODY_USER_NAME);
379 
380         if (uid_is_valid(uid)) {
381                 long bufsize;
382 
383                 bufsize = sysconf(_SC_GETPW_R_SIZE_MAX);
384                 if (bufsize <= 0)
385                         bufsize = 4096;
386 
387                 for (;;) {
388                         struct passwd pwbuf, *pw = NULL;
389                         _cleanup_free_ char *buf = NULL;
390 
391                         buf = malloc(bufsize);
392                         if (!buf)
393                                 return NULL;
394 
395                         r = getpwuid_r(uid, &pwbuf, buf, (size_t) bufsize, &pw);
396                         if (r == 0 && pw)
397                                 return strdup(pw->pw_name);
398                         if (r != ERANGE)
399                                 break;
400 
401                         if (bufsize > LONG_MAX/2) /* overflow check */
402                                 return NULL;
403 
404                         bufsize *= 2;
405                 }
406         }
407 
408         if (asprintf(&ret, UID_FMT, uid) < 0)
409                 return NULL;
410 
411         return ret;
412 }
413 
gid_to_name(gid_t gid)414 char* gid_to_name(gid_t gid) {
415         char *ret;
416         int r;
417 
418         if (gid == 0)
419                 return strdup("root");
420         if (synthesize_nobody() &&
421             gid == GID_NOBODY)
422                 return strdup(NOBODY_GROUP_NAME);
423 
424         if (gid_is_valid(gid)) {
425                 long bufsize;
426 
427                 bufsize = sysconf(_SC_GETGR_R_SIZE_MAX);
428                 if (bufsize <= 0)
429                         bufsize = 4096;
430 
431                 for (;;) {
432                         struct group grbuf, *gr = NULL;
433                         _cleanup_free_ char *buf = NULL;
434 
435                         buf = malloc(bufsize);
436                         if (!buf)
437                                 return NULL;
438 
439                         r = getgrgid_r(gid, &grbuf, buf, (size_t) bufsize, &gr);
440                         if (r == 0 && gr)
441                                 return strdup(gr->gr_name);
442                         if (r != ERANGE)
443                                 break;
444 
445                         if (bufsize > LONG_MAX/2) /* overflow check */
446                                 return NULL;
447 
448                         bufsize *= 2;
449                 }
450         }
451 
452         if (asprintf(&ret, GID_FMT, gid) < 0)
453                 return NULL;
454 
455         return ret;
456 }
457 
gid_list_has(const gid_t * list,size_t size,gid_t val)458 static bool gid_list_has(const gid_t *list, size_t size, gid_t val) {
459         for (size_t i = 0; i < size; i++)
460                 if (list[i] == val)
461                         return true;
462         return false;
463 }
464 
in_gid(gid_t gid)465 int in_gid(gid_t gid) {
466         _cleanup_free_ gid_t *gids = NULL;
467         int ngroups;
468 
469         if (getgid() == gid)
470                 return 1;
471 
472         if (getegid() == gid)
473                 return 1;
474 
475         if (!gid_is_valid(gid))
476                 return -EINVAL;
477 
478         ngroups = getgroups_alloc(&gids);
479         if (ngroups < 0)
480                 return ngroups;
481 
482         return gid_list_has(gids, ngroups, gid);
483 }
484 
in_group(const char * name)485 int in_group(const char *name) {
486         int r;
487         gid_t gid;
488 
489         r = get_group_creds(&name, &gid, 0);
490         if (r < 0)
491                 return r;
492 
493         return in_gid(gid);
494 }
495 
merge_gid_lists(const gid_t * list1,size_t size1,const gid_t * list2,size_t size2,gid_t ** ret)496 int merge_gid_lists(const gid_t *list1, size_t size1, const gid_t *list2, size_t size2, gid_t **ret) {
497         size_t nresult = 0;
498         assert(ret);
499 
500         if (size2 > INT_MAX - size1)
501                 return -ENOBUFS;
502 
503         gid_t *buf = new(gid_t, size1 + size2);
504         if (!buf)
505                 return -ENOMEM;
506 
507         /* Duplicates need to be skipped on merging, otherwise they'll be passed on and stored in the kernel. */
508         for (size_t i = 0; i < size1; i++)
509                 if (!gid_list_has(buf, nresult, list1[i]))
510                         buf[nresult++] = list1[i];
511         for (size_t i = 0; i < size2; i++)
512                 if (!gid_list_has(buf, nresult, list2[i]))
513                         buf[nresult++] = list2[i];
514         *ret = buf;
515         return (int)nresult;
516 }
517 
getgroups_alloc(gid_t ** gids)518 int getgroups_alloc(gid_t** gids) {
519         gid_t *allocated;
520         _cleanup_free_  gid_t *p = NULL;
521         int ngroups = 8;
522         unsigned attempt = 0;
523 
524         allocated = new(gid_t, ngroups);
525         if (!allocated)
526                 return -ENOMEM;
527         p = allocated;
528 
529         for (;;) {
530                 ngroups = getgroups(ngroups, p);
531                 if (ngroups >= 0)
532                         break;
533                 if (errno != EINVAL)
534                         return -errno;
535 
536                 /* Give up eventually */
537                 if (attempt++ > 10)
538                         return -EINVAL;
539 
540                 /* Get actual size needed, and size the array explicitly. Note that this is potentially racy
541                  * to use (in multi-threaded programs), hence let's call this in a loop. */
542                 ngroups = getgroups(0, NULL);
543                 if (ngroups < 0)
544                         return -errno;
545                 if (ngroups == 0)
546                         return false;
547 
548                 free(allocated);
549 
550                 p = allocated = new(gid_t, ngroups);
551                 if (!allocated)
552                         return -ENOMEM;
553         }
554 
555         *gids = TAKE_PTR(p);
556         return ngroups;
557 }
558 
get_home_dir(char ** _h)559 int get_home_dir(char **_h) {
560         struct passwd *p;
561         const char *e;
562         char *h;
563         uid_t u;
564 
565         assert(_h);
566 
567         /* Take the user specified one */
568         e = secure_getenv("HOME");
569         if (e && path_is_valid(e) && path_is_absolute(e)) {
570                 h = strdup(e);
571                 if (!h)
572                         return -ENOMEM;
573 
574                 *_h = path_simplify(h);
575                 return 0;
576         }
577 
578         /* Hardcode home directory for root and nobody to avoid NSS */
579         u = getuid();
580         if (u == 0) {
581                 h = strdup("/root");
582                 if (!h)
583                         return -ENOMEM;
584 
585                 *_h = h;
586                 return 0;
587         }
588         if (synthesize_nobody() &&
589             u == UID_NOBODY) {
590                 h = strdup("/");
591                 if (!h)
592                         return -ENOMEM;
593 
594                 *_h = h;
595                 return 0;
596         }
597 
598         /* Check the database... */
599         errno = 0;
600         p = getpwuid(u);
601         if (!p)
602                 return errno_or_else(ESRCH);
603 
604         if (!path_is_valid(p->pw_dir) ||
605             !path_is_absolute(p->pw_dir))
606                 return -EINVAL;
607 
608         h = strdup(p->pw_dir);
609         if (!h)
610                 return -ENOMEM;
611 
612         *_h = path_simplify(h);
613         return 0;
614 }
615 
get_shell(char ** _s)616 int get_shell(char **_s) {
617         struct passwd *p;
618         const char *e;
619         char *s;
620         uid_t u;
621 
622         assert(_s);
623 
624         /* Take the user specified one */
625         e = secure_getenv("SHELL");
626         if (e && path_is_valid(e) && path_is_absolute(e)) {
627                 s = strdup(e);
628                 if (!s)
629                         return -ENOMEM;
630 
631                 *_s = path_simplify(s);
632                 return 0;
633         }
634 
635         /* Hardcode shell for root and nobody to avoid NSS */
636         u = getuid();
637         if (u == 0) {
638                 s = strdup("/bin/sh");
639                 if (!s)
640                         return -ENOMEM;
641 
642                 *_s = s;
643                 return 0;
644         }
645         if (synthesize_nobody() &&
646             u == UID_NOBODY) {
647                 s = strdup(NOLOGIN);
648                 if (!s)
649                         return -ENOMEM;
650 
651                 *_s = s;
652                 return 0;
653         }
654 
655         /* Check the database... */
656         errno = 0;
657         p = getpwuid(u);
658         if (!p)
659                 return errno_or_else(ESRCH);
660 
661         if (!path_is_valid(p->pw_shell) ||
662             !path_is_absolute(p->pw_shell))
663                 return -EINVAL;
664 
665         s = strdup(p->pw_shell);
666         if (!s)
667                 return -ENOMEM;
668 
669         *_s = path_simplify(s);
670         return 0;
671 }
672 
reset_uid_gid(void)673 int reset_uid_gid(void) {
674         int r;
675 
676         r = maybe_setgroups(0, NULL);
677         if (r < 0)
678                 return r;
679 
680         if (setresgid(0, 0, 0) < 0)
681                 return -errno;
682 
683         return RET_NERRNO(setresuid(0, 0, 0));
684 }
685 
take_etc_passwd_lock(const char * root)686 int take_etc_passwd_lock(const char *root) {
687 
688         struct flock flock = {
689                 .l_type = F_WRLCK,
690                 .l_whence = SEEK_SET,
691                 .l_start = 0,
692                 .l_len = 0,
693         };
694 
695         const char *path;
696         int fd, r;
697 
698         /* This is roughly the same as lckpwdf(), but not as awful. We
699          * don't want to use alarm() and signals, hence we implement
700          * our own trivial version of this.
701          *
702          * Note that shadow-utils also takes per-database locks in
703          * addition to lckpwdf(). However, we don't given that they
704          * are redundant as they invoke lckpwdf() first and keep
705          * it during everything they do. The per-database locks are
706          * awfully racy, and thus we just won't do them. */
707 
708         if (root)
709                 path = prefix_roota(root, ETC_PASSWD_LOCK_PATH);
710         else
711                 path = ETC_PASSWD_LOCK_PATH;
712 
713         fd = open(path, O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, 0600);
714         if (fd < 0)
715                 return log_debug_errno(errno, "Cannot open %s: %m", path);
716 
717         r = fcntl(fd, F_SETLKW, &flock);
718         if (r < 0) {
719                 safe_close(fd);
720                 return log_debug_errno(errno, "Locking %s failed: %m", path);
721         }
722 
723         return fd;
724 }
725 
valid_user_group_name(const char * u,ValidUserFlags flags)726 bool valid_user_group_name(const char *u, ValidUserFlags flags) {
727         const char *i;
728 
729         /* Checks if the specified name is a valid user/group name. There are two flavours of this call:
730          * strict mode is the default which is POSIX plus some extra rules; and relaxed mode where we accept
731          * pretty much everything except the really worst offending names.
732          *
733          * Whenever we synthesize users ourselves we should use the strict mode. But when we process users
734          * created by other stuff, let's be more liberal. */
735 
736         if (isempty(u)) /* An empty user name is never valid */
737                 return false;
738 
739         if (parse_uid(u, NULL) >= 0) /* Something that parses as numeric UID string is valid exactly when the
740                                       * flag for it is set */
741                 return FLAGS_SET(flags, VALID_USER_ALLOW_NUMERIC);
742 
743         if (FLAGS_SET(flags, VALID_USER_RELAX)) {
744 
745                 /* In relaxed mode we just check very superficially. Apparently SSSD and other stuff is
746                  * extremely liberal (way too liberal if you ask me, even inserting "@" in user names, which
747                  * is bound to cause problems for example when used with an MTA), hence only filter the most
748                  * obvious cases, or where things would result in an invalid entry if such a user name would
749                  * show up in /etc/passwd (or equivalent getent output).
750                  *
751                  * Note that we stepped far out of POSIX territory here. It's not our fault though, but
752                  * SSSD's, Samba's and everybody else who ignored POSIX on this. (I mean, I am happy to step
753                  * outside of POSIX' bounds any day, but I must say in this case I probably wouldn't
754                  * have...) */
755 
756                 if (startswith(u, " ") || endswith(u, " ")) /* At least expect whitespace padding is removed
757                                                              * at front and back (accept in the middle, since
758                                                              * that's apparently a thing on Windows). Note
759                                                              * that this also blocks usernames consisting of
760                                                              * whitespace only. */
761                         return false;
762 
763                 if (!utf8_is_valid(u)) /* We want to synthesize JSON from this, hence insist on UTF-8 */
764                         return false;
765 
766                 if (string_has_cc(u, NULL)) /* CC characters are just dangerous (and \n in particular is the
767                                              * record separator in /etc/passwd), so we can't allow that. */
768                         return false;
769 
770                 if (strpbrk(u, ":/")) /* Colons are the field separator in /etc/passwd, we can't allow
771                                        * that. Slashes are special to file systems paths and user names
772                                        * typically show up in the file system as home directories, hence
773                                        * don't allow slashes. */
774                         return false;
775 
776                 if (in_charset(u, "0123456789")) /* Don't allow fully numeric strings, they might be confused
777                                                   * with UIDs (note that this test is more broad than
778                                                   * the parse_uid() test above, as it will cover more than
779                                                   * the 32bit range, and it will detect 65535 (which is in
780                                                   * invalid UID, even though in the unsigned 32 bit range) */
781                         return false;
782 
783                 if (u[0] == '-' && in_charset(u + 1, "0123456789")) /* Don't allow negative fully numeric
784                                                                      * strings either. After all some people
785                                                                      * write 65535 as -1 (even though that's
786                                                                      * not even true on 32bit uid_t
787                                                                      * anyway) */
788                         return false;
789 
790                 if (dot_or_dot_dot(u)) /* User names typically become home directory names, and these two are
791                                         * special in that context, don't allow that. */
792                         return false;
793 
794                 /* Compare with strict result and warn if result doesn't match */
795                 if (FLAGS_SET(flags, VALID_USER_WARN) && !valid_user_group_name(u, 0))
796                         log_struct(LOG_NOTICE,
797                                    LOG_MESSAGE("Accepting user/group name '%s', which does not match strict user/group name rules.", u),
798                                    "USER_GROUP_NAME=%s", u,
799                                    "MESSAGE_ID=" SD_MESSAGE_UNSAFE_USER_NAME_STR);
800 
801                 /* Note that we make no restrictions on the length in relaxed mode! */
802         } else {
803                 long sz;
804                 size_t l;
805 
806                 /* Also see POSIX IEEE Std 1003.1-2008, 2016 Edition, 3.437. We are a bit stricter here
807                  * however. Specifically we deviate from POSIX rules:
808                  *
809                  * - We don't allow empty user names (see above)
810                  * - We require that names fit into the appropriate utmp field
811                  * - We don't allow any dots (this conflicts with chown syntax which permits dots as user/group name separator)
812                  * - We don't allow dashes or digit as the first character
813                  *
814                  * Note that other systems are even more restrictive, and don't permit underscores or uppercase characters.
815                  */
816 
817                 if (!(u[0] >= 'a' && u[0] <= 'z') &&
818                     !(u[0] >= 'A' && u[0] <= 'Z') &&
819                     u[0] != '_')
820                         return false;
821 
822                 for (i = u+1; *i; i++)
823                         if (!(*i >= 'a' && *i <= 'z') &&
824                             !(*i >= 'A' && *i <= 'Z') &&
825                             !(*i >= '0' && *i <= '9') &&
826                             !IN_SET(*i, '_', '-'))
827                                 return false;
828 
829                 l = i - u;
830 
831                 sz = sysconf(_SC_LOGIN_NAME_MAX);
832                 assert_se(sz > 0);
833 
834                 if (l > (size_t) sz)
835                         return false;
836                 if (l > NAME_MAX) /* must fit in a filename */
837                         return false;
838                 if (l > UT_NAMESIZE - 1)
839                         return false;
840         }
841 
842         return true;
843 }
844 
valid_gecos(const char * d)845 bool valid_gecos(const char *d) {
846 
847         if (!d)
848                 return false;
849 
850         if (!utf8_is_valid(d))
851                 return false;
852 
853         if (string_has_cc(d, NULL))
854                 return false;
855 
856         /* Colons are used as field separators, and hence not OK */
857         if (strchr(d, ':'))
858                 return false;
859 
860         return true;
861 }
862 
mangle_gecos(const char * d)863 char *mangle_gecos(const char *d) {
864         char *mangled;
865 
866         /* Makes sure the provided string becomes valid as a GEGOS field, by dropping bad chars. glibc's
867          * putwent() only changes \n and : to spaces. We do more: replace all CC too, and remove invalid
868          * UTF-8 */
869 
870         mangled = strdup(d);
871         if (!mangled)
872                 return NULL;
873 
874         for (char *i = mangled; *i; i++) {
875                 int len;
876 
877                 if ((uint8_t) *i < (uint8_t) ' ' || *i == ':') {
878                         *i = ' ';
879                         continue;
880                 }
881 
882                 len = utf8_encoded_valid_unichar(i, SIZE_MAX);
883                 if (len < 0) {
884                         *i = ' ';
885                         continue;
886                 }
887 
888                 i += len - 1;
889         }
890 
891         return mangled;
892 }
893 
valid_home(const char * p)894 bool valid_home(const char *p) {
895         /* Note that this function is also called by valid_shell(), any
896          * changes must account for that. */
897 
898         if (isempty(p))
899                 return false;
900 
901         if (!utf8_is_valid(p))
902                 return false;
903 
904         if (string_has_cc(p, NULL))
905                 return false;
906 
907         if (!path_is_absolute(p))
908                 return false;
909 
910         if (!path_is_normalized(p))
911                 return false;
912 
913         /* Colons are used as field separators, and hence not OK */
914         if (strchr(p, ':'))
915                 return false;
916 
917         return true;
918 }
919 
maybe_setgroups(size_t size,const gid_t * list)920 int maybe_setgroups(size_t size, const gid_t *list) {
921         int r;
922 
923         /* Check if setgroups is allowed before we try to drop all the auxiliary groups */
924         if (size == 0) { /* Dropping all aux groups? */
925                 _cleanup_free_ char *setgroups_content = NULL;
926                 bool can_setgroups;
927 
928                 r = read_one_line_file("/proc/self/setgroups", &setgroups_content);
929                 if (r == -ENOENT)
930                         /* Old kernels don't have /proc/self/setgroups, so assume we can use setgroups */
931                         can_setgroups = true;
932                 else if (r < 0)
933                         return r;
934                 else
935                         can_setgroups = streq(setgroups_content, "allow");
936 
937                 if (!can_setgroups) {
938                         log_debug("Skipping setgroups(), /proc/self/setgroups is set to 'deny'");
939                         return 0;
940                 }
941         }
942 
943         return RET_NERRNO(setgroups(size, list));
944 }
945 
synthesize_nobody(void)946 bool synthesize_nobody(void) {
947         /* Returns true when we shall synthesize the "nobody" user (which we do by default). This can be turned off by
948          * touching /etc/systemd/dont-synthesize-nobody in order to provide upgrade compatibility with legacy systems
949          * that used the "nobody" user name and group name for other UIDs/GIDs than 65534.
950          *
951          * Note that we do not employ any kind of synchronization on the following caching variable. If the variable is
952          * accessed in multi-threaded programs in the worst case it might happen that we initialize twice, but that
953          * shouldn't matter as each initialization should come to the same result. */
954         static int cache = -1;
955 
956         if (cache < 0)
957                 cache = access("/etc/systemd/dont-synthesize-nobody", F_OK) < 0;
958 
959         return cache;
960 }
961 
putpwent_sane(const struct passwd * pw,FILE * stream)962 int putpwent_sane(const struct passwd *pw, FILE *stream) {
963         assert(pw);
964         assert(stream);
965 
966         errno = 0;
967         if (putpwent(pw, stream) != 0)
968                 return errno_or_else(EIO);
969 
970         return 0;
971 }
972 
putspent_sane(const struct spwd * sp,FILE * stream)973 int putspent_sane(const struct spwd *sp, FILE *stream) {
974         assert(sp);
975         assert(stream);
976 
977         errno = 0;
978         if (putspent(sp, stream) != 0)
979                 return errno_or_else(EIO);
980 
981         return 0;
982 }
983 
putgrent_sane(const struct group * gr,FILE * stream)984 int putgrent_sane(const struct group *gr, FILE *stream) {
985         assert(gr);
986         assert(stream);
987 
988         errno = 0;
989         if (putgrent(gr, stream) != 0)
990                 return errno_or_else(EIO);
991 
992         return 0;
993 }
994 
995 #if ENABLE_GSHADOW
putsgent_sane(const struct sgrp * sg,FILE * stream)996 int putsgent_sane(const struct sgrp *sg, FILE *stream) {
997         assert(sg);
998         assert(stream);
999 
1000         errno = 0;
1001         if (putsgent(sg, stream) != 0)
1002                 return errno_or_else(EIO);
1003 
1004         return 0;
1005 }
1006 #endif
1007 
fgetpwent_sane(FILE * stream,struct passwd ** pw)1008 int fgetpwent_sane(FILE *stream, struct passwd **pw) {
1009         struct passwd *p;
1010 
1011         assert(pw);
1012         assert(stream);
1013 
1014         errno = 0;
1015         p = fgetpwent(stream);
1016         if (!p && errno != ENOENT)
1017                 return errno_or_else(EIO);
1018 
1019         *pw = p;
1020         return !!p;
1021 }
1022 
fgetspent_sane(FILE * stream,struct spwd ** sp)1023 int fgetspent_sane(FILE *stream, struct spwd **sp) {
1024         struct spwd *s;
1025 
1026         assert(sp);
1027         assert(stream);
1028 
1029         errno = 0;
1030         s = fgetspent(stream);
1031         if (!s && errno != ENOENT)
1032                 return errno_or_else(EIO);
1033 
1034         *sp = s;
1035         return !!s;
1036 }
1037 
fgetgrent_sane(FILE * stream,struct group ** gr)1038 int fgetgrent_sane(FILE *stream, struct group **gr) {
1039         struct group *g;
1040 
1041         assert(gr);
1042         assert(stream);
1043 
1044         errno = 0;
1045         g = fgetgrent(stream);
1046         if (!g && errno != ENOENT)
1047                 return errno_or_else(EIO);
1048 
1049         *gr = g;
1050         return !!g;
1051 }
1052 
1053 #if ENABLE_GSHADOW
fgetsgent_sane(FILE * stream,struct sgrp ** sg)1054 int fgetsgent_sane(FILE *stream, struct sgrp **sg) {
1055         struct sgrp *s;
1056 
1057         assert(sg);
1058         assert(stream);
1059 
1060         errno = 0;
1061         s = fgetsgent(stream);
1062         if (!s && errno != ENOENT)
1063                 return errno_or_else(EIO);
1064 
1065         *sg = s;
1066         return !!s;
1067 }
1068 #endif
1069 
is_this_me(const char * username)1070 int is_this_me(const char *username) {
1071         uid_t uid;
1072         int r;
1073 
1074         /* Checks if the specified username is our current one. Passed string might be a UID or a user name. */
1075 
1076         r = get_user_creds(&username, &uid, NULL, NULL, NULL, USER_CREDS_ALLOW_MISSING);
1077         if (r < 0)
1078                 return r;
1079 
1080         return uid == getuid();
1081 }
1082 
get_home_root(void)1083 const char *get_home_root(void) {
1084         const char *e;
1085 
1086         /* For debug purposes allow overriding where we look for home dirs */
1087         e = secure_getenv("SYSTEMD_HOME_ROOT");
1088         if (e && path_is_absolute(e) && path_is_normalized(e))
1089                 return e;
1090 
1091         return "/home";
1092 }
1093