Dru Lavigne
01/10/2001
在第一部分裡,我們已經考查了用adduser工具建立用戶賬號。在這個部分,我們將集中於建立用戶賬號時所修改的文件。
當超級用戶建立一個用戶賬號時,會在口令數據庫裡添加對應於該用戶的項目。實際上,你的FreeBSD系統需要更新四個口令數據庫文件。讓我們在仔細查看它們的格式之前先介紹一下這些文件。第一個文件稱為/etc/passwd,它是個任何人都能讀的ASCII文本文件:
file /etc/passwd
/etc/passwd: ASCII text
ls -l /etc/passwd
-rw-r--r-- 1 root wheel 1054 Dec 30 13:00 /etc/passwd
該文件的權限必須保持這種形式,否則很多FreeBSD工具就不能工作了。但是,在一個任何人都能讀取的文件中保存口令會有安全風險的;為此,通常對應於口令的那一部分都用*來存儲表示。
第二個文件是影子口令文件/etc/master.passwd。該文件包含用戶口令的加密散列。我們會在將來的文章中詳細討論加密和散列;而現在,把散列想象為FreeBSD用於檢測用戶口令是否合法的值。
讓我們來看一下該文件的類型及屬性:
file /etc/master.passwd
/etc/master.passwd: ASCII text
ls -l /etc/master.passwd
-rw------- 1 root wheel 1226 Dec 30 13:00 /etc/master.passwd
影子口令文件仍然是ASCII明文文本,不過只有root可以讀取了。
第三個和第四個口令文件是/etc/pwd.db和/etc/spwd.db。來看一下它們的文件類型:
file /etc/*pwd.db/etc/pwd.db: Berkeley DB Hash file (Version 2, Little
Endian, Bucket Size 4096, Bucket Shift 12, Directory Size 256, Segment Size 256,
Segment Shift 8, Overflow Point 3, Last Freed 2, Max Bucket 7, High Mask 0xf,
Low Mask 0x7, Fill Factor 32, Number of Keys 56)/etc/spwd.db: Berkeley DB
Hash file (Version 2, Little Endian, Bucket Size 4096, Bucket Shift 12,
Directory Size 256, Segment Size 256, Segment Shift 8, Overflow Point 3, Last
Freed 2, Max Bucket 7, High Mask 0xf, Low Mask 0x7, Fill Factor 32, Number of
Keys 56)
哦,它們干脆就不是ASCII文本文件了,所以就不要試圖用cat、more或文本編輯器來打開它們了。這兩個文件包含了與上面ASCII文本文件相同的信息,而用數據庫的形式就提高了性能。這裡的/etc/pwd.db是與/etc/passwd等價的數據庫,它不包含任何散列。/etc/spwd.db的s表示shadow,所以它就是與etc/master.passwd等價的數據庫,也不包含散列。
現在我們已經熟悉了這四文件的名稱,來看一下它們包含的信息類型。以超級用戶身份把/etc/master.passwd發送到屏幕上,結果看起來應該象這樣:
su:
Password
more /etc/master.passwd
# $FreeBSD: src/etc/master.passwd,v 1.25 1999/09/13 17:09:07 peter Exp $
#
root:{GetProperty(Content)}$hnH/w50a$tPdv5HZRsDP46FtsW8eXH/:0:0::0:0:Charlie &:/root:/bin/csh
toor:*:0:0::0:0:Bourne-again Superuser:/root:
daemon:*:1:1::0:0:Owner of many system processes:/root:/sbin/nologin
operator:*:2:5::0:0:System &:/:/sbin/nologin
bin:*:3:7::0:0:Binaries Commands and Source,,,:/:/sbin/nologin
tty:*:4:65533::0:0:Tty Sandbox:/:/sbin/nologin
kmem:*:5:65533::0:0:KMem Sandbox:/:/sbin/nologin
games:*:7:13::0:0:Games pseudo-user:/usr/games:/sbin/nologin
news:*:8:8::0:0:News Subsystem:/:/sbin/nologin
man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/sbin/nologin
bind:*:53:53::0:0:Bind Sandbox:/:/sbin/nologin
uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/libexec/uucp/uucico
xten:*:67:67::0:0:X-10 daemon:/usr/local/xten:/sbin/nologin
pop:*:68:6::0:0:Post Office Owner:/nonexistent:/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/sbin/nologin
genisis:{GetProperty(Content)}$.3tvchjG$C6wtsUV9FcXF4wzBboisJ/:1001:0::0:0:User &:/home/genisis:/bin/csh
dlavigne:pZV8Ju.2sEqsY:1000:1000::0:0:Dru Lavigne:/home/dlavigne:/bin/tcsh
test::1002:1002::0:0:test:/home/test:/bin/tcsh
看起來是不是不太順?當我們理解了它的格式以後就會容易多了。文件中每一行包含一個用戶的記錄,而每條記錄由十個用冒號分隔的字段組成。這些字段是以下面的順序排列的:
name:hash:uid:gid:class:change:expire:gecos:home_dir:shell
你會注意到我的FreeBSD系統有15個系統建立的系統賬號;最後三個賬號(genisis、dlavigne和test)是由超級用戶建立的。
現在單獨來看一下“dlavigne”這條記錄:
dlavigne:pZV8Ju.2sEqsY:1000:1000::0:0:Dru Lavigne:/home/dlavigne:/bin/tcsh
第一個字段(dlavigne)是該用戶用於登錄到系統時所用的用戶名。
第二個字段(pZV8Ju.2sEqsY)是加密散列;dlavigne很幸運,這並不是她在登錄時鍵入的口令,也無法知道從該文件中讀出的她的實際口令是什麼。但是,注意“test”用戶的第二個字段。因為那裡個空白,就說明該用戶沒有使用口令,只要讀一個該文件就知道了。再注意很多系統賬號的第二個字段都是一個星號(*),這說明普通用戶無法用賬號進行登錄。
full_name,office_location,work_phone,home_phone
所以我知道123-4567是用戶Dru Lavigne的工作電話。
現在,我以超級用戶身份運行chpass。如果我給該命令一個用戶名作為參數的話,我可以編輯屬於該用戶的項。來看一下超級可以為用戶“dlavigne”作些什麼:
chpass dlavigne
#Changing user database information for dlavigne.
Login: dlavigne
Password: pZV8Ju.2sEqsY
Uid [#]: 1000
Gid [# or name]: 1000
Change [month day year]:
Expire [month day year]:
Class:
Home directory: /home/dlavigne
Shell: /bin/tcsh
Full Name: Dru Lavigne
Office Location:
Office Phone: 123-4567
Home Phone:
Other information:
~
/etc/pw.B32584: unmodified: line 1
你應該能看懂該用戶的所有十個字段了吧。超級用戶賬號可以用chpass帶上用戶名作參數來更改任何用戶的記錄。如果超級用戶只鍵入:
chpass
他就可以更改root賬號的記錄了。chpass工具帶有一些開關可使超級用戶用於更改一個用戶記錄的特定字段;請看man 1 chpass的細節。
在所有口令數據庫文件中安全更改用戶口令的工具是passwd。我以“test”用戶登錄然後為該用戶建一個口令:
login: test
注意到沒有提示我輸入口令,因為“test”當前只有一個空口令。我用passwd工具來更改一下:
passwd
Changing local password for test.
New password:
Retype new password:
passwd: updating the database...
passwd: done
通常,當用戶更改他們的口令,系統會提示他們輸入舊口令;這就避免了其他用戶來更改口令了。讓我們再次以“test”運行passwd工具:
passwd
Changing local password for test.
Old password:
New password:
Retype new password:
passwd: updating the database...
passwd: done
如果用戶忘了他們的口令會如何?還沒有徹底完蛋,因為超級用戶可以為他們更改口令;當超級用戶更改其它用戶的口令時,系統就不會提示他輸入該用戶的舊口令了:
su:
Password:
passwd test
Changing local password for test.
New password:
Retype new password:
passwd: updating the database...
passwd: done
注意,超級用戶要使用用戶名作為passwd工具的一個參數;如果不帶用戶名,那更改的就是root賬號的口令了。
我要介紹的最後一個更改口令文件的工具是rmuser。該工具用於刪除用戶賬號和任何與該用戶相關的東西;所以它只能由超級用戶運行。讓我們來刪除“test”賬號:
rmuser
Enter login name for user to remove: test
Matching password entry:
test:{GetProperty(Content)}$P6kMmPWG$rZiu/HfaIPVwJC6hdOImc/:1002:1002::0:0:test:/home/test:/bin/tcsh
Is this the entry you wish to remove? y
Remove user's home directory (/home/test)? y
Killed process(es) belonging to test. 來源:www.Examw.com
Updating password file, updating databases, done.
Updating group file: (removing group test -- personal group is empty) done.
Removing user's home directory (/home/test): done.
Removing user's incoming mail file /var/mail/test: done.
Removing files belonging to test from /tmp: done.
Removing files belonging to test from /var/tmp: done.
Removing files belonging to test from /var/tmp/vi.recover: done.
看,這是個很有效的工具;它不僅從口令文件中刪除用戶信息,還從刪除用戶的主目錄、郵件文件和臨時目錄中屬於該用戶的任何文件。你還應該注意到,在我刪除test用戶前,他的口令字段已經不是空的了,看來passwd工具已經成功更新了口令數據庫。