官术网_书友最值得收藏!

4.5 用戶信息

除了著名的init程序以外,所有的Linux程序都是由其他程序或用戶啟動的。你將在第11章中對運行中的程序或進程的交互進行更深入的學習。用戶通常是在一個響應他們命令的shell中啟動程序。你已經看到,程序能夠通過檢查環境變量和讀取系統時鐘來在很大程度上了解它所處的運行環境。程序也能夠發現它的使用者的相關信息。

當一個用戶要登錄進Linux系統時,他有一個用戶名和密碼。一旦用戶名和密碼通過驗證,用戶就可以進入一個shell。從內部機制來說,用戶還有一個唯一的用戶標識符UID。Linux運行的每個程序實際上都是以某個用戶的名義在運行,因此都有一個關聯的UID。

你可以對程序進行設置,讓它們的運行看上去好像是由另一個用戶啟動的。當一個程序的SUID位被置位時,它的運行就好像是由該可執行文件的屬主啟動的。當su命令被執行時,程序的運行就好像它是由超級用戶啟動的,它隨后驗證用戶的訪問權限,將UID改為目標賬戶的UID值并執行該賬戶的登錄shell。采用這種方式還可以允許一個程序的運行就好像是由另一個用戶啟動的,它經常被系統管理員用來執行一些維護任務。

既然UID是用戶身份的關鍵,我們就從它開始吧。

UID有它自己的類型——uid_t,它定義在頭文件sys/types.h中。它通常是一個小整數。有些UID是系統預定義的,其他的則是系統管理員在添加新用戶時創建的。一般情況下,用戶的UID值都大于100。

getuid函數返回程序關聯的UID,它通常是啟動程序的用戶的UID。

getlogin函數返回與當前用戶關聯的登錄名。

系統文件/etc/passwd包含一個用戶賬號數據庫。它由行組成,每行對應一個用戶,包括用戶名、加密口令、用戶標識符(UID)、組標識符(GID)、全名、家目錄和默認shell。下面是一個示例行:

如果編寫一個程序,它能確定啟動它的用戶的UID,那么你就可以對它進行擴展,讓它查找密碼文件以找到用戶的登錄名和全名。但我們并不推薦這種做法,因為為了提高系統的安全性,現代的類UNIX系統都不再使用簡單的密碼文件了。許多系統,包括Linux,都有一個使用shadow密碼文件的選項,原來的密碼文件中不再包含任何有用的加密口令信息(這些信息通常存放在/etc/shadow文件中,這是一個普通用戶不能讀取的文件)。為此,人們定義了一組函數來提供一個標準而又有效的獲取用戶信息的編程接口:

密碼數據庫結構passwd定義在頭文件pwd.h中,它包含表4-4中的成員。

表4-4

有些UNIX系統可能對用戶全名字段使用一個不同的名字。在某些系統(如Linux)上,它是pw_gecos,而在其他系統上,它是pw_comment。這就意味著,我們不能對它給出一個統一的用法。

getpwuid和getpwnam函數都返回一個指針,該指針指向與某個用戶對應的passwd結構。這個用戶通過getpwuid的UID參數或通過getpwnam的用戶登錄名參數來確定。出錯時,它們都返回一個空指針并設置errno。

實驗 用戶信息

下面的程序user.c從密碼數據庫中提取出一些用戶信息:

它給出如下的輸出,在不同的Linux和UNIX版本中,輸出結果可能會稍有差異:

實驗解析

這個程序先調用getuid獲得當前用戶的UID,再把這個UID用在getpwuid函數中來獲得密碼文件中保存的詳細信息。此外,我們還演示了通過在getpwnam中給出用戶名root來獲得用戶信息的方法。


如果查看Linux的源代碼,你就能在id命令的源代碼中看到另一個使用getuid函數的例子。


如果要掃描密碼文件中的所有信息,你可以使用getpwent函數。它的作用是依次取出文件數據項:

getpwent函數依次返回每個用戶的信息數據項。當到達文件尾時,它返回一個空指針。如果已經掃描了足夠多的數據項,你可以使用endpwent函數來終止處理過程。setpwent函數重置讀指針到密碼文件的開始位置,這樣下一個getpwent調用將重新開始一個新的掃描。這些函數的操作方式與我們在第3章討論的目錄掃描函數opendir、readdir和closedir非常相似。

(有效的和實際的)用戶和組標識符還可以被其他一些不太常用的函數獲得:

組標識符和有效用戶標識符的詳細資料請參考系統的手冊頁,雖然你可能會發現自己根本不需要對它們進行處理。


只有超級用戶才能調用setuid和setgid函數。

主站蜘蛛池模板: 平塘县| 阳朔县| 股票| 翁源县| 秦皇岛市| 十堰市| 阳江市| 平远县| 长海县| 区。| 霍林郭勒市| 安多县| 共和县| 丘北县| 太白县| 枣阳市| 营口市| 班戈县| 曲阜市| 昌乐县| 于田县| 田阳县| 望奎县| 镇平县| 鄂托克旗| 天水市| 济阳县| 绥宁县| 敦煌市| 安图县| 铜梁县| 哈密市| 元江| 尤溪县| 高陵县| 英吉沙县| 遂平县| 南川市| 萍乡市| 油尖旺区| 清水河县|