Acontece que a configuração + i no wrapper não não adiciona o recurso ao CAP_INHERITABLE
definido para o processo do wrapper, portanto, ele não é passado por exec
. Portanto, tive que adicionar manualmente CAP_DAC_OVERRIDE
a CAP_INHERITABLE
antes de chamar execl
:
#include <sys/capability.h>
#include <stdio.h>
#include <unistd.h>
int main(int argc, char **argv[]) {
cap_t caps = cap_get_proc();
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
cap_value_t newcaps[1] = { CAP_DAC_OVERRIDE, };
cap_set_flag(caps, CAP_INHERITABLE, 1, newcaps, CAP_SET);
cap_set_proc(caps);
printf("Capabilities: %s\n", cap_to_text(caps, NULL));
cap_free(caps);
return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}
Além disso, tive que adicionar cap_dac_override
aos recursos de arquivo permitidos definidos em /usr/bin/net
e definir o bit efetivo:
~ $ sudo setcap cap_dac_override=p ./registerdns
~ $ sudo setcap cap_dac_override=ei /usr/bin/net
~ $ ./registerdns
Capabilities = cap_dac_override+p
Capabilities = cap_dac_override+ip
Successfully registered hostname with DNS
Acho que agora entendo completamente o que está acontecendo:
- O wrapper precisa de
CAP_DAC_OVERRIDE
em seu conjunto permitido para poder adicioná-lo ao conjunto herdável. - O conjunto herdável do processo do wrapper é diferente do conjunto herdado do arquivo, portanto, a configuração + i no arquivo é inútil; o wrapper deve incluir explicitamente
CAP_DAC_OVERRIDE
toCAP_INHERITABLE
usandocap_set_flag
/cap_set_proc
. - O arquivo
net
precisa terCAP_DAC_OVERRIDE
em seu conjunto herdável para poder herdar o recurso do wrapper no seuCAP_PERMITTED
set. Ele também precisa que o bit efetivo seja definido para que seja promovido automaticamente paraCAP_EFFECTIVE
.