Tornando um programa sempre executado como root no OS X

3

Estou tentando fazer um programa em C ser executado sempre como root, não importa quem esteja chamando. Basicamente, quero que invoque "mkdir / test" como exemplo. Então eu criei o programa em C da seguinte forma:

#include <stdio.h>

int main()
{
system("mkdir /test");
printf("bye...\n");
return 0;
}

Agora, acabei de compilá-lo:     gcc test.c -o teste

E agora tentei definir as permissões:

chmod +s test

No entanto, ao executá-lo como um usuário normal, recebo um erro de permissão negada. Então, ele executa o arquivo, mas não com as permissões do root. Eu também tentei definir as permissões como:

chmod a+s test
chmod o+s test

Mas eu sempre tenho o mesmo problema.

Alguém pode me ajudar com isso? A propósito, o arquivo test.c está sendo criado pelo root e também está sendo compilado como root.

bash-3.2# ls -al | grep test 
-rwxr-xr-x   1 root   staff       8796  5 Ago 19:07 test
bash-3.2# chmod +s test
bash-3.2# ls -al | grep test 
-rwsr-sr-x   1 root   staff       8796  5 Ago 19:07 test
bash-3.2# whoami
root
bash-3.2#

Obrigado antecipadamente! Cheerz!

    
por yaroze 05.08.2012 / 20:05

2 respostas

6

Há duas coisas para saber aqui:

  • O bit adesivo , que pode ser usado em arquivos e diretórios, mas não faz o que você quer. De sticky(8) : bit pegajoso não tem efeito em arquivos executáveis .

  • A sinalização setuid , que permite que um programa seja executado com as permissões de seus proprietários. O que parece ser uma restrição no OS X, e aparentemente não está documentado, é que o bit setuid em um executável tem um efeito somente se o executável estiver em um diretório pertencente à raiz (e não aberto para gravação por outros), etc, até o diretório raiz. Caso contrário, ele será ignorado por razões de segurança.

De qualquer forma, você pode modificar o arquivo sudoers de tal forma que não exija uma senha para um comando. Lembre-se de que você tem para usar visudo para editá-lo. Se você conseguir obter a sintaxe errada ao editar o arquivo, você não poderá mais executar sudo .

sudo visudo

Em seguida, pressione I e, na parte inferior, insira:

username    ALL= NOPASSWD: /path/to/command

Aqui, obviamente, você precisa alterar o username para o usuário que deve executar o comando sem precisar digitar uma senha. Além disso, mude o caminho para o seu executável. Observe que, neste momento, o executável pode ser de propriedade de root e ter permissões de execução apenas para root também.

Pressione Esc , depois escreva :wq , depois Digite .

Agora, o usuário username pode executar o comando com sudo /path/to/command e não precisa digitar uma senha para fazer isso.

    
por 05.08.2012 / 20:22
0

Estou trabalhando no Linux, mas como o OSX é apenas BSD, presumo que segue as mesmas regras (gerais) que qualquer outro Unix.

Dentro do seu programa, você precisa chamar setuid (UID), que retorna 0 em sucesso, para executá-lo como esse UID e você deseja executar como root. O UID da raiz é provavelmente 0, mas se você for especialmente paranoico, use getpwnam (const char * szUserName) para obter o UID.

Então, algo assim:

#include <stdio.h> // needed for printf

#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>

void change_to_user (const char *szUserName)
{
  struct passwd *pw;

  pw = getpwnam(szUserName);
  if (pw != NULL)
  {
    uid_t uid = pw->pw_uid; // we now have the UID of the username

    printf ("UID of user %s is %d\n", szUserName, (int)uid);
    if (setuid (uid) != 0)
    {
      perror ("setuid");
    }
    else
    {
      // this will fail if you try to change to root without the SUID
      // bit set.  This executive needs to be owned by root (probably
      // group owned by root as well), and set the SUID bit with:
      //   suid a+s {executable}
      printf ("UID is now %d\n", (int)uid);
    }
  }
  else
  {
    perror ("getpwnam");
  }
}


int main (int argc, char **argv)
{
  int iIter;

  if (argc == 1)
  {
    printf ("Give me a user name\n");
    return 1;
  }

  for (iIter = 1 ; iIter < argc ; iIter++)
  {
    change_to_user (argv[iIter]);
  }
  return 0;
}

Você pode definir como QUALQUER nome de usuário, então talvez você esteja executando um script cgi e deseja executar como seu nome de usuário em sua própria conta, em vez de "www-data" ou qualquer outra coisa - você pode usá-lo lá. Eu faço isso, e é por isso que posso responder sua pergunta em detalhes.

    
por 23.04.2018 / 20:53