diff -Naurp bind-9.2.3.orig/bin/named/unix/os.c bind-9.2.3/bin/named/unix/os.c --- bind-9.2.3.orig/bin/named/unix/os.c 2004-11-30 11:04:45.000000000 +0100 +++ bind-9.2.3/bin/named/unix/os.c 2004-12-05 15:24:08.000000000 +0100 @@ -155,9 +155,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. @@ -166,6 +184,7 @@ linux_initialprivs(void) { */ caps = 0; + current = linux_getcaps(); /* * We need to be able to bind() to privileged ports, notably port 53! @@ -205,14 +224,15 @@ linux_initialprivs(void) { * of files, the stack size, data size, and core dump size to * support named.conf options, this is now being added to test. */ - caps |= (1 << CAP_SYS_RESOURCE); + if ((current & (1 << CAP_SYS_RESOURCE)) == (1 << CAP_SYS_RESOURCE)) + caps |= (1 << CAP_SYS_RESOURCE); linux_setcaps(caps); } static void linux_minprivs(void) { - unsigned int caps; + unsigned int caps, current; /* * Drop all privileges except the ability to bind() to privileged @@ -223,6 +243,7 @@ linux_minprivs(void) { */ caps = 0; + current = linux_getcaps(); caps |= (1 << CAP_NET_BIND_SERVICE); /* @@ -232,7 +253,8 @@ linux_minprivs(void) { * of files, the stack size, data size, and core dump size to * support named.conf options, this is now being added to test. */ - caps |= (1 << CAP_SYS_RESOURCE); + if ((current & (1 << CAP_SYS_RESOURCE)) == (1 << CAP_SYS_RESOURCE)) + caps |= (1 << CAP_SYS_RESOURCE); linux_setcaps(caps); }