Anteriormente, aqui no blog, demonstrei como a senha de um usuário pode ser alterada de maneira transparente no Oracle Database, através da feature Gradual Password Rollover, através do parâmetro PASSWORD_ROLLOVER_TIME do profile de usuário (leia em: Alteração de senhas no Oracle sem derrubar a aplicação).
Entretanto, uma vez que esse processo de alteração de senha é realizado, como identificar se ainda existem conexões sendo feitas usando a senha antiga? Como podemos ter a segurança de desabilitar o rollover da senha (desativando finalmente a senha antiga), uma vez que o dev nos disse que já alterou a senha, e garantir que quando o fizermos não teremos um cenário onde alguma dependência não mapeada continua usando essa senha antiga?
Sendo objetivo, podemos utilizar o Unified Audit Trail junto com uma política de logon habilitada. Os detalhes mostro na demonstração abaixo.
Demonstração do processo
Para fins de demonstração, vamos utilizar um ambiente com o Unified Audit Trail habilitado:
SQL> SELECT value FROM v$option WHERE parameter = 'Unified Auditing'; VALUE ---------------------------------------------------------------- TRUE
Na sequência, vamos criar o usuário de teste, adicionando o PASSWORD_ROLLOVER_TIME ao seu profile:
SQL> CREATE PROFILE pwrollover_test_prof LIMIT PASSWORD_ROLLOVER_TIME 1/24 FAILED_LOGIN_ATTEMPTS 10; Profile created. SQL> CREATE USER pwrollover_test_user IDENTIFIED BY "Teste_Senha_Antiga_01" PROFILE pwrollover_test_prof; User created. SQL> GRANT CREATE SESSION TO pwrollover_test_user; Grant succeeded. SQL> SELECT username, account_status FROM dba_users WHERE username = 'PWROLLOVER_TEST_USER'; USERNAME ACCOUNT_STATUS ------------------------- ------------------ PWROLLOVER_TEST_USER OPEN
Nesse caso o período de rollover da senha é de apenas uma hora, ou seja, a senha antiga pode coexistir com a nova apenas durante esse período. Em cenários reais de produção, esse período pode ser bem maior.
No momento a sua conta está com o status OPEN e o usuário pode logar usando sua senha normalmente.
Como o profile desse usuário especifica que um PASSWORD_ROLLOVER_TIME, quando a senha é alterada o seu status passa para OPEN & IN ROLLOVER:
SQL> ALTER USER pwrollover_test_user IDENTIFIED BY "Teste_Senha_Nova_02"; User altered. SQL> SELECT username, account_status, password_change_date FROM dba_users WHERE username = 'PWROLLOVER_TEST_USER'; USERNAME ACCOUNT_STATUS --------------------------- ------------------------ PWROLLOVER_TEST_USER OPEN & IN ROLLOVER
Auditando os logons
A parte interessante vem agora: como criamos uma política de auditoria que monitore o uso da senha antiga e como consultar os registros?
Com um usuário com a role de AUDIT_ADMIN, podemos criar a seguinte política de auditoria:
SQL> CREATE AUDIT POLICY pwrollover_logon_pol ACTIONS LOGON; Audit policy created. SQL> AUDIT POLICY pwrollover_logon_pol BY pwrollover_test_user; Audit succeeded.
O ponto importante aqui é limitar ao máximo o escopo da auditoria, para diminuir o impacto da geração de audit trails na performance do banco de dados. No nosso caso, estamos limitando a auditoria de logon apenas para o usuário alvo.
Uma vez habilitada a auditoria, vamos gerar alguns eventos, logando com a senha nova e a senha antiga no banco:
SQL> conn pwrollover_test_user/"Teste_Senha_Antiga_01"@PDBTEST Connected. SQL> conn pwrollover_test_user/"Teste_Senha_Nova_02"@PDBTEST Connected.
Em seguida, com um usuário que esteja associado com as roles AUDIT_VIEWER ou AUDIT_MGMT, executamos a consulta:
SQL> SELECT dbusername,
event_timestamp,
return_code,
authentication_type,
CASE WHEN REGEXP_LIKE(authentication_type, '\(VERIFIER=.*?-OLD\)')
THEN 'SENHA ANTIGA'
ELSE 'SENHA ATUAL'
END AS senha_usada
FROM unified_audit_trail
WHERE dbusername = 'PWROLLOVER_TEST_USER'
AND action_name = 'LOGON'
AND event_timestamp > SYSDATE - 1
ORDER BY event_timestamp;
DBUSERNAME EVENT_TIMESTAMP RETURN_CODE AUTHENTICATION_TYPE SENHA_USADA
--------------------- ----------------------------- ----------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------
PWROLLOVER_TEST_USER 24-AUG-26 04.23.05.460615 PM 0 (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.21)(PORT=47806))));(CLIENT ADDRESS=());(LOGON_INFO=((VERIFIER=12C-OLD)(CLIENT_CAPABILITIES=O5L_NP,O7L_MR,O8L_LI))); SENHA ANTIGA
PWROLLOVER_TEST_USER 24-AUG-26 04.23.30.178146 PM 0 (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.21)(PORT=47816))));(CLIENT ADDRESS=());(LOGON_INFO=((VERIFIER=12C-NEW)(CLIENT_CAPABILITIES=O5L_NP,O7L_MR,O8L_LI))); SENHA ATUAL
Com isso, é possível identificar se ainda existem conexões sendo feitas com a senha antiga, através do campo LOGON_INFO.VERIFIER, presente na coluna AUTHENTICATION_TYPE da view UNIFIED_AUDIT_TRAIL.
Uma vez que seja constatado que não existem mais usuários logando com a senha antiga, o rollover da senha pode ser encerrado, sem a necessidade de aguardar o período de rollover definido no profile finalizar, através do comando:
SQL> ALTER USER pwrollover_test_user EXPIRE PASSWORD ROLLOVER PERIOD; User altered. SQL> SELECT username, account_status FROM dba_users WHERE username = 'PWROLLOVER_TEST_USER'; USERNAME ACCOUNT_STATUS ----------------------- ----------------- PWROLLOVER_TEST_USER OPEN
Após o rollover finalizado, os novos logins não trazem mais o campo LOGON_INFO.VERIFIER na coluna AUTHENTICATION_TYPE:
SQL> conn pwrollover_test_user/"Teste_Senha_Antiga_01"@PDBTEST
ERROR:
ORA-01017: invalid username/password; logon denied
Warning: You are no longer connected to ORACLE.
SQL> conn pwrollover_test_user/"Teste_Senha_Nova_02"@PDBTEST
Connected.
SQL> conn aud_view/senha@PDBTEST
Connected.
SQL> SELECT dbusername,
event_timestamp,
return_code,
authentication_type
FROM unified_audit_trail
WHERE dbusername = 'PWROLLOVER_TEST_USER'
AND action_name = 'LOGON'
AND event_timestamp > SYSDATE - 1
ORDER BY event_timestamp;
DBUSERNAME EVENT_TIMESTAMP RETURN_CODE AUTHENTICATION_TYPE
--------------------- ----------------------------- ----------- -----------------------------------------------------------------------------------------------------------------
PWROLLOVER_TEST_USER 24-AUG-26 04.29.24.156740 PM 1017 (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.21)(PORT=48112))));(CLIENT ADDRESS=());
PWROLLOVER_TEST_USER 24-AUG-26 04.29.29.962064 PM 0 (TYPE=(DATABASE));(CLIENT ADDRESS=((ADDRESS=(PROTOCOL=tcp)(HOST=192.168.1.21)(PORT=48118))));(CLIENT ADDRESS=());
Conclusão
Essa verificação é de suma importância para que a troca de senha seja totalmente transparente e sem o risco de que uma dependência não mapeada do usuário de aplicação acabe ficando com a senha desatualizada, e acabe gerando um incidente ao final do período de rollover da senha antiga.
Referência:
