]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Also parse the minimum uid/gid values
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Fri, 25 Sep 2020 14:50:45 +0000 (16:50 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 1 Oct 2020 15:52:41 +0000 (17:52 +0200)
We don't (and shouldn't I think) look at them when determining the type of the
user, but they should be used during user/group allocation. (For example, an
admin may specify SYS_UID_MIN==200 to allow statically numbered users that are
shared with other systems in the range 1–199.)

meson.build
meson_options.txt
src/core/systemd.pc.in
src/shared/user-record.c
src/shared/user-record.h
src/test/test-user-record.c

index 8083cf655bceec7de6816b5e5f81684dfdbcb20d..0a065fa3e54c11b788184f3cdc44c2b8fa5e699d 100644 (file)
@@ -694,35 +694,31 @@ if time_epoch == -1
 endif
 conf.set('TIME_EPOCH', time_epoch)
 
-system_uid_max = get_option('system-uid-max')
-if system_uid_max == -1
-        system_uid_max = run_command(
-                awk,
-                '/^\s*SYS_UID_MAX\s+/ { uid=$2 } END { print uid }',
-                '/etc/login.defs').stdout().strip()
-        if system_uid_max == ''
-                system_uid_max = 999
-        else
-                system_uid_max = system_uid_max.to_int()
+foreach tuple : [['system-alloc-uid-min', 'SYS_UID_MIN', 1],  # Also see login.defs(5).
+                 ['system-uid-max',       'SYS_UID_MAX', 999],
+                 ['system-alloc-gid-min', 'SYS_GID_MIN', 1],
+                 ['system-gid-max',       'SYS_GID_MAX', 999]]
+        v = get_option(tuple[0])
+        if v == -1
+                v = run_command(
+                        awk,
+                        '/^\s*@0@\s+/ { uid=$2 } END { print uid }'.format(tuple[1]),
+                        '/etc/login.defs').stdout().strip()
+                if v == ''
+                        v = tuple[2]
+                else
+                        v = v.to_int()
+                endif
         endif
+        conf.set(tuple[0].underscorify().to_upper(), v)
+        substs.set(tuple[0].underscorify().to_upper(), v)
+endforeach
+if conf.get('SYSTEM_ALLOC_UID_MIN') >= conf.get('SYSTEM_UID_MAX')
+        error('Invalid uid allocation range')
 endif
-conf.set('SYSTEM_UID_MAX', system_uid_max)
-substs.set('systemuidmax', system_uid_max)
-
-system_gid_max = get_option('system-gid-max')
-if system_gid_max == -1
-        system_gid_max = run_command(
-                awk,
-                '/^\s*SYS_GID_MAX\s+/ { gid=$2 } END { print gid }',
-                '/etc/login.defs').stdout().strip()
-        if system_gid_max == ''
-                system_gid_max = 999
-        else
-                system_gid_max = system_gid_max.to_int()
-        endif
+if conf.get('SYSTEM_ALLOC_GID_MIN') >= conf.get('SYSTEM_GID_MAX')
+        error('Invalid gid allocation range')
 endif
-conf.set('SYSTEM_GID_MAX', system_gid_max)
-substs.set('systemgidmax', system_gid_max)
 
 dynamic_uid_min = get_option('dynamic-uid-min')
 dynamic_uid_max = get_option('dynamic-uid-max')
@@ -3539,12 +3535,12 @@ status = [
                                                               get_option('debug-tty')),
         'TTY GID:                           @0@'.format(tty_gid),
         'users GID:                         @0@'.format(substs.get('USERS_GID')),
-        'maximum system UID:                @0@'.format(system_uid_max),
-        'maximum system GID:                @0@'.format(system_gid_max),
-        'minimum dynamic UID:               @0@'.format(dynamic_uid_min),
-        'maximum dynamic UID:               @0@'.format(dynamic_uid_max),
-        'minimum container UID base:        @0@'.format(container_uid_base_min),
-        'maximum container UID base:        @0@'.format(container_uid_base_max),
+        'system UIDs:                       <=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_UID_MAX'),
+                                                                        conf.get('SYSTEM_ALLOC_UID_MIN')),
+        'system GIDs:                       <=@0@ (alloc >=@1@)'.format(conf.get('SYSTEM_GID_MAX'),
+                                                                        conf.get('SYSTEM_ALLOC_GID_MIN')),
+        '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),
         '/dev/kvm access mode:              @0@'.format(get_option('dev-kvm-mode')),
         'render group access mode:          @0@'.format(get_option('group-render-mode')),
         'certificate root directory:        @0@'.format(get_option('certificate-root')),
index a33b6e27ae1372bf9012b66d25496c0e7be165ac..d5ce647ae6eb3d7a63a89093c36fc92cb3cc30e3 100644 (file)
@@ -194,6 +194,10 @@ option('status-unit-format-default', type : 'combo',
        description : 'use unit name or description in messages by default')
 option('time-epoch', type : 'integer', value : '-1',
        description : 'time epoch for time clients')
+option('system-alloc-uid-min', type : 'integer', value : '-1',
+       description : 'minimum system UID used when allocating')
+option('system-alloc-gid-min', type : 'integer', value : '-1',
+       description : 'minimum system GID used when allocating')
 option('system-uid-max', type : 'integer', value : '-1',
        description : 'maximum system UID')
 option('system-gid-max', type : 'integer', value : '-1',
index 3af9f99830402c336cdd9dc397d194e0db9b1f02..c0554649dea2598706bab2ba51b4838ea7affe88 100644 (file)
@@ -80,9 +80,9 @@ modulesloaddir=${modules_load_dir}
 catalog_dir=/usr/lib/systemd/catalog
 catalogdir=${catalog_dir}
 
-system_uid_max=@systemuidmax@
+system_uid_max=@SYSTEM_UID_MAX@
 systemuidmax=${system_uid_max}
-system_gid_max=@systemgidmax@
+system_gid_max=@SYSTEM_GID_MAX@
 systemgidmax=${system_gid_max}
 
 dynamic_uid_min=@dynamicuidmin@
index f60db5da00f8aadf43faf0e80cb555a148a55cca..3ba78d455f77f71275283b3c13283f3a099503c6 100644 (file)
@@ -41,7 +41,9 @@ static int parse_alloc_uid(const char *path, const char *name, const char *t, ui
 static int read_login_defs(UGIDAllocationRange *ret_defs, const char *path) {
         _cleanup_fclose_ FILE *f = NULL;
         UGIDAllocationRange defs = {
+                .system_alloc_uid_min = SYSTEM_ALLOC_UID_MIN,
                 .system_uid_max = SYSTEM_UID_MAX,
+                .system_alloc_gid_min = SYSTEM_ALLOC_GID_MIN,
                 .system_gid_max = SYSTEM_GID_MAX,
         };
         int r;
@@ -65,13 +67,28 @@ static int read_login_defs(UGIDAllocationRange *ret_defs, const char *path) {
                 if (r == 0)
                         break;
 
-                if ((t = first_word(line, "SYS_UID_MAX")))
+                if ((t = first_word(line, "SYS_UID_MIN")))
+                        (void) parse_alloc_uid(path, "SYS_UID_MIN", t, &defs.system_alloc_uid_min);
+                else if ((t = first_word(line, "SYS_UID_MAX")))
                         (void) parse_alloc_uid(path, "SYS_UID_MAX", t, &defs.system_uid_max);
+                else if ((t = first_word(line, "SYS_GID_MIN")))
+                        (void) parse_alloc_uid(path, "SYS_GID_MIN", t, &defs.system_alloc_gid_min);
                 else if ((t = first_word(line, "SYS_GID_MAX")))
                         (void) parse_alloc_uid(path, "SYS_GID_MAX", t, &defs.system_gid_max);
         }
 
  assign:
+        if (defs.system_alloc_uid_min > defs.system_uid_max) {
+                log_debug("%s: SYS_UID_MIN > SYS_UID_MAX, resetting.", path);
+                defs.system_alloc_uid_min = MIN(defs.system_uid_max - 1, (uid_t) SYSTEM_ALLOC_UID_MIN);
+                /* Look at sys_uid_max to make sure sys_uid_min..sys_uid_max remains a valid range. */
+        }
+        if (defs.system_alloc_gid_min > defs.system_gid_max) {
+                log_debug("%s: SYS_GID_MIN > SYS_GID_MAX, resetting.", path);
+                defs.system_alloc_gid_min = MIN(defs.system_gid_max - 1, (gid_t) SYSTEM_ALLOC_GID_MIN);
+                /* Look at sys_gid_max to make sure sys_gid_min..sys_gid_max remains a valid range. */
+        }
+
         *ret_defs = defs;
         return 0;
 }
@@ -83,7 +100,9 @@ const UGIDAllocationRange *acquire_ugid_allocation_range(void) {
 #else
         static const UGIDAllocationRange defs = {
 #endif
+                .system_alloc_uid_min = SYSTEM_ALLOC_UID_MIN,
                 .system_uid_max = SYSTEM_UID_MAX,
+                .system_alloc_gid_min = SYSTEM_ALLOC_GID_MIN,
                 .system_gid_max = SYSTEM_GID_MAX,
         };
 
index 52348227a5596c38a53accdcae900e3b2faaa005..1f87eff6d5ba06d385f6a2a1624bd79a51c143bd 100644 (file)
@@ -37,7 +37,9 @@ static inline bool gid_is_container(gid_t gid) {
 }
 
 typedef struct UGIDAllocationRange {
+        uid_t system_alloc_uid_min;
         uid_t system_uid_max;
+        gid_t system_alloc_gid_min;
         gid_t system_gid_max;
 } UGIDAllocationRange;
 
index e54e384b09057a878b2b020583aee6cffddeb902..fcab61d6943e7eb84ca7b0b9149f9e8732002476 100644 (file)
@@ -13,7 +13,9 @@ static void test_acquire_ugid_allocation_range(void) {
         const UGIDAllocationRange *defs;
         assert_se(defs = acquire_ugid_allocation_range());
 
+        log_info("system_alloc_uid_min="UID_FMT, defs->system_alloc_uid_min);
         log_info("system_uid_max="UID_FMT, defs->system_uid_max);
+        log_info("system_alloc_gid_min="GID_FMT, defs->system_alloc_gid_min);
         log_info("system_gid_max="GID_FMT, defs->system_gid_max);
 }