從ORA-01031報錯看密碼檔案故障

realkid4發表於2014-03-06

 

登入連線錯誤是我們在環境配置、更改和新客戶端安裝時候最經常遇到的問題。登入過程涉及到客戶端網路、作業系統、TNS配置、監聽器工作狀態、伺服器遠端本地登入模式和各種引數配置。應該說,只要有一個環節有問題,就會導致Oracle使用者登入錯誤,而且故障報錯資訊可能會誤導使用者。

下面介紹筆者解決的一個連線錯誤問題,由於涉及到實際環境,所以採用了事後模擬的策略。

 

1、問題概述

 

同事實驗使用“非標準”方法安裝資料庫,發現在本地連線和遠端連線過程中有異常問題。安裝資料庫版本是11gR2

 

SQL> select * from v$version;

BANNER

--------------------------------------------------

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 – Production

 

同事在伺服器端已經配置了連線本地資料庫的TNS名稱。

 

[oracle@bspdev ~]$ tnsping wilson

TNS Ping Utility for Linux: Version 11.2.0.1.0 - Production on 06-MAR-2014 05:19:23

 

Copyright (c) 1997, 2009, Oracle.  All rights reserved.

 

Used parameter files:

/u01/oracle/network/admin/sqlnet.ora

 

Used TNSNAMES adapter to resolve the alias

Attempting to contact (DESCRIPTION = (ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = 127.0.0.1)(PORT = 1521))) (CONNECT_DATA = (SERVICE_NAME = wilson)))

OK (10 msec)

 

由於是測試,透過ssh客戶端登入主機後進行各種配置操作。使用匿名/登入是可以的。

 

SQL> conn / as sysdba

Connected.

SQL> conn sys/oracle as sysdba

Connected.

SQL> conn sys/xxx as sysdba

Connected.

 

但是,無論是從遠端還是本地,如果加入@wilson服務名,就不能實現登入。

 

--本地使用登入

SQL> conn sys/oracle@wilson as sysdba

ERROR:

ORA-01031: insufficient privileges

 

 

--遠端登入

C:\Users\51ibm>sqlplus /nolog

 

SQL*Plus: Release 11.2.0.1.0 Production on 星期三 3 5 21:36:43 2014

 

Copyright (c) 1982, 2010, Oracle.  All rights reserved.

 

SQL> conn sys/oracle@wilson as sysdba

ERROR:

ORA-01031: insufficient privileges

 

使用者sys的密碼是oracle,為什麼會報錯說“許可權不足”?

 

2、問題分析

 

預設情況下,無論是Windows還是Linux,作業系統使用者都是在系統級別的dba組中(名稱可能有差異)。而且,伺服器一般都是選擇作業系統級別的驗證方式進行登入。

這就是說,只要我們透過了作業系統層面的使用者名稱/密碼驗證,就可以直接登入到Oracle裡面。而且,如果能夠進行這樣的登入方式,使用者名稱/密碼即使輸入也不會進行驗證。

這也就是為什麼我們輸入錯誤的密碼xxx,也可以進行登入的原因。

 

SQL> conn sys/oracle as sysdba

Connected.

SQL> conn sys/xxx as sysdba

Connected.

 

那麼,問題就轉化為,Oracle作為一個執行在作業系統層面上的軟體程式。是怎麼判斷說這次進行的是作業系統級別驗證,還是密碼驗證?

答案就是:監聽器程式。下面兩個在本機上執行的語句告訴我們端倪。

 

SQL> conn sys/mmm as sysdba

Connected.

SQL> conn sys/mmm@wilson as sysdba

ERROR:

ORA-01017: invalid username/password; logon denied

 

Warning: You are no longer connected to ORACLE.

 

監聽程式listener是我們連線客戶端程式和伺服器程式過程中的一個重要元件。注意是“連線過程中”,而不是連線之後。當監聽器收到請求之後,按照例項Instance註冊列表查詢請求的例項名稱,請求相應例項分出Server Process。使用者名稱密碼驗證不在監聽器中進行。

在之前的文章中,筆者討論過是否經過監聽器的判斷標準就是連線串中是否帶@。如果有@,無論連到本地例項還是遠端例項,都需要訪問監聽器。

所以,對於連線是否進行的作業系統層面驗證,關鍵點其實不在我們是否遠端登入主機,而是我們是否經過監聽器!

如果不經過監聽器,首先就可以保證連線的是本機,不會是到其他伺服器host上。如果經過監聽器,都會被判定為遠端登入,都不會應用上作業系統層面驗證。

回到問題本身,同事不使用@連線的時候,是正常的。只要透過監聽器,就出現錯誤,無論本地還是遠端連入。

另一線索是針對sys使用者,在進行登入的時候出錯。

綜合各種要素,當Oracle不使用本地登入,而且是sys這類sysdba使用者登陸的時候,採用什麼樣的驗證方法?答案就是密碼檔案。

懷疑密碼檔案之後,我們可以到$ORACLE_HOME/dbs目錄中找尋字首為orapw的檔案去看。

 

 

[oracle@bspdev dbs]$ cd $ORACLE_HOME/dbs

[oracle@bspdev dbs]$ ls -l | grep orapw

 

密碼檔案不存在,也沒有被建立。嘗試手工建立檔案:

 

[oracle@bspdev dbs]$ orapwd password=oracle file=orapwWILSON

[oracle@bspdev dbs]$ ls -l | grep orapw

-rw-r----- 1 oracle oinstall     1536 Mar  6 05:51 orapwWILSON

 

嘗試連線資料庫。

 

[oracle@bspdev dbs]$ sqlplus /nolog

 

SQL*Plus: Release 11.2.0.1.0 Production on Thu Mar 6 05:54:24 2014

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

 

SQL> conn sys/oracle@wilson as sysdba

ERROR:

ORA-01031: insufficient privileges

 

依然錯誤。看來需要進一步分析。

 

3、問題分析二

 

從思路上,應該是沒有問題。而且在無故障環境下,我們透過實驗是可以驗證結論的。首先一種思路是判斷是不是密碼檔案被正確的使用。

 

SQL> conn / as sysdba

Connected.

SQL> select * from v$pwfile_users;

 

no rows selected

 

檢視v$pwfile_users是檢視密碼檔案內容提供的一種檢視。我們沒有找到記錄,這就是問題,因為無論如何,sys使用者起碼在其中的。

sysdba許可權是一種特殊的許可權,透過grant顯示授權就可以寫入到密碼檔案中。

 

 

SQL> grant sysdba to sys;

grant sysdba to sys

*

ERROR at line 1:

ORA-01994: GRANT failed: password file missing or disabled

 

看來,密碼檔案建立有問題。建立程式orapwd執行沒有報錯,密碼檔案也存在。這樣,我們需要考慮Oracle是如何定位密碼檔案的?

 

經過資料確定,Oracle確定密碼檔案和引數檔案很類似。都是透過環境變數$ORACLE_HOME找到$ORACLE_HOME/dbs目錄,找其中的orapw。其中的SID是透過環境變數$ORACLE_SID來確定。

當前密碼檔名稱orapwWILSON。但是環境變數卻有問題。

 

[oracle@bspdev dbs]$ env | grep ORACLE_SID

ORACLE_SID=wilson

 

環境變數wilson定義的是小寫!在Linux中,一個和windows很大的差異就是大小寫問題。

重新生成檔案orapw

 

 

[oracle@bspdev dbs]$ orapwd file=orapwwilson password=oracle

[oracle@bspdev dbs]$ ls -l | grep orapw

-rw-r----- 1 oracle oinstall     1536 Mar  6 05:59 orapwwilson

-rw-r----- 1 oracle oinstall     1536 Mar  6 05:51 orapwWILSON

 

之後,登入成功,密碼檔案確認。

 

SQL> conn sys/oracle@wilson as sysdba

Connected.

SQL> select * from v$pwfile_users;

 

USERNAME                       SYSDB SYSOP SYSAS

------------------------------ ----- ----- -----

SYS                            TRUE  TRUE  FALSE

 

故障解決。

 

4、結論

 

Oracle是一個複雜的體系,多個元件都會影響到資料庫的正常執行和工作。當故障發生時,考驗的是我們對於問題的分析能力、基礎知識的牢固程度和對資料庫的理解。抽絲剝繭、小心求證往往是我們最後走向成功的必須過程。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/17203031/viewspace-1102253/,如需轉載,請註明出處,否則將追究法律責任。

相關文章