【PROFILE】使用Oracle的PROFILE對使用者資源限制和密碼限制的研究與探索
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。
sys@ora10g> select distinct profile from dba_profiles;
PROFILE
----------
DEFAULT
2)全面檢視一下這個PROFILE都包含哪些限制定義
sys@ora10g> 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(包含資源限制和密碼限制)
sys@ora10g> 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密碼複雜度校驗函式
sys@ora10g> @?/rdbms/admin/utlpwdmg.sql
Function created.
Profile altered.
4)utlpwdmg.sql指令碼中的小秘密
細心的您在執行utlpwdmg.sql指令碼的過程中一定發現了有一個“Profile altered”的提示,難道這個指令碼修改了某個PROFILE資訊麼?正如您所料,它修改了系統的預設PROFILE “DEFAULT”,再次檢視一下現在的DEFAULT的定義資訊:
sys@ora10g> 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使用者被鎖定了。
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
Warning: You are no longer connected to ORACLE.
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
sys@ora10g> conn sec/a
ERROR:
ORA-28000: the account is locked
6)使用dba_users檢視比較一下使用者的前後狀態
使用者sec已經因錯誤密碼輸入次數超過3此導致使用者被鎖定了,進一步比較一下使用者的狀態。
sys@ora10g> col USERNAME for a10
sys@ora10g> col ACCOUNT_STATUS for a20
sys@ora10g> col PROFILE for a10
sys@ora10g> select USERNAME,ACCOUNT_STATUS,LOCK_DATE,EXPIRY_DATE from dba_users where username = 'SEC';
USERNAME ACCOUNT_STATUS LOCK_DATE EXPIRY_DATE
---------- -------------------- ------------------- -------------------
SEC OPEN
sys@ora10g> 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命令修改成原來的模樣
sys@ora10g> 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,可以預測,這次一定會成功滴~~~
sys@ora10g> 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的資訊
sys@ora10g> col PROFILE for a12
sys@ora10g> col RESOURCE_NAME for a25
sys@ora10g> col LIMIT for a15
sys@ora10g> 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對該使用者進行限制。
刪除示例如下:
sys@ora10g> drop profile SEC_PROFILE cascade;
Profile dropped.
如果該PROFILE已經授權給具體的使用者,使用不帶有cascade選項的刪除命令將得到如下的報錯資訊:
sys@ora10g> 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”的狀態
sys@ora10g> show parameter resource_limit
NAME TYPE VALUE
--------------- -------------------- ----------------------
resource_limit boolean FALSE
這裡有一個小細節不得不提:
之所以稱這個引數為resource_limit(資源限制)而沒有稱作“profile_limit”,是因為這個引數只對PROFILE中的資源限制部分起作用,如果是預設的FALSE狀態,表示PROFILE定義中的資源限制條件不起作用,只有該引數為TRUE時,資源限制的定義才生效。
不過,關於PROFILE中密碼限制的條件則與這個引數無關,無論這個引數設定為什麼值,有關密碼限制的條件都會預設生效,從這個細節上可以看出來Oracle對使用者密碼的重視程度。
因此關於PROFILE的生效情況結論是:
1)使用者所有擁有的PROFILE中有關密碼的限制永遠生效,不受限制。
2)使用者所有擁有的PROFILE中有關資源的限制與resource_limit引數的設定有關,當為TRUE時生效,當為FALSE時(預設值是FALSE)無效。
7.一切都OK了,最後我們來演示一下將新建立的PROFILE sec_profile指定給具體使用者sec的操作
sys@ora10g> alter user sec profile sec_profile;
User altered.
sys@ora10g> select USERNAME,PROFILE from dba_users where USERNAME = 'SEC';
USERNAME PROFILE
---------- ------------
SEC SEC_PROFILE
8.【附】密碼驗證函式VERIFY_FUNCTION的建立指令碼內容utlpwdmg.sql,供參考。
ora10g@secDB /home/oracle$ cat $ORACLE_HOME/rdbms/admin/utlpwdmg.sql
Rem
Rem $Header: utlpwdmg.sql 31-aug-2000.11:00:47 nireland Exp $
Rem
Rem utlpwdmg.sql
Rem
Rem Copyright (c) Oracle Corporation 1996, 2000. All Rights Reserved.
Rem
Rem NAME
Rem utlpwdmg.sql - script. for Default Password Resource Limits
Rem
Rem DESCRIPTION
Rem This is a script. for enabling the password management features
Rem by setting the default password resource limits.
Rem
Rem NOTES
Rem This file contains a function for minimum checking of password
Rem complexity. This is more of a sample function that the customer
Rem can use to develop the function for actual complexity checks that the
Rem customer wants to make on the new password.
Rem
Rem MODIFIED (MM/DD/YY)
Rem nireland 08/31/00 - Improve check for username=password. #1390553
Rem nireland 06/28/00 - Fix null old password test. #1341892
Rem asurpur 04/17/97 - Fix for bug479763
Rem asurpur 12/12/96 - Changing the name of password_verify_function
Rem asurpur 05/30/96 - New script. for default password management
Rem asurpur 05/30/96 - Created
Rem
-- This script. sets the default password resource parameters
-- This script. needs to be run to enable the password features.
-- However the default resource parameters can be changed based
-- on the need.
-- A default password complexity function is also provided.
-- This function makes the minimum complexity checks like
-- the minimum length of the password, password not same as the
-- username, etc. The user may enhance this function according to
-- the need.
-- This function must be created in SYS schema.
-- connect sys/<password> as sysdba before running the script
CREATE OR REPLACE FUNCTION verify_function
(username varchar2,
password varchar2,
old_password varchar2)
RETURN boolean IS
n boolean;
m integer;
differ integer;
isdigit boolean;
ischar boolean;
ispunct boolean;
digitarray varchar2(20);
punctarray varchar2(25);
chararray varchar2(52);
BEGIN
digitarray:= '0123456789';
chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
punctarray:='!"#$%&()``*+,-/:;<=>?_';
-- Check if the password is same as the username
IF NLS_LOWER(password) = NLS_LOWER(username) THEN
raise_application_error(-20001, 'Password same as or similar to user');
END IF;
-- Check for the minimum length of the password
IF length(password) < 4 THEN
raise_application_error(-20002, 'Password length less than 4');
END IF;
-- Check if the password is too simple. A dictionary of words may be
-- maintained and a check may be made so as not to allow the words
-- that are too simple for the password.
IF NLS_LOWER(password) IN ('welcome', 'database', 'account', 'user', 'password', 'oracle', 'computer', 'abcd') THEN
raise_application_error(-20002, 'Password too simple');
END IF;
-- Check if the password contains at least one letter, one digit and one
-- punctuation mark.
-- 1. Check for the digit
isdigit:=FALSE;
m := length(password);
FOR i IN 1..10 LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(digitarray,i,1) THEN
isdigit:=TRUE;
GOTO findchar;
END IF;
END LOOP;
END LOOP;
IF isdigit = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one digit, one character and one punctuation');
END IF;
-- 2. Check for the character
<<findchar>>
ischar:=FALSE;
FOR i IN 1..length(chararray) LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(chararray,i,1) THEN
ischar:=TRUE;
GOTO findpunct;
END IF;
END LOOP;
END LOOP;
IF ischar = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one \
digit, one character and one punctuation');
END IF;
-- 3. Check for the punctuation
<<findpunct>>
ispunct:=FALSE;
FOR i IN 1..length(punctarray) LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(punctarray,i,1) THEN
ispunct:=TRUE;
GOTO endsearch;
END IF;
END LOOP;
END LOOP;
IF ispunct = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one \
digit, one character and one punctuation');
END IF;
<<endsearch>>
-- Check if the password differs from the previous password by at least
-- 3 letters
IF old_password IS NOT NULL THEN
differ := length(old_password) - length(password);
IF abs(differ) < 3 THEN
IF length(password) < length(old_password) THEN
m := length(password);
ELSE
m := length(old_password);
END IF;
differ := abs(differ);
FOR i IN 1..m LOOP
IF substr(password,i,1) != substr(old_password,i,1) THEN
differ := differ + 1;
END IF;
END LOOP;
IF differ < 3 THEN
raise_application_error(-20004, 'Password should differ by at \
least 3 characters');
END IF;
END IF;
END IF;
-- Everything is fine; return TRUE ;
RETURN(TRUE);
END;
/
-- This script. alters the default parameters for Password Management
-- This means that all the users on the system have Password Management
-- enabled and set to the following values unless another profile is
-- created with parameter values set to different value or UNLIMITED
-- is created and assigned to the user.
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 60
PASSWORD_GRACE_TIME 10
PASSWORD_REUSE_TIME 1800
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 3
PASSWORD_LOCK_TIME 1/1440
PASSWORD_VERIFY_FUNCTION verify_function;
仔細閱讀上面的指令碼,您可以得到關於verify_function函式的密碼複雜性校驗規則如下:
1)密碼最小長度為4個字元
2)密碼不能和使用者名稱相同
3)密碼要包含至少一個字元、一個數字和一個特殊字元
4)密碼需要至少有3個字元與之前的口令不相同
9.小結
透過PROFILE對使用者的資源和登入密碼的限制方法使用起來還是很貼心的,畢竟Oracle提供了這樣一種便捷的管理手段,對付資料庫方面的一般性審計還是遊刃有餘的,即使這些規則仍然不能滿足需求,Oracle也提供了新增和修改的介面,以便按需定製,當然會有一定的開發週期和成本。
Oracle對資料庫的安全性方面提供了非常多的手段來保證,如審計和許可權控制等優秀手段。對於一個商業資料庫的安全性審計是非常重要的,如果後臺的資料庫存在安全隱患,可以說必定會帶來一場浩劫,只是早晚的事情。如果您是一名維護DBA,一定要從資料庫的安全性上多多動腦筋,不要等待問題出現了才恍然大悟:哇塞,原來Oracle同學早就有補救的措施啦!
BTW:關於許可權控制的策略在使用前一定要做好充分的測試,確保對每一條限制規則理解透徹,不然會帶來不必要的麻煩,另外一個經驗就是:將每一步的限制規則記錄到一個特定的資料庫維護手冊中,方便查詢,同時也便於知識的傳承,利己利人,“好事兩樁”。
-- The End --
如果大家細心的話,在建立使用者的語法中有這麼一個選項“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。
sys@ora10g> select distinct profile from dba_profiles;
PROFILE
----------
DEFAULT
2)全面檢視一下這個PROFILE都包含哪些限制定義
sys@ora10g> 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(包含資源限制和密碼限制)
sys@ora10g> 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密碼複雜度校驗函式
sys@ora10g> @?/rdbms/admin/utlpwdmg.sql
Function created.
Profile altered.
4)utlpwdmg.sql指令碼中的小秘密
細心的您在執行utlpwdmg.sql指令碼的過程中一定發現了有一個“Profile altered”的提示,難道這個指令碼修改了某個PROFILE資訊麼?正如您所料,它修改了系統的預設PROFILE “DEFAULT”,再次檢視一下現在的DEFAULT的定義資訊:
sys@ora10g> 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使用者被鎖定了。
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
Warning: You are no longer connected to ORACLE.
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
sys@ora10g> conn sec/a
ERROR:
ORA-01017: invalid username/password; logon denied
sys@ora10g> conn sec/a
ERROR:
ORA-28000: the account is locked
6)使用dba_users檢視比較一下使用者的前後狀態
使用者sec已經因錯誤密碼輸入次數超過3此導致使用者被鎖定了,進一步比較一下使用者的狀態。
sys@ora10g> col USERNAME for a10
sys@ora10g> col ACCOUNT_STATUS for a20
sys@ora10g> col PROFILE for a10
sys@ora10g> select USERNAME,ACCOUNT_STATUS,LOCK_DATE,EXPIRY_DATE from dba_users where username = 'SEC';
USERNAME ACCOUNT_STATUS LOCK_DATE EXPIRY_DATE
---------- -------------------- ------------------- -------------------
SEC OPEN
sys@ora10g> 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命令修改成原來的模樣
sys@ora10g> 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,可以預測,這次一定會成功滴~~~
sys@ora10g> 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的資訊
sys@ora10g> col PROFILE for a12
sys@ora10g> col RESOURCE_NAME for a25
sys@ora10g> col LIMIT for a15
sys@ora10g> 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對該使用者進行限制。
刪除示例如下:
sys@ora10g> drop profile SEC_PROFILE cascade;
Profile dropped.
如果該PROFILE已經授權給具體的使用者,使用不帶有cascade選項的刪除命令將得到如下的報錯資訊:
sys@ora10g> 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”的狀態
sys@ora10g> show parameter resource_limit
NAME TYPE VALUE
--------------- -------------------- ----------------------
resource_limit boolean FALSE
這裡有一個小細節不得不提:
之所以稱這個引數為resource_limit(資源限制)而沒有稱作“profile_limit”,是因為這個引數只對PROFILE中的資源限制部分起作用,如果是預設的FALSE狀態,表示PROFILE定義中的資源限制條件不起作用,只有該引數為TRUE時,資源限制的定義才生效。
不過,關於PROFILE中密碼限制的條件則與這個引數無關,無論這個引數設定為什麼值,有關密碼限制的條件都會預設生效,從這個細節上可以看出來Oracle對使用者密碼的重視程度。
因此關於PROFILE的生效情況結論是:
1)使用者所有擁有的PROFILE中有關密碼的限制永遠生效,不受限制。
2)使用者所有擁有的PROFILE中有關資源的限制與resource_limit引數的設定有關,當為TRUE時生效,當為FALSE時(預設值是FALSE)無效。
7.一切都OK了,最後我們來演示一下將新建立的PROFILE sec_profile指定給具體使用者sec的操作
sys@ora10g> alter user sec profile sec_profile;
User altered.
sys@ora10g> select USERNAME,PROFILE from dba_users where USERNAME = 'SEC';
USERNAME PROFILE
---------- ------------
SEC SEC_PROFILE
8.【附】密碼驗證函式VERIFY_FUNCTION的建立指令碼內容utlpwdmg.sql,供參考。
ora10g@secDB /home/oracle$ cat $ORACLE_HOME/rdbms/admin/utlpwdmg.sql
Rem
Rem $Header: utlpwdmg.sql 31-aug-2000.11:00:47 nireland Exp $
Rem
Rem utlpwdmg.sql
Rem
Rem Copyright (c) Oracle Corporation 1996, 2000. All Rights Reserved.
Rem
Rem NAME
Rem utlpwdmg.sql - script. for Default Password Resource Limits
Rem
Rem DESCRIPTION
Rem This is a script. for enabling the password management features
Rem by setting the default password resource limits.
Rem
Rem NOTES
Rem This file contains a function for minimum checking of password
Rem complexity. This is more of a sample function that the customer
Rem can use to develop the function for actual complexity checks that the
Rem customer wants to make on the new password.
Rem
Rem MODIFIED (MM/DD/YY)
Rem nireland 08/31/00 - Improve check for username=password. #1390553
Rem nireland 06/28/00 - Fix null old password test. #1341892
Rem asurpur 04/17/97 - Fix for bug479763
Rem asurpur 12/12/96 - Changing the name of password_verify_function
Rem asurpur 05/30/96 - New script. for default password management
Rem asurpur 05/30/96 - Created
Rem
-- This script. sets the default password resource parameters
-- This script. needs to be run to enable the password features.
-- However the default resource parameters can be changed based
-- on the need.
-- A default password complexity function is also provided.
-- This function makes the minimum complexity checks like
-- the minimum length of the password, password not same as the
-- username, etc. The user may enhance this function according to
-- the need.
-- This function must be created in SYS schema.
-- connect sys/<password> as sysdba before running the script
CREATE OR REPLACE FUNCTION verify_function
(username varchar2,
password varchar2,
old_password varchar2)
RETURN boolean IS
n boolean;
m integer;
differ integer;
isdigit boolean;
ischar boolean;
ispunct boolean;
digitarray varchar2(20);
punctarray varchar2(25);
chararray varchar2(52);
BEGIN
digitarray:= '0123456789';
chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
punctarray:='!"#$%&()``*+,-/:;<=>?_';
-- Check if the password is same as the username
IF NLS_LOWER(password) = NLS_LOWER(username) THEN
raise_application_error(-20001, 'Password same as or similar to user');
END IF;
-- Check for the minimum length of the password
IF length(password) < 4 THEN
raise_application_error(-20002, 'Password length less than 4');
END IF;
-- Check if the password is too simple. A dictionary of words may be
-- maintained and a check may be made so as not to allow the words
-- that are too simple for the password.
IF NLS_LOWER(password) IN ('welcome', 'database', 'account', 'user', 'password', 'oracle', 'computer', 'abcd') THEN
raise_application_error(-20002, 'Password too simple');
END IF;
-- Check if the password contains at least one letter, one digit and one
-- punctuation mark.
-- 1. Check for the digit
isdigit:=FALSE;
m := length(password);
FOR i IN 1..10 LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(digitarray,i,1) THEN
isdigit:=TRUE;
GOTO findchar;
END IF;
END LOOP;
END LOOP;
IF isdigit = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one digit, one character and one punctuation');
END IF;
-- 2. Check for the character
<<findchar>>
ischar:=FALSE;
FOR i IN 1..length(chararray) LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(chararray,i,1) THEN
ischar:=TRUE;
GOTO findpunct;
END IF;
END LOOP;
END LOOP;
IF ischar = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one \
digit, one character and one punctuation');
END IF;
-- 3. Check for the punctuation
<<findpunct>>
ispunct:=FALSE;
FOR i IN 1..length(punctarray) LOOP
FOR j IN 1..m LOOP
IF substr(password,j,1) = substr(punctarray,i,1) THEN
ispunct:=TRUE;
GOTO endsearch;
END IF;
END LOOP;
END LOOP;
IF ispunct = FALSE THEN
raise_application_error(-20003, 'Password should contain at least one \
digit, one character and one punctuation');
END IF;
<<endsearch>>
-- Check if the password differs from the previous password by at least
-- 3 letters
IF old_password IS NOT NULL THEN
differ := length(old_password) - length(password);
IF abs(differ) < 3 THEN
IF length(password) < length(old_password) THEN
m := length(password);
ELSE
m := length(old_password);
END IF;
differ := abs(differ);
FOR i IN 1..m LOOP
IF substr(password,i,1) != substr(old_password,i,1) THEN
differ := differ + 1;
END IF;
END LOOP;
IF differ < 3 THEN
raise_application_error(-20004, 'Password should differ by at \
least 3 characters');
END IF;
END IF;
END IF;
-- Everything is fine; return TRUE ;
RETURN(TRUE);
END;
/
-- This script. alters the default parameters for Password Management
-- This means that all the users on the system have Password Management
-- enabled and set to the following values unless another profile is
-- created with parameter values set to different value or UNLIMITED
-- is created and assigned to the user.
ALTER PROFILE DEFAULT LIMIT
PASSWORD_LIFE_TIME 60
PASSWORD_GRACE_TIME 10
PASSWORD_REUSE_TIME 1800
PASSWORD_REUSE_MAX UNLIMITED
FAILED_LOGIN_ATTEMPTS 3
PASSWORD_LOCK_TIME 1/1440
PASSWORD_VERIFY_FUNCTION verify_function;
仔細閱讀上面的指令碼,您可以得到關於verify_function函式的密碼複雜性校驗規則如下:
1)密碼最小長度為4個字元
2)密碼不能和使用者名稱相同
3)密碼要包含至少一個字元、一個數字和一個特殊字元
4)密碼需要至少有3個字元與之前的口令不相同
9.小結
透過PROFILE對使用者的資源和登入密碼的限制方法使用起來還是很貼心的,畢竟Oracle提供了這樣一種便捷的管理手段,對付資料庫方面的一般性審計還是遊刃有餘的,即使這些規則仍然不能滿足需求,Oracle也提供了新增和修改的介面,以便按需定製,當然會有一定的開發週期和成本。
Oracle對資料庫的安全性方面提供了非常多的手段來保證,如審計和許可權控制等優秀手段。對於一個商業資料庫的安全性審計是非常重要的,如果後臺的資料庫存在安全隱患,可以說必定會帶來一場浩劫,只是早晚的事情。如果您是一名維護DBA,一定要從資料庫的安全性上多多動腦筋,不要等待問題出現了才恍然大悟:哇塞,原來Oracle同學早就有補救的措施啦!
BTW:關於許可權控制的策略在使用前一定要做好充分的測試,確保對每一條限制規則理解透徹,不然會帶來不必要的麻煩,另外一個經驗就是:將每一步的限制規則記錄到一個特定的資料庫維護手冊中,方便查詢,同時也便於知識的傳承,利己利人,“好事兩樁”。
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29067253/viewspace-2006088/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- [轉載] 使用Oracle的PROFILE對使用者資源限制和密碼限制的研究與探索Oracle密碼
- profile對密碼的限制密碼
- Oracle profile 使用者資源限制 說明Oracle
- 【PROFILE】使用Oracle PROFILE限制會話中每一次呼叫所使用的CPU資源Oracle會話
- 修改profile實現資源限制
- profile資源限制基礎記載
- 利用profile限制某使用者的連線數
- Oracle限制某個使用者的連線數及PROFILE介紹Oracle
- profile使用者密碼管理密碼
- profile中SESSIONS_PER_USER 資源限制特性測試Session
- profile限制user連線session數Session
- Oracle 限制業務使用者自身修改密碼Oracle密碼
- Oracle profile的使用Oracle
- Oracle中對使用者所能使用的資料庫資源進行限制Oracle資料庫
- Oracle中的使用者資源限制的幾點說明Oracle
- Oracle使用者profile詳解Oracle
- Oracle 使用者 profile 屬性Oracle
- AIX 使用者的系統資源使用限制AI
- MySQL Profile檢視SQL的資源使用MySql
- profile檔案對sysdba使用者的影響
- oracle透過trigger來限制使用者和ip連線資料庫的限制Oracle資料庫
- mysql 8.0.11 資料庫使用者密碼修改詭異的限制MySql資料庫密碼
- ORACLE SQL PROFILE使用OracleSQL
- AIX環境oracle使用者的.profile檔案(轉)AIOracle
- Oracle密碼規則及資源限制函式指令碼utlpwdmg.sqlOracle密碼函式指令碼SQL
- Docker的資源限制Docker
- profile進行密碼設定密碼
- 使用Oracle自帶profile以及函式簡單設定Oracle使用者名稱密碼規則Oracle函式密碼
- Oracle Profile 使用詳解Oracle
- sql profile的使用SQL
- Oracle profileOracle
- 【PROFILE】Oracle11g密碼複雜度說明Oracle密碼複雜度
- Oracle Profile 使用詳解(轉)Oracle
- oracle中sequence使用的限制Oracle
- oracle之profile的應用Oracle
- oracle之 profile的應用Oracle
- VSFTP針對不同的使用者限制不同的速度FTP
- Oracle的過載保護-資料庫資源限制Oracle資料庫