UNIX口令文件包含了以下圖所示的個字段,這些字段包含在<pwd.h>中定義的passwd結構中。node
口令文件是/etc/passwd,並且是一個ASCII文件。每一行包含以下圖所示的各字段,用冒號分隔,通常結構是算法
LOGNAME:PASSWORD:UID:GID:USERINFO:HOME:SHELL
關於這些登陸項,注意下面各點:shell
提供finger(l)命令的某些支持註釋字段中的附加信息。如:
數組
#include <pwd.h> struct passwd *getpuid(uid_t uid);//給出用戶id獲取口令文件項 struct passwd *getpwnam(const char *name);//給出用戶名獲取口令文件項 //返回值:若成功,返回指針;若出錯,返回NULL
這兩個函數都返回一個指向passwd結構的指針。該結構已由這兩個函數在執行時填入信息。passwd結構一般是函數內部的靜態變量,只要調用任一相關函數,其內容就會被重寫。安全
調用getpwent時,他返回口令文件的下一個記錄項。每次調用此函數都重寫passw結構。 函數setpwent反繞它所使用的文件,endpwent則關閉這些文件。在使用getpwent查看完口令文件後,必定要調用endpwent關閉這些文件。網絡
#include <pwd.h> struct passwd *getpwent(void); //返回值:若成功,返回指針;若出錯或者到達文件尾端,返回NULL void setpwent(void); void endpwent(void);
demo函數
#include <pwd.h> #include <stddef.h> #include <string.h> struct passwd *getpwnam(const char *name) { struct passwd *ptr; setpwent(); while ((ptr = getpwent()) != NULL) { if (strcmp(name,ptr->pw_name) == 0) breakl; } endpwent(); return ptr; }
加密口令是通過單項加密算法處理過的用戶口令副本。由於此算法是單向的,因此不能從加密口令猜想到原來的口令。爲了避免讓人得到原始資料(加密口令),如今,某些系統將加密口令存放在另外一個陰影口令(shadow password)文件中。該用戶至少包含用戶名和加密口令。與該口令相關的其餘信息也能夠存放在該文件中。ui
只有用戶登陸名和加密口令這兩個字段是必須的,陰影口令文件不該是通常用戶能夠讀取的。 有一組函數能夠訪問陰影口令文件。加密
#include <shadow.h> struct spwd *getspnam(const char *name); struct spwd *getspent(void); //兩個函數返回值:若成功,返回指針;若出錯,返回NULL void setspent(void); void endspent(void);
字段gr_mem是一個指針數組,其中每一個指針指向一個屬於該組的用戶名。該數組以null指針結尾。 能夠用下面函數查看組名或數值組ID。spa
#include <grp.h> struct group *getgrpid(gid_t gid); struct group *getgrnam(const char *name); //返回值:若成功,返回指針;出錯,返回NULL
這兩個函數也返回一個靜態變量的指針,在每次調用時都重寫該靜態變量。 若要搜索整個組文件,則使用另外幾個函數。
#include <grp.h> struct group *getgrent(void); //返回值:若成功,返回指針;;若出錯或者到達文件尾端,返回NULL void setgrent(void); void endgrent(void);
在UNIX系統中,對組的使用已經作了更改。在V7中,每一個用戶任什麼時候候都只屬於一個組。當用戶登陸時,系統就按口令文件記錄項中的數值組ID,付給他實際組ID。能夠在任什麼時候候執行newgrp(l)以更改組ID。若是newgrp執行成功,則實際組ID更改成新的組ID,將用於後續的文件訪問權限檢查。執行不帶任何參數的newgrp,則可返回到原來的組。
在使用附屬組時,咱們不只能夠屬於口令文件記錄項中組ID所對應的的組,也可屬於多至16個另外的組。文件訪問權限檢查相應的被修改成:不只將進程的有效組ID與文件的組ID進行比較,並且也將全部附屬組ID與文件的組ID進行比較。
使用附屬組ID的有點事沒必要顯式的常常更改組。一個組用戶會參與多個項目,所以也就要同時屬於多個組。
爲了獲取和設置組ID,提供以下函數
#include <unistd.h> int getgroups(int gidsize, gid_t grouplist[]); //返回值:若成功,返回附屬組ID數量;若出錯,返回-1 #include <grp.h> int setgroups(int ngroups, const gid_t grouplist[]); #include <grp.h> int initgroups(const char *username, gid_t basegid); //兩個函數返回值:若成功,返回0;出錯,返回-1
UNIX還有不少其餘文件,如記錄各網絡所提供服務的數據文件(/etc/services),有一個記錄協議信息的數據文件(/etc/networks)。
通常狀況下,對於每一個數據文件至少有3個函數。
以下爲訪問系統數據文件的一些例程:
/* 大多數UNUX系統都提供下列兩個數據文件:utmp文件記錄當前登錄到系統的各個用戶:wtmp文件跟蹤各個登錄和註銷事件。 每次寫入這兩個文件的是包含下列結構的一個二進制記錄: */ struct utmp { char ut_line[8];/* tty line: "ttyh0","ttyd0", "ttyp0,..." */ char ut_name[8]; /*login name*/ long it_time; /*seconds since Epoch*/ };
登陸時,login程序填寫此類型結構,而後將其寫入到utmp文件中,同時也將其添寫到wtmp文件中。註銷時,init進程將utmp文件中相應記錄擦除,並將一個新紀錄添寫到wtmp文件中。在wtmp文件的註銷記錄中,ut_name字段清除爲0.在系統再啓動時,以及更改系統時間和日期的先後,都在wtmp文件中追加特殊的記錄項。who(l)程序讀取utmp文件,並以可讀格式打印其內容。後來的UNIX版本提供last(l)命令,它讀wtmp文件並打印所選擇的記錄。
#include <sys/utsname.h> int uname(struct utsname *name);//返回與主機和操做系統有關的信息 //返回值:若成功,返回非負值;若出錯,返回-1 struct ustname { char sysname[]; //操做系統名稱 char nodename[]; //節點名 char release[]; //當前發行的操做系統 char version[]; //系統版本 char machine[]; //硬件類型名 }; //每一個字符串都以null字節結尾。utsname結構中的信息一般用uname(l)命令打印 /* namelen參數指定name緩衝區長度,如若提供足夠的空間,則經過name返回的字符串以null字節結尾。如若沒有提供足夠的空間,則沒有說明經過name返回的字符串是否以null結尾。 若是宿主主機鏈接到TCP/IP網絡中,則此主機名一般是該主機的完整域名。 hostname(l)命令可用來獲取和設置主機名。 */ #include <unistd.h> int gethostname(char *name, int namelen); //返回值:若成功,返回0;若出錯,返回-1