C,C++ & Linux

C/C++ setuid(2), setgid(2)

KyooDong 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

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