ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • C/C++ setuid(2), setgid(2)
    C,C++ & Linux 2020. 6. 4. 02:21
    728x90

    함수 기능

    사용자 ID와 그룹 ID 를 변경하는 함수입니다.

     

    setuid() 함수를 실행한 프로세스가 루트 권한을 갖고 있다면 Read User ID, Effective User ID, Saved User ID 모두를 uid 로 바꿉니다.

    루트 권한은 갖고 있지 않으나 uid가 Real User ID 혹은 Saved User ID와 같다면 Effective User ID 만을 uid 로 바꿉니다.

     

    setgid() 함수는 그룹 아이디를 제어한다는 점만 다르고 setuid() 와 동일하게 동작합니다.

    함수 원형

    #include <unistd.h>
    #include <sys/types.h>
    
    int setuid(uid_t uid);
    int setgid(gid_t gid);

     

    매개변수

    uid

    새로운 uid

     

    gid

    새로운 gid

    반환값

    성공 시 0 리턴

    에러 시 -1 리턴하고 errno 설정

    예제

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    
    int main(int argc, char *argv[]) {
        char line[256];
        FILE *fp;
        int uid;
    
        printf("Initially uid = %d and euid = %d\n", getuid(), geteuid());
    	
    	// 파일을 한 번 열기
    	// argv[1]은 dongkyoo 계정의 파일이므로 dongkyoo 는 당연히 열리고
    	// unix-dongkyoo 계정에서는 열리지 않음
        fp = fopen(argv[1], "r");
        if (fp == NULL) {
            fprintf(stderr, "first open error for %s\n", argv[1]);
            exit(1);
        }
    
        printf("first open successful:\n");
    
    	// 파일 내용 읽고 출력
        while (fgets(line, 255, fp) != NULL)
            fputs(line, stdout);
    
        fclose(fp);
    
    	// 일반 사용자로 실행할 것이므로 Effective user id 를 uid 로 변경
    	// dongkyoo 계정으로 Effective User id 를 변경
        setuid(uid = getuid());
        printf("after setuid(%d):\n uid = %d and euid = %d\n", uid, getuid(), geteuid());
    
        fp = fopen(argv[1], "r");
    
        if (fp == NULL) {
            fprintf(stderr, "second open error for %s\n", argv[1]);
            exit(1);
        }
    
        printf("second open successful:\n");
    
        while (fgets(line, 255, fp) != NULL)
            fputs(line, stdout);
    
        fclose(fp);
        exit(0);
    }
    

     

    결과

    dongkyoo 계정에서 최초로 실행함

    ssu_setuid_test 파일은 dongkyoo 계정의 소유이므로 정상적으로 동작하는 모습

     

    unix-dongkyoo 계정에서 그 다음 실행함

    ssu_setuid_test 파일은 dongkyoo 계정의 소유이므로 unix-dongkyoo 는 파일을 열지 못함

     

    dongkyoo 계정에서 SUID 비트를 설정하고, 한 번 더 실행

    unix-dongkyoo 계정에서 한 번 더 실행

    SUID 비트가 설정되어 있었기 때문에 unix-dongkyoo 가 a.out 을 실행시켰지만 Effective User ID 는 501 (dongkyoo) 로 뜹니다.

    덕분에 첫 번째 fopen 때에는 파일을 열 수 있었지만

    이후 setuid() 함수를 통해 Effective User ID 를 다시 본인의 것으로 되돌렸기 때문에 두 번째 fopen 때에는 파일을 열 수 없습니다.

     

     

     

     

    리눅스시스템프로그래밍 저자 : 홍지만
    https://book.naver.com/bookdb/book_detail.nhn?bid=14623672

    책에 기술된 예제 프로그램입니다. 책 내부에는 훨씬 더 많은 자료가 있습니다. (개인적으로 좋았습니다.)

    'C,C++ & Linux' 카테고리의 다른 글

    C/C++ seteuid(2), setegid(2)  (0) 2020.06.05
    C/C++ setreuid(2), setregid(2)  (0) 2020.06.05
    C/C++ wait3(2), wait4(2)  (0) 2020.06.04
    C/C++ execl(3), execv(3), execle(3), execve(2), execlp(3), execvp(3)  (0) 2020.06.04
    C/C++ waitid(2)  (0) 2020.06.04

    댓글

Designed by Tistory.