在UNIX系統中,特權(例如能改變當前日期的表示法以及訪問控制(例如,能否讀、寫一特定文件))是基于用戶ID和組ID的。當程序需要增加特權,或需要訪問當前并不允許訪問的資源時,我們需要更換自己的用戶ID或組ID,使得新ID具有合適的特權或訪問權限。與此類似,當程序需要降低其特權或阻止對某些資源的訪問時,也需要更換用戶ID或組ID,從而使新ID不具有相應特權或訪問這些資源的能力。
一般而言,在設計應用程序時,我們總是試圖使用最小特權(least PRivilege)模型。依照此模型,我們的程序應當只具有為完成給定任務所需的最小特權。這減少了安全性受到損害的可能性。
可以用setuid函數設置實際用戶ID和有效用戶ID。與此類似,可以用setgid函數設置實際組ID和有效組ID。
#include <unistd.h>int setuid( uid_t uid );int setgid( gid_t gid );兩個函數返回值:若成功則返回0,若出錯則返回-1
關于誰能更改ID有若干規則?,F在先考慮有關改變用戶ID的規則(關于用戶ID所說明的一切都適用于組ID)。
與進程關聯的ID可參考:http://www.CUOXin.com/nufangrensheng/p/3501832.html
(1)若進程具有超級用戶特權,則setuid函數將實際用戶ID、有效用戶ID,以及保存的設置用戶ID設置為uid。
(2)若進程沒有超級用戶特權,但是uid等于實際用戶ID或保存的設置用戶ID,則setuid只將有效用戶ID設置為uid。不改變實際用戶ID和保存的設置用戶ID。
(3)如果上面兩個條件都不滿足,則將errno設置為EPERM,并返回-1。
關于內核所維護的三個用戶ID,還要注意下列幾點:
(1)只有超級用戶進程可以更改實際用戶ID。
(2)僅當對程序文件設置了設置用戶ID位時,exec函數才會設置有效用戶ID。如果設置用戶ID位沒有設置,則exec函數不會改變有效用戶ID,而將其維持為原先值。任何時候都可以調用setuid,將有效用戶ID設置為實際用戶ID或保存的設置用戶ID(也只會在這兩個ID之間切換)。自然,不能將有效用戶ID設置為任意隨機值。
(3)保存的設置用戶ID是由exec復制有效用戶ID得來的。如果設置了文件的設置用戶ID位,則在exec根據文件的用戶ID設置了進程的有效用戶ID以后,就將這個副本保存起來。
注意,http://www.CUOXin.com/nufangrensheng/p/3509352.html中所述的getuid和geteuid函數只能獲得實際用戶ID和有效用戶ID的當前值。我們不能獲得所保存的設置用戶ID的當前值。
表8-7 改變三個用戶ID的不同方法
從表8-7中可明確一點:無論設置用戶ID位是關閉還是打開,保存的設置用戶ID都是從有效用戶ID復制得來的。
1、setreuid和setregid函數
功能是交換實際用戶ID(組ID)和有效用戶ID(組ID)的值。
#include <unistd.h>int setreuid( uid_t ruid, uid_t euid );int setregid( gid_t rgid, gid_t egid );兩個函數返回值:若成功則返回0,若出錯則返回-1
如若其中任一參數的值為-1,則表示相應的ID應當保持不變。
相關規則很簡單:一個非特權用戶總能交換實際用戶ID和有效用戶ID。這就允許一個設置用戶ID程序轉換成只具有普通用戶的普通權限,以后又可再次轉換回設置用戶ID所得到的額外權限。
2、seteuid和setegid函數
類似于setuid和setgid,但只更改有效用戶ID和有效組ID。
#include <unistd.h>int seteuid( uid_t uid );int setegid( gid_t gid );兩個函數返回值:若成功則返回0,若出錯則返回-1
一個非特權用戶可將其有效用戶ID設置為其實際用戶ID或其保存的設置用戶ID。對于一個特權用戶,則可將其有效用戶ID設置為uid。(這有別于setuid函數,它會更改所有三個用戶ID)。
圖8-3 設置不同用戶ID的各函數
3、組ID
關于用戶ID所說明的一切都適用于組ID。附加組ID不受setgid、setregid或setegid函數的影響。
本篇博文內容摘自《UNIX環境高級編程》(第二版),僅作個人學習記錄所用。關于本書可參考:http://www.apuebook.com/。
新聞熱點
疑難解答