1. 程式人生 > >linux/unix下setuid/seteuid/setreuid/setresuid

linux/unix下setuid/seteuid/setreuid/setresuid

其中setresuid()具有最清晰的語法:

setresuid()被執行的條件有:

①當前程序的euid是root

②三個引數,每一個等於原來某個id中的一個

如果滿足以上條件的任意一個,setresuid()都可以正常呼叫,並執行,將

程序的ID設定成對應的ID。

例子:

如果ruid=100,euid=0,suid=300

則setresuid(200,300,100)可以執行,因為原來的euid=0.

如果ruid=100,euid=300,suid=200

則setresuid(200,300,100)也可以執行,因為這三個新的id都是原來id中的某一個。

但是setresuid(100,200,400)就不能執行,因為400不等於原來三個id中的任意一個。

setresuid()有個性質,英文名稱是all-or-nothing effect,意思是,如果setresuid()

對某一個ID設定成功了,其他的失敗了,比如只改變了ruid,suid和euid都改失敗了

那麼程式會將ruid改回原來的值,即保證要麼三個ID都能成功修改,要麼三個都沒能修改成功。

PS:FreeBSD和Linux支援setresuid,Solaris不支援setresuid,但有自己的實現方式。

seteuid()也有較清晰的語法:

  無論什麼情況,它只改變程序euid,而不改變ruid和suid。

  如果原來的euid==0,則新的euid隨意設,都可以成功改變。

  如果原來的euid!=0,不同的系統的處理方式是不一樣的:

-Solaris和Linux只允許新的euid等於原來三個id中的任意一個;

-但是FreeBSD只允許新的euid等於ruid和suid中的一個;

貌似FreeBSD這個限制是多餘的,因為新的euid==原來的euid的時候應該是可以的,但是它會報錯,不允許。

setreuid()有點小複雜:

  它會修改ruid和euid,也某些情況下,也會修改suid。

  而且不同的系統對setreuid也有不同的處理方式:

-在Solaris和Linux中,setreuid(geteuid(),getuid())可以實現ruid和euid的交換

-FreeBSD則會失敗;

setuid()

如果原來的euid==0,則該函式將會設定所有的id都等於新的id。

如果原來的三個id為:ruid=300,euid=0,suid=100

則setuid(200)執行以後,ruid=200,euid=200,suid=200

如果原來的euid!=0,但是新的id等於原來ruid和suid中的一個,那麼也是可以執行的。否則就不能執行。

比如原來的三個id為:ruid=100,euid=200,suid=300

則setuid(300)可以執行,執行結束以後ruid=100,euid=300,suid=300(也就是說只改變了euid)。

setuid(400)就不能執行。

不同的系統有不同的處理方式:

-Linux和Solaris:如果euid不等於0,那麼新的id必須等於ruid或者suid中的一個(就是我們上面說的);

-FreeBSD待定,還沒搞清楚;

setuid()的行為不僅取決於系統,還取決於程序的優先順序:

-Linux和Solaris:如果euid==0,那麼將三個id都設定為新的id;否則,只設置euid;

-FreeBSD:不管euid值,如果執行成功,直接設定所有的id都為新的id;