diff -Nurp bind-9.3.2.orig/bin/named/unix/os.c bind-9.3.2/bin/named/unix/os.c --- bind-9.3.2.orig/bin/named/unix/os.c 2005-05-20 03:37:19.000000000 +0200 +++ bind-9.3.2/bin/named/unix/os.c 2006-03-16 18:04:35.000000000 +0100 @@ -172,9 +172,27 @@ linux_setcaps(unsigned int caps) { } } +static unsigned int +linux_getcaps(void) { + struct __user_cap_header_struct caphead; + struct __user_cap_data_struct cap; + char strbuf[ISC_STRERRORSIZE]; + + memset(&caphead, 0, sizeof(caphead)); + caphead.version = _LINUX_CAPABILITY_VERSION; + caphead.pid = 0; + memset(&cap, 0, sizeof(cap)); + if (syscall(SYS_capget, &caphead, &cap) < 0) { + isc__strerror(errno, strbuf, sizeof(strbuf)); + ns_main_earlyfatal("capget failed: %s", strbuf); + } + + return cap.permitted; +} + static void linux_initialprivs(void) { - unsigned int caps; + unsigned int caps, current; /* * We don't need most privileges, so we drop them right away. @@ -183,6 +201,7 @@ linux_initialprivs(void) { */ caps = 0; + current = linux_getcaps(); /* * We need to be able to bind() to privileged ports, notably port 53! @@ -224,12 +243,12 @@ linux_initialprivs(void) { */ caps |= (1 << CAP_SYS_RESOURCE); - linux_setcaps(caps); + linux_setcaps(caps & current); } static void linux_minprivs(void) { - unsigned int caps; + unsigned int caps, current; /* * Drop all privileges except the ability to bind() to privileged @@ -240,6 +259,7 @@ linux_minprivs(void) { */ caps = 0; + current = linux_getcaps(); caps |= (1 << CAP_NET_BIND_SERVICE); /* @@ -251,7 +271,7 @@ linux_minprivs(void) { */ caps |= (1 << CAP_SYS_RESOURCE); - linux_setcaps(caps); + linux_setcaps(caps & current); } #ifdef HAVE_SYS_PRCTL_H