Linuxで一般ユーザーに特権プログラムを実行させて制限ファイルにアクセスする方法

2878 ワード

質問:rootアカウントから作成されたこのファイルは、rw-r---の権限を持つ、つまり一般ユーザーにとってread/write権限がない.
-rw-r-----  1 root   root         0 7    9 21:22 rootfile

root以外のアカウント、つまり普通のユーザーアカウントの下で、このファイルを読み込もうとするとエラーが発生します.
$ cat rootfile 
cat: rootfile:     

特殊な場合、一般ユーザーもそのファイルの内容を読み取る必要があります.どうすればいいですか?
解決策:
1.owner idがrootのプログラムを作成し、readRootFileというrootfileを読み書きします(ソースコードは以下を参照).この場合、このプログラムはrootアカウントでのみ実行できます.
-rwxr-xr-x  1 root   root      8968 7    9 21:37 ReadRootFile

通常のアカウントでプログラムを実行しようとすると、エラーが発生します.
$ ./ReadRootFile rootfile 
Open fail: : Permission denied
Real User ID:1000, name=liuwei
Effective User ID:1000, name=liuwei

2.rootアカウントの下でchmod u+s./ReadRootFile、Set-User-IDビットを開きます.設定後、ファイルのプロパティを再度表示します.可視ファイルのユーザ実行可能権限ビットがsになり、変更に成功したことを示す.
$ sudo chmod u+s ./ReadRootFile
$ ls -l ReadRootFile
-rwsr-xr-x 1 root root 8968 7    9 21:37 ReadRootFile

3.普通口座に切り替えて再度実行する./ReadRootFile、rootfileを開けました.
$ ./ReadRootFile ./rootfile 
Open ./rootfile ok.
Real User ID:1000, name=liuwei
Effective User ID:0, name=root

注意ステップ1とステップ3の前後を比較すると、Effective User IDとNameが変化する.
原理説明:
まずいくつかの概念を説明する.
Owner ID:ファイルの所有者、すなわちls-lで見た名前.ReadRootFileのOwner IDはroot.
Real User ID:プロセスの実際のユーザーID、私たちはどの口座の下でこのプロセスを実行して、そのプロセスのReal User IDはこの口座です.
Effective User ID:プロセスの有効ユーザID.デフォルトでは、Effective User IDはReal User IDに等しいが、chmod u+sでSet-User-IDを設定と、Effective User IDはプロセスのOwner IDに等しい.
プロセスのEffective User IDがファイルのOwner IDと同じである場合、プロセスはファイルにアクセスする権限があります.Groupへの適用も同様に成立する.
本来rootfileではrootとrootグループアカウントのみがアクセスできるようにしていましたが、上記の手順2を実行した後、一般アカウントliuweiで実行します./ReadRootFileは、プロセスのEffective User IDがReadRootFileのOwner ID、すなわちrootになります.したがってrootfileにも正常にアクセスできます.
ReadRootFile.c:
/*
 * getuid() returns the real user ID of the calling process.
 * geteuid() returns the effective user ID of the calling process.
 */

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

char * get_username_by_id(uid_t uid)
{
    struct passwd *pwd;

    pwd = getpwuid(uid);
    return (pwd == NULL) ? NULL : pwd->pw_name;
}

int main(int argc, char *argv[])
{
	int fd;

	fd = open(argv[1], O_RDWR);
	if(fd == -1)
		perror("Open fail: ");
	else
		printf("Open %s ok.
", argv[1]); printf("Real User ID:%d, name=%s
", getuid(), get_username_by_id(getuid())); /* Set-User-ID(chmod u+s), Effective User ID Owner ID 。 */ printf("Effective User ID:%d, name=%s
", geteuid(), get_username_by_id(geteuid())); close(fd); return 0; }