by:
潘雲登
對於商業目的下對本文的任何行為需經作者同意。
寫在前面
1.本文內容對應《
unix
環境高階程式設計》(第
2版)》第
4章。 2.
總結了使用者
id和檔案訪問許可權檢查的概念,以及設定使用者
id的用法。 3.
使用者
id
乙個程序與兩類
id相關: l
實際使用者id
和實際組id
,用於標識使用者究竟是誰。這兩個欄位在登入時取自口令檔案中的登入項。可以使用
getuid
和getgid
函式查詢。 l
有效使用者id
和有效組id
,與附加組
id一起,用於檔案訪問許可權檢查。可以使用
geteuid
和getegid
函式查詢。通常,等於實際使用者
id和實際組id。
乙個檔案僅將其所有者
id和所有組
id記錄在
stat
結構的st_uid
和st_gid
字段。
檔案訪問許可權檢查
程序每次開啟,建立或刪除乙個檔案時,核心就進行檔案訪問許可權檢查。核心按順序執行以下四步,一旦滿足就停止檢查: l
若程序的有效使用者id是
0(超級使用者),則允許訪問。 l
若程序的有效使用者
id等於檔案的所有者
id,並且所有者適當的訪問許可權位被設定,則允許訪問,否則拒絕訪問。 l
若程序的有效組
id或程序的附加組
id之一等於檔案的組
id,並且適當的訪問許可權位被設定,則允許訪問,否則拒絕訪問。 l
若其他使用者適當的訪問許可權位被設定,則允許訪問,否則拒絕訪問。
設定使用者
id
可以看到,許可權檢查依賴於有效
id,而與實際
id無關。使用
access
函式可以按照實際使用者
id和實際組
id進行許可權檢查。通常,程序的有效
id等於實際
id。乙個例外是使用設定使用者
id位和設定組
id位。如果乙個程式檔案的設定使用者
id位被置位,那麼,當執行此檔案時,將程序的有效使用者
id設定為檔案所有者id(
st_uid
)。設定組
id的機制與此類似。檔案的設定使用者
id位和設定組
id位包含在
stat
結構的st_mode
欄位中,可用巨集
s_isuid
和s_isgid
測試。
實驗程式如下:
#include
#include
#include
#include
#include
int main(int argc, char *argv)
stat(argv[1], &st);
printf("uid=%d, gid=%d, euid=%d, egid=%d./n",
getuid(), getgid(), geteuid(), getegid());
printf("%s: st_uid=%d, st_gid=%d./n", argv[1], st.st_uid, st.st_gid);
if(access(argv[1], r_ok) < 0)
printf("access error for %s./n", argv[1]);
else
printf("access ok for %s./n", argv[1]);
if(open(argv[1], o_rdonly) < 0)
printf("open error for %s./n", argv[1]);
else
printf("open ok for %s./n", argv[1]);
exit(0); }
執行結果為:
pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chown root a.out
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod u+s a.out
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# ls -l a.out
-rwsr-xr-x 1 root pydeng 9566 2009-08-12 19:28 a.out
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit
pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /etc/shadow
uid=1000, gid=1000, euid=0, egid=1000.
/etc/shadow: st_uid=0, st_gid=42.
access error for /etc/shadow.
open ok for /etc/shadow.
新檔案和目錄的所有權
新檔案的使用者
id設定為程序的有效使用者
id。至於組
id有些複雜。在
linux
下,新檔案的組
id取決於它所在目錄的設定組
id位是否設定。如果該目錄的這一位已經設定,則將新檔案的組
id設定為目錄的組
id,否則將新檔案的組
id設定為程序的有效組id。
實驗程式如下:
#include
#include
#include
#include
int main(int argc, char *argv)
if(open(argv[1], o_creat) < 0)
stat(argv[1], &st);
printf("%s: st_uid=%d, st_gid=%d./n", argv[1], st.st_uid, st.st_gid);
exit(0); }
執行結果為:
pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod 777 /usr/
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit
pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /usr/mytemp
/usr/mytemp: st_uid=1000, st_gid=1000.
pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod g+s /usr/
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# ls -l /
drwxrwsrwx12 root root4096 2009-08-12 19:46 usr
...root@pydeng-laptop:/home/pydeng/apue.2e/mytest# exit
pydeng@pydeng-laptop:~/apue.2e/mytest$ ./a.out /usr/mytemp2
/usr/mytemp2: st_uid=1000, st_gid=0.
pydeng@pydeng-laptop:~/apue.2e/mytest$ sudo su
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod g-s /usr
root@pydeng-laptop:/home/pydeng/apue.2e/mytest# chmod 755 /usr
設定使用者ID與設定使用者組ID
當執行乙個程式檔案時,程序的有效使用者id通常就是實際使用者id,有效組id通常是實際組id。檔案的 設定使用者id 位的作用是 若為程式檔案設定了 設定使用者id 位,那麼當執行此檔案時,將程序的有效使用者id設定為檔案所有者的使用者id 檔案的 設定組id 位的作用是 若為程式檔案設定了 設定組...
設定使用者ID和設定組ID
與乙個程序關聯的id有6個或更多,如下圖所示 與每個程序相關聯的使用者id和組id 實際使用者id 實際組id 我們實際是誰 有效使用者id 有效組id 附加組id 用於檔案訪問許可權檢索 儲存的設定使用者id 儲存的設定組id 由exec函式儲存 通常,有效使用者id等於實際使用者id,有效組id...
設定使用者ID和設定組ID
1.實際使用者id 實際組id 2.有效使用者id 有效組id 附屬組id 3.儲存的使用者id 儲存的組id第一組標識我們實際的id,比如登入shell使用的id 第二組是程序執行時用於判斷檔案訪問許可權的id,這個是跟訪問許可權息息相關的 第三組是當我們的id發生變化時儲存的值,方便我們找回。正...