]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: startup: do set_identity() if needed in one place
authorValentine Krasnobaeva <vkrasnobaeva@haproxy.com>
Thu, 4 Jul 2024 16:06:01 +0000 (18:06 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 16 Oct 2024 20:02:39 +0000 (22:02 +0200)
There are two set_identity() calls, both under quite same:

    'if ((global.mode & (MODE_MWORKER|MODE_DAEMON...)...'

The first call serves to change uid/gid and set some needed Linux capabilities
only for process in the foreground mode. The second comes after master-worker
fork and allows to do the same in daemon and in worker modes.

Due to moving the master-worker fork in init() in some previous commit, the
second set_identity() now is no longer under the 'if'. So, it is executed
for all modes, except MODE_MWORKER. Now in MODE_MWORKER process enters in its
wait polling loop just after forking a worker and it terminates almost
immediately, if it exits this loop.

Worker, daemon and process in a foreground mode will perform set_identity() as
before, but now it will be called in a one place at main().

global.last_checks should be verified just after set_identity() call. As it's
stated in comments some configuration options may require full privileges or
some Linux capabilities need to be granted to process. set_identity() via
prepare_caps_for_setuid() may put configured capabilities in process Effective
set and, hence, remove respective flag from global.last_checks.

src/haproxy.c

index 79e417a6f159c1dec70c97ac83abcebd9cb3bbd2..296769def0b9f55eb9a9d523ddfb522f9cfad2b0 100644 (file)
@@ -3513,37 +3513,6 @@ int main(int argc, char **argv)
         * be able to restart the old pids.
         */
 
-       if ((global.mode & (MODE_MWORKER | MODE_DAEMON)) == 0)
-               set_identity(argv[0]);
-
-       /* set_identity() above might have dropped LSTCHK_NETADM or/and
-        * LSTCHK_SYSADM if it changed to a new UID while preserving enough
-        * permissions to honnor LSTCHK_NETADM/LSTCHK_SYSADM.
-        */
-       if ((global.last_checks & (LSTCHK_NETADM|LSTCHK_SYSADM)) && getuid()) {
-               /* If global.uid is present in config, it is already set as euid
-                * and ruid by set_identity() just above, so it's better to
-                * remind the user to fix uncoherent settings.
-                */
-               if (global.uid) {
-                       ha_alert("[%s.main()] Some configuration options require full "
-                                "privileges, so global.uid cannot be changed.\n", argv[0]);
-#if defined(USE_LINUX_CAP)
-                       ha_alert("[%s.main()] Alternately, if your system supports "
-                                "Linux capabilities, you may also consider using "
-                                "'setcap cap_net_raw' or 'setcap cap_net_admin' in the "
-                                "'global' section.\n", argv[0]);
-#endif
-                       protocol_unbind_all();
-                       exit(1);
-               }
-               /* If the user is not root, we'll still let them try the configuration
-                * but we inform them that unexpected behaviour may occur.
-                */
-               ha_warning("[%s.main()] Some options which require full privileges"
-                          " might not work well.\n", argv[0]);
-       }
-
        /* check ulimits */
        limit.rlim_cur = limit.rlim_max = 0;
        getrlimit(RLIMIT_NOFILE, &limit);
@@ -3646,6 +3615,34 @@ int main(int argc, char **argv)
        ha_free(&global.chroot);
        set_identity(argv[0]);
 
+       /* set_identity() above might have dropped LSTCHK_NETADM or/and
+        * LSTCHK_SYSADM if it changed to a new UID while preserving enough
+        * permissions to honnor LSTCHK_NETADM/LSTCHK_SYSADM.
+        */
+       if ((global.last_checks & (LSTCHK_NETADM|LSTCHK_SYSADM)) && getuid()) {
+               /* If global.uid is present in config, it is already set as euid
+                * and ruid by set_identity() just above, so it's better to
+                * remind the user to fix uncoherent settings.
+                */
+               if (global.uid) {
+                       ha_alert("[%s.main()] Some configuration options require full "
+                                "privileges, so global.uid cannot be changed.\n", argv[0]);
+#if defined(USE_LINUX_CAP)
+                       ha_alert("[%s.main()] Alternately, if your system supports "
+                                "Linux capabilities, you may also consider using "
+                                "'setcap cap_net_raw' or 'setcap cap_net_admin' in the "
+                                "'global' section.\n", argv[0]);
+#endif
+                       protocol_unbind_all();
+                       exit(1);
+               }
+               /* If the user is not root, we'll still let them try the configuration
+                * but we inform them that unexpected behaviour may occur.
+                */
+               ha_warning("[%s.main()] Some options which require full privileges"
+                          " might not work well.\n", argv[0]);
+       }
+
        /*
         * This is only done in daemon mode because we might want the
         * logs on stdout in mworker mode. If we're NOT in QUIET mode,