?
本文檔使用 PHP中文網(wǎng)手冊 發(fā)布
數(shù)據(jù)庫安全性策略
數(shù)據(jù)庫安全性問題一直是圍繞著數(shù)據(jù)庫管理員的惡夢,數(shù)據(jù)庫數(shù)據(jù)的丟失以及數(shù)據(jù)庫 被非法用戶的侵入使得數(shù)據(jù)庫管理員身心疲憊不堪。本文圍繞數(shù)據(jù)庫的安全性問題提出了 一些安全性策略,希望對數(shù)據(jù)庫管理員有所幫助,不再夜夜惡夢。 數(shù)據(jù)庫安全性問題應(yīng)包括兩個部分: 一、數(shù)據(jù)庫數(shù)據(jù)的安全 它應(yīng)能確保當(dāng)數(shù)據(jù)庫系統(tǒng)DownTime時,當(dāng)數(shù)據(jù)庫數(shù)據(jù)存儲媒體被破壞時以及當(dāng)數(shù)據(jù) 庫用戶誤操作時,數(shù)據(jù)庫數(shù)據(jù)信息不至于丟失。 二、數(shù)據(jù)庫系統(tǒng)不被非法用戶侵入 它應(yīng)盡可能地堵住潛在的各種漏洞,防止非法用戶利用它們侵入數(shù)據(jù)庫系統(tǒng)。 對于數(shù)據(jù)庫數(shù)據(jù)的安全問題,數(shù)據(jù)庫管理員可以參考有關(guān)系統(tǒng)雙機熱備份功能以及 數(shù)據(jù)庫的備份和恢復(fù)的資料。 以下就數(shù)據(jù)庫系統(tǒng)不被非法用戶侵入這個問題作進一步的闡述。 組和安全性 在操作系統(tǒng)下建立用戶組也是保證數(shù)據(jù)庫安全性的一種有效方法。Oracle程序為了安 全性目的一般分為兩類:一類所有的用戶都可執(zhí)行,另一類只DBA可執(zhí)行。在Unix環(huán)境下組 設(shè)置的配置文件是/etc/group,關(guān)于這個文件如何配置,請參閱Unix的有關(guān)手冊,以下是 保證安全性的幾種方法: (1) 在安裝Oracle Server前,創(chuàng)建數(shù)據(jù)庫管理員組(DBA)而且分配root和Oracle軟件 擁有者的用戶ID給這個組。DBA能執(zhí)行的程序只有710權(quán)限。在安裝過程中SQL*DBA 系統(tǒng)權(quán)限命令被自動分配給DBA組。 (2) 允許一部分Unix用戶有限制地訪問Oracle服務(wù)器系統(tǒng),增加一個由授權(quán)用戶組成 的Oracle組,確保給Oracle服務(wù)器實用例程Oracle組ID,公用的可執(zhí)行程序,比 如SQL*Plus,SQL*Forms等,應(yīng)該可被這組執(zhí)行,然后該這個實用例程的權(quán)限為 710,它將允許同組的用戶執(zhí)行,而其他用戶不能。 (3) 改那些不會影響數(shù)據(jù)庫安全性的程序的權(quán)限為711。 注:在我們的系統(tǒng)中為了安裝和調(diào)試的方便,Oracle數(shù)據(jù)庫中的兩個具有DBA權(quán)限的 用戶Sys和System的缺省密碼是manager。為了您數(shù)據(jù)庫系統(tǒng)的安全,我們強烈 建議您該掉這兩個用戶的密碼,具體操作如下: 在SQL*DBA下鍵入: alter user sys indentified by password; alter user system indentified by password; 其中password為您為用戶設(shè)置的密碼。 Oracle服務(wù)器實用例程的安全性 以下是保護Oracle服務(wù)器不被非法用戶使用的幾條建議: (1) 確保$ORACLE_HOME/bin目錄下的所有程序的擁有權(quán)歸Oracle軟件擁有者所有; (2) 給所有用戶實用便程(sqiplus,sqiforms,exp,imp等)711權(quán)限,使服務(wù)器上所有的 用戶都可訪問Oracle服務(wù)器; (3) 給所有的DBA實用例程(比如SQL*DBA)700權(quán)限。 Oracle服務(wù)器和Unix組 當(dāng)訪問本地的服務(wù)器時,您可以通過在操作系統(tǒng)下把Oracle服務(wù)器的角色映射到Unix 的組的方式來使用Unix管理服務(wù)器的安全性,這種方法適應(yīng)于本地訪問。 在Unix中指定Oracle服務(wù)器角色的格式如下: ora_sid_role[_dla] 其中 sid 是您Oracle數(shù)據(jù)庫的oracle_sid; role 是Oracle服務(wù)器中角色的名字; d (可選)表示這個角色是缺省值; a (可選)表示這個角色帶有WITH ADMIN選項,您只可以把這個角色 授予其他角色,不能是其他用戶。 以下是在/etc/group文件中設(shè)置的例子: ora_test_osoper_d:NONE:1:jim,narry,scott ora_test_osdba_a:NONE:3:pat ora_test_role1:NONE:4:bob,jane,tom,mary,jim bin: NONE:5:root,oracle,dba root:NONE:7:root 詞組“ora_test_osoper_d”表示組的名字;詞組“NONE”表示這個組的密碼;數(shù)字1 表示這個組的ID;接下來的是這個組的成員。前兩行是Oracle服務(wù)器角色的例子,使 用test作為sid,osoper和osdba作為Oracle服務(wù)器角色的名字。osoper是分配給用戶 的缺省角色,osdba帶有WITH ADMIN選項。 為了使這些數(shù)據(jù)庫角色起作用,您必須shutdown您的數(shù)據(jù)庫系統(tǒng),設(shè)置Oracle數(shù)據(jù)庫 參數(shù)文件initORACLE_SID.ora中os_roles參數(shù)為True,然后重新啟動您的數(shù)據(jù)庫。如 果您想讓這些角色有connect internal權(quán)限,運行orapwd為這些角色設(shè)置密碼。當(dāng)您 嘗試connect internal時,您鍵入的密碼表示了角色所對應(yīng)的權(quán)限。 SQL*DBA命令的安全性 如果您沒有SQL*PLUS應(yīng)用程序,您也可以使用SQL*DBA作SQL查權(quán)限相關(guān)的命令只能分 配給Oracle軟件擁有者和DBA組的用戶,因為這些命令被授予了特殊的系統(tǒng)權(quán)限。 (1) startup (2) shutdown (3) connect internal 數(shù)據(jù)庫文件的安全性 Oracle軟件的擁有者應(yīng)該這些數(shù)據(jù)庫文件($ORACLE_HOME/dbs
#############################
#the following demostrate the open method.
$newOda->Open("select * from test")) or die $newOda->err;
#Get data from RS
echo "count is" .$newOda->Rows;
for($i=0;$i<$newOda->Rows;$i++)
???for($j=0;$j<$newOda->Cols;$j++)
????{
???????echo $newOda->RS[$i][$j];
???????
???????}
$newOda->Logoff();
?>
<?
???file://$conn = OCILogon("www_ce", "ceonline99", "wsgp");
??// $conn = OCILogon("www_cec", "webchn99", "unicorn");
//??if ($SERVER_NAME == "")
//??????????$SERVER_NAME = $HTTP_HOST;
class ODA
{
??
??
??function ODA($cn="") {
???if($cn!="")
????$this->conn=$cn;
????return TRUE;
??
??}
??
??function Logon($user,$pass,$db) {
??
????if(!($this->conn = OCILogon($user, $pass, $db))){
????
?????$this->err_no=106;
?????$this->err="Error 106: Failed to logon.";
?????return FALSE;
????};
????
????return TRUE;
????
??}
??function Open($sql="") file://$this->CmdString
??{
?????if($this->conn=="") {
????????$this->err_no=100;
????????$this->err="Error 100,Connection Object Required.";
????????return FALSE;
??????}
?????
?????if($sql=="" and $this->CmdString=="") {
????????$this->err_no=101;
????????$this->err="Error 101,SQL Statement Required.";
????????return FALSE;
??????}
?????if($sql=="")
????????$sql=$this->CmdString;
????if(!($cursor=OCIParse($this->conn,$sql))) {
???????$this->err_no=102;
???????$this->err="Server Internal Error: Failed to parse SQL Statement.";
???????return FALSE;
????}
????
????if(!OCIExecute($cursor))??{
??????$this->err_no=103;
??????$this->err="Server Internal Error: Failed to execute SQL Statement.";
??????return FALSE;
????}
????$this->Rows=0;
????while(OCIFetchInto($cursor,$this->RS[$this->Rows])){
????
??????$this->Rows++;
??????
?????}
?????$this->Cols=OCINumCols($cursor);
????if($this->Rows==0) {
????
?????$this->err_no=104;
?????$this->err="Warning: No rows affectted.RS result is not available.";
????}
?????OCIFreeStatement($cursor);
?????
?????return TRUE;
??}
??
??
????function Execute($sql="") {
?????if($this->conn=="") {
????????$this->err_no=100;
????????$this->err="Error 100,Connection Object Required.";
????????return FALSE;
??????}
????
?????if($sql=="" and $this->CmdString=="") {
????????$this->err_no=101;
????????$this->err="Error 101,SQL Statement Required.";
????????return FALSE;
??????}
?????if($sql=="")
????????$sql=$this->CmdString;
????
????if(!($cursor=OCIParse($this->conn,$sql))) {
???????$this->err_no=102;
???????$this->err="Server Internal Error: Failed to parse SQL Statement.";
???????return FALSE;
????}
???
????
????if(!OCIExecute($cursor))??{
??????$this->err_no=103;
??????$this->err="Server Internal Error: Failed to execute SQL Statement.";
??????return FALSE;
????}
????$this->Rows=OCIRowCount($cursor);
????OCIFreeStatement($cursor);
????
????return TRUE;
??}
??function LogOff(){
??
??if(!OCILogoff($conn)){
????
????$this->err_no=105;
????$this->err="Server Internal Error: Failed to logoff database.";
????return FALSE;
???}
??return TRUE;
??
??}
}
?>