領導要我策劃一個網頁設計大賽和Flash創作大賽,要求必須實現線上報名和上傳作品。通過FreeBSD+Apache+PHP+Mysql+FTP我實現了該要求。
實現線上報名和上傳作品的思路是利用網頁表單收集使用者填寫的資料儲存到Mysql資料庫內,同時以該使用者的註冊名建立一個FTP上傳帳號並建立該使用者的相應目錄。
FTP伺服器是系統預設帶的,採用系統使用者的使用者名稱和密碼,建立系統使用者就等於建立FTP使用者,FreeBSD是屬於UNIX陣營的作業系統,它沒有象Linux一樣的useradd和groupadd等建立使用者和組的命令,其取而代之的是pw命令加上相應參數來實現,在Freebsd上以管理員的身份建立一個使用者的命令是
echo | pw useradd [-g][groupname] [-s][shelldir][-h 0]
參數g指定使用者組,參數s指定使用者的shell。
如果是普通使用者登陸的話還必須用到su命令,調用的方法是
su root –c ‘echo | pw useradd [-g][groupname] [-s][shelldir][-h 0] ’
執行之後系統會要求輸入管理員密碼,輸入密碼就可以以管理員的身份執行這個命令了。
實現這步操作的主要痛點在於如何通過PHP來調用上面這些系統命令去建立一個使用者,本例是使用PHP中的popen()函數來實現的,該函數執行指令開啟檔案,文法是int popen(string command, string mode),其開啟的檔案只能是單向的,只能讀或只能寫,對應的“string mode”為’r’或’w’,“string command” 就是命令字串,在對檔案的操作上可使用 fgets()、fgetss()與fputs()函數,本例用fputs()函數往檔案裡面輸入管理員密碼。若是開檔發生錯誤將返回 false 值,最後函數要記得調用pclose()關閉。
下面我們來規劃一下FTP使用者的組,事先我們先用pw groupadd ftpuser建立ftpuse組,讓線上申請的使用者為這個組的成員。為了安全起見,我們不應該給FTP使用者Telnet許可權,所以我們還要專門給他們建立一個shell,使得他們不能通過Telnet正常登陸系統,方法如下:先建立一個檔案/bin/ftponly
#!/bin/csh
/bin/cat << XX
You can ony use this username to login ftp server!
And you can not use it to telnet to this system! XX
sleep 10
該檔案中XX之間就是顯示給用telnet登陸的使用者看的資訊。資訊顯示10秒鐘就自動結束了。最後不要忘記用chmod +x /bin/ftponly給這個檔案可執行屬性。
然後在/bin/shell檔案中添加“/bin/ftponly”,在以後的命令裡面我們就可以利用pw中-s參數把這個shell指定給FTP使用者了。
最後還要注意一個問題,su命令僅僅是wheel管理組的使用者成員才可以使用,當PHP調用su命令的時候也必須以wheel群組成員的身份運行,否則系統拒絕運行,而PHP運行系統命令的身份就是Apache web伺服器啟動並執行身份,初始的使用者名稱和使用者組都是nobody,所以先得建立一個wheel組的使用者www供apache使用,接著更改Apache的設定檔httpd.conf中的user為www,group為wheel,重新啟動Apache,就可以以新使用者身份運行了。
下面可以建立PHP源檔案checkin.php了,代碼如下:
<?if (($username!="") and ($userpasswd!=""))//判斷是否有表單提交了資訊
{ $rootpasswd="adminpassword"; //定義管理員密碼
$creatuser="su --login root -c 'echo ".$userpasswd." | pw useradd ".$username." -s /bin/ftponly -g ftpuser –s /bin/ftponly -h 0' "; //這是利用su和pw命令建立使用者的用到的字串
$fp=popen($creatuser,"w"); //調用popen()函數執行字串中的命令,返迴文控制代碼給$fp
fputs($fp,$rootpasswd); //寫入管理員密碼到檔案$fp,相當於輸入密碼給系統
pclose($fp);//關閉檔案
$creatdir="su --login root -c 'mkdir /home/".$username."'";//建立使用者目錄的命令字串
$fp=popen($creatdir,"w");//執行命令建立使用者目錄
fputs($fp,$rootpasswd); //輸入管理員密碼
pclose($fp);
$creatdir="su --login root -c 'mkdir /home/".$username."/public_html'";
$fp=popen($creatdir,"w"); //執行命令建立使用者網站根目錄
fputs($fp,$rootpasswd); //輸入管理員密碼
pclose($fp);
$creatdir="su --login root -c 'chown ".$username." /home/".$username."'"; //改變使用者目錄的所有者為使用者自己,初始為運行Apache的使用者www。
$fp=popen($creatdir,"w"); //執行命令
fputs($fp,$rootpasswd); //輸入管理員密碼
pclose($fp);
$creatdir="su --login root -c 'chown ".$username." /home/".$username."/public_html'"; //改變網站根目錄的歸屬
$fp=popen($creatdir,"w");
fputs($fp,$rootpasswd);
pclose($fp);
echo "恭喜".$username.",您的的FTP帳號已經申請成功!請到FTP上登陸,請注意,您沒有Telnet許可權";}
else{?>
<html>
<head>
<title>申請FTP帳號</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
</head>
<body bgcolor="#FFFFFF">
<div align="center">
<p>申請FTP帳號</p>
<form method=POST action="<? echo $PHP_SELF; ?>">
<table width="36%" border="0">
<tr>
<td width="40%">
<div align="right">帳號名稱:</div>
</td>
<td width="60%">
<input type="text" name="username">
</td>
</tr>
<tr>
<td width="40%">
<div align="right">密碼:</div>
</td>
<td width="60%">
<input type="password" name="userpasswd">
</td>
</tr>
<tr>
<td colspan="2"><input type="submit" name="Submit" value="申請"></td>
</tr>
</table>
</form>
</div><?}?>
</body>
</html>