本章將詳細(xì)介紹SVN權(quán)限配置涉及的兩個(gè)配置文件, svnserve.conf 和 authz.conf,通過(guò)對(duì)配置逐行的描述,來(lái)闡明其中的一些細(xì)節(jié)含義。除此之外的其他配置、安裝等內(nèi)容,不是本文重點(diǎn),讀者若有什么疑問(wèn),請(qǐng)參考后面“參考文獻(xiàn)”中列出的一些文檔。
這里首先要注意一點(diǎn),任何配置文件的有效配置行,都 **不允許存在前置空格** ,否則程序可能會(huì)出錯(cuò),給你一個(gè) ``Option expected`` 的提示。也就是說(shuō),如果你直接從本文的純文本格式中拷貝了相關(guān)的配置行過(guò)去,需要手動(dòng)將前置的4個(gè)空格全部刪除。當(dāng)然了,如果你覺(jué)得一下子要?jiǎng)h除好多行的同樣數(shù)目的前置空格是一件苦差使,那么也許 UltraEdit 的“Column Mode”編輯模式,可以給你很大幫助。
svnserve.conf
-------------
``arm\conf\svnserve.conf`` 文件,是 svnserve.exe 這個(gè)服務(wù)器進(jìn)程的配置文件,我們逐行解釋如下。
首先,我們告訴 svnserve.exe,用戶名與密碼放在 passwd.conf 文件下。當(dāng)然,你可以改成任意的有效文件名,比如默認(rèn)的就是 passwd::
password-db = passwd.conf
接下來(lái)這兩行的意思,是說(shuō)只允許經(jīng)過(guò)驗(yàn)證的用戶,方可訪問(wèn)代碼庫(kù)。 那么哪些是“經(jīng)過(guò)驗(yàn)證的”用戶呢?噢,當(dāng)然,就是前面說(shuō)那些在 passwd.conf 文件里面持有用戶名密碼的家伙。這兩行的等號(hào)后面,目前只允許 read write none 三種值,你如果想實(shí)現(xiàn)一些特殊的值,比如說(shuō)“read-once”之類(lèi)的,建議你自己動(dòng)手改源代碼,反正它也是自由軟件::
anon-access = none
auth-access = write
接下來(lái)就是最關(guān)鍵的一句呢,它告訴 svnserve.exe,項(xiàng)目目錄訪問(wèn)權(quán)限的相關(guān)配置是放在 authz.conf 文件里::
authz-db = authz.conf
當(dāng)然,svn 1.3.2 引入本功能的時(shí)候,系統(tǒng)默認(rèn)使用 authz 而不是 authz.conf 作為配置文件。不過(guò)可能由于鄙人是處女座的,據(jù)說(shuō)有著強(qiáng)烈的完美主義情結(jié),看著 svnserve.conf 有后綴而 passwd 和 authz 沒(méi)有就是不爽,硬是要改了。
上述的 passwd.conf 和 authz.conf 兩個(gè)文件也可以作為多個(gè)代碼庫(kù)共享使用,我們只要將它們放在公共目錄下,比如說(shuō)放在 ``D:\svn`` 目錄下,然后在每個(gè)代碼庫(kù)的 svnserve.conf 文件中,使用如下語(yǔ)句::
password-db = ..\..\passwd.conf
authz-db = ..\..\authz.conf
或者::
password-db = ../../passwd.conf
authz-db = ../../authz.conf
這樣就可以讓多個(gè)代碼庫(kù)共享同一個(gè)用戶密碼、目錄控制配置文件,這在有些情況下是非常方便的。
authz.conf 之用戶分組
---------------------
``arm\conf\authz.conf`` 文件的配置段,可以分為兩類(lèi), ``[group]`` 是一類(lèi),里面放置著所有用戶分組信息。其余以 ``[arm:/]`` 開(kāi)頭的是另外一類(lèi),每一段就是對(duì)應(yīng)著項(xiàng)目的一個(gè)目錄,其目錄相關(guān)權(quán)限,就在此段內(nèi)設(shè)置。
首先,我們將人員分組管理,以便以后由于人員變動(dòng)而需要重新設(shè)置權(quán)限時(shí)候,盡量少改動(dòng)?xùn)|西。我們一共設(shè)置了5個(gè)用戶分組,分組名稱統(tǒng)一采用 ``g_`` 前綴,以方便識(shí)別。當(dāng)然了,分組成員之間采用逗號(hào)隔開(kāi)::
[groups]
# 任何想要查看所有文檔的非本部門(mén)人士
g_vip = morson
# 經(jīng)理
g_manager = michael
# 北京辦人員
g_beijing = scofield
# 上海辦人員
g_shanghai = lincon
# 總部一般員工
g_headquarters = rory, linda
# 小秘,撰寫(xiě)文檔
g_docs = linda
注意到?jīng)]有, linda 這個(gè)賬號(hào)同時(shí)存在“總部”和“文檔員”兩個(gè)分組里面,這可不是我老眼昏花寫(xiě)錯(cuò)了,是因?yàn)?Subversion 允許我這樣設(shè)置。它意味著,這個(gè)家伙所擁有的權(quán)限,將會(huì)比他的同事 rory 要多一些,這樣的確很方便。具體多了哪些呢?請(qǐng)往下看!
authz.conf 之項(xiàng)目根目錄
-----------------------
接著,我們對(duì)項(xiàng)目根目錄做了限制,該目錄只允許arm事業(yè)部的經(jīng)理才能修改,其他人都只能眼巴巴的看著::
[arm:/]
@g_manager = rw
* = r
- ``[arm:/]`` 表示這個(gè)目錄結(jié)構(gòu)的相對(duì)根節(jié)點(diǎn),或者說(shuō)是 arm 項(xiàng)目的根目錄。其中的 arm 字樣,其實(shí)就是代碼庫(kù)的名稱,即前面用 svnadmin create 命令創(chuàng)建出來(lái)的那個(gè) arm。
- 這里的 ``@`` 表示接下來(lái)的是一個(gè)組名,不是用戶名。因?yàn)槟壳?g_manager 組里面只有一個(gè) michael,你當(dāng)然也可以將 ``@g_manager = rw`` 這一行替換成 ``michael = rw`` ,而表達(dá)的意義完全一樣。
- ``*`` 表示“除了上面提到的那些人之外的其余所有人”,也就是“除了部門(mén)經(jīng)理外的其他所有人”,當(dāng)然也包括總經(jīng)理那個(gè)怪老頭
- ``* = r`` 則表示“那些人只能讀,不能寫(xiě)”
authz.conf 之項(xiàng)目子目錄
-----------------------
然后,我們要給總部人員開(kāi)放日志目錄的讀寫(xiě)權(quán)限::
[arm:/diary/headquarters]
@g_manager = rw
@g_headquarters = rw
@g_vip = r
* =
這個(gè)子目錄的設(shè)置有些特色,因?yàn)閺男枨蠓治鲋形覀冎?,這個(gè)子目錄的權(quán)限范圍要比其父目錄小,它不允許除指定了的之外其他任何人訪問(wèn)。在這段設(shè)置中,我們需要注意以下幾點(diǎn):
- 我敢打賭,設(shè)計(jì)svn的家伙們,大部分都是在類(lèi) unix 平臺(tái)下工作,所以他們總喜歡使用 ``/`` 來(lái)標(biāo)識(shí)子目錄,而完全忽視在 MS Windows 下是用 ``\`` 來(lái)做同樣的事情。所以這兒,為了表示 ``diary\headquarters`` 這個(gè)目錄,我們必須使用 ``[arm:/diary/headquarters]`` 這樣的格式。當(dāng)然如果你一定要用 ``\`` ,那么唯一的結(jié)果就是,Subversion 會(huì)將你的這部分設(shè)置置之不理,全當(dāng)沒(méi)看到。
- 這里最后一行的 ``* =`` 表示,除了經(jīng)理、總部人員、特別人士之外,任何人都被禁止訪問(wèn)本目錄。這一行是否可以省略呢?不行,因?yàn)?**權(quán)限具備繼承性** ,子目錄會(huì)自動(dòng)擁有父目錄的權(quán)限。若沒(méi)有這一行,則所有賬號(hào)都可以讀取 ``/diary/headquarters`` 目錄下的文件。因?yàn)殡m然我們并沒(méi)有設(shè)置這個(gè)目錄的父目錄權(quán)限,可是默認(rèn)的規(guī)則使得 ``/diary`` 目錄的權(quán)限與根目錄完全一樣,從而讓其余賬號(hào)獲得對(duì) ``/diary/headquarters`` 目錄的 r 權(quán)限。所以簡(jiǎn)單來(lái)說(shuō), ``* =`` 這一句的目的,就是割斷權(quán)限繼承性,使得管理員可以定制某個(gè)目錄及其子目錄的權(quán)限,從而完全避開(kāi)其父目錄權(quán)限設(shè)置的影響。
- 之所以這兒需要將 ``@g_vip = r`` 一句加上,就是因?yàn)榇嬖谏鲜鲞@個(gè)解釋。如果說(shuō)你沒(méi)有明確地給總經(jīng)理授予讀的權(quán)力,則他會(huì)和其他人一樣,被 ``* =`` 給排除在外。
- 如果眾位看官中間,有誰(shuí)玩過(guò)防火墻配置的話,可能會(huì)感覺(jué)上述的配置很熟悉。不過(guò)這里有一點(diǎn)與防火墻配置不一樣,那就是各個(gè)配置行之間,沒(méi)有 **先后順序** 一說(shuō)。也就是說(shuō),如果我將本段配置的 ``* =`` 這一行挪到最前面,完全不影響整個(gè)配置的最終效果。
接下來(lái)我們看看這一段::
[arm:/ref]
@g_manager = rw
@g_docs = rw
* = r
這里的主要看點(diǎn),就是 g_docs 組里面包含了一個(gè) linda 賬號(hào),她也同時(shí)在 g_headquarters 組里面出現(xiàn),這就意味著, linda 將具備對(duì) ``/ref`` 和 ``diary\headquarters`` 兩個(gè)目錄的讀寫(xiě)權(quán)限。
authz.conf 之目錄表示法
-----------------------
在前面的描述中,我們都采用 ``[repos:/some/dir]`` 這樣的格式來(lái)表示項(xiàng)目的某個(gè)目錄,比如上一小節(jié)中的 ``[arm:/diary/headquarters]`` 。而實(shí)際上,Subversion 允許你采用 ```[/some/dir]`` 這樣的格式,即不指定代碼庫(kù)的方式來(lái)表示目錄,此時(shí)的目錄就匹配所有項(xiàng)目。
對(duì)于使用 svnserve 的用戶來(lái)說(shuō),只有當(dāng) svnserve 運(yùn)行的時(shí)候使用了 ``-r`` 參數(shù),并且讓多個(gè)代碼庫(kù)共享同一個(gè)目錄權(quán)限文件(即 authz.conf 或 authz)時(shí),不指明代碼庫(kù)名稱才有可能惹麻煩。一般情況下,我們對(duì)每個(gè)代碼庫(kù)都會(huì)獨(dú)立使用配置文件,畢竟每個(gè)項(xiàng)目的目錄結(jié)構(gòu),都有很大不同,混在一起意義不大。因此一般來(lái)說(shuō),為簡(jiǎn)潔起見(jiàn),都可以不指明代碼庫(kù)名稱。本文全都指明了代碼庫(kù)名稱,主要是為了將來(lái)擴(kuò)展成同一個(gè)配置文件,以方便配合 Apache 服務(wù)器。
對(duì)于使用 Apache 的用戶來(lái)說(shuō),它們二者可有著很大的不同,因?yàn)榇藭r(shí)往往習(xí)慣于使用一個(gè)公共的目錄權(quán)限配置文件。如果你使用了 SVNParentPath 指令,則指定版本庫(kù)的名字是很重要的,因?yàn)榧偃裟闶褂煤笳?,那?``[/some/dir]`` 部分就會(huì)與所有代碼庫(kù)項(xiàng)目的 ``[/some/dir]`` 目錄匹配。如果你使用 SVNPath 指令,則這兩種表示方式就沒(méi)有什么區(qū)別了,畢竟只有一個(gè)版本庫(kù)。
authz.conf 的其他注意點(diǎn)
-----------------------
1. 父目錄的 ``r`` 權(quán)限,對(duì)子目錄 ``w`` 權(quán)限的影響
把這個(gè)問(wèn)題專門(mén)提出來(lái),是因?yàn)樵?.3.1及其以前的版本里面,有個(gè)bug,即某個(gè)賬號(hào)為了對(duì)某個(gè)子目錄具備寫(xiě)權(quán)限,則必須對(duì)其父目錄具備讀權(quán)限。因此現(xiàn)在使用了1.3.2及其更高的版本,就方便了那些想在一個(gè)代碼庫(kù)存放多個(gè)相互獨(dú)立的項(xiàng)目的管理員,來(lái)分配權(quán)限了。比如說(shuō)央舜公司建立一個(gè)大的代碼庫(kù)用于存放所有員工日志,叫做 diary,而arm事業(yè)部只是其中一個(gè)部門(mén),則可以這樣做::
[diary:/]
@g_chief_manager = rw
[diary:/arm]
@g_arm_manager = rw
@g_arm = r
這樣,對(duì)于所有arm事業(yè)部的人員來(lái)說(shuō),就可以將 svn://192.168.0.1/diary/arm 這個(gè)URL當(dāng)作根目錄來(lái)進(jìn)行日常操作,而完全不管它其實(shí)只是一個(gè)子目錄,并且當(dāng)有少數(shù)好奇心比較強(qiáng)的人想試著 checkout 一下 svn://192.168.0.1/diary 的時(shí)候,馬上就會(huì)得到一個(gè)警告“Access denied”,哇,太酷了。
2. 默認(rèn)權(quán)限
如果說(shuō)我對(duì)某個(gè)目錄不設(shè)置任何權(quán)限,會(huì)怎樣?馬上動(dòng)手做個(gè)試驗(yàn),將::
[diary:/]
@g_chief_manager = rw
改成::
[diary:/]
# @g_chief_manager = rw
這樣就相當(dāng)于什么都沒(méi)有設(shè)置。在我的 svn 1.3.2 版本上,此時(shí)是禁止任何訪問(wèn)。也就是說(shuō),如果你想要讓某人訪問(wèn)某目錄,你一定要顯式指明這一點(diǎn)。這個(gè)策略,看起來(lái)與防火墻的策略是一致的。
3. 只讀權(quán)限帶來(lái)的一個(gè)小副作用
若設(shè)置了::
[arm:/diary]
* = r
則 Subversion 會(huì)認(rèn)為,任何人都不允許改動(dòng) diary 目錄,包括刪除、 **改名** ,和 **新增** 。
也就是說(shuō),如果你在項(xiàng)目初期創(chuàng)建目錄時(shí)候,一不小心寫(xiě)錯(cuò)目錄名稱,比如因拼寫(xiě)錯(cuò)誤寫(xiě)成 dairy,以后除非你改動(dòng) authz.conf 里面的這行設(shè)置,否則無(wú)法利用 svn mv 命令將錯(cuò)誤的目錄更正。
4. anon-access 屬性對(duì)目錄權(quán)限的影響
你想將你的代碼庫(kù)開(kāi)放給所有人訪問(wèn),于是你就開(kāi)放了匿名訪問(wèn)權(quán)限,在 svnserve.conf 文件中添加一行: ``anon-access=read`` ??墒菍?duì)于部分目錄,你又不希望別人看到,于是針對(duì)那些特別目錄,你在 authz.conf 里面進(jìn)行配置,添加了授權(quán)訪問(wèn)的人,并添加了 ``* =`` 標(biāo)記。你認(rèn)為一切OK了,可是你缺發(fā)現(xiàn),那個(gè)特別目錄卻無(wú)法訪問(wèn)了,總是提示 ``Not authorized to open root of edit operation`` 或者 ``未授權(quán)打開(kāi)根進(jìn)行編輯操作`` 。你再三檢查你配置的用戶名與密碼,確認(rèn)一切正確,還是無(wú)法解決問(wèn)題。
原來(lái),Subversion 有個(gè)小 bug ,當(dāng) ``anon-access=read`` 并且某個(gè)目錄有被設(shè)置上 ``* =`` 標(biāo)記,則會(huì)出現(xiàn)上述問(wèn)題。這個(gè) bug 在當(dāng)前最新版本上(v1.4)還存在,也許在下一版本內(nèi)可以被改正吧。
解決的辦法是,在 svnserve.conf 中,將 anon-access 設(shè)置成 none 。
改進(jìn)
====
對(duì)中文目錄的支持
----------------
上午上班的時(shí)候,Morson 來(lái)到 Michael 的桌子前面,說(shuō)道:“你是否可以將我們的北京辦、上海辦目錄,改成用中文的,看著那些拼音我覺(jué)得很難受?” Michael 心想,還好這兩天剛了解了一些與 unicode 編碼相關(guān)的知識(shí),于是微笑地回答:“當(dāng)然可以,你明天下午就可以看到中文目錄名稱了。”
1. 使用 svn mv 指令,將原來(lái)的一些目錄改名并 commit 入代碼庫(kù),改名后的目錄結(jié)構(gòu)如下::
arm
├─工作日志
│ ├─總部人員
│ ├─北京辦
│ └─上海辦
├─公司公共文件參考目錄
└─臨時(shí)文件存放處
2. 修改代碼庫(kù)的 authz.conf 文件,將相應(yīng)目錄逐一改名
3. UTF-8 格式的 authz.conf 文件,以及 BOM
將配置文件轉(zhuǎn)換成 UTF-8 格式之后,Subversion 就能夠正確識(shí)別中文字符了。但是這里需要注意一點(diǎn),即必須保證 UTF-8 文件不包含 BOM 。BOM 是 Byte Order Mark 的縮寫(xiě),指 UNICODE 文件頭部用于指明高低字節(jié)排列順序的幾個(gè)字符,通常是 ``FF FE`` ,而將之用 UTF-8 編碼之后,就是 ``EF BB BF`` 。由于 UTF-8 文件本身不存在字節(jié)序問(wèn)題,所以對(duì) UTF-16 等編碼方式有重大意義的 BOM,對(duì)于 UTF-8 來(lái)說(shuō),只有一個(gè)作用——表明這個(gè)文件是 UTF-8 格式。由于 BOM 會(huì)給文本處理帶來(lái)很多難題,所以現(xiàn)在很多軟件都要求使用不帶 BOM 的 UTF-8 文件,特別是一些處理文本的軟件,如 PHP、 UNIX 腳本文件等,svn 也是如此。
目前常用的一些文本編輯工具中,MS Windows 自帶的“記事本”里面,“另存為”菜單保存出來(lái)的 UTF-8 格式文件,會(huì)自動(dòng)帶上 BOM 。新版本 UltraEdit 提供了選項(xiàng),允許用戶選擇是否需要 BOM,而老版本的不會(huì)添加 BOM。請(qǐng)各位查看一下自己常用的編輯器的說(shuō)明文件,看看它是否支持這個(gè)功能。
對(duì)于已經(jīng)存在 BOM 的 UTF-8 文件,比如說(shuō)就是微軟“記事本”弄出來(lái)的,我們可以利用 UltraEdit 來(lái)將 BOM 去掉。方法是,首先利用“UTF-8 TO ASCII”菜單將文件轉(zhuǎn)換成本地編碼,通常是GB2312碼,然后再使用“ASCII TO UTF-8(UNICODE Editing)”來(lái)轉(zhuǎn)換到 UTF-8 即可。當(dāng)然,這么操作之前,你肯定得先保證,你的 UltraEdit 保存出來(lái)的 UTF-8 文件的確是不帶 BOM 的。
Subversion 為什么討厭 BOM 呢?我不知道,畢竟我也只是一個(gè)普通用戶,不是開(kāi)發(fā)人員。如果你感興趣,并且英文夠好的話,不妨參考一下這個(gè)討論: http://subversion.tigris.org/ser ... ers&msgNo=51334