2013-09-27 16 views
8

Ich habe ein Programm, das ich als root ausführen. Ich möchte, dass das Programm eine andere Anwendung als normaler Benutzer ausführt. Ich habe versucht setgid() und es funktioniert, aber ich kann dann nicht zurück zu root oder einem anderen Benutzer. Das Programm ist vorerst sehr einfach;Linux C-Programmierung als Benutzer ausführen

#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; 
} 

Wie kann ich das tun? Es ist wie die Aktion des Befehls su $user-c $command

Antwort

4

Wenn Sie fork+exec verwenden, können Sie euid des untergeordneten Prozesses ändern, während Sie als Stamm im übergeordneten Zweig bleiben. Der Code könnte in etwa so aussehen:

#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

Von Setuid Handbuch: [if caller was root] it is impossible for the program to regain root privileges.

Was möchten Sie tun? Sie könnten SUID-Bit auf Ihr Programm setzen und es als Benutzer ausführen - dann können Sie mit seteuid temporär Root-Privileges löschen und Benutzer anruft, dann setzen Sie die Rechte wieder zurück. Wenn Sie es wirklich als root ausführen müssen - ich denke, Sie sollten fork(), einen Prozess als root, und einen anderen als setuid() verlassen.

2

Wenn Sie eine Sache als normaler Benutzer und eine andere als root ausführen möchten, können Sie Fork und Setuid im untergeordneten Prozess immer so einrichten, dass Sie keine Root-Berechtigungen haben, während sie für den anderen Teil Ihres Programms beibehalten werden.