国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統 > Linux > 正文

《Linux/Unix系統編程手冊》讀書筆記5

2024-06-28 13:26:45
字體:
來源:轉載
供稿:網友
《linux/Unix系統編程手冊》讀書筆記5

《Linux/Unix系統編程手冊》讀書筆記 目錄

第8章

本章講了用戶和組,還有記錄用戶的密碼文件/etc/passwd,shadow密碼文件/etc/shadow還有組文件/etc/group。

每個用戶都有唯一的用戶名和相關的用戶標識符(UID)。用戶可以屬于一個或多個組,每個組都有唯一的組名和相關的組標識符(GID)。

用戶和組的用途為:1、可以確定各種系統資源的所有權;2、對賦予進程訪問上述資源的權限加以控制。

首先來看一下密碼文件/etc/passwd

lancelot@debian:~$ cat /etc/passwdroot:x:0:0:root:/root:/bin/bashdaemon:x:1:1:daemon:/usr/sbin:/bin/shbin:x:2:2:bin:/bin:/bin/shsys:x:3:3:sys:/dev:/bin/shsync:x:4:65534:sync:/bin:/bin/syncgames:x:5:60:games:/usr/games:/bin/shman:x:6:12:man:/var/cache/man:/bin/shlp:x:7:7:lp:/var/spool/lpd:/bin/shmail:x:8:8:mail:/var/mail:/bin/shnews:x:9:9:news:/var/spool/news:/bin/shuucp:x:10:10:uucp:/var/spool/uucp:/bin/shPRoxy:x:13:13:proxy:/bin:/bin/shwww-data:x:33:33:www-data:/var/www:/bin/shbackup:x:34:34:backup:/var/backups:/bin/shlist:x:38:38:Mailing List Manager:/var/list:/bin/shirc:x:39:39:ircd:/var/run/ircd:/bin/shgnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/shnobody:x:65534:65534:nobody:/nonexistent:/bin/shlibuuid:x:100:101::/var/lib/libuuid:/bin/shmessagebus:x:101:105::/var/run/dbus:/bin/falsecolord:x:102:106:colord colour management daemon,,,:/var/lib/colord:/bin/falseusbmux:x:103:46:usbmux daemon,,,:/home/usbmux:/bin/falseDebian-exim:x:104:112::/var/spool/exim4:/bin/falseavahi:x:105:115:Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/falsepulse:x:106:116:PulseAudio daemon,,,:/var/run/pulse:/bin/falsespeech-dispatcher:x:107:29:Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/shhplip:x:108:7:HPLIP system user,,,:/var/run/hplip:/bin/falsesshd:x:109:65534::/var/run/sshd:/usr/sbin/nologinrtkit:x:110:118:RealtimeKit,,,:/proc:/bin/falsestatd:x:111:65534::/var/lib/nfs:/bin/falsesaned:x:112:119::/home/saned:/bin/falseDebian-gdm:x:113:120:Gnome Display Manager:/var/lib/gdm3:/bin/falselancelot:x:1000:1000:lancelot,,,:/home/lancelot:/bin/bashMySQL:x:114:121:MySQL Server,,,:/nonexistent:/bin/falseftp:x:115:122:ftp daemon,,,:/srv/ftp:/bin/falsetelnetd:x:116:124::/nonexistent:/bin/false

第一個字段是登錄名;第二個字段是經過加密后的密碼(x),實際上經過加密后的密碼是存放在shadow密碼文件;

第三個字段是用戶的ID(UID);第四個字段是組ID(GID);第五個字段是注釋;

第六個字段是主目錄,是用戶登錄后的初始路徑;第七個字段是登錄shell。

接著來看實際存放密碼的shadow 密碼文件/etc/shadow

格式如下:

lancelot:$6$tnTgvJYU$OhoUNZNIeNU7rlZf/f14oD2g.Uz8SbrnWeZbR4yL4XXRvzbCeijsAZE7Y9HlzU4thKVBVcqucwntJBi/4BoY60:15880:0:99999:7:::mysql:!:15905:0:99999:7:::ftp:*:16039:0:99999:7:::telnetd:*:16180:0:99999:7:::

很明顯可以看到第一個字段為用戶登錄名,第二個字段為見過加密后的密碼,后面的字段為與安全性相關的字段。

看完用戶,我們來看組文件/etc/group

lancelot@debian:~$ cat /etc/grouproot:x:0:daemon:x:1:bin:x:2:sys:x:3:adm:x:4:tty:x:5:disk:x:6:lp:x:7:mail:x:8:news:x:9:uucp:x:10:man:x:12:proxy:x:13:kmem:x:15:dialout:x:20:fax:x:21:voice:x:22:cdrom:x:24:lancelotfloppy:x:25:lancelottape:x:26:sudo:x:27:audio:x:29:pulse,lancelotdip:x:30:lancelotwww-data:x:33:backup:x:34:Operator:x:37:list:x:38:irc:x:39:src:x:40:gnats:x:41:shadow:x:42:utmp:x:43:telnetdvideo:x:44:lancelotsasl:x:45:plugdev:x:46:lancelotstaff:x:50:games:x:60:users:x:100:nogroup:x:65534:libuuid:x:101:crontab:x:102:fuse:x:103:scanner:x:104:saned,lancelotmessagebus:x:105:colord:x:106:lpadmin:x:107:ssl-cert:x:108:bluetooth:x:109:lancelotutempter:x:110:netdev:x:111:lancelotDebian-exim:x:112:mlocate:x:113:ssh:x:114:avahi:x:115:pulse:x:116:pulse-access:x:117:rtkit:x:118:saned:x:119:Debian-gdm:x:120:lancelot:x:1000:mysql:x:121:ftp:x:122:vboxusers:x:123:telnetd:x:124:

第一個字段是組的名稱,第二個字段是經過加密的密碼,第三個字段是組ID(GID),第四個字段是用戶列表。

對于加密后的密碼存放在類似/etc/shadow的文件(/etc/gshadow),格式如下:

cdrom:*::lancelotfloppy:*::lancelottape:*::sudo:*::audio:*::pulse,lancelotdip:*::lancelotwww-data:*::backup:*::operator:*::list:*::irc:*::src:*::gnats:*::shadow:*::utmp:*::telnetdvideo:*::lancelot

最后一個字段很明顯是用戶列表。

接著,我們來看如何通過庫函數來獲取上面提到的信息。

一、從/etc/shadow獲取記錄:

1 #include <pwd.h>2 3 struct passwd *getpwnam(const char *name);4 5 struct passwd *getpwuid(uid_t uid);

getpwnam()是根據提供的登錄名返回一個指向對應的密碼記錄的指針。getpwuid()是根據提供的uid來返回一個指向對應的密碼記錄的指針。

如果出現錯誤返回NULL。

PS:對于getpwnam和getpwuid返回的指針都是指向由靜態分配而成的內存,因此都是不可重入。

這個應該是練習8-1的答案。

8-1:執行下列代碼時,將會發現,盡管這兩個用戶在密碼文件中對應不同的ID,但該程序的輸出還是會將同一個數字顯示兩次。請問為什么?

printf("%ld %ld/n", (long)(getpwnam("avr")->pw_uid), (long)(getpwnam("tsr")->pw_uid));

書本的答案是這樣的:getpwnam()的調用在printf()輸出之前,那么getpwnam()返回的結果存放在靜態分配的緩沖區中,第二個getpwnam()的返回結果會覆蓋第一個的結果。

然后我測試了一下,代碼如下:

 1 /* 2  * ===================================================================================== 3  * 4  *       Filename:  tt1.c 5  * 6  *    Description:   7  * 8  *        Version:  1.0 9  *        Created:  2014年04月22日 14時56分10秒10  *       Revision:  none11  *       Compiler:  gcc12  *13  *         Author:  alan (), alan19920626@Gmail.com14  *   Organization:  15  *16  * =====================================================================================17  */18 19 #include <stdio.h>20 #include <pwd.h>21 22 int main(int argc, char *argv[]){23     printf("%ld %ld/n", (long)(getpwnam("lancelot")->pw_uid), (long)(getpwnam("root")->pw_uid));24     return 0;25 }
View Code

測試結果:

lancelot@debian:~/Code/tlpi$ ./a.out 1000 0

然后整個人就凌亂了。。。。。。。。。。。。。。

后來,我把程序改成這樣:

 1 #include <stdio.h> 2 #include <pwd.h> 3  4 int main(int argc, char *argv[]){ 5     struct passwd *p1, *p2; 6     p1 = getpwnam("lancelot"); 7     p2 = getpwnam("root"); 8     printf("%ld %ld/n", p1->pw_uid, p2->pw_uid); 9     //printf("%ld %ld/n", (long)(getpwnam("lancelot")->pw_uid), (long)(getpwnam("root")->pw_uid));10     return 0;11 }

才能輸出相同的值,因為兩個指針變量指向的地址是一樣的。但是之前那種是正確的,因為函數的參數是一值傳遞的方式傳遞,所以不存在題目說的兩個值相同。

后來我查找了作者的網站的磡誤:http://www.man7.org/tlpi/errata/index.html

發現這條題的題目修改了!!!!!!

這樣傳遞指針,兩個輸出的名字就是一樣的。。。。。。。。。。。。。。

下面是作者的解釋:

好吧,以后還要把書上的錯誤修改。。。。。。。

PS:再次證明不管例子多簡單也要試一試。。。。。

二、從/etc/group獲取記錄

1 #include <grp.h>2 3 struct group *getgrnam(const char *name);4 5 struct group *getgrgid(gid_t gid);

getgrnam根據提供的組名返回指向組的密碼記錄的指針,getgrigid則根據提供的組號GID返回該指針。失敗調用返回NULL

PS:這兩個函數也是不可重入的函數。

三、掃描密碼文件和組文件

1 #include <pwd.h>2 3 struct passwd *getpwent(void);4 5 void setpwent(void);6 7 void endpwent(void);

getpwent()可以逐條返回記錄。setpwent()可以重置為。/etc/passwd文件的起始處。endpwent()可以關閉文件。

四、從/etc/shadow密碼文件中獲取記錄

1 #include <shadow.h>2 3 struct spwd *getspnam(const char *name);4 5 struct spwd *getspent(void);6 7 void setspent(void);8 9 void endspent(void);

getspnam和getspent會返回指向shadow密碼記錄的指針,失敗調用返回NULL。

setspent會重置為文件的起始位置,endspent會關閉文件。

五、密碼加密

1 #define _XOPEN_SOURCE2 #include <unistd.h>3 4 char *crypt(const char *key, const key *salt);

#define _XOPEN_SOURCE 是為了獲取crypt的聲明。

key為輸入的密碼,salt指向一個兩字節的字符串,用來改變DES算法。成功調用返回加密后的密碼,失敗返回NULL。

---------------------吐槽:好好寫博客,寫博客的時候思考的感覺真好,要多讀書,多code,多思考---------------------------

聽同學說有很多厲害的人已經找到實習了,真的后悔大一大二的無作為。正因為后悔,所以要做得更好!!!!

繼續努力!!!!!!

---------------------------------------------------------------------------------------------------------------------------------------------------

練習:

8-2: 使用sptwent()、getpwent()和endpwent()來實現getpwnam()。

這題個人覺得很簡單,因為getpwent()是逐條查找,查找匹配就輸出。輸出完應該調用sptwent將文件的偏移量重置為文件的起始位置。結束的時候調用endpwent關閉文件。

 1 /* 2  * ===================================================================================== 3  * 4  *       Filename:  8-2.c 5  * 6  *    Description:   7  * 8  *        Version:  1.0 9  *        Created:  2014年04月22日 16時48分09秒10  *       Revision:  none11  *       Compiler:  gcc12  *13  *         Author:  alan (), alan19920626@gmail.com14  *   Organization:  15  *16  * =====================================================================================17  */18 19 #include <pwd.h>20 #include <string.h>21 #include <stdio.h>22 #include "tlpi_hdr.h"23 24 struct passwd * Getpwnam(const char *name){25     struct passwd *pwd;26     while((pwd = getpwent()) != NULL){27         if(strcmp(pwd->pw_name, name) == 0){28             setpwent();29             return pwd;30         }31     }32     setpwent();33     return NULL;34 }35 36 int main(int argc, char *argv[]){37     int i;38     struct passwd *p;39     if(argc < 2 || strcmp(argv[1], "--help") == 0)40         usageErr("%s user-names...", argv[0]);41 42     for(i = 1; i < argc; ++i){43         p = Getpwnam((const char *)argv[i]);44         if(p == NULL)45             printf("%s does not exit/n", argv[i]);46         else{47             printf("%s, UID: %ld, GID: %ld/n", argv[i], (long)p->pw_uid, (long)p->pw_gid);48         }49     }50     51     endpwent();52     exit(EXIT_SUCCESS);53 }

測試結果:

lancelot@debian:~/Code/tlpi$ ./a.out lancelot rootlancelot, UID: 1000, GID: 1000root, UID: 0, GID: 0


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 房山区| 镇原县| 肇庆市| 民丰县| 宾川县| 永昌县| 怀来县| 象山县| 体育| 合肥市| 揭阳市| 青海省| 黎平县| 宿迁市| 西乌珠穆沁旗| 陆河县| 太原市| 内黄县| 泰州市| 饶阳县| 曲松县| 安龙县| 德化县| 青阳县| 囊谦县| 资中县| 喀喇沁旗| 略阳县| 集贤县| 屏山县| 元谋县| 马公市| 东山县| 大同市| 沿河| 射洪县| 隆德县| 灵丘县| 灵石县| 友谊县| 连州市|