2013-09-27 4 views
8

나는 루트로 실행되는 프로그램이 있습니다. 나는 프로그램이 일반 사용자로서 다른 응용 프로그램을 실행하기를 원합니다. 내가 setgid() 시도하고 작동하지만 루트 또는 다른 사용자에게 다시 갈 수 없습니다. 당분간 프로그램은 매우 간단합니다.리눅스 C 프로그래밍을 사용자로 실행

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

어떻게하면됩니까? 그것은 명령의 행동과 같습니다. su $user-c $command

답변

4

fork+exec을 사용하는 경우 상위 프로세스에있는 부모 프로세스에서 euid을 변경할 수 있습니다. 코드는 다음과 같습니다.

#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

setuid 매뉴얼에서 : [if caller was root] it is impossible for the program to regain root privileges.

무엇을하려하십니까? 프로그램에 SUID-bit를 설정하여 사용자로 실행할 수 있습니다. 그러면 seteuid를 사용하여 루트 권한을 일시적으로 삭제하고 user를 호출 한 다음 다시 권한을 재설정 할 수 있습니다. 루트로 실행해야한다면, 루트 (root)로두고, 다른 하나는 setuid()로두고 fork()해야한다.

2

일반 사용자와 루트 사용자 중 하나를 수행하려면 루트 권한이없는 하위 프로세스에서 fork 및 setuid를 항상 수행 할 수 있으며 프로그램의 다른 부분은 유지해야합니다.