mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 00:14:32 +09:00
Define uid range for greeter
In multi-seat scenarios, a display manager might need to start multiple greeter sessions. But systemd allows at most one graphical session per user. So, display managers now have a range of UIDs to dynamically allocate users for their greeter sessions.
This commit is contained in:
committed by
Zbigniew Jędrzejewski-Szmek
parent
2dcf0ee0ef
commit
554130faf3
@@ -100,7 +100,18 @@ possible.
|
||||
attempted to make UID assignments stable, by deriving them from a hash of
|
||||
the user name.
|
||||
|
||||
2. 61184…65519 → UIDs for dynamic users are allocated from this range (see the
|
||||
2. 60578…60705 → UIDs for dynamic greeter users are allocated from this range.
|
||||
In multiseat scenarios, multiple greeter sessions may be running at once.
|
||||
However, systemd only permits one graphical session at a time per user
|
||||
([documentation](/DESKTOP_ENVIRONMENTS)). Thus, multiseat-enabled display
|
||||
managers (like GDM) must run each greeter session under a unique user. To
|
||||
make use of this UID range, the display manager should implement the
|
||||
[userdb Varlink API](/USER_GROUP_API) and dynamically allocate users whenever
|
||||
they are needed by the display manager. Display managers may also use these
|
||||
UIDs for other purposes where dynamic users may be helpful (i.e. guest user
|
||||
sessions or kiosk sessions)
|
||||
|
||||
3. 61184…65519 → UIDs for dynamic users are allocated from this range (see the
|
||||
`DynamicUser=` documentation in
|
||||
[`systemd.exec(5)`](https://www.freedesktop.org/software/systemd/man/systemd.exec.html)).
|
||||
This range has been chosen so that it is below the 16-bit boundary
|
||||
@@ -114,7 +125,7 @@ possible.
|
||||
for all currently allocated dynamic users from this range.
|
||||
Thus, NSS-based user record resolving works correctly without those users being in `/etc/passwd`.
|
||||
|
||||
3. 524288…1879048191 → UID range for `systemd-nspawn`'s automatic allocation of
|
||||
4. 524288…1879048191 → UID range for `systemd-nspawn`'s automatic allocation of
|
||||
per-container UID ranges.
|
||||
When the `--private-users=pick` switch is used (or `-U`) then it will automatically find a so far unused 16-bit subrange of this
|
||||
range and assign it to the container.
|
||||
@@ -129,7 +140,7 @@ possible.
|
||||
erroneously considers UIDs signed integers, and hence can't deal with values above 2^31.
|
||||
The `systemd-machined.service` service will synthesize user database records for all UIDs assigned to a running container from this range.
|
||||
|
||||
4. 2147352576…2147418111 → UID range used for foreign OS images. For various
|
||||
5. 2147352576…2147418111 → UID range used for foreign OS images. For various
|
||||
usecases (primarily: containers) it makes sense to make foreign OS images
|
||||
available locally whose UID/GID ownerships do not make sense in the local
|
||||
context but only within the OS image itself. This 64K UID range can be used
|
||||
@@ -157,6 +168,10 @@ The most important boundaries of the local system may be queried with
|
||||
```sh
|
||||
$ pkg-config --variable=system_uid_max systemd
|
||||
999
|
||||
$ pkg-config --variable=greeter_uid_min systemd
|
||||
60578
|
||||
$ pkg-config --variable=greeter_uid_max systemd
|
||||
60705
|
||||
$ pkg-config --variable=dynamic_uid_min systemd
|
||||
61184
|
||||
$ pkg-config --variable=dynamic_uid_max systemd
|
||||
@@ -263,7 +278,8 @@ i.e. somewhere below `/var/` or similar.
|
||||
| 1000…60000 | 0x000003E8…0x00001770 | 59000 | Regular users | Distributions | `/etc/passwd` + LDAP/NIS/… |
|
||||
| 60001…60513 | 0x0000EA61…0x0000EC61 | 513 | Human users (homed) | `systemd` | `nss-systemd` |
|
||||
| 60514…60577 | 0x0000EC62…0x0000ECA1 | 64 | Host users mapped into containers | `systemd` | `systemd-nspawn` |
|
||||
| 60578…61183 | 0x0000ECA2…0x0000EEFF | 606 | *unused* | | |
|
||||
| 60578…60705 | 0x0000ECA2…0x0000ED21 | 128 | Dynamic greeter users | `systemd` | `nss-systemd` |
|
||||
| 60706…61183 | 0x0000ED22…0x0000EEFF | 478 | *unused* | | |
|
||||
| 61184…65519 | 0x0000EF00…0x0000FFEF | 4336 | Dynamic service users | `systemd` | `nss-systemd` |
|
||||
| 65520…65533 | 0x0000FFF0…0x0000FFFD | 13 | *unused* | | |
|
||||
| 65534 | 0x0000FFFE | 1 | `nobody` user | Linux | `/etc/passwd` + `nss-systemd` |
|
||||
@@ -279,7 +295,7 @@ i.e. somewhere below `/var/` or similar.
|
||||
Note that "Unused" in the table above doesn't mean that these ranges are really unused.
|
||||
It just means that these ranges have no well-established
|
||||
pre-defined purposes between Linux, generic low-level distributions and `systemd`.
|
||||
There might very well be other packages that allocate from theseranges.
|
||||
There might very well be other packages that allocate from these ranges.
|
||||
|
||||
Note that the range 2147483648…4294967294 (i.e. 2^31…2^32-2) should be handled with care.
|
||||
Various programs (including kernel file systems — see `devpts` — or
|
||||
|
||||
@@ -810,6 +810,11 @@ if conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')
|
||||
error('Invalid gid allocation range')
|
||||
endif
|
||||
|
||||
greeter_uid_min = get_option('greeter-uid-min')
|
||||
greeter_uid_max = get_option('greeter-uid-max')
|
||||
conf.set('GREETER_UID_MIN', greeter_uid_min)
|
||||
conf.set('GREETER_UID_MAX', greeter_uid_max)
|
||||
|
||||
dynamic_uid_min = get_option('dynamic-uid-min')
|
||||
dynamic_uid_max = get_option('dynamic-uid-max')
|
||||
conf.set('DYNAMIC_UID_MIN', dynamic_uid_min)
|
||||
@@ -2951,6 +2956,7 @@ summary({
|
||||
conf.get('SYSTEM_ALLOC_UID_MIN')),
|
||||
'system GIDs' : '<=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
|
||||
conf.get('SYSTEM_ALLOC_GID_MIN')),
|
||||
'greeter UIDs' : '@0@…@1@'.format(greeter_uid_min, greeter_uid_max),
|
||||
'dynamic UIDs' : '@0@…@1@'.format(dynamic_uid_min, dynamic_uid_max),
|
||||
'container UID bases' : '@0@…@1@'.format(container_uid_base_min, container_uid_base_max),
|
||||
'foreign UID base' : '@0@'.format(foreign_uid_base),
|
||||
|
||||
@@ -256,6 +256,10 @@ option('system-uid-max', type : 'integer', value : 0,
|
||||
description : 'maximum system UID')
|
||||
option('system-gid-max', type : 'integer', value : 0,
|
||||
description : 'maximum system GID')
|
||||
option('greeter-uid-min', type : 'integer', value : 0x0000ECA2,
|
||||
description : 'minimum greeter UID')
|
||||
option('greeter-uid-max', type : 'integer', value : 0x0000ED21,
|
||||
description : 'maximum greeter UID')
|
||||
option('dynamic-uid-min', type : 'integer', value : 0x0000EF00,
|
||||
description : 'minimum dynamic UID')
|
||||
option('dynamic-uid-max', type : 'integer', value : 0x0000FFEF,
|
||||
|
||||
@@ -129,5 +129,5 @@ bool uid_for_system_journal(uid_t uid) {
|
||||
|
||||
/* Returns true if the specified UID shall get its data stored in the system journal. */
|
||||
|
||||
return uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY || uid_is_container(uid) || uid_is_foreign(uid);
|
||||
return uid_is_system(uid) || uid_is_dynamic(uid) || uid_is_greeter(uid) || uid == UID_NOBODY || uid_is_container(uid) || uid_is_foreign(uid);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,10 @@ assert_cc((FOREIGN_UID_BASE & 0xFFFFU) == 0);
|
||||
bool uid_is_system(uid_t uid);
|
||||
bool gid_is_system(gid_t gid);
|
||||
|
||||
static inline bool uid_is_greeter(uid_t uid) {
|
||||
return GREETER_UID_MIN <= uid && uid <= GREETER_UID_MAX;
|
||||
}
|
||||
|
||||
static inline bool uid_is_dynamic(uid_t uid) {
|
||||
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
|
||||
}
|
||||
|
||||
@@ -92,6 +92,9 @@ systemuidmax=${system_uid_max}
|
||||
system_gid_max={{SYSTEM_GID_MAX}}
|
||||
systemgidmax=${system_gid_max}
|
||||
|
||||
greeter_uid_min={{GREETER_UID_MIN}}
|
||||
greeter_uid_max={{GREETER_UID_MAX}}
|
||||
|
||||
dynamic_uid_min={{DYNAMIC_UID_MIN}}
|
||||
dynamicuidmin=${dynamic_uid_min}
|
||||
dynamic_uid_max={{DYNAMIC_UID_MAX}}
|
||||
|
||||
@@ -260,7 +260,7 @@ static int fix_acl(int fd, uid_t uid, bool allow_user) {
|
||||
if (!allow_user)
|
||||
return 0;
|
||||
|
||||
if (uid_is_system(uid) || uid_is_dynamic(uid) || uid == UID_NOBODY)
|
||||
if (uid_is_system(uid) || uid_is_dynamic(uid) || uid_is_greeter(uid) || uid == UID_NOBODY)
|
||||
return 0;
|
||||
|
||||
/* Make sure normal users can read (but not write or delete) their own coredumps */
|
||||
|
||||
@@ -1293,7 +1293,7 @@ static const char *pick_color_for_uid_gid(uid_t uid) {
|
||||
return ansi_highlight_yellow4(); /* files should never be owned by 'nobody' (but might happen due to userns mapping) */
|
||||
if (uid_is_system(uid))
|
||||
return ansi_normal(); /* files in disk images are typically owned by root and other system users, no issue there */
|
||||
if (uid_is_dynamic(uid))
|
||||
if (uid_is_dynamic(uid) || uid_is_greeter(uid))
|
||||
return ansi_highlight_red(); /* files should never be owned persistently by dynamic users, and there are just no excuses */
|
||||
if (uid_is_container(uid) || uid_is_foreign(uid))
|
||||
return ansi_highlight_cyan();
|
||||
|
||||
@@ -3719,6 +3719,8 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
if (uid_is_system(uid))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "UID " UID_FMT " is in system range, refusing.", uid);
|
||||
if (uid_is_greeter(uid))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "UID " UID_FMT " is in greeter range, refusing.", uid);
|
||||
if (uid_is_dynamic(uid))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "UID " UID_FMT " is in dynamic range, refusing.", uid);
|
||||
if (uid == UID_NOBODY)
|
||||
|
||||
@@ -86,7 +86,8 @@ static int suitable_home_record(UserRecord *hr) {
|
||||
|
||||
/* Insist we are outside of the dynamic and system range */
|
||||
if (uid_is_system(hr->uid) || gid_is_system(user_record_gid(hr)) ||
|
||||
uid_is_dynamic(hr->uid) || gid_is_dynamic(user_record_gid(hr)))
|
||||
uid_is_dynamic(hr->uid) || gid_is_dynamic(user_record_gid(hr)) ||
|
||||
uid_is_greeter(hr->uid))
|
||||
return -EADDRNOTAVAIL;
|
||||
|
||||
/* Insist that GID and UID match */
|
||||
|
||||
@@ -2070,7 +2070,7 @@ UserDisposition user_record_disposition(UserRecord *h) {
|
||||
if (uid_is_system(h->uid))
|
||||
return USER_SYSTEM;
|
||||
|
||||
if (uid_is_dynamic(h->uid))
|
||||
if (uid_is_dynamic(h->uid) || uid_is_greeter(h->uid))
|
||||
return USER_DYNAMIC;
|
||||
|
||||
if (uid_is_container(h->uid))
|
||||
|
||||
Reference in New Issue
Block a user