Ecco una sorgente completo di un programma che illustra il mio problema (il sistema operativo è Ubuntu 14.04 a 32 bit se è importante):risultato strano quando si esegue un programma come una radice
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, const char *argv[])
{
int status, fd;
printf("CURRENT UID: %d, CURRENT GID: %d\n", getuid(), getgid());
fd = open("/dev/ttyS0", O_WRONLY);
if(fd < 0)
{
printf("Error opening /dev/ttyS0: %s\n", strerror(errno));
return 1;
}
printf("Successfully opened /dev/ttyS0\n");
close(fd);
/* DROP PRIVILEGES */
setgid(1000);
setuid(1000);
printf("CURRENT UID: %d, CURRENT GID: %d\n", getuid(), getgid());
fd = open("/dev/ttyS0", O_WRONLY);
if(fd < 0)
{
printf("Error opening /dev/ttyS0: %s\n", strerror(errno));
return 1;
}
printf("Successfully opened /dev/ttyS0\n");
return 0;
}
ci sono due utenti in il sistema: root e un utente normale, non root (chiamiamolo "ubuntu") con id = 1000. Il programma di cui sopra sta cercando di aprire una porta seriale (/ dev/ttyS0) due volte: la prima volta come root o ubuntu (a seconda di come viene invocato) e la seconda volta sempre come ubuntu. Il primo tentativo fallito causa l'abortire del programma. L'utente ubuntu è un membro del gruppo dialout quindi, in teoria, ha le autorizzazioni necessarie per aprire/dev/ttyS0. Invoco il programma in quattro modi diversi:
1) gestito direttamente come ubuntu
invocazione:
< percorso per il mio programma >
2) eseguito come Ubuntu, ma l'uso di sudo
invocazione:
sudo -u ubuntu < percorso al mio programma >
3) eseguito come root, ma con privilegi sceso a quelli di ubuntu (così, in modo efficace, eseguito come ubuntu):
invocazione:
sudo su
sudo -u ubuntu < percorso al mio programma >
In tutti e tre i casi ottengo il seguente risultato atteso:
CURRENT UID: 1000, CURRENT GID: 1000
Successfully opened /dev/ttyS0
CURRENT UID: 1000, CURRENT GID: 1000
Successfully opened /dev/ttyS0
In quest'ultimo caso, però, accade qualcosa di strano:
4) gestiti direttamente come root
invocazione:
sudo su
< percorso per il mio programma >
risultato:
CURRENT UID: 0, CURRENT GID: 0
Successfully opened /dev/ttyS0
CURRENT UID: 1000, CURRENT GID: 1000
Error opening /dev/ttyS0: Permission denied
Ovviamente sono le ultime due righe dell'output che non capisco: questa volta, quando root elimina i suoi privilegi, risulta che ubuntu ha privilegi insufficienti per aprire/dev/ttyS0, ma perché? In che modo questo caso è diverso dai casi 1-3?
Un'ultima cosa vale la pena menzionare: se cambio questa riga del mio codice:
setgid(1000);
a questo:
setgid(20); /* 20 is the id of dialout group */
poi l'ultimo tentativo di aprire/dev/ttyS0 è successo pure .
Significa che le informazioni su Ubuntu come membro del gruppo dialout vengono perse per qualche motivo quando eseguo il programma come root e poi rilasciamo i privilegi a quelli di ubuntu cambiando uid e gid a 1000? Potete per favore fornirmi una spiegazione dettagliata di cosa succede nel caso 4 del mio esempio e perché il risultato è diverso da quanto mi aspettassi?
"ID utente reale ed effettivo". Oppure [vedi questo] (http://stackoverflow.com/questions/32455684/difference-between-real-user-id-effective-user-id-and-saved-user-id). –
Vedete gli stessi risultati usando 'seteuid' e' setegid'? – tkausl
Se sostituisco tutte le occorrenze di UID, GID, getuid(), getgid(), setuid (1000) e setgid (1000) con EUID, EGID, geteuid(), getegid(), seteuid (1000) e setegid (1000), rispettivamente, il risultato rimane esattamente lo stesso in tutti e quattro i casi. – Peter