[리눅스 시스템 프로그래밍] 8.1 실제 사용자 ID(Real User ID)와 유효 사용자 ID(Effective User ID)

리눅스 시스템은 다중 사용자가 사용할 수 있는 서버용 운영체제입니다. 따라서 사용자에 따라 사용 권한을 다르게 지정할 수 있습니다.

리눅스 시스템에서는 사용자 계정에 따라 사용자 ID를 부여하여 관리합니다. 사용자 ID는 정수 값이며 사용자를 구분하기 위한 값입니다. 리눅스 시스템은 사용자가 로긴하면 해당 사용자 계정에 대응하는 사용자 ID를 실제 사용자 ID(Real User ID)라고 부르고 프로세스가 수행할 때 권한은 유효 사용자 ID(Effective User ID)에 따릅니다.

일반적으로 로긴한 사용자 계정의 권한은 프로세스 수행할 때의 권한과 일치합니다. 이는 대부분 실제 사용자 ID와 유효 사용자 ID는 같다는 거입니다. 그런데 set user id bit를 설정한 프로그램을 실행할 때는 실제 사용자 ID와 유효 사용자 ID가 일치하지 않을 수 있습니다. 이 때는 해당 프로그램 소유자 계정과 대응하는 사용자 ID가 유효 사용자 ID입니다.

이는 일부 프로그램을 동작할 때 수행 권한이 일반 사용자 권한이 아닌 관리자 권한으로 동작할 수 있게 하기 위해서입니다.

또한 리눅스 시스템에서는 프로그램이 동작 중에 유효 사용자 ID를 변경하는 기능을 제공하고 있습니다.

이를 확인하기 위해 간단한 실습을 해 볼게요. 먼저 루투 계정으로 변환한 후에 빈 파일을 생성하고 chmod 명령을 통해 사용자만 읽기/쓰기가 가능하고 다른 계정은 아무 권한도 부여하지 마세요.

[그림 8.1] root 계정으로 파일 생성 및 chmod 0644 부여
[그림 8.1] root 계정으로 파일 생성 및 chmod 0644 부여

그리고 다음처럼 dum 파일에 “Hello\n”를 기록하는 프로그램을 작성하고 컴파일하세요.

/**********************************************************************
* ex_write.c                                                          *
* exmple source – write data                                          *
**********************************************************************/

#include <stdio.h>

int main(int argc, char **argv)
{
    FILE *fp = fopen("dum","w");
    if(fp)
    {
        fprintf(fp, "Hello\n");
        fclose(fp);
    }
    else
    {
        printf("fopen error\n");
    }
    return 0;
}

그리고 ex_write 실행 파일에 set user id bit을 설정합니다. chmod u+s ex_write 명령을 통해 설정하세요.

[그림 8.2] set user id bit 설정
[그림 8.2] set user id bit 설정

그리고 일반 계정으로 전환한 후에 ex_write를 실행해 보세요. 분명 dum 파일은 root만 쓰기 권한을 갖고 있음에도 쓰기 작업을 성공한 것을 확인할 수 있습니다. 이는 ex_write 파일에 set user id bit를 설정하여 프로그램을 동작할 때 유효 사용자 ID가 실제 사용자 ID인 ehpub가 아닌 ex_write 파일의 소유자인 root이기 때문입니다.

[그림 8.3] 일반 계정으로 실행
[그림 8.3] 일반 계정으로 실행

리눅스 시스템에서는 실제 사용자 ID와 유효 사용자 ID 및 실제 그룹 ID와 유효 그룹 ID를 확인할 수 있는 시스템 호출을 제공합니다.

#include <sys/types.h >

#include <unistd.h>

uid_t getuid(void);

uid_t geteuid(void);

gid_t getgid(void);

gid_t getegid(void);

 
이번에는 앞에서 만든 ex_write.c 파일을 복사하여 프로그램 시작할 때 실제 사용자 ID와 유효 사용자 ID를 출력하는 구문을 추가하세요.

/**********************************************************************
* ex_write2.c                                                         *
* exmple source – write data, print real user id and effective user id*
**********************************************************************/

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int main(int argc, char **argv)
{
    printf("real user id:%d\n", getuid());
    printf("effective user id:%d\n",geteuid());
    FILE *fp = fopen("dum","w");
    if(fp)
    {
        fprintf(fp, "Hello\n");
        fclose(fp);
    }
    else
    {
        printf("fopen error\n");
    }
    return 0;
}

ex_write2.c 파일을 컴파일 한 후 마찬가지로 chmod u+s ex_write2를 명령하여 set user id bit을 설정하세요. 그리고 일반 계정으로 전환한 후에 실행하여 실제 사용자 ID와 유효 사용자 ID를 확인해 보세요. 테스트 화면을 보면 실제 사용자 ID는 1000번이고 /etc/passwd 파일을 확인한 결과 ehpub임을 알 수 있습니다. 하지만 유효 사용자 ID는 0번이고 /etc/passwd 파일을 확인한 결과 root임을 알 수 있어요.

[그림 8.4] ex_write2 실행
[그림 8.4] ex_write2 실행