maildrop - Webmail dev problem - 解決了幾個隱晦問題

這兩天解決了幾個開發中遇到的疑難雜症,特此篆文記錄。

無論在軟件項目的實施,還是系統的開發甚至只是編寫一小段代碼,經常會遇到一些讓人白思不得其解的問題,耗費了大量的時間,用盡了辦法卻位能解決。感覺就有點得了疑難雜症,便訪天下名醫卻不得根治一樣。

但最後發現這些問題的症結,往往都是很小小的問題,卻不爲人所注意,或者隱藏得非常深入,常人難以發現。

Maildrop 的0x0B故障分析及解決

使用maildrop作爲VDA/MDA的用戶爲數不少,絕大多數用戶使用maildrop都是因爲其過濾能力強,過濾語言靈活,支持Quota,並可與MySQL/LDAP及小型dbm對接,可外挂各種程序,如SpamAssassin,殺毒軟件,甚至SMS等,實現複雜的功能。

但是maildrop常見的一個問題就是經常會遇到0x0B的意外退出問題。除了編譯器(使用的Gcc c++版本問題)和編譯優化指令太高(如高于O2等)的問題外,還有少數問題是不爲人們所注意的。

在自己開發一個全新的webmail系統中,maildrop的投遞uid/gid都是250,這樣的配置跑了幾年都沒任何問題,工作得非常可靠。但是由于webmail需要直讀Maildir,按常規的方法必須設置成setuid/gid程序,或將apache的User/Group設置成250,這樣非常麻煩,尤其在新的SELinux下會造成諸多不便,爲此使用了Suexec的配置,但是Suexec的RPM包默認UID_MIN = 500,于是將user/group從250/250改成了1000/1000,結果問題就來了。

投遞郵件時,maildrop死活都返回0x0B錯誤,無論我將user/group改成多少也好,包括mysql裏的uidnumber/gidnumber、maildropmysql.config裏的default等都改了,完全沒有任何效果。

後來再試驗su成uid=1000的用戶呼叫maildrop發現也是0x0B錯誤,只有在root權限下沒問題,于是又查了maildrop的INSTALL甚至看了source!都是無任何迹象顯示與這個錯誤有關,于是只有google了。但也沒什麽有效的解決辦法。

後來偶然看到一個法文的郵件列表上,看到有人在討論maildrop的mysql配置,忽然想到,自己的maildrop rpm包自動設置了/etc/maildropmysql.config文件屬性是uid=250, gid=250的,于是ls -l /etc/maildropmysql.config一看,原來症結就在這裏!

我改了所有該改的地方,就是沒有對配置文件的owner/group進行修改,而配置文件原本的屬性是600,這樣導致了maildrop換成其他uid/gid運行時無法讀取配置文件,導致了0x0B錯誤。執行:

chown -R 1000.1000 /etc/maildropmysql.config

之後一切問題就迎刃而解了。

Webmail解決setuid/gid問題

昨天正在著手解決全新設計的webmail系統setuid/gid的問題,以適應在SELinux下的應用。自己怕麻煩,暫時不想去做相應的policy,所以只有動腦筋了。

幸好RHEL/CentOS/FC3等自帶的policy都支持suexec,因此就決定利用suexec來實現與apache不同的運行uid/gid,以達到直接訪問Maildir的目的。

在虛擬主機中的配置:

.....SuexecUserGroup vuser vgroupAlias /extmail/ /var/www/cgi-bin/extmail/ SetHandler cgi-script Options +ExecCGI.......

注意: 之所以將cgi程序放到/var/www下是因爲Suexec的docroot限制在了這裏,詳細的suexec編譯參數可以通過Suexec -V查看,以下是CentOS 4.1的結果:

-D AP_DOC_ROOT="/var/www" -D AP_GID_MIN=100 -D AP_HTTPD_USER="apache" -D AP_LOG_EXEC="/var/log/httpd/suexec.log" -D AP_SAFE_PATH="/usr/local/bin:/usr/bin:/bin" -D AP_UID_MIN=500 -D AP_USERDIR_SUFFIX="public_html"

最後,將程序及模板等屬性全部改爲要運行的uid/gid即可:

chown -R vuser.vgroup /var/www/cgi-bin/extmail

重新啓動httpd,通過/var/log/httpd/suexec.log可以看到如下的信息:

[2005-07-26 20:55:51]: uid: (1000/vuser) gid: (1000/1000) cmd: folders.cgi

證明配置成功,這樣webmail就不必再設置爲setuid了,而且apahce也不必以1000/1000的id來運行了。

chdir()引起的模板問題之解決

開發Webmail時,引入了模板機制,這將大大提高了用戶修改的便捷程度,也縮短了開發人員的工作周期。但是這幾天遇到了一個問題,在調用了Storage::Maildir模塊之後,模板的解析就無論如何都不正常了,總說file not found,但明明文件沒有任何錯誤。

而如果先于呼叫Storage::Maildir之前解析模板則完全沒問題,開始懷疑是SELinux的問題,但kernel日志裏又無任何不妥。

後來通過一點一點分析,包括對template解析庫的修改等都印證了各種代碼都沒有問題。最後將目光放到了Storage::Maildir,該模塊在use的時候會利用chdir()初始化當前工作路徑,這樣做之後,將使cgi程序的工作路徑和之前不同了,對于沒使用絕對路徑進行模板解析的應用,自然會遇到問題。

代碼分析:

my $tpl = Ext::Template-new("../html/");my $mm = Ext::Storage::Maildir;$tpl-assign(TEST = 1);restore_path(); # XXX recover working directory$tpl-process("index.html");$tpl-print;....sub restore_path { my $src=$ENV{SCRIPT_FILENAME}; $src=~s#(.*)/[^\/]+$#$1#; chdir($src);}

上述代碼中,在進行模板解析之前,呼叫restore_path(),將工作路徑恢複到調用Storage::Maildir之前的原始狀態。這樣解析就不再有問題了。

再談NEC150--解決幾個網友提出的問題
我是在今年五一的時候買的150手叫,一個星期的工夫就把功能摸的基本上透了,最近網友加我QQ問了我幾個比較常見的問題,我給大家說明下,希望對大家有用! 1.有幾個網友說進MP3播放器之後,點清單但是沒有音樂,但是自己明...查看完整版>>再談NEC150--解決幾個網友提出的問題
 
自己動手,解決手機容易出現的幾個小問題
手機使用時間長了,我們經常會遇到各種各樣的問題,用的是行貨又處于保修期內當然不要緊,但如果你用的是水貨或手機已過保修怎麽辦?首先不要忙著找維修點,其實很多問題都是一些小問題或者是設置問題,或者是根本沒...查看完整版>>自己動手,解決手機容易出現的幾個小問題
 
8310的幾個常見問題的解決方法
很多8310用戶反映偶爾會出現某些短信無法顯示人名的現象,其實,在MOTO P7689以前的版本中,手機軟件開發根本沒考慮短信號碼是會加入中國代碼,比如 +86 138******** 要記住幾百個電話號碼的確不容易,而要在幾百...查看完整版>>8310的幾個常見問題的解決方法
 
c58使用中的幾個常見問題和解決方法
1.C58怎樣設置50秒提示音?在告警裏面有一項說的是:備忘錄,但是設置他以後就在每50秒鍾有一聲提示,但好像是從撥打電話開始的。 2.呼叫轉移的設置方法*72(92)+電話, 然後發送就可以了3.電話簿如何分組?在編輯記錄的...查看完整版>>c58使用中的幾個常見問題和解決方法
 
幾個常見的關于日期的問題解決方法
  1. 怎樣計算兩個時間之間的間隔?  間隔=Date1.getTime()-Date2.getTime();得出來的是毫秒數.  除1000是秒,再除60是分,再除60是小時..............................    記住Java標准庫中所有時間類都以此...查看完整版>>幾個常見的關于日期的問題解決方法
 
解決中文問題的幾個常用的函數(2)
  解決中文問題的幾個常用的函數(2) 8:字符串分割:     public int getCount(String str,String sign){//查找某一字符串中str,特定子串s的出現次數 if(str==null) return 0; StringTokenize...查看完整版>>解決中文問題的幾個常用的函數(2)
 
解決中文問題的幾個常用的函數
  解決Java中文問題:針對applet和awt: 1:) Font f = new Font(UIResource.getString( "Default_font"),Font.PLAIN,12); UIManager.put("Label.font",f); UIManager.put("Label.foreground",Co...查看完整版>>解決中文問題的幾個常用的函數
 
幾個常見的關于日期的問題解決方法
  1. 怎樣計算兩個時間之間的間隔?  間隔=Date1.getTime()-Date2.getTime();得出來的是毫秒數.  除1000是秒,再除60是分,再除60是小時..............................  記住java標准庫中所有時間類都以此爲基...查看完整版>>幾個常見的關于日期的問題解決方法
 
解決JSP中文顯示問題的幾個方法
  總結了以下幾條方法:  1、在jsp頁中加入一條語句: <%@ page contentType="text/html;charset=gb2312" %>中文顯示就正常了。   2、對于從網頁中的文本框通過String parameter = request.getParameter...查看完整版>>解決JSP中文顯示問題的幾個方法
 
 
回到王朝網路首頁