From: Valentine Krasnobaeva Date: Thu, 4 Jul 2024 16:06:01 +0000 (+0200) Subject: MEDIUM: startup: do set_identity() if needed in one place X-Git-Tag: v3.1-dev10~49 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fe04c2ad37d0b34323f7e8afaa39543f173c713b;p=thirdparty%2Fhaproxy.git MEDIUM: startup: do set_identity() if needed in one place 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. --- diff --git a/src/haproxy.c b/src/haproxy.c index 79e417a6f1..296769def0 100644 --- a/src/haproxy.c +++ b/src/haproxy.c @@ -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,