oracle中prad函数_等保测评2.0:Oracle身份鉴别

一、说明

本篇文章主要说一说oracle数据库中身份鉴别控制点中测评项a的相关内容和理解。

二、测评项a

a)应对登录的用户进行身份标识和鉴别,身份标识具有唯一性,身份鉴别信息具有复杂度要求并定期更换;

三、测评项a要求1

应对登录的用户进行身份标识和鉴别

oracle使用用户名对登录用户进行身份标识,这没啥好说的。oracle在身份鉴别这一块,拥有密码文件验证和操作系统验证两种方式。

密码文件验证的话,是需要登录用户输入用户名、口令的,但是操作系统验证则不需要。

对于数据库特殊账户的操作系统验证,仅由sqlnet.ora文件中的SQLNET.AUTHENTICATION_SERVICES进行控制。

这里大家如果不想麻烦的话,其实也没有必要把SQLNET.AUTHENTICATION_SERVICES参数的值在linux和windows系统中代表的意义都搞清楚,测评的时候直接测试即可。

以centos系统为例子,也就是测评的时候先登录oracle数据库服务器的oracle账户,如果被测评方不清楚oracle账户的口令,也可以登录到root账户,然后使用“su - oracle”命令切换过去。

其实这里需要登录的是属于oinstall用户组的用户,但是一般情况下没人会去改默认配置,默认安装情况下操作系统的oracle用户会属于oinstall用户组。

登录oracle账户成功后,使用sqlplus / as sysdba命令去登录oracle数据库,这里就是使用数据库特殊账户的操作系统验证方式去验证。

如果能登录成功则说明开启了这种验证方式,不能则说明没开启。

如果开启了,那么这个要求项它就不能满足了,顶多是部分符合,因为这种方式登录数据库特殊账户不需要用户名、密码(虽然只能在本地登录,且登录的操作系统账户需要隶属于oinstall用户组),是一个比较大的安全隐患。

还有一种针对数据库普通账户的操作系统验证方式,这种验证方式对于登录的操作系统账户没有啥要求。

先去查看remote_os_authent和os_authent_prefix参数,它们的默认值分别是FALSE和ops$。

如果remote_os_authent是FALSE,那么是否开启这种验证方式还是由SQLNET.AUTHENTICATION_SERVICES决定。

如果开启了,假定os_authent_prefix的值是ops$,假定操作系统中存在一个cv的账户。

那么只要oracle数据库中建立一个名为ops$cv的账户并给与基础权限(连接权限等),用户在登录操作系统中的cv后,可以直接使用sqlplus /或sqlplus / as normal(两个命令是一个意思),以普通账户的身份登录ops$cv账户(当然这里需在cv账户的环境变量里配置一下好方便的使用sqlplus命令)。

同样的,如果开启了这种验证方式,那么也就顶多是部分符合了。

如果remote_os_authent为TRUE,那不用看了,数据库普通账户的操作系统验证方式肯定开启了,并且数据库普通账户的远程操作系统验证方式也开启了。

还是用上面的数据举例子,假定os_authent_prefix的值是ops$,假定远程终端存在一个cv的操作系统账户,那么在远程终端那也可以用空用户名、空口令的方式登录ops$cv账户,更不安全了。

至于空口令,在oracle中似乎不能设置空口令,我反正没有尝试成功……

四、测评项a要求2

身份标识具有唯一性

即用户名不会重复,oracle自动实现,默认符合。

五、测评项a要求3

身份鉴别信息具有复杂度要求

这个要从两个方面看,我个人觉得两个方面都符合才能算达到要求。

第一个方面即实际的口令是否具有一定的复杂度,也即口令至少8位,且包含大写字母、小写字母、数字、特殊字符这四类字符种的三种,且口令不包含简单排列规律,如admin!@#123此类弱口令。

第二个方面就是在oracle中是否设置了口令复杂度策略,这里要看的就是配置表中的PASSWORD_VERIFY_FUNCTION字段的值:

select * from dba_profiles;

704c469af5e8ba03a8fb13b0337e75a9.png

这里插一句嘴,说一说配置表的规则,用户是可以自定义多个配置给不同的用户使用。

比如这里的PASSWORD_VERIFY_FUNCTION的Profile字段值为Default,某用户要使用Default的相关配置,就要设置DBA_USERS表中的Profile字段值为Default。

默认情况下,用户使用的都是Default:

select username,profile from DBA_USERS

753993b3599ac03175f3d12de3a4ecf8.png

好,咱们说一说PASSWORD_VERIFY_FUNCTION字段是什么意思,该字段的值应该为oracle中某函数对象的名字,当创建、更改用户口令时会调用到该函数对口令进行校验,默认情况下这里的值是null,也即不使用任何函数对口令进行校验。

在初级教材中,让我们去查看utlpwdmg.sql中的相关信息,其实是不准确的。

因为utlpwdmg.sql并不是函数本身,它只是创建函数的一段语句而已。

实际上在oracle11g中,运行utlpwdmg.sql会创建两个函数,一个是新版本的口令校验函数,一个是老版本的,在里面还会对配置表进行修改,让PASSWORD_VERIFY_FUNCTION的值为新版本的口令校验函数的名字。

这个是utlpwdmg.sql文件中新版本的口令校验函数FUNCTION verify_function_11G的定义语句:

CREATE OR REPLACE FUNCTION verify_function_11G(username varchar2,  password varchar2,  old_password varchar2)  RETURN boolean IS   n boolean;   m integer;   differ integer;   isdigit boolean;   ischar  boolean;   ispunct boolean;   db_name varchar2(40);   digitarray varchar2(20);   punctarray varchar2(25);   chararray varchar2(52);   i_char varchar2(10);   simple_password varchar2(10);   reverse_user varchar2(32);BEGIN   digitarray:= '0123456789';   chararray:= 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';   -- Check for the minimum length of the password   IF length(password) < 8 THEN      raise_application_error(-20001, 'Password length less than 8');   END IF;   -- Check if the password is same as the username or username(1-100)   IF NLS_LOWER(password) = NLS_LOWER(username) THEN     raise_application_error(-20002, 'Password same as or similar to user');   END IF;   FOR i IN 1..100 LOOP      i_char := to_char(i);      if NLS_LOWER(username)|| i_char = NLS_LOWER(password) THEN        raise_application_error(-20005, 'Password same as or similar to user name ');      END IF;    END LOOP;   -- Check if the password is same as the username reversed   FOR i in REVERSE 1..length(username) LOOP     reverse_user := reverse_user || substr(username, i, 1);   END LOOP;   IF NLS_LOWER(password) = NLS_LOWER(reverse_user) THEN     raise_application_error(-20003, 'Password same as username reversed');   END IF;   -- Check if the password is the same as server name and or servername(1-100)   select name into db_name from sys.v$database;   if NLS_LOWER(db_name) = NLS_LOWER(password) THEN      raise_application_error(-20004, 'Password same as or similar to server name');   END IF;   FOR i IN 1..100 LOOP      i_char := to_char(i);      if NLS_LOWER(db_name)|| i_char = NLS_LOWER(password) THEN        raise_application_error(-20005, 'Password same as or similar to server name ');      END IF;    END LOOP;   -- 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 ('welcome1', 'database1', 'account1', 'user1234', 'password1', 'oracle123', 'computer1', 'abcdefg1', 'change_on_install') THEN      raise_application_error(-20006, 'Password too simple');   END IF;   -- Check if the password is the same as oracle (1-100)    simple_password := 'oracle';    FOR i IN 1..100 LOOP      i_char := to_char(i);      if simple_password || i_char = NLS_LOWER(password) THEN        raise_application_error(-20007, 'Password too simple ');      END IF;    END LOOP;   -- Check if the password contains at least one letter, one digit   -- 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(-20008, 'Password must contain at least one digit, one character');   END IF;   -- 2\. Check for the character   <>   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 endsearch;         END IF;      END LOOP;   END LOOP;   IF ischar = FALSE THEN      raise_application_error(-20009, 'Password must contain at least one \              digit, and one character');   END IF;   <>   -- 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);     differ := abs(differ);     IF differ < 3 THEN       IF length(password) < length(old_password) THEN         m := length(password);       ELSE         m := length(old_password);       END IF;       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(-20011, 'Password should differ from the \            old password by at least 3 characters');       END IF;     END IF;   END IF;   -- Everything is fine; return TRUE ;   RETURN(TRUE);END;/

然后在这里,对配置文件进行了修改,设置PASSWORD_VERIFY_FUNCTION的值为verify_function_11G:

-- 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 LIMITPASSWORD_LIFE_TIME 180PASSWORD_GRACE_TIME 7PASSWORD_REUSE_TIME UNLIMITEDPASSWORD_REUSE_MAX UNLIMITEDFAILED_LOGIN_ATTEMPTS 10PASSWORD_LOCK_TIME 1PASSWORD_VERIFY_FUNCTION verify_function_11G;

这个是老版本的校验函数FUNCTION verify_function的定义语句:

-- Below is the older version of the script-- 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/ as sysdba before running the scriptCREATE 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   <>   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   <>   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;   <>   -- 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;/

所以,实际上想要知道现在实际使用的校验函数的内容,就应该直接在数据库中查看校验函数的内容,而不是去查看utlpwdmg.sql文件。

在这里,使用的是verify_function_11G,由于其内容我没有修改过,所以和utlpwdmg.sql中所定义的是一样的:

1ba4a183aa4fb39c720a9accc20da7b6.png

至于其中的内容嘛,注释写得很清楚的,我就从上到下大概说明下:

检查口令的最小长度,如果小于8就返回错误,所以口令的最小长度是9

 -- Check for the minimum length of the password   IF length(password) < 8 THEN      raise_application_error(-20001, 'Password length less than 8');   END IF;

检查被创建或被更改口令的账户的用户名是否和新的口令一样,如果一样返回错误

检查新的口令是是否等于用户名后面加上1到100的数字,比如用户名时user,那么口令如果是user0到user100中的任何一个,也会返回错误。

  -- Check if the password is same as the username or username(1-100)   IF NLS_LOWER(password) = NLS_LOWER(username) THEN     raise_application_error(-20002, 'Password same as or similar to user');   END IF;   FOR i IN 1..100 LOOP      i_char := to_char(i);      if NLS_LOWER(username)|| i_char = NLS_LOWER(password) THEN        raise_application_error(-20005, 'Password same as or similar to user name ');      END IF;    END LOOP;

这里是检查口令是否等于倒序的用户名,或者与其相似,比如用户名是user,则口令不能是r、re、res、resu中的任何一个

  -- Check if the password is same as the username reversed   FOR i in REVERSE 1..length(username) LOOP     reverse_user := reverse_user || substr(username, i, 1);   END LOOP;   IF NLS_LOWER(password) = NLS_LOWER(reverse_user) THEN     raise_application_error(-20003, 'Password same as username reversed');   END IF;

这里检查口令是否和数据库名相等,以及是否和数据库名0到数据库名100相等。

我这里是默认的数据库名:ORCL

616889ae37bc91fe459bbe1333e80032.png

  -- Check if the password is the same as server name and or servername(1-100)   select name into db_name from sys.v$database;   if NLS_LOWER(db_name) = NLS_LOWER(password) THEN      raise_application_error(-20004, 'Password same as or similar to server name');   END IF;   FOR i IN 1..100 LOOP      i_char := to_char(i);      if NLS_LOWER(db_name)|| i_char = NLS_LOWER(password) THEN        raise_application_error(-20005, 'Password same as or similar to server name ');      END IF;    END LOOP;

检查口令是否是一些简单的单词,只不过这里只是一个示例而已,用户可以根据需要多添加一些弱口令。

   -- 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 ('welcome1', 'database1', 'account1', 'user1234', 'password1', 'oracle123', 'computer1', 'abcdefg1', 'change_on_install') THEN      raise_application_error(-20006, 'Password too simple');   END IF;

检查口令是否是oracle1到oracle100中的一个,不过这里口令可以等于oracle,不知道为啥这里是否等于oracle的校验

   -- Check if the password is the same as oracle (1-100)    simple_password := 'oracle';    FOR i IN 1..100 LOOP      i_char := to_char(i);      if simple_password || i_char = NLS_LOWER(password) THEN        raise_application_error(-20007, 'Password too simple ');      END IF;    END LOOP;

检查口令是否包含至少一个数字和一个字母(同时包含才可以通过校验)

由于这里字母数组的定义是:chararray:= ‘abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

所以指的是至少一个大写或小写字母。

  -- Check if the password contains at least one letter, one digit   -- 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(-20008, 'Password must contain at least one digit, one character');   END IF;   -- 2\. Check for the character   <>   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 endsearch;         END IF;      END LOOP;   END LOOP;   IF ischar = FALSE THEN      raise_application_error(-20009, 'Password must contain at least one \              digit, and one character');   END IF;

检查口令和旧口令的相似程度:

假设新口令是user,旧口令是admin

新口令长度和旧口令长度的差值大于等于3的话,直接通过校验。

这里的差值是1,所以需要进行校验。

循环的次数为长度小的那一边的口令的长度,也就是user字符串的长度4。

顺序取字符串来对比:

u不等于a,differ的值加1,为1

s不等于d,differ加1,为2

最后循环4次结束,differ为4,

如果最后differ小于3,则未通过校验,大于等3,则通过校验。

 -- 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);     differ := abs(differ);     IF differ < 3 THEN       IF length(password) < length(old_password) THEN         m := length(password);       ELSE         m := length(old_password);       END IF;       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(-20011, 'Password should differ from the \            old password by at least 3 characters');       END IF;     END IF;   END IF;

最后,如果通过了所有的校验(中途没有返回错误),就直接返回true:

 -- Everything is fine; return TRUE ;   RETURN(TRUE);

从整个默认的新版的校验函数看来,主要就是口令长度不低于9位,需要同时包含数字、字母(大小写皆可),感觉稍微差了那么一点。

理论上比较好的应该是口令长度不低于8位(这里是9位当然更好了),同时包含数字、大写字母、小写字母、特殊字符其中的3种字符。

另外,不知道为什么,SYS账户的口令的更改,不受到这个校验函数的限制。

登录SYS按道理来说使用的是密码文件或操作系统的验证,所以不知道在USER$中SYS账户的PASSWORD字段的值有什么用,虽然也会跟着口令的更改而更改就是了。

六、测评项a要求4

并定期更换

一方面查看实际的更换时间:

select name,PTIME from USER$

36bccf75e8750aa9745fc15a0c3bb784.png

另一方面查看相关的策略,先看和口令过期直接相关的两个参数:

PASSWORD_LIFE_TIME和PASSWORD_GRACE_TIME

5fb28192d6ca967353255fe7a80bb8bf.png

这里的时间单位是天,我这里自己修改过,默认情况下PASSWORD_LIFE_TIME的值是180,PASSWORD_GRACE_TIME的值是7。

PASSWORD_LIFE_TIME代表口令过期时间,而PASSWORD_GRACE_TIME则代表口令过期后的宽恕时间。

口令过期但还未超过宽恕期时,登录时会提醒你口令在多久后过期(这里的过期是指超过宽恕期),询问你是否修改口令,可以不修改,然后正常登录账户。

但是超过宽恕期再登录,就无法登录上去了。

oracle在这里的逻辑是这样的,需要通过用户的登录来改变用户的状态。

举个例子,假如PASSWORD_LIFE_TIME的值是1,PASSWORD_GRACE_TIME的值是也是1。

我在2020年4月7日10点整,创建了一个账户,在DBA_USERS表中,该账户的CREATED(创建时间)就是2020年4月7日10点,ACCOUNT_STATUS(账户状态)是OPEN,在USER$表中该账户的PTIME(口令修改时间)也是2020年4月7日10点整。

在DBA_USERS表中,该账户的EXPIRY_DATE是PTIME+PASSWORD_LIFE_TIME的值,也就是2020年4月8日10点整。

(注意,在USER$表中也有一个EXPTIME字段,但是好像这个字段有时候不是实时的,需要用户的登录才会更新,比如现在,该字段就是一个空字符串)

那么,在到达2020年4月8日10点整后,这个账户的ACCOUNT_STATUS是不会自动变成EXPIRED(GRACE)(口令过期但还处于宽恕期内),只要你不登录这个账户,那么该账户会一直处于OPEN状态。哪怕是过了两天,也就是超过PASSWORD_LIFE_TIME+PASSWORD_GRACE_TIME的值,仍然是OPEN状态。

在2020年4月8日10点整后,登录该账户,会更新账户的ACCOUNT_STATUS,更新成EXPIRED(GRACE),而EXPIRY_DATE也会更新,更新为登录时间点+PASSWORD_GRACE_TIME的值。

同样的,如果在这之后一直不登录账户,则超过宽恕期后,账户的状态还是EXPIRED(GRACE),只有等你尝试登录这个账户时,才会更新状态值为EXPIRED,当然这个时候你也登录不上了。

所以根据账户状态值不同,EXPIRY_DATE代表的意思有所不同,状态值为OPEN,则代表过期时间是什么时间。状态值为EXPIRED(GRACE),则代表宽恕期结束是什么时间。

另外,更新PASSWORD_LIFE_TIME值,也会实时的更新账户的EXPIRY_DATE值,但是仅对处于OPEN状态的账户有效。

如某账户为OPEN状态,其EXPIRY_DATE值为2020年4月8日10点,此时将PASSWORD_LIFE_TIME更改为2,则EXPIRY_DATE值就变成2020年4月9日10点了。

但是如果该账户是处于EXPIRED(GRACE)状态,修改PASSWORD_LIFE_TIME或PASSWORD_GRACE_TIME对它都是没用的。

不知道为什么,SYS账户不受到口令过期的限制,我测试的时候确实是这样。

可能是因为它属于特殊账户?毕竟判断是否过期也要去先读取数据库,而SYS账户可以在数据库未开启的时候连接它。

与口令过期间接相关的两个参数:PASSWORD_REUSE_TIME和PASSWORD_REUSE_MAX

a7b44c36c577b81bf6eecdc8c7bfd24c.png

PASSWORD_REUSE_TIME:指定了口令在多少天内不能重用,单位为1天。

PASSWORD_REUSE_MAX:指定了当前口令在被重用之前需要更改几次。

这里的重用是针对每个账户的自己的口令,如果不设置这两个参数,设置账户新口令的时候就可以使用当前的口令,那么口令过期就不存在意义了。

这里光看说明是看是不太容易理解的,试一试就明白了:

在PASSWORD_REUSE_TIME、PASSWORD_REUSE_MAX均为默认值UNLIMITED的时候,修改口令的时候可以随意重用,用当前的口令当新口令也都可以。

这里会突然想到verify_function_11G,如果新口令和旧口令一样的话,应该通不过校验的才对。

经过实验,不知道是为什么old_password是空字符串,压根就没有传值进来,所以实际上直接跳过了旧口令和新口令的对比校验……

当PASSWORD_REUSE_TIME、PASSWORD_REUSE_MAX均非默认值UNLIMITED的时候,则需要两个条件都满足才可以更改口令。

如PASSWORD_REUSE_TIME从UNLIMITED变成1,以及PASSWORD_REUSE_MAX从UNLIMITED变成1开始,oracle开始记录使用过的口令。

如某账户,这个时候依次设置新口令a、b、c、d、e,此时的口令是e,在1天内,该账户设置新口令的话,使用a、b、c、d、e中的任何一个都不可以。

超过1天后,a、b、c、d均可作为新口令,但是e不可以,因为PASSWORD_REUSE_MAX的值是1,相当于从e往前数,有1个口令不能被当做新口令,那就是e自己了。如果PASSWORD_REUSE_MAX的值是2,那么e、d均不可以作为新口令。

而如果PASSWORD_REUSE_TIME为unlimited、PASSWORD_REUSE_MAX为某个数值,或者PASSWORD_REUSE_TIME为某个数值,PASSWORD_REUSE_MAX为unlimited的时候,账户使用的口令都不能当做新口令进行设置。

所以为了满足定期更换的要求,PASSWORD_REUSE_TIME、PASSWORD_REUSE_MAX都应该设置为非unlimited的值。

最后,不知道为什么,SYS账户也不受到这两个参数的限制,可以随意重用口令。

*本文作者:起于凡而非于凡,转载请注明来自FreeBuf.COM

685b6a852d58cf10a32d8cc57afc9cdf.gif

精彩推荐

bdeae2277cea3ae942e8f3f0b8983e57.png

04baa7bb42ac7f6b7008a90f15c8fb8d.png

3b881f75e4d93322738fa59b96e5f81d.png

cfe371c9b7ad7e1ede7224278437c54d.png

1d2ed476bde59bec61a4938fa89ae96c.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/520452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

区块链真的会火吗?

区块链的境地如何&#xff1f;2019年10月25日&#xff0c;应该是区块链技术人以及对区块链感兴趣的人狂欢的一天&#xff0c;因为在那天国家领导人发表讲话&#xff0c;将区块链作为核心技术自主创新重要突破&#xff0c;随着这个新闻爆出&#xff0c;区块链市场炸开了锅&#…

双11奇迹背后的大数据平台,不喧哗,自有声!

00:02:05 成交额超100亿 00:57:56 成交额超666亿 01:47:26 成交额超1000亿 15:49:39 成交额超1682亿 22:28:37 成交额超2000亿 2018年双11新纪录2135亿 高速跳转的数字&#xff0c;不断刷新的状态&#xff0c;光缆中狂奔的代码&#xff0c;键盘上飞舞的手指… 新的记录 绝非十…

阿里云推PostgreSQL 10 高可用版

2015年&#xff0c;阿里云宣布正式推出RDS for PostgreSQL服务,届时&#xff0c;阿里云成为国内首家同时支持MySQL、SQL Server 和PostgreSQL关系型数据库的云计算服务商。 用户在云上就能享受PostgreSQL引擎带来的对SQL标准和NoSQL的高度兼容、强大的处理复杂查询能力、以及丰…

百度万亿流量的转发引擎BFE开源了!华为折叠屏曝光,采用传统翻盖式手机折叠方案;微软将关闭安卓iOS平台Cortana……...

关注并标星星CSDN云计算 速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周两次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go goOPPO Realme 5s&#xff08;图片来源网络&#xf…

《TableStore最佳实践:GEO索引打造店铺搜索系统》

一、方案背景 对于一套GEO管理系统&#xff0c;其核心点与瓶颈在于数据库的存储性能与查询能力&#xff1b;一方面&#xff0c;存储服务需要应对海量数据的低延迟存、读&#xff0c;另一方面&#xff0c;存储服务也要提供高效的GEO多维度数据检索。表格存储&#xff08;TableS…

单一窗口关区备案_深圳跨境电商企业进出口备案,赶紧码下学习

小编君抽空为大家梳理了深圳跨境企业各项出口资质及需要的材料&#xff0c;如下&#xff1a;1工商局营业执照经营范围的变更&#xff0c;税务局办理经营范围变更公司经营范围上如果没有“进出口”或“货物及技术进出口”字样&#xff0c;就得先变更经营范围。如果公司在注册时已…

《TableStore最佳实践:轻松实现轨迹管理与地理围栏》

一、方案背景 轨迹管理系统日常生活中使用非常普遍&#xff0c;如外卖派送轨迹、快递物流流转、车辆定位轨迹等。该场景与地理位置管理类似&#xff0c;核心点与瓶颈都在数据库的存储性能与查询能力&#xff0c;同时需要时间字段正序排列&#xff0c;保证轨迹点顺序&#xff1…

蚂蚁金服、微众银行、度小满都来了,智能金融将何去何从?(文末福利)

&#xff08;大会官网 https://t.csdnimg.cn/U1wA&#xff09;金融业是一个数据堆砌起来的行业&#xff0c;有客户信息、风险控制数据、交易数据等等&#xff0c;如果这些数据没有被有效的管理和分析&#xff0c;会增加企业的经营风险和降低企业的盈利能力。但有了云计算与人工…

RuoYi-Vue 部署 Linux环境 若依前后端分离项目(jar包+nginx 单机版本)

文章目录一、软件安装部署1. 安装jdk2. mysql8安装部署3. redis安装4. nginx 安装部署5. 克隆项目二、后端项目2.1. 修改数据库连接2.2. 修改Redis连接信息2.3. 文件路径2.4. 日志存储路径调整2.5. 编译打包三、前端项目3.1. 安装依赖3.2. 构建生产环境四、项目部署4.1.创建目录…

五子棋项目结束总结_居家活动系列总结

刚开始一直待家里真的好无聊......不过后来电气学院举办了一系列线上活动&#xff0c;在家里也能参与&#xff01;我们一起来看看吧&#xff01;厨艺比赛2020年3月2日-3月6日&#xff0c;为了鼓励大家好好利用假期时间&#xff0c;享受生活。电气工程学院学生会举办“厨艺分享”…

4K超清,2500万人在线,猫晚直播技术全解读

2018天猫双11已经过去一周&#xff0c;各路快递也在快马加鞭送到大家手中。但对于剁手党而言&#xff0c;天猫双11也不仅仅是简单意义上的“买买买”&#xff0c;更是一场边看边玩的狂欢盛宴。 作为双11的必备节目&#xff0c;今年的猫晚通过优酷、浙江卫视、东方卫视进行了全…

shell取当前月份第一天_红帽认证8.0版本即将发布!Ansible和shell脚本自动化将重点考察...

红帽厂商官方通知&#xff0c;红帽RHCE考试&#xff08;包含EX200和EX300两门&#xff09;版本7的截止时间是&#xff1a;2020年4月30日。 即2020年5月份之后将停止版本7的考试&#xff0c;包括正考和补考。RHCE版本7中包含EX200&#xff08;v7&#xff09;和EX300&#xff08;…

阿里云重磅发布RDS for SQL Server AlwaysOn集群版

2018年双十一刚过&#xff0c;阿里云数据库发布RDS for SQL Server AlwaysOn集群版&#xff0c;这是业界除微软云SQL Database外&#xff0c;首家云计算公司基于SQL Server最新AlwaysOn核心技术实现的数据库集群版&#xff0c;并且是经过双十一检验的商业化版本。 全形态的产品…

Linux Shell脚本_设置时区并同步时间

① 脚本编写 vim autoSyncTime.sh脚本内容&#xff1a; ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime if ! crontab -l |grep ntpdate &>/dev/null ; then(echo "* 1 * * * ntpdate ntp1.aliyun.com >/dev/null 2>&1";hwclock -w;cro…

“12306”的架构到底有多6?

戳蓝字“CSDN云计算”关注我们哦&#xff01;作者 | 绘你一世倾城责编 | 阿秃每到节假日期间&#xff0c;一二线城市返乡、外出游玩的人们几乎都面临着一个问题&#xff1a;抢火车票&#xff01;12306 抢票&#xff0c;极限并发带来的思考虽然现在大多数情况下都能订到票&…

【阿里云总监课第四期】时髦的云原生应用怎么写?

概述 应用已经跨入了云原生的时代。要写一个时髦的云原生应用&#xff0c;首先当然要了解什么是云原生。CNCF&#xff0c;也就是云原生计算基金会&#xff0c;作为目前人气最旺的云计算行业协会&#xff0c;在今年6月份给出了云原生的定义&#xff0c;阿里云牵头做了一个官方的…

信号扫描_图文并茂,一文读懂信号源

信号源是四大通用电子测量仪器之一&#xff0c;其他三种是&#xff1a;网络分析仪&#xff0c;频谱分析仪和示波器。这篇介绍信号源所涉及的相关基础知识。信号源的最常用的功能是用来产生一个正弦波&#xff0c;所以先从介绍正弦波的特征开始本篇文章。一、正弦波的信号特性通…

支撑双十一的网络引擎:飞天洛神

对刚刚过去的2018天猫双十一&#xff0c;各位网友应该记忆犹新。尤其是午夜零点时&#xff0c;亿万网友几乎不约而同地打开满满的购物车&#xff0c;抢下商家优惠券和红包&#xff0c;完成下单&#xff0c;付款这一系列流程。根据我个人的经历&#xff0c;这次体验堪称顺畅&…

IPv6时代已来:双十一中的IPv6大规模应用实践

摘要&#xff1a; 刚刚过去的双十一&#xff0c;大家对猫晚、抢红包、组团购还记忆犹新。大家不了解的是&#xff0c;不知不觉间&#xff0c;你可能已经成为首批互联网IPv6用户了。今年天猫双十一期间&#xff0c;阿里巴巴全面支持了IPv6&#xff0c;这是IPv6在我国的互联网领域…

说真的,程序员相亲,真的太太太太太太难了 | IT巨能唠

众所周知&#xff0c;程序员这个群体&#xff0c;是单身狗的重灾区&#xff01;程序员的成就感&#xff0c;来自于公众对他代码的认可&#xff01;因此&#xff0c;广大程序员将大量精力时间用于技术&#xff0c;他们关注新技术的诞生&#xff0c;关注自身内功的修炼&#xff0…