2013-09-27 12 views
8

Ho un programma che eseguo come root. Vorrei che il programma eseguisse un'altra applicazione come utente normale. Ho provato setgid() e funziona, ma non posso quindi tornare a root o un altro utente. Il programma per il momento è molto semplice;Programmazione Linux C eseguita come utente

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

int main(int argc, char *argv[]) 
{ 
    if (argc != 2) { 
     printf("usage: %s command\n",argv[0]); 
     exit(1); 
    } 
    setgid(100); 
    setuid(1000); 
    putenv("HOME=/home/caroline"); 
    putenv("DISPLAY=:0"); 
    system(argv[1]); 
    seteuid(1001); 
    putenv("HOME=/home/john"); 
    putenv("DISPLAY=:1"); 
    system(argv[1]); 
    return 0; 
} 

Come posso fare questo? È come l'azione di comando su $user-c $command

risposta

4

Se si utilizza fork+exec è possibile modificare euid del processo figlio rimanendo come root nel genitore. Il codice potrebbe essere qualcosa del genere:

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 

int runAs(int gid, int uid, char **env, char *command) { 
    int child = fork(); 
    if (child == 0) { 
    setgid(100); 
    setuid(1000); 
    do { 
     putenv(*env); 
     env++; 
    } while (env != null); 
    exec(command); 
    } else if (child > 0) { 
    waitpid(child); 
    } else { 
    // Error: fork() failed! 
    } 
} 


int main(int argc, char *argv[]) 
{ 
    char *env[3]; 
    if (argc != 2) { 
     printf("usage: %s command\n",argv[0]); 
     exit(1); 
    } 
    env[0] = "HOME=/home/caroline"; 
    env[1] = "DISPLAY=:0"; 
    env[2] = NULL; 
    runAs(100, 1000, env, argv[1]); 

    env[0] = "HOME=/home/john"; 
    env[1] = "DISPLAY=:1"; 
    runAs(100, 1001, env, argv[1]); 
    return 0; 
} 
2

dal manuale setuid: [if caller was root] it is impossible for the program to regain root privileges.

Che cosa stai cercando di fare? È possibile impostare SUID-bit sul programma ed eseguirlo come utente, quindi è possibile utilizzare seteuid per eliminare temporaneamente i privilegi di root e diventare utente chiamante, quindi ripristinare nuovamente i privilegi. Se devi davvero eseguirlo come root, suppongo che dovresti fork(), lasciando un processo come root e un altro come setuid().

2

Se si desidera eseguire una cosa come utente normale e un'altra come utente root, è sempre possibile eseguire il fork e setuid nel processo figlio per il quale si desidera non disporre dei privilegi di root conservandoli per l'altra parte del programma.