Передача полномочий через exec

Передача полномочий через exec

Я пытаюсь понять, как возможности Linux передаются процессу, который был exec()'использован другим процессом. Из того, что я читал, для того, чтобы возможность сохранилась после exec, она должна быть в наследуемом наборе. Однако я не уверен, как этот набор заполняется.

Моя цель — иметь возможность запускать программу как обычный пользователь, который обычно требует root. Необходимая ей возможность — cap_dac_overrideчитать личный файл. Я не хочу давать ей никаких других возможностей.

Вот моя обертка:

#include <unistd.h>

int main(int argc, char *argv[]) {
    return execl("/usr/bin/net", "net", "ads", "dns", "register", "-P", NULL);
}

Это работает, когда я устанавливаю разрешение setuid для полученного исполняемого файла:

~ $ sudo chown root: ./registerdns
~ $ sudo chmod u+s ./registerdns
~ $ ./registerdns 
Successfully registered hostname with DNS

Я бы хотел использовать capabilities вместо setuid. Я пробовал устанавливать capabilities cap_dac_overrideв обертке:

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

Я также попробовал установить флаг наследуемости для cap_dac_overrideвозможности netсамого исполняемого файла:

~ $ sudo setcap cap_dac_override=eip ./registerdns
~ $ sudo setcap cap_dac_override=i /usr/bin/net
~ $ ./registerdns 
Failed to open /var/lib/samba/private/secrets.tdb
ERROR: Unable to open secrets database

Мне нужно использовать оболочку, чтобы гарантировать, что эта возможность будет доступна только при использовании именно этого набора аргументов; программа netвыполняет ряд других действий, предоставление пользователям слишком широких прав доступа к ней может быть опасным.

Я, очевидно, не понимаю, как работает наследование. Я не могу понять, как настроить обертку, чтобы передать ее возможности процессу замены, чтобы он мог их использовать. Я прочитал страницу руководства и бесчисленное множество других документов о том, как этодолженработа, и я думал, что делаю то, что там описано.

решение1

Оказывается, установка +i на обертке делаетнетдобавить возможность в CAP_INHERITABLEнабор для процесса-обертки, таким образом, он не передается exec. Поэтому мне пришлось вручную добавить CAP_DAC_OVERRIDEперед CAP_INHERITABLEвызовом 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);
}

Кроме того, мне пришлось добавить cap_dac_overrideк разрешенным возможностям файла набор /usr/bin/netи установить эффективный бит:

~ $ 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

Думаю, теперь я полностью понимаю, что происходит:

  1. Обертке необходим CAP_DAC_OVERRIDEразрешенный набор, чтобы она могла добавить его в свой наследуемый набор.
  2. Наследуемый набор процесса оболочки отличается от наследуемого набора файла, поэтому установка +i для файла бесполезна; оболочка должна явно добавить CAP_DAC_OVERRIDEиспользование CAP_INHERITABLE/ .cap_set_flagcap_set_proc
  3. Файл netдолжен иметь CAP_DAC_OVERRIDEв своем наследуемом наборе, чтобы он мог фактически наследовать возможности от оболочки в свой CAP_PERMITTEDнабор. Также необходимо установить эффективный бит, чтобы он автоматически был повышен до CAP_EFFECTIVE.

решение2

Я думаю, вам нужно и то, и другое:

setcap cap_dac_override+pe ./registerdns
setcap cap_dac_override+i /usr/bin/net

Флаги peon registerdnsговорят, что запуск программы приобретает возможность. Флаг ion netговорит, что разрешено наследовать возможность от вызывающей программы.

Связанный контент