Introducción
Buenas, en este post vamos a hacer una serie de ejercicios relacionados con la gestión de usuarios en OracleDB.
Crea un usuario llamado Becario y, sin usar los roles de ORACLE, dale los siguientes privilegios:
CREATE USER becario
IDENTIFIED BY becario;
-
Conectarse a la base de datos.
GRANT CREATE SESSION TO becario;
-
Modificar el número de errores en la introducción de la contraseña de cualquier usuario.
Vamos a usar perfiles en Oracle, para ello, primero los activamos:
ALTER SYSTEM SET RESOURCE_LIMIT=TRUE;
Le damos el privilegio a becario para que pueda crear perfiles:
GRANT CREATE PROFILE, ALTER PROFILE, DROP PROFILE TO becario;
Creamos uno que se llamará ERRORPASSWORD:
CREATE PROFILE errorpassword LIMIT;
Y modificamos dicho perfil para que el número de errores sea el deseado:
ALTER PROFILE errorpassword LIMIT FAILED_LOGIN_ATTEMPTS 5;
También le damos el privilegio a becario para que pueda modificar usuarios:
GRANT ALTER USER TO becario;
Y asignamos el perfil al usuario deseado:
ALTER USER becario PROFILE errorpassword;
-
Modificar índices en cualquier esquema (este privilegio podrá pasarlo a quien quiera)
GRANT INDEX ON *.* TO becario WITH GRANT OPTION;
-
Insertar filas en scott.emp (este privilegio podrá pasarlo a quien quiera)
GRANT INSERT ON scott.emp TO becario WITH GRANT OPTION;
-
Crear objetos en cualquier tablespace.
GRANT CREATE ANY TABLE TO becario;
-
Gestión completa de usuarios, privilegios y roles.
GRANT ALL PRIVILEGES TO becario;
Realiza una función de verificación de contraseñas que compruebe que la contraseña difiere en más de cinco caracteres de la anterior y que la longitud de la misma es diferente de la anterior. Asígnala al perfil CONTRASEÑASEGURA. Comprueba que funciona correctamente.
Creamos la función:
CREATE OR REPLACE FUNCTION password_verify
(
old_password VARCHAR2,
new_password VARCHAR2
)
RETURN boolean
AS
v_mayus_old VARCHAR2(30):=UPPER(old_password);
v_mayus_new VARCHAR2(30):=UPPER(new_password);
v_dif NUMBER:=0;
v_valida NUMBER:=0;
BEGIN
FOR i IN 1..LENGTH(v_mayus_new) LOOP
IF INSTR(v_mayus_old,SUBSTR(v_mayus_new,i,1),1) = 0
THEN
v_dif:=v_dif+1;
END IF;
END LOOP;
IF v_dif < 5 THEN
RAISE_APPLICATION_ERROR(-20001,'Debe cambiar en mas
de 5 caracteres');
END IF;
IF LENGTH(old_password) = LENGTH(new_password) THEN
RAISE_APPLICATION_ERROR(-20002,'Debe ser de
diferente longitud');
END IF;
RETURN TRUE;
END password_verify;
/
Activamos los perfiles en Oracle:
ALTER SYSTEM SET RESOURCE_LIMIT=TRUE
Creamos el perfil y le asignamos la función:
CREATE PROFILE passwordsegura LIMIT
PASSWORD_VERIFY_FUNCTION password_verify;
Realiza un procedimiento llamado MostrarPrivilegiosdelRol que reciba el nombre de un rol y muestre los privilegios de sistema y los privilegios sobre objetos que lo componen.
CREATE OR REPLACE PROCEDURE MostrarPrivilegiosDelRol
(
p_nombre_rol role_tab_privs.role%TYPE
)
AS
CURSOR c_priv_sys IS
SELECT PRIVILEGE
FROM role_sys_privs
WHERE role=p_nombre_rol;
CURSOR c_priv_tab IS
SELECT OWNER,TABLE_NAME,PRIVILEGE
FROM role_tab_privs
WHERE role=p_nombre_rol;
BEGIN
ComprobarRolInexistente(p_nombre_rol);
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Nombre rol: '||p_nombre_rol);
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Privilegios de sistema:');
FOR v_privs_sys IN c_priv_sys LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE(v_privs_sys.PRIVILEGE);
END LOOP;
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Privilegios sobre objetos:');
FOR v_privs_tab IN c_priv_tab LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Propietario: '||
v_privs_tab.OWNER);
DBMS_OUTPUT.PUT_LINE('Nombre tabla: '||
v_privs_tab.TABLE_NAME);
DBMS_OUTPUT.PUT_LINE('Privilegio: '||
v_privs_tab.PRIVILEGE);
END LOOP;
END MostrarPrivilegiosDelRol;
/
CREATE OR REPLACE PROCEDURE ComprobarRolInexistente
(
p_nombre_rol role_tab_privs.role%TYPE
)
AS
v_count_rol NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count_rol
FROM DBA_ROLES
WHERE ROLE=p_nombre_rol;
IF v_count_rol=0 THEN
RAISE_APPLICATION_ERROR(-20104,'Rol no existe');
END IF;
END ComprobarRolInexistente;
/
Resultado:
SQL> exec MostrarPrivilegiosDelRol('PRUEBA');
Nombre rol: PRUEBA
Privilegios de sistema:
CREATE USER
Privilegios sobre objetos:
Propietario: PRUEBA2
Nombre tabla: POBLACIONES
Privilegio: SELECT
Propietario: SYS
Nombre tabla: PROVINCIAS
Privilegio: SELECT
PL/SQL procedure successfully completed.
Realiza un procedimiento llamado PermisosdeAsobreB que reciba dos nombres de usuario y muestre los permisos que tiene el primero de ellos sobre objetos del segundo.
CREATE OR REPLACE PROCEDURE ComprobarRolInexistente
(
p_nombre_rol role_tab_privs.role%TYPE
)
AS
v_count_rol NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count_rol
FROM DBA_ROLES
WHERE ROLE=p_nombre_rol;
IF v_count_rol=0 THEN
RAISE_APPLICATION_ERROR(-20104,'Rol no existe');
END IF;
END ComprobarRolInexistente;
/
CREATE OR REPLACE PROCEDURE ComprobarUsuInexistente
(
p_usuario dba_tab_privs.OWNER%TYPE
)
AS
v_count_usu NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count_usu
FROM DBA_USERS
WHERE USERNAME=p_usuario;
IF v_count_usu=0 THEN
RAISE_APPLICATION_ERROR(-20105,'Usuario no existe');
END IF;
END ComprobarUsuInexistente;
/
Resultado:
SQL> exec PermisosDeAsobreB('PRUEBA1','PRUEBA2');
Permisos sobre objetos de PRUEBA1 sobre PRUEBA2
Propietario: PRUEBA2
Nombre tabla: POBLACIONES
Privilegio: SELECT
Privilegiado: PRUEBA1
PL/SQL procedure successfully completed.
Realiza un procedimiento llamado MostrarInfoPerfil que reciba el nombre de un perfil y muestre su composición y los usuarios que lo tienen asignado.
Creamos un perfil de prueba:
CREATE PROFILE lim_prueba LIMIT CONNECT_TIME 45;
Procedimientos:
CREATE OR REPLACE PROCEDURE MostrarInfoPerfil
(
p_perfil dba_profiles.profile%TYPE
)
AS
CURSOR c_perfiles IS
SELECT RESOURCE_NAME,LIMIT
FROM dba_profiles
WHERE profile=p_perfil;
CURSOR c_usuarios_asignados IS
SELECT USERNAME
FROM dba_users
WHERE PROFILE=p_perfil;
BEGIN
ComprobarPerfilInexistente(p_perfil);
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Composicion perfil '|| p_perfil||':');
FOR v_perfil IN c_perfiles LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Atributo: '|| v_perfil.RESOURCE_NAME);
DBMS_OUTPUT.PUT_LINE('Valor: '||v_perfil.LIMIT);
END LOOP;
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Usuarios que tienen el perfil '|| p_perfil||':');
FOR v_usuarios IN c_usuarios_asignados LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Nombre usuario: '|| v_usuarios.USERNAME);
END LOOP;
END MostrarInfoPerfil;
/
CREATE OR REPLACE PROCEDURE ComprobarPerfilInexistente
(
p_perfil dba_profiles.profile%TYPE
)
AS
v_count_perfil NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count_perfil
FROM DBA_PROFILES
WHERE PROFILE=p_perfil;
IF v_count_perfil=0 THEN
RAISE_APPLICATION_ERROR(-20106,'Perfil no existe');
END IF;
END ComprobarPerfilInexistente;
/
Resultado:
SQL> exec MostrarInfoPerfil('LIM_PRUEBA');
Composicion perfil LIM_PRUEBA:
Atributo: COMPOSITE_LIMIT
Valor: DEFAULT
Atributo: SESSIONS_PER_USER
Valor: DEFAULT
Atributo: CPU_PER_SESSION
Valor: DEFAULT
Atributo: CPU_PER_CALL
Valor: DEFAULT
Atributo: LOGICAL_READS_PER_SESSION
Valor: DEFAULT
Atributo: LOGICAL_READS_PER_CALL
Valor: DEFAULT
Atributo: IDLE_TIME
Valor: DEFAULT
Atributo: CONNECT_TIME
Valor: 45
Atributo: PRIVATE_SGA
Valor: DEFAULT
Atributo: FAILED_LOGIN_ATTEMPTS
Valor: DEFAULT
Atributo: PASSWORD_LIFE_TIME
Valor: DEFAULT
Atributo: PASSWORD_REUSE_TIME
Valor: DEFAULT
Atributo: PASSWORD_REUSE_MAX
Valor: DEFAULT
Atributo: PASSWORD_VERIFY_FUNCTION
Valor: DEFAULT
Atributo: PASSWORD_LOCK_TIME
Valor: DEFAULT
Atributo: PASSWORD_GRACE_TIME
Valor: DEFAULT
Usuarios que tienen el perfil LIM_PRUEBA:
Nombre usuario: PRUEBA1
PL/SQL procedure successfully completed.
(ORACLE, Postgres) Realiza un procedimiento que reciba un nombre de usuario y nos muestre cuántas sesiones tiene abiertas en este momento. Además, para cada una de dichas sesiones nos mostrará la hora de comienzo y el nombre de la máquina, sistema operativo y programa desde el que fue abierta.
CREATE OR REPLACE PROCEDURE MostrarSesionesAbiertas
(
p_usuario V$SESSION.USERNAME%TYPE
)
AS
CURSOR c_sesiones IS
SELECT LOGON_TIME,MACHINE,PROGRAM
FROM V$SESSION
WHERE USERNAME=p_usuario
AND STATUS='ACTIVE';
BEGIN
ComprobarUsuInexistente(p_usuario);
ComprobarSesionesInactivas(p_usuario);
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Sesiones abiertas de '|| p_usuario||':');
FOR v_sesion IN c_sesiones LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Login: '|| v_sesion.LOGON_TIME);
DBMS_OUTPUT.PUT_LINE('Nombre host: '|| v_sesion.MACHINE);
DBMS_OUTPUT.PUT_LINE('Programa: '|| v_sesion.PROGRAM);
END LOOP;
END MostrarSesionesAbiertas;
/
CREATE OR REPLACE PROCEDURE ComprobarSesionesInactivas
(
p_usuario V$SESSION.USERNAME%TYPE
)
AS
v_count_sesion NUMBER;
BEGIN
SELECT COUNT(*) INTO v_count_sesion
FROM V$SESSION
WHERE USERNAME=p_usuario
AND STATUS='ACTIVE';
IF v_count_sesion=0 THEN
RAISE_APPLICATION_ERROR(-20107,'El usuario '|| p_usuario||' no tiene sesiones activas');
END IF;
END ComprobarSesionesInactivas;
/
Resultado:
SQL> exec MostrarSesionesAbiertas('SYS');
Sesiones abiertas de SYS:
Login: 01-FEB-21
Nombre host: oracle
Programa: sqlplus@oracle (TNS V1-V3)
PL/SQL procedure successfully completed.
Realiza un procedimiento que muestre los usuarios que pueden conceder privilegios de sistema a otros usuarios y cuales son dichos privilegios.
CREATE OR REPLACE PROCEDURE MostrarUsuariosPrivilegios
AS
CURSOR c_privi IS
SELECT GRANTEE,PRIVILEGE
FROM dba_sys_privs
WHERE ADMIN_OPTION='YES'
GROUP BY GRANTEE,PRIVILEGE
ORDER BY GRANTEE;
BEGIN
FOR v_privs IN c_privi LOOP
DBMS_OUTPUT.PUT_LINE(chr(9));
DBMS_OUTPUT.PUT_LINE('Usuario: '||v_privs.GRANTEE);
DBMS_OUTPUT.PUT_LINE('Privilegio que puede conceder: '||v_privs.PRIVILEGE);
END LOOP;
END MostrarUsuariosPrivilegios;
/
Resultado:
SQL> exec MostrarUsuariosPrivilegios;
Usuario: APEX_040200
Privilegio que puede conceder: CREATE CLUSTER
Usuario: APEX_040200
Privilegio que puede conceder: CREATE DIMENSION
Usuario: APEX_040200
Privilegio que puede conceder: CREATE INDEXTYPE
Usuario: APEX_040200
Privilegio que puede conceder: CREATE JOB
Usuario: APEX_040200
Privilegio que puede conceder: CREATE MATERIALIZED VIEW
Usuario: APEX_040200
Privilegio que puede conceder: CREATE OPERATOR
Usuario: APEX_040200
Privilegio que puede conceder: CREATE PROCEDURE
Usuario: APEX_040200
Privilegio que puede conceder: CREATE SEQUENCE
Usuario: APEX_040200
Privilegio que puede conceder: CREATE SESSION
Usuario: APEX_040200
Privilegio que puede conceder: CREATE SYNONYM
Usuario: APEX_040200
Privilegio que puede conceder: CREATE TABLE
Usuario: APEX_040200
Privilegio que puede conceder: CREATE TRIGGER
Usuario: APEX_040200
Privilegio que puede conceder: CREATE TYPE
Usuario: APEX_040200
Privilegio que puede conceder: CREATE VIEW
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: CREATE EVALUATION CONTEXT
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: CREATE RULE
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: CREATE RULE SET
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: DEQUEUE ANY QUEUE
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: ENQUEUE ANY QUEUE
Usuario: AQ_ADMINISTRATOR_ROLE
Privilegio que puede conceder: MANAGE ANY QUEUE
Usuario: DVSYS
Privilegio que puede conceder: CREATE EVALUATION CONTEXT
Usuario: DVSYS
Privilegio que puede conceder: CREATE RULE
Usuario: DVSYS
Privilegio que puede conceder: CREATE RULE SET
Usuario: DV_ACCTMGR
Privilegio que puede conceder: CREATE SESSION
Usuario: PRUEBA1
Privilegio que puede conceder: CREATE USER
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: CREATE ANY CREDENTIAL
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: CREATE ANY JOB
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: CREATE CREDENTIAL
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: CREATE EXTERNAL JOB
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: CREATE JOB
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: EXECUTE ANY CLASS
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: EXECUTE ANY PROGRAM
Usuario: SCHEDULER_ADMIN
Privilegio que puede conceder: MANAGE SCHEDULER
Usuario: SYS
Privilegio que puede conceder: ALTER ANY EVALUATION CONTEXT
Usuario: SYS
Privilegio que puede conceder: ALTER ANY RULE
Usuario: SYS
Privilegio que puede conceder: ALTER ANY RULE SET
Usuario: SYS
Privilegio que puede conceder: CREATE ANY EVALUATION CONTEXT
Usuario: SYS
Privilegio que puede conceder: CREATE ANY RULE
Usuario: SYS
Privilegio que puede conceder: CREATE ANY RULE SET
Usuario: SYS
Privilegio que puede conceder: CREATE EVALUATION CONTEXT
Usuario: SYS
Privilegio que puede conceder: CREATE RULE
Usuario: SYS
Privilegio que puede conceder: CREATE RULE SET
Usuario: SYS
Privilegio que puede conceder: DELETE ANY TABLE
Usuario: SYS
Privilegio que puede conceder: DEQUEUE ANY QUEUE
Usuario: SYS
Privilegio que puede conceder: DROP ANY EVALUATION CONTEXT
Usuario: SYS
Privilegio que puede conceder: DROP ANY RULE
Usuario: SYS
Privilegio que puede conceder: DROP ANY RULE SET
Usuario: SYS
Privilegio que puede conceder: ENQUEUE ANY QUEUE
Usuario: SYS
Privilegio que puede conceder: EXECUTE ANY EVALUATION CONTEXT
Usuario: SYS
Privilegio que puede conceder: EXECUTE ANY RULE
Usuario: SYS
Privilegio que puede conceder: EXECUTE ANY RULE SET
Usuario: SYS
Privilegio que puede conceder: INSERT ANY TABLE
Usuario: SYS
Privilegio que puede conceder: MANAGE ANY QUEUE
Usuario: SYS
Privilegio que puede conceder: READ ANY TABLE
Usuario: SYS
Privilegio que puede conceder: SELECT ANY TABLE
Usuario: SYS
Privilegio que puede conceder: UPDATE ANY TABLE
Usuario: SYSKM
Privilegio que puede conceder: ADMINISTER KEY MANAGEMENT
Usuario: SYSTEM
Privilegio que puede conceder: DEQUEUE ANY QUEUE
Usuario: SYSTEM
Privilegio que puede conceder: ENQUEUE ANY QUEUE
Usuario: SYSTEM
Privilegio que puede conceder: MANAGE ANY QUEUE
PL/SQL procedure successfully completed.