詳解Samba下的Trivial Database文件
Samba 使用 Trivial Database 文件來(lái)存儲(chǔ)永久性和臨時(shí)性數(shù)據(jù),作為其在 Linux 和 Windows 之間的工作集成文件和打印共享的一部分。本文將主要講解有關(guān) Samba 用來(lái)存儲(chǔ)信息的 Samba Trivial Database (TDB) 格式、如何查看 TDB 文件內(nèi)部以及如何將它們備份的所有信息。
了解 TDB 文件
在運(yùn)行時(shí),Samba 存儲(chǔ)許多信息,從本地密碼到希望從中收到信息的一系列客戶端。這類數(shù)據(jù)其中一些是暫時(shí)的,在 Samba 重啟時(shí)可能會(huì)被丟棄,但是另一些卻是永久的,不會(huì)被丟棄。這類數(shù)據(jù)可能是很大的,也可能是不經(jīng)常訪問(wèn)只是在內(nèi)存中保留,或者在重啟時(shí)保持存在。要滿足這些要求,Samba 團(tuán)隊(duì)創(chuàng)建了 Trivial Database。它實(shí)際上是一個(gè)鍵值存儲(chǔ),這意味著數(shù)據(jù)通過(guò)惟一鍵的方式存儲(chǔ)和檢索,且沒(méi)有像在關(guān)系數(shù)據(jù)庫(kù)中那樣的表聯(lián)接。鍵值存儲(chǔ) — 尤其是 TDB — 被設(shè)計(jì)成將數(shù)據(jù)存儲(chǔ)到磁盤并將其取回的一種快速方式。
鍵值存儲(chǔ)
雖然有許多 TDB 的替代品,例如 GNU 數(shù)據(jù)庫(kù)管理器(GNU Database Manager,GDBM),但是 Samba 項(xiàng)目特別需要多個(gè)進(jìn)程同時(shí)向數(shù)據(jù)庫(kù)寫(xiě)入以及支持鎖定數(shù)據(jù)的內(nèi)部片段。因此,該團(tuán)隊(duì)構(gòu)建了它們自己的數(shù)據(jù)庫(kù)管理器并稱其為 Trivial Database 管理器。通過(guò)集群 TDB(Clustered TDB,CTDB)項(xiàng)目,TDB 已經(jīng)擴(kuò)展為支持集群的操作且可用于其他項(xiàng)目。
如果您熟悉關(guān)系數(shù)據(jù)庫(kù),例如 IBM DB2、MySQL 或 PostgreSQL,則相比之下您將發(fā)現(xiàn)鍵值存儲(chǔ)非常簡(jiǎn)單。關(guān)系數(shù)據(jù)庫(kù)可能有包含多個(gè)列的表,而鍵值存儲(chǔ)實(shí)際上有兩列:鍵列和值列。關(guān)系數(shù)據(jù)庫(kù)使用結(jié)構(gòu)化查詢語(yǔ)言(Structured Query Language,SQL)以便從多個(gè)表和列中提取信息,但是鍵值存儲(chǔ)僅限于對(duì)鍵列的操作。
由于其簡(jiǎn)單,鍵值存儲(chǔ)對(duì)于較小系列的作業(yè)非常有用,而且可以非??焖俚貓?zhí)行那些作業(yè)。鍵值存儲(chǔ)從基本上說(shuō)就是磁盤上的哈希表,因此在無(wú)需借助索引的情況下可以猜測(cè)一塊數(shù)據(jù)的位置。
TDB 特別被編寫(xiě)來(lái)處理許多并發(fā)的編寫(xiě)器和二進(jìn)制數(shù)據(jù),例如內(nèi)部數(shù)據(jù)結(jié)構(gòu)。因此,存儲(chǔ)并檢索此數(shù)據(jù)的最快方式是運(yùn)用二進(jìn)制格式。二進(jìn)制存儲(chǔ)意味著數(shù)據(jù)庫(kù)文件可以更小,且在數(shù)據(jù)移入和移出數(shù)據(jù)庫(kù)時(shí)無(wú)需在不同格式之間轉(zhuǎn)換數(shù)據(jù)。
用于 Samba 的 TDB 文件
Samba 在幾個(gè)不同的地方存儲(chǔ)其 TDB 文件。找到這些文件的最容易方式是查看 smbd -b 的輸出,如清單 1 所示。
清單 1. 顯示 smbd 構(gòu)建信息
# smbd -b ... Paths: SBINDIR: /usr/sbin BINDIR: /usr/bin SWATDIR: /usr/share/swat CONFIGFILE: /etc/samba/smb.conf LOGFILEBASE: /var/log/samba LMHOSTSFILE: /etc/samba/lmhosts LIBDIR: /usr/lib MODULESDIR: /usr/lib/samba SHLIBE1T: so LOCKDIR: /var/lib/samba STATEDIR: /var/lib/samba CACHEDIR: /var/lib/samba PIDDIR: /var/run SMB_PASSWD_FILE: /var/lib/samba/private/smbpasswd PRIVATE_DIR: /var/lib/samba/private
清單 1 中的多個(gè)路徑均指向帶有 TDB 文件的位置。幸運(yùn)的是,許多都是相同的,這會(huì)減少您需要查看的位置。例如,LOCKDIR、STATEDIR 和 CACHEDIR 都指向 /var/lib/samba,且 PRIVATE_DIR 位于稱為私有 的子目錄中。您可以進(jìn)入那些子目錄并查看自己需要的文件。
TDB 文件大致可分為兩組:持久的和臨時(shí)的。表 1 顯示了持久文件的名稱和功能。
Table 1. 持久的 TDB 文件
文件名 | 目的 |
account_policy.tdb | 存儲(chǔ)帳戶策略,例如鎖定閾值和密碼長(zhǎng)度 |
group_mapping.tdb | 存儲(chǔ) Windows NT 用戶標(biāo)識(shí)符 (SID) 和 UNIX® 用戶 ID 之間的關(guān)系 |
ntdrivers.tdb | 存儲(chǔ)有關(guān)打印機(jī)驅(qū)動(dòng)程序的信息 |
ntforms.tdb | 存儲(chǔ)有關(guān)打印隊(duì)列形式的信息 — 例如,紙張大小 |
ntprinters.tdb | 存儲(chǔ)有關(guān)打印機(jī)初始化設(shè)置的信息 |
passdb.tdb | 僅用于一些安全模式以便存儲(chǔ)認(rèn)證證書(shū) |
registry.tdb | 可通過(guò)其他 Windows 系統(tǒng)訪問(wèn)的骨架注冊(cè)表 |
secrets.tdb | 存儲(chǔ)本地秘密,例如類似輕量級(jí)目錄訪問(wèn)協(xié)議(Lightweight Directory Access Protocol,LDAP)密碼的工作站計(jì)算機(jī)密鑰和憑證 |
share_info.tdb | 為每一個(gè)本地共享存儲(chǔ)訪問(wèn)控件列表(Access Control List,ACL)信息 |
winbindd_idmap.tdb | 如果您正在使用 winbind,那么持久存儲(chǔ) Windows NT SID 和動(dòng)態(tài)創(chuàng)建的用戶之間的映射信息 |
應(yīng)該備份如表 1 所示的 TDB 文件。本文后面會(huì)提供此操作的過(guò)程。
另外,存在許多存儲(chǔ)狀態(tài)信息和緩存數(shù)據(jù)的臨時(shí) TDB 文件。因?yàn)樵?Samba 啟動(dòng)時(shí)會(huì)重建這些文件,所以無(wú)需備份它們。
#p#
使用 TDB 文件
Samba 附帶了三種用于處理 TDB 文件的工具:
●tdbdump:打印 TDB 文件的內(nèi)容。
●tdbbackup:備份并驗(yàn)證 TDB 文件。
●tdbtool:創(chuàng)建、查看并修改 TDB 文件。
快速查看 TDB 文件內(nèi)部
查看 TDB 文件中的內(nèi)容的最快方式是通過(guò) tdbdump 命令將其轉(zhuǎn)儲(chǔ)。清單 2 顯示了 ntprinters.tdb 文件的轉(zhuǎn)儲(chǔ)。
清單 2. 在 TDB 文件上使用 tdbdump
[root@bob ~]# tdbdump /var/lib/samba/ntprinters.tdb { key(21) = "GLOBALS/c_setprinter\00" data(4) = "\00\00\00\00" } { key(13) = "SECDESC/test\00" data(140) = "\80\00\00\00\00\00\02\00\80\00\00\00\01\00\04\80\14\00\00\00$\00\00 \00\00\00\00\004\00\00\00\01\02\00\00\00\00\00\05 \00\00\00 \02\00\00\01\02\00\00 ... \00 \02\00\00\00\02\18\00\0C\00\0F\10\01\02\00\00\00\00\00\05 \00\00\00 \02\00\00" } { key(17) = "SECDESC/cups-pdf\00" data(140) = "\80\00\00\00\00\00\02\00\80\00\00\00\01\00\04\80\14\00\00\00$\00\00 \00\00\00\00\004\00\00\00\01\02\00\00\00\00\00\05 \00\00\00 \02\00\00\01\02\00\00 ... \00 \02\00\00\00\02\18\00\0C\00\0F\10\01\02\00\00\00\00\00\05 \00\00\00 \02\00\00" }
從清單 2 的輸出,您可以看到在數(shù)據(jù)庫(kù)中有三個(gè)鍵。第一個(gè)鍵為 21 字節(jié)(字節(jié)長(zhǎng)度顯示在括號(hào)中 [()]),被稱為GLOBALS/c_setprinter,后跟 NULL,其為 ASCII 碼零。非輸出字符用十六進(jìn)制格式顯示,其是后跟兩個(gè)十六進(jìn)制字符的反斜線。第一個(gè)鍵的值為 4 字節(jié)且其完全為 NULL。
接下來(lái)的兩個(gè)鍵被稱為 SECDESC/test 和 SECDESC/cups-pdf 且兩個(gè)都是以 NULL 結(jié)束。因?yàn)樵摂?shù)據(jù)完全是二進(jìn)制且不可輸出,所以已經(jīng)以十六進(jìn)制格式的非輸出字符輸出了。
備份并恢復(fù) TDB 文件
表 1 顯示了幾種在重啟持久存在并應(yīng)該備份的 TDB 文件。像大多數(shù)數(shù)據(jù)庫(kù)那樣,您不能只復(fù)制文件,因?yàn)閺?fù)制可能會(huì)損壞。如果文件正在被寫(xiě)入時(shí)您復(fù)制該文件,會(huì)發(fā)生備份損壞,從而您具有處于不一致?tīng)顟B(tài)的備份。一個(gè)替代辦法是關(guān)閉 Samba 守護(hù)進(jìn)程,然后復(fù)制這些文件。
備份 TDB 文件最容易的方式是使用 Samba 附帶的 tdbbackup 實(shí)用工具。此實(shí)用工具可以安全復(fù)制 TDB 文件,即使其正在被積極地寫(xiě)入。tdbbackup 的另一幫助功能是可以查看 TDB 文件是否損壞,且如果發(fā)現(xiàn)損壞則自動(dòng)恢復(fù)為備份文件。清單 3 顯示了正在備份的 TDB 文件。
清單 3. 備份 TDB 文件
[root@bob samba]# ls -l account_policy.* -rw------- 1 root root 8192 Apr 7 2008 account_policy.tdb [root@bob samba]# tdbbackup account_policy.tdb [root@bob samba]# ls -l account_policy.* -rw------- 1 root root 8192 Apr 7 2008 account_policy.tdb -rw------- 1 root root 36864 Dec 8 21:42 account_policy.tdb.bak [root@bob samba]# tdbdump account_policy.tdb | md5sum 53ea608f0d93061480549c511756b778 - [root@bob samba]# tdbdump account_policy.tdb.bak | md5sum 53ea608f0d93061480549c511756b778 -
清單 3 中的第一個(gè)命令簡(jiǎn)要列出了所有以 account_policy 開(kāi)始的文件,以便確認(rèn)只存在一份副本。接下來(lái)通過(guò)運(yùn)行 tdbbackup account_policy.tdb 來(lái)備份帳戶策略數(shù)據(jù)庫(kù)。第三個(gè)命令尋找任何以 account_policy 開(kāi)始的文件,以便顯示已經(jīng)創(chuàng)建的帶有 .bak 擴(kuò)展名的新文件。雖然大小不同于原文件,但是轉(zhuǎn)儲(chǔ)每一個(gè)文件并計(jì)算 MD5 哈希顯示了它們的校驗(yàn)和是相同的。因此更大的文件大小并不是問(wèn)題,因?yàn)槊總€(gè)鍵值對(duì)的內(nèi)容是相同的。
如果由于某種原因原始的 account_policy.tdb 文件受到損壞,例如在系統(tǒng)不正常關(guān)機(jī)期間,您可以從其備份恢復(fù)舊的文件。清單 4 顯示了此過(guò)程。
清單 4. 驗(yàn)證并恢復(fù) TDB 文件
[root@bob samba]# ls -l account_policy.tdb -rw------- 1 root root 1213 Dec 8 21:49 account_policy.tdb [root@bob samba]# tdbbackup -v account_policy.tdb tdb_oob len 1256 beyond eof at 1213 restoring account_policy.tdb [root@bob samba]# ls -l account_policy.tdb* -rw------- 1 root root 36864 Dec 8 21:49 account_policy.tdb -rw------- 1 root root 36864 Dec 8 21:42 account_policy.tdb.bak [root@bob samba]# tdbbackup -v account_policy.tdb account_policy.tdb : 17 records [root@bob samba]# tdbdump account_policy.tdb | md5sum 53ea608f0d93061480549c511756b778 -
清單 4 中的第一個(gè)命令顯示文件大小已經(jīng)顯著地減少。tdbbackup 命令再次運(yùn)行,但是帶有 -v 標(biāo)記,其驗(yàn)證 TDB 文件。如果該文件受到損壞,您將看到錯(cuò)誤摘要,后面是文件已經(jīng)恢復(fù)的通知。通過(guò) ls 命令比較文件的大小,您可以看到備份被用于替換當(dāng)前的數(shù)據(jù)庫(kù)。
您可以安全地多次運(yùn)行 tdbbackup 命令。在有效的數(shù)據(jù)庫(kù)文件上運(yùn)行它,類似 清單 4 中的倒數(shù)第二個(gè)命令, 則會(huì)提供文件中的記錄數(shù)。MD5 總和與損壞之前所看到的相匹配。
注意:tdbbackup 命令接受通配,所以您可以同時(shí)備份并驗(yàn)證多個(gè)文件。
變更 TDB 文件
tdbtool 實(shí)用工具使您可以更改 TDB 文件內(nèi)部的數(shù)據(jù)。此實(shí)用工具還檢查文件內(nèi)的個(gè)別鍵和值,而不必轉(zhuǎn)儲(chǔ)整個(gè)文件并對(duì)整個(gè)輸出排序。
tdbtool 可在命令行上接受命令,或者您可以打開(kāi)交互式控制臺(tái)。要在命令行上完成任務(wù),請(qǐng)運(yùn)行 tdbtool example.tdb command options,其中 example.tdb 是文件名,command 是命令,針對(duì)命令的選項(xiàng)位于最后。要使用 tdb shell,只需單獨(dú)運(yùn)行 tdbtool 或在命令行上傳遞文件的名稱。
要?jiǎng)?chuàng)建數(shù)據(jù)庫(kù),請(qǐng)單獨(dú)運(yùn)行 tdbtool,然后輸入 create test.tdb。這樣做可以在磁盤上創(chuàng)建名為 test.tdb 的數(shù)據(jù)庫(kù)并打開(kāi)它以便您在此會(huì)話中進(jìn)行的任何變更都在該文件上。如果您有現(xiàn)成的 TDB 文件,您可以在命令行上指定該名稱或使用 open 命令。奇怪的是,直接從命令行創(chuàng)建 TDB 文件的惟一方式涉及指定名稱兩次,例如 tdbtool test.tdb create test.tdb,其返回一個(gè)錯(cuò)誤但成功地創(chuàng)建一個(gè)數(shù)據(jù)庫(kù)。
在您創(chuàng)建完數(shù)據(jù)庫(kù)或者打開(kāi)現(xiàn)有數(shù)據(jù)庫(kù)時(shí),可以使用以下選項(xiàng):
●dump:顯示數(shù)據(jù)庫(kù)中的所有內(nèi)容,就像 tdbdump。
●keys:只以 ASCII 顯示鍵,或通過(guò) hexkeys 命令,用十六進(jìn)制格式顯示它們。
●erase:在沒(méi)有提示的情況下刪除數(shù)據(jù)庫(kù)中的所有內(nèi)容。
●info:顯示數(shù)據(jù)庫(kù)使用的鍵和字節(jié)數(shù)的概要。
●check:查看數(shù)據(jù)庫(kù)是否有效。
●speed:執(zhí)行測(cè)試以便查看數(shù)據(jù)以多快的速度讀取并寫(xiě)入數(shù)據(jù)庫(kù)。
●show key:輸出與鍵存儲(chǔ)在一起的值。
●delete key:刪除鍵和值。
要添加并處理數(shù)據(jù),您需要有 insert 和 store 命令。它們每一個(gè)都接受鍵和值的參數(shù),值為可選。如果您不指定一個(gè)值,那么您將看到鍵在值中存儲(chǔ)零字節(jié)數(shù)據(jù)。
插入記錄 意味著創(chuàng)建新的記錄,而存儲(chǔ)記錄 可以覆蓋現(xiàn)有的條目。清單 5 顯示了這兩個(gè)命令之間的差異。
清單 5. 存儲(chǔ)與插入記錄
tdb> insert mykey myvalue tdb> insert mykey newvalue insert failed tdb> store mykey newvalue Storing key: key 5 bytes mykey data 8 bytes [000] 6E 65 77 76 61 6C 75 65 newvalue tdb> store newkey someothervalue Storing key: key 6 bytes newkey data 14 bytes [000] 73 6F 6D 65 6F 74 68 65 72 76 61 6C 75 65 someothe rvalue
清單 5 中的事件順序是:
1、插入名為 mykey 的鍵,具有值 myvalue。此操作成功。
2、插入與以前名稱相同的鍵但是具有新的值。此操作失敗,因?yàn)殒I已經(jīng)存在。
3、存儲(chǔ)鍵而不是插入它。此操作成功,且您將獲得更詳細(xì)的輸出。
4、存儲(chǔ)具有新值的新鍵。即使鍵不存在此操作也會(huì)成功。
您可以在 tdb shell 中使用事務(wù),以便允許您運(yùn)行一系列命令并作為一個(gè)組應(yīng)用它們,或者作為一個(gè)組取消它們。清單 6 顯示了兩個(gè)事務(wù)。
清單 6. 使用事務(wù)
tdb> transaction_start tdb> insert somekey somevalue tdb> show somekey key 7 bytes somekey data 9 bytes [000] 73 6F 6D 65 76 61 6C 75 65 somevalu e tdb> transaction_cancel tdb> show somekey fetch failed tdb> transaction_start tdb> insert somekey somevalue tdb> transaction_commit tdb> show somekey key 7 bytes somekey data 9 bytes [000] 73 6F 6D 65 76 61 6C 75 65 somevalu e
該事務(wù)首先以 transaction_start 命令開(kāi)始。下一步是插入一個(gè)鍵。如果另一個(gè)進(jìn)程要讀取數(shù)據(jù)庫(kù),則不會(huì)看到此鍵,因?yàn)樗菦](méi)有提交。打開(kāi)該事務(wù)的進(jìn)程確實(shí)可以看到該鍵。然后,通過(guò) transaction_cancel 取消該事務(wù)。該鍵不再出現(xiàn)。
然后重新運(yùn)行該進(jìn)程,但是通過(guò) transaction_commit 提交事務(wù)。然后該鍵對(duì)于所有讀取器都存在。
如果您位于事務(wù)中,則其他讀取器可能受阻,這意味著它們將掛起直到事務(wù)完成。所以當(dāng)在生產(chǎn)數(shù)據(jù)庫(kù)中使用事務(wù)時(shí)請(qǐng)小心!雖然它們是非常安全的功能,但是如果過(guò)度使用就會(huì)潛在地傷害性能。#p#
超越 TDB
根據(jù)您的配置,用戶帳戶可存儲(chǔ)在各種不同的位置,兩種工具為您提供一種命令行界面,同時(shí)也考慮到后端通信。例如,您可以使用相同的命令,即使用戶數(shù)據(jù)存儲(chǔ)在 LDAP 中而不是 TDB 文件中。
使用 smbpasswd
smbpasswd 實(shí)用工具可添加并刪除用戶或計(jì)算機(jī)帳戶并變更密碼。其最常用于執(zhí)行后面的任務(wù),更改當(dāng)前用戶的密碼,或者根本更改其他用戶的密碼。
在后面的文章中,您將更深入地了解有關(guān)不同密碼后端的信息,但是在較高的等級(jí)上,Samba 密碼可以用幾種不同的方式進(jìn)行存儲(chǔ),這取決于 Samba 的制作時(shí)間和您正在集成的系統(tǒng)。smbpasswd 和 pdbedit(下面將進(jìn)行描述)可以針對(duì)任何后端(即使它不是 TDB)執(zhí)行其操作。
Microsoft 客戶端以 Microsoft 專用的哈希而不是純文本或 UNIX 密碼哈希形式在網(wǎng)絡(luò)中傳遞密碼。這意味著無(wú)法采用 Microsoft 密碼哈希并確定該密碼是否與存儲(chǔ)在 UNIX 密碼數(shù)據(jù)庫(kù)中的密碼相同。因此,Samba 必須為 Microsoft 哈希保留單獨(dú)的密碼數(shù)據(jù)庫(kù);這就被稱為密碼后臺(tái)。
使用 pdbedit
pdbedit 管理 Samba 用戶數(shù)據(jù)庫(kù)和帳戶策略。它可以做任何事情,從而 smbpasswd 可以增加管理策略并在不同后臺(tái)之間遷移帳戶。
要顯示數(shù)據(jù)庫(kù)中的所有用戶,請(qǐng)運(yùn)行 pdbedit -L。通過(guò)傳遞 -v 標(biāo)記,您可以獲得有關(guān)用戶的更多詳細(xì)資料,如清單 7 所示。
清單 7. 用戶的詳細(xì)清單
[root@bob tmp]# pdbedit -L -v --------------- Unix username: sean NT username: Account Flags: [U ] User SID: S-1-5-21-2287037134-1443008385-640796334-1001 Primary Group SID: S-1-5-21-2287037134-1443008385-640796334-513 Full Name: Sean Home Directory: \\bob\sean HomeDir Drive: Logon Script: Profile Path: \\bob\sean\profile Domain: BOB Account desc: Workstations: Munged dial: Logon time: 0 Logoff time: never Kickoff time: never Password last set: Mon, 24 May 2010 21:28:49 CDT Password can change: Mon, 24 May 2010 21:28:49 CDT Password must change: never Last bad password : 0 Bad password count : 0 Logon hours : FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
您必須作為 root 用戶登錄,pdbedit 命令才能工作。您可以編輯各種用戶設(shè)置,例如最后登錄時(shí)間、密碼變更以及主目錄,就像您正在使用 Microsoft 實(shí)用工具一樣。
每一個(gè)用戶參數(shù)都有自己的命令行選項(xiàng),為了獲得細(xì)節(jié),請(qǐng)查看 pdbedit(8) 聯(lián)機(jī)幫助頁(yè)。
同樣重要的是,要注意 Samba 用類似的方式處理計(jì)算機(jī)帳戶和用戶帳戶。清單 8 顯示了配置為域控制器的 Samba 服務(wù)器的密碼數(shù)據(jù)庫(kù)。
清單 8. 密碼數(shù)據(jù)庫(kù),包括計(jì)算機(jī)帳戶
[root@sergeant ~]# pdbedit -L root:0:root mythupstairs$:4294967295:MYTHUPSTAIRS BOB$:1043:Machine sean:1002:Sean,,, sergeant$:4294967295:Machine
以美元符號(hào) ($) 結(jié)束的名稱都是計(jì)算機(jī)帳戶,用于向域驗(yàn)證計(jì)算機(jī)。相應(yīng)的秘密將存儲(chǔ)在遠(yuǎn)程服務(wù)器中的 secrets.tdb 上和域控制器中的 passdb.tdb 上。
【編輯推薦】