next up previous
Next: Interesse do que foi Up: Identificadores dos usuários Previous: Identificadores dos usuários

Obtenção e modificação dos identificadores do usuário

Os identificadores (ou IDs) do usuário real e efetivo são obtidos com a ajuda das chamadas de sistema getuid() e geteuid().

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

   uid_t getuid(void)  /* determina o ID do usuário real */
   uid_t geteuid(void) /* determina o ID do usuário efetivo */

Valor de retorno: identificador real ou efetivo. Não existe erro possível neste caso.

Estes identificadores podem ser modificados pela chamada de sistema setuid().

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

   int setuid(uid_t uid)    /* muda o ID do usuário */
   uid_t uid                /* novo valor do ID */

Valor de retorno: -1 em caso de erro.

Além disso, a utilização das primitivas implicam no salvamento (backup) do identificador precedente. A gestão de setuid() é definida pelas três regras:

  1. Se essa chamada de sistema é empregada pelo super-usuário, ele posicionará o ID do usuário efetivo, assim que o ID do usuário real para o valor definido como argumento. Ele permitirá assim que o super-usuário de se tornar não importa qual usuário.

  2. Se o ID do usuário real é igual ao valor passado como argumento, então o ID do usuário efetivo terá esse valor. Isto permite ao processo de encontrar as permissões do usuário que o executa, após a aplicação da terceira regra;

  3. Se o usuário salvo é igual ao valor passado como argumento, o ID do usuário efetivo receberá este valor. Isto permite a um processo de se executar temporariamente com as permissões de um outro usuário. O programa pode encontrar as permissões originais através da aplicação da segunda regra.

O exemplo a seguir tenta esclarecer as dúvidas relativas ao assunto:

O código foi escrito e compilado sobre o login saibel, com os IDs real e ID efetivo valendo 1198.

O programa é lançado sucessivamente da conta saibel, e após da conta usertest (ID real e ID efetivo valendo).

                 /* arquivo test_uid.c */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h> /* primitiva system */
#include <unistd.h>
#include <sys/types.h>

int main()
{       
        system("echo Meu login e: $LOGNAME");
        printf("Meu user id real e: %d\n",getuid()) ;
        printf("Meu user id efetivo e: %d\n",geteuid()) ;
        if (setuid(4010) == -1) {
               perror("Error setuid()") ;
               exit(-1) ;
        }
        printf("Meu user id real : %d\n",getuid()) ;
        printf("Meu user id efetivo: %d\n",geteuid()) ;
        
        if (setuid(1198) == -1) {
               perror("Error setuid()") ;
               exit(-1) ;
        }
        printf("Meu user id real : %d\n",getuid()) ;
        printf("Meu user id efetivo : %d\n",geteuid()) ;
        exit(0);
}

Resultado da execução:

euler:~/> ls -l test_uid
-rwxr-xr-x   1 saibel   profs       12633 Sep 26 20:47 test_uid*
euler:~/> test_uid
Meu login e: saibel
Meu user id real e: 1198
Meu user id efetivo e: 1198
Error setuid(): Operation not permitted

O primeiro setuid() é interrompido, dado que nenhuma das regras da aplicação foi respeitada. Se por outro lado o programa é lançado a partir do login usertest, não proprietário do arquivo a execução será:

lyapunov:~/> /home/saibel/test_uid
Meu login e: usertest
Meu user id real e: 1275
Meu user id efetivo e: 1275
Meu user id real : 1275
Meu user id efetivo: 1275
Error setuid():  Operation not permitted

O primeiro setuid() é executado com sucesso: o ID do usuário real 1275 é igual ao valor passado como argumento. Para poder acessar o segundo setuid(), o proprietário do arquivo, saibel, deve posicionar o bit s em 1 para que usertest seja durante o tempo de execução proprietário do arquivo.

euler:~/> chmod u+s test_uid
euler:~/> ls -l test_uid
-rwsrwxr-x   1 saibel   profs       12633 Sep 26 20:47 test_uid*

lyapunov:~/> /home/saibel/test_uid
Meu login e: usertest
Meu user id real e: 1275
Meu user id efetivo e: 1198
Meu user id real : 1275
Meu user id efetivo: 1275
Meu user id real : 1275
Meu user id efetivo: 1198

Antes do lançamento do programa, os IDes real e efetivo são iguais (1275). Em seguida, o ID efetivo torna-se 1198 quando o programa está sendo executado, em razão da presença do bit s. Na chamada de setuid(1275), o ID real é igual ao argumento (2ª regra), ele então gravou o valor 1198 no ID que foi salvo. Na chamada setuid(1198) o ID salvo 1198 é igual ao argumento (3ª regra), o processo encontra seu ID inicial, e portanto suas permissões associadas.

Observação: As mesmas observações da seção 1.4.2 são válidas nesse caso.



Subsections
next up previous
Next: Interesse do que foi Up: Identificadores dos usuários Previous: Identificadores dos usuários
Celso Alberto Saibel Santos 2000-11-14