Oracle的口令文件(passwordfile)的講解(摘錄)

初學oracle,很多概念迷糊,今天看到這文章,讓我有一個比較清晰的認識。
轉載[url]http://www.itpub.net/viewthread.php?tid=906008&extra=&page=1[/url]

1、os認證
    oracle安裝之後默認情況下是啓用了os認證的,這裏提到的os認證是指服務器端os認證。os認證的意思把登錄數據庫的用戶和口令校驗放在了操作系統一級。如果以安裝oracle時的用戶登錄os,那麼此時在登錄oracle數據庫時不需要任何驗證,如:

    SQL> connect /as sysdba
    已連接。

    SQL> connect sys/aaa@dmt as sysdba
    已連接。

    SQL> connect sys/bbb as sysdba
    已連接。

    SQL> connect aaa/bbb as sysdba
    已連接。

    SQL> show user
    USER 爲 "SYS"

    SQL>

    不論輸入什麼用戶(哪怕這個用戶如aaa在數據庫中根本不存在),只要以sysdba權限連接數據庫,都可以連接上,並且連接用戶是sys,這樣很方便,有時候,如果忘記了數據庫的密碼,而又想登錄數據庫,可以通過這種方式,前提是在數據庫服務器上;但是方便的同時也帶來了一些安全隱患,於是很多人想屏蔽 os認證,在win下只要把oracle_home/NETWORK/admin/sqlnet.ora中的 SQLNET.AUTHENTICATION_SERVICES= (nts)nts改成none或者註釋掉這句話(在前面加上#),就可以屏蔽os功能,要想以sys用戶連上數據庫必須輸入正確的sys口令,如:

    SQL> connect /as sysdba
    ERROR:
    ORA-01031: 權限不足

    SQL> connect sys/aaa as sysdba
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕

    SQL> connect aaa/bbb as sysdba
    ERROR:
    ORA-01031: 權限不足

    SQL> connect sys/system as sysdba
    已連接。

    SQL>

    或者可以把oracle的安裝用戶從組ora_dba中刪除掉,當然也可以直接把ora_dba這個組也刪除,都可以屏蔽os功能。在 unix/linux下也可以在文件sqlnet.ora中增加SQLNET.AUTHENTICATION_SERVICES=(none)以及刪除 dba(groupdel dba)組或者把oracle用戶從dba組中刪除都可以屏蔽os認證。利用這兩種方法屏蔽os功能似乎總有些讓人不放心,或者說不能讓人完全信服,因爲畢竟系統管理員還是可以創建ora_dba or dba組以及修改sqlnet.ora文件,如何徹底屏蔽os功能?讓它"永世不得翻身"呢?我沒有這方面的經驗,大家可以補充!

    2、口令文件
    oracle的口令文件的作用是存放所有以sysdba或者sysoper權限連接數據庫的用戶的口令,如果想以sysdba權限遠程連接數據庫,必須使用口令文件,否則不能連上,由於sys用戶在連接數據庫時必須以sysdba or sysoper方式,也就是說sys用戶要想連接數據庫必須使用口令文件,因此我認爲在數據庫中存放sys用戶的口令其實沒有任何意義!使用口令文件的好處是即使數據庫不處於open狀態,依然可以通過口令文件驗證來連接數據庫。開始安裝完oracle,沒有給普通用戶授予sysdba權限,口令文件中只存放了sys的口令,如果之後把sysdba權限授予了普通用戶,那麼此時會把普通用戶的口令從數據庫中讀到口令文件中保存下來,當然這時必須要求數據庫處於open狀態。如:

    SQL> grant sysdba to test;
    授權成功。

    SQL> connect test/aaa@orcl as sysdba
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕
    警告: 您不再連接到 ORACLE。

    SQL> connect test/test@orcl as sysdba
    已連接。

    SQL> alter database close;
    數據庫已更改。

    SQL> grant sysdba, sysoper to test;
    grant sysdba, sysoper to test
    *
    第 1 行出現錯誤:
    ORA-01109: 數據庫未打開

    到底有幾個用戶被授予了sysdba或者sysoper權限,可以通過查詢如下v$pwfile_users獲得,v$pwfile_users的信息就是源於口令文件的(This view lists users who have been granted SYSDBA and SYSOPER privileges as derived from the password file.)

    SQL> select * from v$pwfile_users;
    USERNAME SYSDB SYSOP
    ------------------------------ ----- -----
    SYS TRUE TRUE
    TEST TRUE FALSE

    到底可以有幾個用戶被授予sysdba或者sysoper權限,是由創建口令文件時指定的entries數決定的,準確的說還不完全是,最終還和os block的大小有關,如果entries指定了5,一個os block可以存放8個用戶的口令,那麼可以由8個用戶被授予sysdba或者sysoper。

    下面看一個簡單的測試
    SQL> declare
      2     v_string varchar2(100);
      3  begin
      4  for i in 1..100 loop
      5     v_string := 'create user test'||i||' identified by test'||i;
      6     execute immediate v_string ;
      7  end loop;
      8  end;
      9  /
    PL/SQL 過程已成功完成。

    SQL> select count(*) from dba_users where username like '%TEST%';
      COUNT(*)
    ----------
           101

    這裏之所以是101,是因爲之前已經創建過test用戶

    SQL> declare
      2     v_string varchar2(100);
      3  begin
      4          for i in 1..100 loop
      5             v_string := 'grant sysdba to test'||i;
      6                  execute immediate v_string ;
      7          end loop ;
      8  end ;
      9  /

    declare
    *
    第 1 行出現錯誤:
    ORA-01996: GRANT 失敗: 口令文件 '' 已滿
    ORA-06512: 在 line 6

    SQL> select * from v$pwfile_users;
    USERNAME                       SYSDB SYSOP
    ------------------------------ ----- -----
    SYS                            TRUE  TRUE
    TEST1                          TRUE  FALSE
    TEST2                          TRUE  FALSE
    TEST3                          TRUE  FALSE
    TEST4                          TRUE  FALSE
    TEST5                          TRUE  FALSE
    TEST6                          TRUE  FALSE
    TEST7                          TRUE  FALSE
    TEST8                          TRUE  FALSE

    已選擇9行。

    SQL>

    可以清楚的看到v$pwfile_users裏面並不是創建口令文件時指定的entries=5而是9條記錄,意味着9個用戶的口令佔用了一個os block,其實也可能是多個os block,總之這些block都是滿的,但是觀察口令文件,還是佔了2k,這是我解釋不清的地方。通過os命令發現;每個簇字節數4096;這裏其實就是os block 大小實際上是4k,但是口令文件佔用了2k,根本沒有用滿一個os block,不知道何故,也是我的疑惑 (
    This parameter specifies the number of entries that you require the password file to accept. This number corresponds to the number of distinct users allowed to connect to the database as SYSDBA or SYSOPER. The actual number of allowable entries can be higher than the number of users, because the ORAPWD utility continues to assign password entries until an operating system block is filled. For example, if your operating system block size is 512 bytes, it holds four password entries. The number of password entries allocated is always a multiple of four.
    )

    win下查看os block大小
    C:\WINDOWS\system32>fsutil fsinfo ntfsinfo e:
    NTFS 卷序列號 :       0x12afb454f6e54b31
    版本 :                         3.1
    區數量 :                  0x00000000040270d0
    簇總數 :                  0x0000000000804e1a
    可用簇  :                  0x00000000000b8d41
    保留總數 :                  0x0000000000000000
    每個扇區字節數  :               512
    每個簇字節數 :               4096
    每個 FileRecord 段的字節數    : 1024
    每個 FileRecord 段的簇數 : 0
    Mft 有效數據長度 :           0x00000000058d0000
    Mft 起始 Lcn  :                  0x0000000000000004
    Mft2 起始 Lcn :                  0x0000000000080000
    Mft 區域起始 :                  0x0000000000483740
    Mft 區域結尾   :                  0x000000000049c760

    C:WINDOWS\system32>
    還有一個問題修改了口令,口令長度增加了,按說佔用的空間多了,但是查詢v$pwfile_users發現還是9條記錄?不過這個問題突然想到了答案,那就是不論我們的口令多長,加密之後的長度幾乎都是相同的,也就是說口令文件佔用的大小和口令指定的長度幾乎關係不大!

    SQL> edit
    已寫入 file afiedt.buf
      1  declare
      2     v_string varchar2(100);
      3  begin
      4          for i in 1..100 loop
      5             v_string := 'alter user test'||i||' identified by  aaaaaaaaaaaaaaaaaaaaaa'||i;
      6                  execute immediate v_string ;
      7          end loop ;
      8* end ;
    SQL> /
    PL/SQL 過程已成功完成。

    SQL> declare
      2     v_string varchar2(100);
      3  begin
      4          for i in 1..100 loop
      5             v_string := 'grant sysdba to test'||i;
      6                  execute immediate v_string ;
      7          end loop ;
      8  end ;
      9  /
    declare
    *
    第 1 行出現錯誤:
    ORA-01996: GRANT 失敗: 口令文件 '' 已滿
    ORA-06512: 在 line 6

    SQL> select * from v$pwfile_users;
    USERNAME                       SYSDB SYSOP
    ------------------------------ ----- -----
    SYS                            TRUE  TRUE
    TEST1                          TRUE  FALSE
    TEST2                          TRUE  FALSE
    TEST3                          TRUE  FALSE
    TEST4                          TRUE  FALSE
    TEST5                          TRUE  FALSE
    TEST6                          TRUE  FALSE
    TEST7                          TRUE  FALSE
    TEST8                          TRUE  FALSE

    已選擇9行。

    SQL>
    E:\oracle\product\10.2.0\db_1\data\base>orapwd file=E:\oracle\product\10.2.0\db_1
    databasepwd.ora password=system entries=5
    OPW-00005: 存在相同名稱的文件 - 請刪除或重命名

    E:\oracle\product\10.2.0\db_1\data\base>orapwd file=E:oracleproduct10.2.0db_1
    databasepwd.ora password=system entries=5 force=y

    創建口令文件需要注意的是=前後沒有空格!另外值得一提的是10g增加了一個新的參數force default值n,它的作用類似於創建表空間時的reuse功能,當同名文件存在時是否覆蓋。

    是否使用口令文件,是通過oracle提供的一個參數remote_login_passwordfile來控制的, remote_login_passwordfile有none,shared,exclusive3個值,none表示不使用口令文件, exclusive表示實例獨佔使用口令文件,也就是各自實例使用單獨的口令文件,shared表示多個實例共享一個口令文件,缺省情況下,win下口令文件的格式是pwdsid.ora,unix下的格式是orapwSID(大小寫敏感),unix下尋找口令文件的順序是oracle_home\dbs \orapwSID,如果找不到,會在dbs目錄想尋找orapw文件,如果找不到9i下會報錯,數據庫可以啓動到mount狀態,當然再次alter database open之後還是可以打開數據庫。10g下open數據庫時不在檢查口令文件。win下如果在oracle_home/database/下找不到 pwdsid.ora文件,不會尋找任何文件。這裏所說的win下如果找不到PWDsid.ora文件之後不會尋找任何文件其實是相對unix下如果找不到orapwSID文件之後會尋找orapw文件而言的。其實win下尋找口令文件也是有順序的。尋找順序是這樣的:首先尋找註冊表中 ora_sid_pwfile環境變量所指向的口令文件,其次尋找ora_pwfile執行的口令文件,最後才尋找$ ORACLE_HOME/database/PWDsid.ora,下面做一個簡單的測試:

    開始存在一個口令文件PWDtsid.ora,之後又創建了兩個口令文件pwd.ora和orapwd.ora
    C:>orapwd file=E:\oracle\product\10.2.0\db_1\databasepwd.ora password=manager entries=5 force=y

    C:>orapwd file=E:\oracle\product\10.2.0\db_1\databaseorapwd.ora password=manager_system entries=5

    C:>e:
    E:>cd E:\oracle\product\10.2.0\db_1\database

    E:\oracle\product\10.2.0\db_1\database>dir *pwd*

     驅動器 E 中的卷沒有標籤。
     卷的序列號是 F6E5-4B31
     E:\oracle\product\10.2.0\db_1\database 的目錄

    2007-12-07  21:30             2,048 orapwd.ora
    2007-12-07  21:29             2,048 pwd.ora
    2007-12-06  21:44             2,048 PWDtsid.ora

    3個口令文件的口令分別是system, manager, system_manager沒有什麼特別的意義,都是隨意指定的,其中在註冊表中ora_tsid_pwfile指向了文件E:\oracle\ product\10.2.0\db_1\databasepwd.ora,ora_pwfile指向了E:\oracle\product \10.2.0\db_1\databaseorapwd.ora,然後通過遠程client端進行測試:

    SQL> connect sys/system@testdb as sysdba
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕
    警告: 您不再連接到 ORACLE。

    SQL> connect sys/manager@testdb as sysdba
    已連接。

    SQL> connect sys/manager_system@testdb as sysdba
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕
    警告: 您不再連接到 ORACLE。

    SQL>

    測試結果顯示要求輸入的口令是manager,而manager對應的口令文件是環境變量ora_tsid_pwfile所指向的pwd.ora,之後刪除環境變量ora_tsid_pwfile再次連接:


    SQL> connect sys/system@testdb as sysdba
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕
    警告: 您不再連接到 ORACLE。

    SQL> connect sys/manager_system@testdb as sysdba
    已連接。

    SQL>
    這次要求輸入的口令是manager_system,而manager_system對應的口令文件是環境變量ora_pwfile所指向的orapwd.ora,之後刪除環境變量ora_pwfile進行連接測試:

    SQL> connect sys/system@testdb as sysdba
    已連接。

    SQL>

    連接成功,system對應的口令文件正是$ORACLE_HOME/database/PWDtsid.ora

    接着上面介紹共享口令文件,由於在unix下會尋找orapw文件(該文件不含sid的信息),因此各個實例可以shared口令文件,前提是需要把參數 remote_login_passwordfile設置爲shared,該參數是靜態參數,修改之後需要重啓實例,當然也可以通過連接的方式(unix 下ls)實現口令文件共享,不過沒感覺到共享口令文件有什麼好處;win下可以通過在註冊表中指定環境變量ora_sid_pwfile或者 ora_pwfile來改變口令文件的位置和名稱,從而也可以實現口令文件共享。

    共享口令文件會有很多問題:
    首先要求所有的sys口令相同,其次orcl庫上的用戶xys被授予了sysdba,結果在test1庫上通過v$pwfile_users也可以看到xys用戶。

    SQL> connect sys/system as sysdba
    ERROR:
    ORA-01017: invalid username/password; logon denied

    SQL> connect sys/manager as sysdba
    已連接到空閒例程。

    SQL> startup
    ORACLE 例程已經啓動。
    Total System Global Area 167772160 bytes
    Fixed Size 1247900 bytes
    Variable Size 62915940 bytes
    Database Buffers 100663296 bytes
    Redo Buffers 2945024 bytes
    數據庫裝載完畢。
    數據庫已經打開。

    SQL> alter user sys identified by system;
    用戶已更改。

    SQL> show user
    USER 爲 SYS;

    SQL> show parameter db_name
    NAME TYPE VALUE
    ------------------------------------ ----------- ------------------------------
    db_name string test1

    SQL> select * from v$pwfile_users;
    USERNAME SYSDB SYSOP
    ------------------------------ ----- -----
    SYS TRUE TRUE
    XYS TRUE FALSE

    SQL> select username from dba_users;
    USERNAME
    ------------------------------
    OUTLN
    SYS
    SYSTEM
    TEST
    DBSNMP
    TSMSYS
    DIP
    已選擇7行。

    從上面查詢結果看到數據庫orcl和test1,準確的說是實例共享了口令文件之後,test1中根本不存在用戶xys,但是通過v$pwfile_users還是查詢出來了

    還有一個問題是如果remote_login_passwordfile=shared則sys的口令通過

    alter user...不能修改!

    SQL> show parameter remote_log
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- ------------------------------
    remote_login_passwordfile            string      SHARED

    SQL> alter user sys identified by manager;
    alter user sys identified by manager
    *
    第 1 行出現錯誤:
    ORA-28046: 不允許更改 SYS 口令

    提到alter user...這個系統權限,我覺得oracle做的不是很安全,只要有了alter user權限,sys用戶的口令可以隨意修改

    ,另外凡是修改具有sysdba or sysoper權限的用戶,如果通過alter user來修改口令,那麼同時修改了口令文件和數據庫中的口令。

    簡單的測試如下:
    SQL> create user test11 identified by test11;
    用戶已創建。

    SQL> grant connect , alter user to test11;
    授權成功。

    SQL> connect test11/test11
    已連接。

    SQL> CONNECT / as sysdba
    已連接。

    SQL> grant select on dba_users to test11;
    授權成功。

    SQL> connect test11/test11
    已連接。

    SQL> col username format a10
    SQL> col password format a30
    SQL> select password , username from dba_users where username ='SYS';
    PASSWORD                       USERNAME
    ------------------------------ ----------
    75800913E1B66343               SYS

    SQL> show user
    USER 爲 TEST11;

    SQL> alter user sys identified by manager;
    用戶已更改。

    SQL> select password , username from dba_users where username ='SYS';
    PASSWORD                       USERNAME
    ------------------------------ ----------
    5638228DAF52805F               SYS

    SQL>

    remote_login_passwordfile=shared時,也不能把sysdba or sysoper授予普通用戶!

    SQL> grant sysdba to test;
    grant sysdba to test
    *
    第 1 行出現錯誤:
    ORA-01999: 口令文件不能在 SHARED 模式下更新

    SQL> grant sysoper to test;
    grant sysoper to test
    *
    第 1 行出現錯誤:
    ORA-01999: 口令文件不能在 SHARED 模式下更新

    通過上面兩部分內容的解釋,瞭解了os認證和口令文件之後,如果爲了安全不想讓用戶以sysdba or sysoper權限連接數據庫,可以通過上面的方法屏蔽os認證的同時靜止使用口令文件。

    3、sysdba 和 sysoper
    很多人可能不瞭解sysdba and sysoper到底是什麼,其實他們是oracle的system privilege,通過查詢系統權限表system_privilege_map可以清楚的知道:

    SQL> select name from system_privilege_map where name like 'SYS%';
    NAME
    ----------------------------------------------------------------------------
    SYSOPER
    SYSDBA

    只不過這兩個權限就是以這種方式發揮作用的!

    兩種權限的比較在oracle doc上給出了明確的交代:
    The following operations are authorized by the SYSDBA and SYSOPER system privileges:
    System Privilege Operations Authorized
    SYSDBA Perform. STARTUP and SHUTDOWN operations
    ALTER DATABASE: open, mount, back up, or change character set
    CREATE DATABASE
    DROP DATABASE
    CREATE SPFILE
    ALTER DATABASE ARCHIVELOG
    ALTER DATABASE RECOVER
    Includes the RESTRICTED SESSION privilege
    Effectively, this system privilege allows a user to connect as user SYS.
    SYSOPER Perform. STARTUP and SHUTDOWN operations
    CREATE SPFILE
    ALTER DATABASE OPEN/MOUNT/BACKUP
    ALTER DATABASE ARCHIVELOG
    ALTER DATABASE RECOVER (Complete recovery only. Any form. of incomplete recovery, such as UNTIL TIME|CHANGE|CANCEL|CONTROLFILE requires connecting as SYSDBA.)
    Includes the RESTRICTED SESSION privilege
    This privilege allows a user to perform. basic operational tasks, but without the ability to look at user data.

    值的一提的是win下尤其是home版的xp控制面板中沒有組的可操作界面,而oracle默認安裝之後也沒有爲我們創建ora_oper 這個組,因此在以sysoper權限連接數據庫時提示沒有權限:

    SQL> connect / as sysoper
    ERROR:
    ORA-01031: 權限不足

    爲了能夠以sysoper方式連接數據庫,於是可以通過dos命令方式創建ora_oper組,同時把os用戶加入到這個組中:

    E:>net  localgroup ora_oper /add
    命令成功完成。

    E:>net  localgroup ora_oper wch /add
    命令成功完成。

    有關localgroup的詳細說明可以通過命令net help localgroup獲得更多的幫助,注意和group的區別,group用在domain中
    再次嘗試接連,連接成功:
    SQL> connect / as sysoper
    已連接。

    SQL> show user
    USER 爲 PUBLIC;

    SQL>
    但是需要注意的是以sysoper權限連接數據庫時顯示的schema是public,而以sysdba連接時顯示的schema是我們衆所周知的sys,這也是sysdba和sysoper的區別之一。

    同時需要注意的是在linux下默認是可以以sysoper 連接數據庫的:

    [oracle@xys oracle]$ sqlplus /nolog
    SQL*Plus: Release 11.1.0.6.0 - Production on Fri Dec 7 23:52:49 2007
    Copyright (c) 1982, 2007, Oracle.  All rights reserved.
    SQL> connect / as sysoper
    Connected to an idle instance.

    SQL> create user wch identified externally;
    用戶已創建。

    SQL> grant create session to wch;
    授權成功。

    SQL> show parameter auth
    NAME                                 TYPE        VALUE
    ------------------------------------ ----------- -------------------------
    os_authent_prefix                    string      OPS$
    remote_os_authent                    boolean     FALSE

    SQL> col username format a10
    SQL> col password format a30
    SQL> select username , password from dba_users where username='WCH';
    USERNAME   PASSWORD
    ---------- ------------------------------
    WCH        EXTERNAL

    SQL> connect /
    ERROR:
    ORA-01017: 用戶名/口令無效; 登錄被拒絕
    警告: 您不再連接到 ORACLE。

    SQL>

使用普通用戶os認證的好處是可以在執行一些批處理腳本時屏蔽數據庫連接用戶的口令,如exp ,expdp . sqlldr等至
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章