mirror of
https://github.com/isc-projects/bind9.git
synced 2026-05-28 04:34:54 -04:00
[9.20] fix: usr: Delay release of root privileges until after configuring controls
Delay relinquishing root privileges until the control channel has been configured, for the benefit of systems that require root to use privileged port numbers. This mostly affects systems without fine-grained privilege systems (i.e., other than Linux). Closes #4793 Backport of MR !9123 Merge branch 'backport-4793-bind-9-19-24-not-listening-to-rndc-port-953-on-localhost-9.20' into 'bind-9.20' See merge request isc-projects/bind9!9444
This commit is contained in:
commit
0b7eb9d7a9
3 changed files with 52 additions and 14 deletions
|
|
@ -39,10 +39,13 @@ void
|
|||
named_os_inituserinfo(const char *username);
|
||||
|
||||
void
|
||||
named_os_changeuser(void);
|
||||
named_os_changeuser(bool permanent);
|
||||
|
||||
void
|
||||
named_os_restoreuser(void);
|
||||
|
||||
uid_t
|
||||
ns_os_uid(void);
|
||||
named_os_uid(void);
|
||||
|
||||
void
|
||||
named_os_adjustnofile(void);
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@ static struct passwd *runas_pw = NULL;
|
|||
static bool done_setuid = false;
|
||||
static int dfd[2] = { -1, -1 };
|
||||
|
||||
static uid_t saved_uid = (uid_t)-1;
|
||||
static gid_t saved_gid = (gid_t)-1;
|
||||
|
||||
#if HAVE_LIBCAP
|
||||
|
||||
static bool non_root = false;
|
||||
|
|
@ -461,12 +464,33 @@ named_os_inituserinfo(const char *username) {
|
|||
}
|
||||
|
||||
void
|
||||
named_os_changeuser(void) {
|
||||
named_os_restoreuser(void) {
|
||||
if (runas_pw == NULL || done_setuid) {
|
||||
return;
|
||||
}
|
||||
|
||||
REQUIRE(saved_uid != (uid_t)-1);
|
||||
REQUIRE(saved_gid != (gid_t)-1);
|
||||
|
||||
setperms(saved_uid, saved_gid);
|
||||
}
|
||||
|
||||
void
|
||||
named_os_changeuser(bool permanent) {
|
||||
char strbuf[ISC_STRERRORSIZE];
|
||||
if (runas_pw == NULL || done_setuid) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!permanent) {
|
||||
saved_uid = getuid();
|
||||
saved_gid = getgid();
|
||||
|
||||
setperms(runas_pw->pw_uid, runas_pw->pw_gid);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
done_setuid = true;
|
||||
|
||||
if (setgid(runas_pw->pw_gid) == -1) {
|
||||
|
|
@ -495,7 +519,7 @@ named_os_changeuser(void) {
|
|||
}
|
||||
|
||||
uid_t
|
||||
ns_os_uid(void) {
|
||||
named_os_uid(void) {
|
||||
if (runas_pw == NULL) {
|
||||
return (0);
|
||||
}
|
||||
|
|
@ -551,7 +575,7 @@ void
|
|||
named_os_minprivs(void) {
|
||||
#if HAVE_LIBCAP
|
||||
linux_keepcaps();
|
||||
named_os_changeuser();
|
||||
named_os_changeuser(true);
|
||||
linux_minprivs();
|
||||
#endif /* HAVE_LIBCAP */
|
||||
}
|
||||
|
|
@ -678,19 +702,16 @@ named_os_openfile(const char *filename, mode_t mode, bool switch_user) {
|
|||
free(f);
|
||||
|
||||
if (switch_user && runas_pw != NULL) {
|
||||
uid_t olduid = getuid();
|
||||
gid_t oldgid = getgid();
|
||||
|
||||
/*
|
||||
* Set UID/GID to the one we'll be running with
|
||||
* Temporarily set UID/GID to the one we'll be running with
|
||||
* eventually.
|
||||
*/
|
||||
setperms(runas_pw->pw_uid, runas_pw->pw_gid);
|
||||
named_os_changeuser(false);
|
||||
|
||||
fd = safe_open(filename, mode, false);
|
||||
|
||||
/* Restore UID/GID to previous uid/gid */
|
||||
setperms(olduid, oldgid);
|
||||
named_os_restoreuser();
|
||||
|
||||
if (fd == -1) {
|
||||
fd = safe_open(filename, mode, false);
|
||||
|
|
|
|||
|
|
@ -9420,10 +9420,12 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
#endif /* HAVE_LMDB */
|
||||
|
||||
/*
|
||||
* Relinquish root privileges.
|
||||
* Switch to the effective UID for setting up files.
|
||||
* Later, after configuring all the listening ports,
|
||||
* we'll relinquish root privileges permanently.
|
||||
*/
|
||||
if (first_time) {
|
||||
named_os_changeuser();
|
||||
named_os_changeuser(false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -9770,6 +9772,11 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
isc_loopmgr_resume(named_g_loopmgr);
|
||||
exclusive = false;
|
||||
|
||||
/* Take back root privileges temporarily */
|
||||
if (first_time) {
|
||||
named_os_restoreuser();
|
||||
}
|
||||
|
||||
/* Configure the statistics channel(s) */
|
||||
result = named_statschannels_configure(named_g_server, config,
|
||||
named_g_aclconfctx);
|
||||
|
|
@ -9796,6 +9803,13 @@ load_configuration(const char *filename, named_server_t *server,
|
|||
|
||||
(void)ns_interfacemgr_scan(server->interfacemgr, true, true);
|
||||
|
||||
/*
|
||||
* Permanently drop root privileges now.
|
||||
*/
|
||||
if (first_time) {
|
||||
named_os_changeuser(true);
|
||||
}
|
||||
|
||||
/*
|
||||
* These cleans up either the old production view list
|
||||
* or our temporary list depending on whether they
|
||||
|
|
@ -13315,7 +13329,7 @@ nzd_env_close(dns_view_t *view) {
|
|||
/*
|
||||
* Database files must be owned by the eventual user, not by root.
|
||||
*/
|
||||
ret = chown(dbpath_copy, ns_os_uid(), -1);
|
||||
ret = chown(dbpath_copy, named_os_uid(), -1);
|
||||
UNUSED(ret);
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in a new issue