
Estou tentando criar um serviço que inicia um processo.
Quero que a inicialização do processo seja capaz de executar alguns comandos como root e depois executar o restante do processo como um usuário não humano menos privilegiado.
Por exemplo: eu sei que o apache
usuário requer alguns privilégios de root para fazer alguma configuração do servidor web com portas e iniciar vários processos do servidor, mas ele não é executado como root o tempo todo. Não consigo encontrar nenhum código que faça algo semelhante a isso e gostaria de saber se há outros exemplos que eu possa usar.
Essencialmente, minha pergunta é:como concedo privilégios de root temporários a um usuário não root para executar processos específicos apenas de root?
Ou estou pensando nisso da maneira errada:Não concedo privilégios de root ao usuário e, em vez disso, faço com que o usuário root execute os processos exigidos pelo root?
Responder1
Existem algumas opções dependendo exatamente do que você está fazendo como usuário root. No entanto, para serviços automatizados ("como o Apache"), você geralmente inicia como root e passa para um usuário restrito.
A configuração do estilo Debian (incluindo Ubuntu e Mint) teria então um arquivo em /etc/default/meu-nome-serviçodefinir para qual usuário é alternado. Outras distribuições Linux têm um local diferente para armazenar a configuração, mas a técnica é a mesma.
Se você mesmo estiver escrevendo o programa de serviço, você usariasetuid(). Depois de chamar setuid, o processo não pode voltar a ter privilégios de root. Você vai precisarprocure o usuário pelo nomee tambémdefinir os grupos para o usuário.
simplificando algum código que escrevi há muito tempo:
int lockToUser(const char * user) {
# Look up the username in /etc/passwd
struct passwd * pwd = getpwnam(user);
if (!pwd) {
# Failed... Could not find user, see errno
return 0;
}
# setuid sets the user
# setgid sets the main group similar to the group in /etc/passwd
# Sets the other groups which will grant additional permissions.
# similar to the groups in /etc/groups
if (initgroups(user, pwd->pw_gid) || setgid(pwd->pw_gid) || setuid(pwd->pw_uid)) {
# Failed... Could not lock down to user, see errno
return 0;
}
return 1;
}