]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/user-util.h
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
12 #include <sys/types.h>
15 /* Users managed by systemd-homed. See https://systemd.io/UIDS-GIDS for details how this range fits into the rest of the world */
16 #define HOME_UID_MIN ((uid_t) 60001)
17 #define HOME_UID_MAX ((uid_t) 60513)
19 /* Users mapped from host into a container */
20 #define MAP_UID_MIN ((uid_t) 60514)
21 #define MAP_UID_MAX ((uid_t) 60577)
23 bool uid_is_valid ( uid_t uid
);
25 static inline bool gid_is_valid ( gid_t gid
) {
26 return uid_is_valid (( uid_t
) gid
);
29 int parse_uid ( const char * s
, uid_t
* ret_uid
);
30 int parse_uid_range ( const char * s
, uid_t
* ret_lower
, uid_t
* ret_upper
);
32 static inline int parse_gid ( const char * s
, gid_t
* ret_gid
) {
33 return parse_uid ( s
, ( uid_t
*) ret_gid
);
36 char * getlogname_malloc ( void );
37 char * getusername_malloc ( void );
39 typedef enum UserCredsFlags
{
40 USER_CREDS_PREFER_NSS
= 1 << 0 , /* if set, only synthesize user records if database lacks them. Normally we bypass the userdb entirely for the records we can synthesize */
41 USER_CREDS_ALLOW_MISSING
= 1 << 1 , /* if a numeric UID string is resolved, be OK if there's no record for it */
42 USER_CREDS_CLEAN
= 1 << 2 , /* try to clean up shell and home fields with invalid data */
45 int get_user_creds ( const char ** username
, uid_t
* ret_uid
, gid_t
* ret_gid
, const char ** ret_home
, const char ** ret_shell
, UserCredsFlags flags
);
46 int get_group_creds ( const char ** groupname
, gid_t
* ret_gid
, UserCredsFlags flags
);
48 char * uid_to_name ( uid_t uid
);
49 char * gid_to_name ( gid_t gid
);
51 int in_gid ( gid_t gid
);
52 int in_group ( const char * name
);
54 int merge_gid_lists ( const gid_t
* list1
, size_t size1
, const gid_t
* list2
, size_t size2
, gid_t
** result
);
55 int getgroups_alloc ( gid_t
** gids
);
57 int get_home_dir ( char ** ret
);
58 int get_shell ( char ** ret
);
60 int fully_set_uid_gid ( uid_t uid
, gid_t gid
, const gid_t supplementary_gids
[], size_t n_supplementary_gids
);
61 static inline int reset_uid_gid ( void ) {
62 return fully_set_uid_gid ( 0 , 0 , NULL
, 0 );
65 int take_etc_passwd_lock ( const char * root
);
67 #define UID_INVALID ((uid_t) -1)
68 #define GID_INVALID ((gid_t) -1)
70 #define UID_NOBODY ((uid_t) 65534U)
71 #define GID_NOBODY ((gid_t) 65534U)
73 /* If REMOUNT_IDMAPPING_HOST_ROOT is set for remount_idmap() we'll include a mapping here that maps the host
74 * root user accessing the idmapped mount to the this user ID on the backing fs. This is the last valid UID in
75 * the *signed* 32-bit range. You might wonder why precisely use this specific UID for this purpose? Well, we
76 * definitely cannot use the first 0…65536 UIDs for that, since in most cases that's precisely the file range
77 * we intend to map to some high UID range, and since UID mappings have to be bijective we thus cannot use
78 * them at all. Furthermore the UID range beyond INT32_MAX (i.e. the range above the signed 32-bit range) is
79 * icky, since many APIs cannot use it (example: setfsuid() returns the old UID as signed integer). Following
80 * our usual logic of assigning a 16-bit UID range to each container, so that the upper 16-bit of a 32-bit UID
81 * value indicate kind of a "container ID" and the lower 16-bit map directly to the intended user you can read
82 * this specific UID as the "nobody" user of the container with ID 0x7FFF, which is kinda nice. */
83 #define UID_MAPPED_ROOT ((uid_t) (INT32_MAX-1))
84 #define GID_MAPPED_ROOT ((gid_t) (INT32_MAX-1))
86 #define ETC_PASSWD_LOCK_FILENAME ".pwd.lock"
87 #define ETC_PASSWD_LOCK_PATH "/etc/" ETC_PASSWD_LOCK_FILENAME
89 /* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer
91 #define PTR_TO_UID(p) ((uid_t) (((uintptr_t) (p))-1))
92 #define UID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1))
94 #define PTR_TO_GID(p) ((gid_t) (((uintptr_t) (p))-1))
95 #define GID_TO_PTR(u) ((void*) (((uintptr_t) (u))+1))
97 static inline bool userns_supported ( void ) {
98 return access ( "/proc/self/uid_map" , F_OK
) >= 0 ;
101 typedef enum ValidUserFlags
{
102 VALID_USER_RELAX
= 1 << 0 ,
103 VALID_USER_WARN
= 1 << 1 ,
104 VALID_USER_ALLOW_NUMERIC
= 1 << 2 ,
107 bool valid_user_group_name ( const char * u
, ValidUserFlags flags
);
108 bool valid_gecos ( const char * d
);
109 char * mangle_gecos ( const char * d
);
110 bool valid_home ( const char * p
);
112 static inline bool valid_shell ( const char * p
) {
113 /* We have the same requirements, so just piggy-back on the home check.
115 * Let's ignore /etc/shells because this is only applicable to real and
116 * not system users. It is also incompatible with the idea of empty /etc.
118 return valid_home ( p
);
121 int maybe_setgroups ( size_t size
, const gid_t
* list
);
123 bool synthesize_nobody ( void );
125 int fgetpwent_sane ( FILE * stream
, struct passwd
** pw
);
126 int fgetspent_sane ( FILE * stream
, struct spwd
** sp
);
127 int fgetgrent_sane ( FILE * stream
, struct group
** gr
);
128 int putpwent_sane ( const struct passwd
* pw
, FILE * stream
);
129 int putspent_sane ( const struct spwd
* sp
, FILE * stream
);
130 int putgrent_sane ( const struct group
* gr
, FILE * stream
);
132 int fgetsgent_sane ( FILE * stream
, struct sgrp
** sg
);
133 int putsgent_sane ( const struct sgrp
* sg
, FILE * stream
);
136 bool is_nologin_shell ( const char * shell
);
137 const char * default_root_shell_at ( int rfd
);
138 const char * default_root_shell ( const char * root
);
140 int is_this_me ( const char * username
);
142 const char * get_home_root ( void );
144 static inline bool hashed_password_is_locked_or_invalid ( const char * password
) {
145 return password
&& password
[ 0 ] != '$' ;
148 /* A locked *and* invalid password for "struct spwd"'s .sp_pwdp and "struct passwd"'s .pw_passwd field */
149 #define PASSWORD_LOCKED_AND_INVALID "!*"
151 /* A password indicating "look in shadow file, please!" for "struct passwd"'s .pw_passwd */
152 #define PASSWORD_SEE_SHADOW "x"
154 /* A password indicating "hey, no password required for login" */
155 #define PASSWORD_NONE ""
157 /* Used by sysusers to indicate that the password should be filled in by firstboot.
158 * Also see https://github.com/systemd/systemd/pull/24680#pullrequestreview-1439464325.
160 #define PASSWORD_UNPROVISIONED "!unprovisioned"
162 int getpwuid_malloc ( uid_t uid
, struct passwd
** ret
);
163 int getpwnam_malloc ( const char * name
, struct passwd
** ret
);
165 int getgrnam_malloc ( const char * name
, struct group
** ret
);
166 int getgrgid_malloc ( gid_t gid
, struct group
** ret
);