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;