日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux进程号为一,一步步探究linux进程中的用户ID

發(fā)布時間:2025/3/15 linux 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux进程号为一,一步步探究linux进程中的用户ID 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

轉(zhuǎn)載請注明來源chengyaogen.blog.chinaunix.net

一、進(jìn)程與權(quán)限

A.進(jìn)程時Linux/Unix操作系統(tǒng)中最重要的抽象之一

B.進(jìn)程是一個處于執(zhí)行期的程序(目標(biāo)代碼存儲在某種介質(zhì)上)

A ? ?process ? is ? a ?program(object ?code ?stored ?on some ?media) ?in the ?midst ?of

execution.

而進(jìn)程在執(zhí)行過程中經(jīng)常涉及到文件訪問操作等

1.一個運行中的進(jìn)程究竟可以訪問哪些資源,而不能訪問哪些資源?

2.一個進(jìn)程運行過程中如何實現(xiàn)在某個執(zhí)行階段擁有一些權(quán)限而在另一個階段又具備另外一種權(quán)限呢?

上述狀況對應(yīng)于進(jìn)程的訪問權(quán)限以及進(jìn)程執(zhí)行中不同權(quán)限的切換。這一切都和進(jìn)程實際用戶ID,進(jìn)程有效用戶ID,進(jìn)程保存設(shè)置用戶ID有關(guān)聯(lián)。

二、進(jìn)程的用戶ID

1.實際用戶ID(real user id,RUID)

為該進(jìn)程的創(chuàng)建者的用戶ID,也可以說是進(jìn)程的執(zhí)行者。該ID僅root用戶可以修改

2.有效用戶ID(effective ?user ?id,EUID)

該ID用戶標(biāo)識用戶進(jìn)程執(zhí)行操作的權(quán)限。例如:如果EUID是0即(root),此時進(jìn)程擁有root用戶權(quán)限。普通用戶可以將EUID設(shè)置為RUID或者SUID,而超級用戶可以將EUID設(shè)置為任意的合法UID。

注意:對于一個可執(zhí)行的二進(jìn)制文件,如果其set-user-id bit被設(shè)置,則運行改程序時,對應(yīng)進(jìn)程的有效用戶ID(EUID)為該文件的文件所有者用戶ID。

3.保存設(shè)置用戶ID(saved set-user-id,SUID)

對于沒有設(shè)置set-uid-bit的可執(zhí)行程序而言,其對應(yīng)進(jìn)程的保存設(shè)置用戶ID(SUID)為其實際用戶ID;而對于設(shè)置了set-uid-bit的程序而言,其對應(yīng)的保存設(shè)置用戶ID(SUID)為該可執(zhí)行文件的文件擁有者用戶ID。只能root用戶權(quán)限,才能更改(當(dāng)一個程序文件運行的時候,其值已經(jīng)確定)。

注意:linux不提供返回保存的設(shè)置-用戶-ID的函數(shù)

總結(jié):

RUID代表此進(jìn)程是哪個用戶創(chuàng)建的, EUID代表此進(jìn)程所擁有的權(quán)限,SUID保存了EUID,當(dāng)EUID改變后,如果想回到以前的EUID,此時SUID將發(fā)揮作用。

三、相關(guān)API

#include

#include

int ? setuid(uid);

可以用setuid函數(shù)設(shè)置實際用戶ID和有效用戶ID。注意,我們并不能想怎么設(shè)就怎么設(shè)。有若干規(guī)則需要我們遵守:

(1)若進(jìn)程具有超級用戶特權(quán),則setuid函數(shù)將實際用戶ID、有效用戶ID,以及保存的設(shè)置-用戶-D設(shè)置為uid。

(2)若進(jìn)程沒有超級用戶特權(quán),但是uid等于實際用戶ID或保存的設(shè)置-用戶-ID,則setuid只將有效用戶ID設(shè)置為。不改變實際用戶ID和保存的設(shè)置-用戶-ID。

(3)如果上面兩個條件都不滿足,則errno設(shè)置為EPERM,并返回出錯.。

關(guān)于內(nèi)核所維護(hù)的三個用戶ID,還要注意下列幾點

(1)只有超級用戶進(jìn)程可以更改實際用戶ID。通常,實際用戶ID是在用戶登錄時,由login(1)程序設(shè)置的,而且決不會改變它。因為login是一個超級用戶進(jìn)程,當(dāng)它調(diào)用setuid時,設(shè)置所有三個用戶ID。

(2)僅當(dāng)對程序文件設(shè)置了 set-user-id bit時,exec函數(shù)設(shè)置有效用戶ID為文件所有者。如果set-user-id bit沒有設(shè)置,則exec函數(shù)不會改變有效用戶ID,而將其位置原先值。任何時候都可以調(diào)用setuid,將有效用戶ID設(shè)置為實際用戶ID或保存的設(shè)置-用戶-ID。自然,不能講有效用戶ID設(shè)置為任意隨機值。

四、探究

案例一:

有個要在MacOS上實現(xiàn)一個關(guān)機程序,它熟悉linux,其實老祖宗都是unix,所以MacOS對他并不陌生。如下他寫了如下程序?qū)崿F(xiàn)關(guān)機

編譯運行:

從上面看,這段代碼可以實現(xiàn)關(guān)機,但是有個不符合要求的地方,運行程序不能是超級用戶,只能是普通用戶。

他很苦惱,后來找到了我,我做了如下事情

呵呵,可以了。我將這個可執(zhí)行文件的owner和group都改為了root,然后有講其set-user-id bit位加以了設(shè)置。這樣以普通用戶運行這個程序時,此進(jìn)程的EUID就是root了,這樣滿足了shutdown命令執(zhí)行的權(quán)限。案例二:

#include

#include

#include

#include

#include

#include

void test_read_file(const char *name)

{

int fd = -1;

fd = open(name ,O_RDWR);

if(fd < 0){

printf("=[ERROR]:read failed.\n");

}else{

printf("=[OK]:read successful\n");

close(fd);

}

}

//打印uid和euid

void p_states()

{

int uid = 0;

int euid = 0;

printf("------Current states--------\n");

printf("real uid\t %d\n",getuid());

printf("effective uid\t %d\n",geteuid());

printf("----------------------------\n");

}

//調(diào)用setuid

void run_setuid_fun(int uid)

{

if(setuid(uid) == -1)

{

printf("=[ERROR]:setuid(%d) error\n",uid);

}

p_states();

}

//調(diào)用setuid

void run_seteuid_fun(int uid)

{

if(setuid(uid) == -1)

{

printf("=[ERROR]:seteuid(%d) error\n",uid);

}

p_states();

}

int main()

{

int t_re = 0;

const char *file = "root_only.txt";

printf("\nTEST 1:\n");

p_states();

//此時real uid = login user id

//effective uid = root

//saved uid = root

test_read_file(file);

getchar();

printf("\nTEST 2:setuid(getuid())\n");

run_seteuid_fun(getuid());

//此時real uid = login user id

//effective uid = login user id

//saved uid = root

test_read_file(file);

getchar();

printf("\nTEST 3:setuid(0)\n");

run_setuid_fun(0);

//此時real uid = login user id

//effective uid = root

//saved uid = root

test_read_file(file);

getchar();

printf("\nTEST 4:setuid(0)\n");

run_setuid_fun(0);

//此時real uid = root

//effective uid = root

//saved uid = root

test_read_file(file);

getchar();

printf("\nTEST 5:setuid(503)\n");

run_setuid_fun(503);

//此時real uid = login user id

//effective id = login user id

//saved uid = login user id

test_read_file(file);

getchar();

printf("\nTEST 6:setuid(0)\n");

//read uid = login user id

//effective uid = login user id

//saved uid = login user id

run_setuid_fun(0);

test_read_file(file);

return 0;

}編譯運行:

root_only.txt文件建立:

第一次:

RUID:實際用戶

EUID:文件所有者(root)

SUID:文件所有者(root)此時進(jìn)程擁有root用戶權(quán)限,能對root_only.txt進(jìn)行讀寫操作

第二次:

此時普通用戶調(diào)用setuid(getuid()),只會將EUID改為getuid(),其他都不變

RUID:實際用戶

EUID:實際用戶

SUID:root

此時進(jìn)程沒有有root用戶權(quán)限,不能能對root_only.txt進(jìn)行讀寫操作

第三次:

此時普通用戶調(diào)用seteuid(0),只會將EUID改為0,其他都不變

RUID:實際用戶

EUID:root

SUID:root此時進(jìn)程擁有root用戶權(quán)限,能對root_only.txt進(jìn)行讀寫操作

第四次:

此時進(jìn)程擁有root用戶權(quán)限,調(diào)用setuid(0),會將三個ID都設(shè)置為0

RUID:root

EUID:root

SUID:root

此時進(jìn)程擁有root用戶權(quán)限,能對root_only.txt進(jìn)行讀寫操作

第五次:

此時進(jìn)程擁有root用戶權(quán)限,調(diào)用setuid(503),會將三個ID都設(shè)置為503

RUID:503

EUID:503

SUID:503

此時進(jìn)程擁有普通用戶權(quán)限,不能對root_only.txt進(jìn)行讀寫操作

第六次:

此時進(jìn)程擁有普通用戶權(quán)限,調(diào)用setuid(0),此時RUID,SUID都不為0,這一次操作將失敗

RUID:503

EUID:503

SUID:503

此時進(jìn)程擁有普通用戶權(quán)限,不能能對root_only.txt進(jìn)行讀寫操作

總結(jié)

以上是生活随笔為你收集整理的linux进程号为一,一步步探究linux进程中的用户ID的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。