[轉載] 使用Oracle的PROFILE對使用者資源限制和密碼限制的研究與探索

tolywang發表於2009-11-12

 


1.使用者建立語句PROFILE選項“引發的血案”
如果大家細心的話,在建立使用者的語法中有這麼一個選項“PROFILE profile”。
下面是Oracle 11gR2官方文件中關於建立使用者的語法描述(較之10g的文件可讀性加強了,當然功能也同樣有所增加):
CREATE USER user
   IDENTIFIED { BY password
              | EXTERNALLY [ AS 'certificate_DN'  |  AS 'kerberos_principal_name' ]
              | GLOBALLY [ AS '[ directory_DN ]' ]
              }
   [ DEFAULT TABLESPACE tablespace
   | TEMPORARY TABLESPACE
        { tablespace | tablespace_group_name }
   | { QUOTA { size_clause | UNLIMITED } ON tablespace }...
   | PROFILE profile
   | PASSWORD EXPIRE
   | ACCOUNT { LOCK | UNLOCK }
     [ DEFAULT TABLESPACE tablespace
     | TEMPORARY TABLESPACE
          { tablespace | tablespace_group_name }
     | { QUOTA { size_clause | UNLIMITED } ON tablespace }...
    | PROFILE profile
     | PASSWORD EXPIRE
     | ACCOUNT { LOCK | UNLOCK }
     | ENABLE EDITIONS
     ]...
  ] ;

2.提問:PROFILE選項是做什麼用的呢?
回答:簡要的說,PROFILE在Oracle資料庫對資料庫使用者能夠使用的資源做進一步的限制的一種手段,如對連線到某個使用者的session或sql所能使用的CPU資源進行控制,又如控制Oracle使用者的密碼管理策略等等……

3.檢視系統的預設PROFILE
1)透過dba_profiles檢視檢視一下系統中預設都有哪些PROFILE
資料庫建立以後,系統中只會存在一個名為DEFAULT的預設PROFILE,在使用者建立之後,如果不做特殊指定,每個使用者的PROFILE都會預設的使用個預設的PROFILE。
> select distinct profile from dba_profiles;

PROFILE
----------
DEFAULT

2)全面檢視一下這個PROFILE都包含哪些限制定義
> select * from dba_profiles;

PROFILE    RESOURCE_NAME                    RESOURCE LIMIT
---------- -------------------------------- -------- -----------------
DEFAULT    COMPOSITE_LIMIT                  KERNEL   UNLIMITED
DEFAULT    SESSIONS_PER_USER                KERNEL   UNLIMITED
DEFAULT    CPU_PER_SESSION                  KERNEL   UNLIMITED
DEFAULT    CPU_PER_CALL                     KERNEL   UNLIMITED
DEFAULT    LOGICAL_READS_PER_SESSION        KERNEL   UNLIMITED
DEFAULT    LOGICAL_READS_PER_CALL           KERNEL   UNLIMITED
DEFAULT    IDLE_TIME                        KERNEL   UNLIMITED
DEFAULT    CONNECT_TIME                     KERNEL   UNLIMITED
DEFAULT    PRIVATE_SGA                      KERNEL   UNLIMITED
DEFAULT    FAILED_LOGIN_ATTEMPTS            PASSWORD 10
DEFAULT    PASSWORD_LIFE_TIME               PASSWORD UNLIMITED
DEFAULT    PASSWORD_REUSE_TIME              PASSWORD UNLIMITED
DEFAULT    PASSWORD_REUSE_MAX               PASSWORD UNLIMITED
DEFAULT    PASSWORD_VERIFY_FUNCTION         PASSWORD NULL
DEFAULT    PASSWORD_LOCK_TIME               PASSWORD UNLIMITED
DEFAULT    PASSWORD_GRACE_TIME              PASSWORD UNLIMITED

16 rows selected.

3)結論
透過上面的檢視,可以得到這個系統預設的PROFILE “DEFAULT”的配置資訊只對密碼的錯誤嘗試次數做了限制(最多可以錯誤輸錯10次密碼),如果我們啟用了PROFILE(下面有介紹如何啟用和停止PROFILE),預設的限制只有這些。如果想要改變限制條件,有兩種方法:第一種方法是可以對這個預設的PROFILE做個性化的調整;第二種方法是再重新定製一個新的PROFILE滿足新的需求。

4.對建立PROFILE的標準語法做一下“解剖麻雀”(更多細節可以參考Oracle的官方文件)
1)建立PROFILE的語法如下:
CREATE PROFILE profile
   LIMIT { resource_parameters 對資源的限制
         | password_parameters 對密碼的限制
         }...
;

2)對資料庫資源做限制時,下面是全部可用的引數:
{ { SESSIONS_PER_USER 每個使用者名稱所允許的並行會話數
  | CPU_PER_SESSION   一個會話一共可以使用的CPU時間,單位是百分之一秒
  | CPU_PER_CALL      一次SQL呼叫(解析、執行和獲取)允許使用的CPU時間
  | CONNECT_TIME      限制會話連線時間,單位是分鐘
  | IDLE_TIME         允許空閒會話的時間,單位是分鐘
  | LOGICAL_READS_PER_SESSION 限制會話對資料塊的讀取,單位是塊
  | LOGICAL_READS_PER_CALL    限制SQL呼叫對資料塊的讀取,單位是塊
  | COMPOSITE_LIMIT   “組合打法”
  }
  { integer | UNLIMITED | DEFAULT }
| PRIVATE_SGA   限制會話在SGA中Shared Pool中私有空間的分配
  { size_clause | UNLIMITED | DEFAULT }
}

3)對密碼做限制時,下面是全部可用的引數:
{ { FAILED_LOGIN_ATTEMPTS 帳戶被鎖定之前可以錯誤嘗試的次數
  | PASSWORD_LIFE_TIME    密碼可以被使用的天數,單位是天,預設值180天
  | PASSWORD_REUSE_TIME   密碼可重用的間隔時間(結合PASSWORD_REUSE_MAX)
  | PASSWORD_REUSE_MAX    密碼的最大改變次數(結合PASSWORD_REUSE_TIME)
  | PASSWORD_LOCK_TIME    超過錯誤嘗試次數後,使用者被鎖定的天數,預設1天
  | PASSWORD_GRACE_TIME   當密碼過期之後還有多少天可以使用原密碼
  }
  { expr | UNLIMITED | DEFAULT }
| PASSWORD_VERIFY_FUNCTION
  { function | NULL | DEFAULT }
}

5.OK,語法已經瞭然於胸,那麼我們來實際建立一個PROFILE(這裡的名字我們稱其為:sec_profile),在感性認識的同時一同探索一下在這個過程中會遇到的一些有趣現象。
1)嘗試建立一個混合型的PROFILE(包含資源限制和密碼限制)
> CREATE PROFILE sec_profile LIMIT
  2     SESSIONS_PER_USER          UNLIMITED
  3     CPU_PER_SESSION            UNLIMITED
  4     CPU_PER_CALL               6000
  5     CONNECT_TIME               60
  6     LOGICAL_READS_PER_SESSION  DEFAULT
  7     LOGICAL_READS_PER_CALL     6000
  8     COMPOSITE_LIMIT            6000000
  9     PRIVATE_SGA                66K
 10     FAILED_LOGIN_ATTEMPTS      6
 11     PASSWORD_LIFE_TIME         60
 12     PASSWORD_REUSE_TIME        60
 13     PASSWORD_REUSE_MAX         5
 14     PASSWORD_LOCK_TIME         1/24
 15     PASSWORD_GRACE_TIME        10  
 16     PASSWORD_VERIFY_FUNCTION   verify_function
 17  /
CREATE PROFILE sec_profile LIMIT
*
ERROR at line 1:
ORA-07443: function VERIFY_FUNCTION not found

2)報錯原因
為什麼會報錯?錯誤提示很清楚,VERIFY_FUNCTION這個函式不存在。既然知道不存在,那我們如何建立它呢?
回答:
VERIFY_FUNCTION函式是透過utlpwdmg.sql指令碼建立的,該指令碼所在的目錄是$ORACLE_HOME/rdbms/admin/

3)建立密碼複雜性檢驗函式VERIFY_FUNCTION
我們使用utlpwdmg.sql指令碼建立以下這個VERIFY_FUNCTION密碼複雜度校驗函式
> @?/rdbms/admin/utlpwdmg.sql

Function created.


Profile altered.

4)utlpwdmg.sql指令碼中的小秘密
細心的您在執行utlpwdmg.sql指令碼的過程中一定發現了有一個“Profile altered”的提示,難道這個指令碼修改了某個PROFILE資訊麼?正如您所料,它修改了系統的預設PROFILE “DEFAULT”,再次檢視一下現在的DEFAULT的定義資訊:
> select * from dba_profiles;

PROFILE    RESOURCE_NAME                    RESOURCE LIMIT
---------- -------------------------------- -------- -----------------
DEFAULT    COMPOSITE_LIMIT                  KERNEL   UNLIMITED
DEFAULT    SESSIONS_PER_USER                KERNEL   UNLIMITED
DEFAULT    CPU_PER_SESSION                  KERNEL   UNLIMITED
DEFAULT    CPU_PER_CALL                     KERNEL   UNLIMITED
DEFAULT    LOGICAL_READS_PER_SESSION        KERNEL   UNLIMITED
DEFAULT    LOGICAL_READS_PER_CALL           KERNEL   UNLIMITED
DEFAULT    IDLE_TIME                        KERNEL   UNLIMITED
DEFAULT    CONNECT_TIME                     KERNEL   UNLIMITED
DEFAULT    PRIVATE_SGA                      KERNEL   UNLIMITED
DEFAULT    FAILED_LOGIN_ATTEMPTS            PASSWORD 3
DEFAULT    PASSWORD_LIFE_TIME               PASSWORD 60
DEFAULT    PASSWORD_REUSE_TIME              PASSWORD 1800
DEFAULT    PASSWORD_REUSE_MAX               PASSWORD UNLIMITED
DEFAULT    PASSWORD_VERIFY_FUNCTION         PASSWORD VERIFY_FUNCTION
DEFAULT    PASSWORD_LOCK_TIME               PASSWORD .0006
DEFAULT    PASSWORD_GRACE_TIME              PASSWORD 10

16 rows selected.

與系統建立時的DEFAULT PROFILE相比較,之前只有10次密碼輸入錯誤的限制,執行完成這個函式建立之後,我們發現系統預設的PROFILE已經對系統有了一個非常嚴格的約束。也就是說現在系統上的每一個使用者在預設情況下都多了這些密碼方面的限制。

5)驗證一下新預設的PROFILE “DEFAULT”關於錯誤密碼輸入次數的限制
我們模擬一下錯誤輸錯密碼三次後的效果,可以看到,在第四次輸入後,sec使用者被鎖定了。
> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied


Warning: You are no longer connected to ORACLE.
> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied


> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied


> conn sec/a
ERROR:
ORA-28000: the account is locked

6)使用dba_users檢視比較一下使用者的前後狀態
使用者sec已經因錯誤密碼輸入次數超過3此導致使用者被鎖定了,進一步比較一下使用者的狀態。
> col USERNAME for a10
> col ACCOUNT_STATUS for a20
> col PROFILE for a10
> select USERNAME,ACCOUNT_STATUS,LOCK_DATE,EXPIRY_DATE from dba_users where username = 'SEC';

USERNAME   ACCOUNT_STATUS       LOCK_DATE           EXPIRY_DATE
---------- -------------------- ------------------- -------------------
SEC        OPEN

> select USERNAME,ACCOUNT_STATUS,LOCK_DATE,EXPIRY_DATE from dba_users where username = 'SEC';

USERNAME   ACCOUNT_STATUS       LOCK_DATE           EXPIRY_DATE
---------- -------------------- ------------------- -------------------
SEC        LOCKED(TIMED)        2009-10-11 16:05:03 2009-12-09 08:46:36

7)既然預設的PROFILE發生了變化,那麼就會面臨一個實際問題,如何恢復成原始狀態呢?這裡給出一個比較簡單的方法,就是使用ALTER PROFILE命令修改成原來的模樣
> ALTER PROFILE DEFAULT LIMIT
  2   COMPOSITE_LIMIT             UNLIMITED
  3   SESSIONS_PER_USER           UNLIMITED
  4   CPU_PER_SESSION             UNLIMITED
  5   CPU_PER_CALL                UNLIMITED
  6   LOGICAL_READS_PER_SESSION   UNLIMITED
  7   LOGICAL_READS_PER_CALL      UNLIMITED
  8   IDLE_TIME                   UNLIMITED
  9   CONNECT_TIME                UNLIMITED
 10   PRIVATE_SGA                 UNLIMITED
 11   FAILED_LOGIN_ATTEMPTS       10
 12   PASSWORD_LIFE_TIME          UNLIMITED
 13   PASSWORD_REUSE_TIME         UNLIMITED
 14   PASSWORD_REUSE_MAX          UNLIMITED
 15   PASSWORD_VERIFY_FUNCTION    NULL
 16   PASSWORD_LOCK_TIME          UNLIMITED
 17   PASSWORD_GRACE_TIME         UNLIMITED
 18  /

Profile altered.

8)最後我們重新建立一下這個實驗PROFILE:sec_profile,可以預測,這次一定會成功滴~~~
> CREATE PROFILE sec_profile LIMIT
  2     SESSIONS_PER_USER          UNLIMITED
  3     CPU_PER_SESSION            UNLIMITED
  4     CPU_PER_CALL               6000
  5     CONNECT_TIME               60
  6     LOGICAL_READS_PER_SESSION  DEFAULT
  7     LOGICAL_READS_PER_CALL     6000
  8     COMPOSITE_LIMIT            6000000
  9     PRIVATE_SGA                66K
 10     FAILED_LOGIN_ATTEMPTS      6
 11     PASSWORD_LIFE_TIME         60
 12     PASSWORD_REUSE_TIME        60
 13     PASSWORD_REUSE_MAX         5
 14     PASSWORD_LOCK_TIME         1/24
 15     PASSWORD_GRACE_TIME        10 
 16     PASSWORD_VERIFY_FUNCTION   verify_function
 17  /

Profile created.

建立成功鳥~~
在這個實驗中,我們使用了PROFILE幾乎所有的引數,惟一沒有包含的引數是IDLE_TIME,目的僅僅是為了說明一個細節:如果該PROFILE被授權給使用者後,這個被省略的IDLE_TIME引數將繼承預設PROFILE “DEFALT”中的定義。

對上面我們建立的PROFILE逐行做一下詮釋,以便加深理解:
第 2行:對使用者的併發連線會話數不做限制
第 3行:對於連線到使用者的每一個session的CPU時間的使用不做限制
第 4行:一次呼叫消耗的CPU時間不能超過60秒(不超過一分鐘)
第 5行:連線到使用者的每次會話時間不能超過60分鐘(不超過一個小時)
第 6行:一次會話使用的物理讀與邏輯讀資料塊總量與DEFAULT profile中定義保持一致
第 7行:一次呼叫使用的物理讀與邏輯讀資料塊總量不超過6000個資料塊
第 8行:一次會話總的資源消耗不超過6000000個服務單元(service units)
第 9行:一次會話在SGA中不能分配超過66K的空間
第10行:帳戶被鎖定之前允許6次的錯誤嘗試
第11行:超過此生命週期後密碼作廢
第12行:密碼重用時間60天
第13行:密碼重用之前密碼需要完成5次改變
第14行:超過錯誤嘗試次數後,使用者將被鎖定1小時
第15行:當密碼過期之後原密碼還可以使用10天
第16行:使用密碼複雜度校驗函式verify_function對密碼做檢查

再單獨深入解釋一下第12行和13行組合搭配之後的含義:也就是說只有完成了5次的密碼修改後並且已經超過60天后,之前的密碼才能夠再一次被使用。

9)透過dba_profiles檢視再一次檢視一下此時系統中存在的PROFILE的資訊
> col PROFILE for a12
> col RESOURCE_NAME for a25
> col LIMIT for a15
> select * from dba_profiles order by 1,2;

PROFILE      RESOURCE_NAME             RESOURCE LIMIT
------------ ------------------------- -------- ---------------
DEFAULT      COMPOSITE_LIMIT           KERNEL   UNLIMITED
DEFAULT      CONNECT_TIME              KERNEL   UNLIMITED
DEFAULT      CPU_PER_CALL              KERNEL   UNLIMITED
DEFAULT      CPU_PER_SESSION           KERNEL   UNLIMITED
DEFAULT      FAILED_LOGIN_ATTEMPTS     PASSWORD 3
DEFAULT      IDLE_TIME                 KERNEL   UNLIMITED
DEFAULT      LOGICAL_READS_PER_CALL    KERNEL   UNLIMITED
DEFAULT      LOGICAL_READS_PER_SESSION KERNEL   UNLIMITED
DEFAULT      PASSWORD_GRACE_TIME       PASSWORD 10
DEFAULT      PASSWORD_LIFE_TIME        PASSWORD 60
DEFAULT      PASSWORD_LOCK_TIME        PASSWORD .0006
DEFAULT      PASSWORD_REUSE_MAX        PASSWORD UNLIMITED
DEFAULT      PASSWORD_REUSE_TIME       PASSWORD 1800
DEFAULT      PASSWORD_VERIFY_FUNCTION  PASSWORD VERIFY_FUNCTION
DEFAULT      PRIVATE_SGA               KERNEL   UNLIMITED
DEFAULT      SESSIONS_PER_USER         KERNEL   UNLIMITED
SEC_PROFILE  COMPOSITE_LIMIT           KERNEL   5000000
SEC_PROFILE  CONNECT_TIME              KERNEL   45
SEC_PROFILE  CPU_PER_CALL              KERNEL   3000
SEC_PROFILE  CPU_PER_SESSION           KERNEL   UNLIMITED
SEC_PROFILE  FAILED_LOGIN_ATTEMPTS     PASSWORD 5
SEC_PROFILE  IDLE_TIME                 KERNEL   DEFAULT
SEC_PROFILE  LOGICAL_READS_PER_CALL    KERNEL   1000
SEC_PROFILE  LOGICAL_READS_PER_SESSION KERNEL   DEFAULT
SEC_PROFILE  PASSWORD_GRACE_TIME       PASSWORD 10
SEC_PROFILE  PASSWORD_LIFE_TIME        PASSWORD 60
SEC_PROFILE  PASSWORD_LOCK_TIME        PASSWORD .0416
SEC_PROFILE  PASSWORD_REUSE_MAX        PASSWORD 5
SEC_PROFILE  PASSWORD_REUSE_TIME       PASSWORD 60
SEC_PROFILE  PASSWORD_VERIFY_FUNCTION  PASSWORD VERIFY_FUNCTION
SEC_PROFILE  PRIVATE_SGA               KERNEL   15360
SEC_PROFILE  SESSIONS_PER_USER         KERNEL   UNLIMITED

32 rows selected.

10)刪除PROFILE
既然有建立,就一定對應著刪除,刪除方法很簡單,語法如下:
DROP PROFILE profile [ CASCADE ] ;

如果建立的PROFILE已經授權給了具體的使用者,則需要使用CASCADE選項級聯的收回相應的限制資訊,在收回這些限制資訊之後將會以系統預設的PROFILE對該使用者進行限制。
刪除示例如下:
> drop profile SEC_PROFILE cascade;

Profile dropped.

如果該PROFILE已經授權給具體的使用者,使用不帶有cascade選項的刪除命令將得到如下的報錯資訊:
> drop profile SEC_PROFILE;
drop profile SEC_PROFILE
*
ERROR at line 1:
ORA-02382: profile SEC_PROFILE has users assigned, cannot drop without CASCADE

6.關於PROFILE內容何時生效的一點注意事項
這裡討論需要談到一個系統引數,它就是resource_limit。

如果要開啟“資源限制”的話,這個引數必須是“TRUE”的狀態
> show parameter resource_limit

NAME            TYPE                 VALUE
--------------- -------------------- ----------------------
resource_limit  boolean              FALSE

 

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

相關文章