Problema al usar roles

Los roles se usan para facilitar la administración de permisos asignados a usuarios, en ellos se agrupan distintos permisos y luego el rol se asigna a uno o varios usuarios.

Por ejemplo, se puede crear un rol llamado DESARROLLADOR con los privilegios para que pueda crear procedimientos y funciones, pero no crear tablas ni borrar objetos. Si este rol se asigna a un usuario, este podrá realizar solamente lo que acabo de comentar. Pero…

Antecedentes

Haciendo unas pruebas para un cliente, analicé una peculiaridad de Oracle que rompe un poco el uso de los roles en la base de datos, ¿cómo es esto?

Hay permisos que aunque son asignados a un rol y este es asignado a un usuario, al conectarse con dicho usuario, no funciona el permiso asignado a través del rol desde un programa almacenado.

Esto no pasa cuando se hace de manera directa como se puede ver en las pruebas que hice en Manejo de sinónimos.

Ejemplo

Les voy a mostrar paso por paso este punto en la tal vez falla de Oracle en el uso de roles:

1. Creo un usuario USUARIO_A con roles CONNECT y RESOURCE que contenga una tabla llamada DATOS:

SQL> create user usuario_a identified by prueba;  <--- Se crea USUARIO_A

User created.

SQL> grant connect, resource to usuario_a;   <--- Se le asignan privilegios

Grant succeeded.

SQL> create table usuario_a.datos (  <--- Se crea la tabla DATOS en el usuario USUARIO_A.
  2    texto varchar2(50)
  3  ) tablespace datos;

Table created.

2. Creo un usuario USUARIO_B con privilegio de DBA para hacer “lo que sea” en la base de datos:

SQL> create user usuario_b identified by prueba;  <--- Se crea USUARIO_B

User created.

SQL> grant dba to usuario_b;        <--- Se asigna rol DBA

Grant succeeded.

3. Me conecto con el usuario USUARIO_B y trato de truncar la tabla DATOS que pertenece al usuario USUARIO_A:

SQL> connect usuario_b/prueba;       <--- Me conecto con USUARIO_B
Connected. 
SQL>  
SQL> truncate table usuario_a.datos;  <--- Se trunca la tabla sin problema

Table truncated.

como se puede ver, no hubo problema para truncar la tabla por tener el privilegio DBA asignado de manera directa en el USUARIO_B. Pasemos a la siguiente prueba:

4. Ahora, dentro del USUARIO_B, voy a crear un procedimiento que realice la misma tarea:

SQL> create or replace procedure borra_datos is 
  2  begin 
  3    execute immediate 'truncate table usuario_a.datos'; 
  4  end; 
  5  / 

Procedure created.

y lo ejecuto:

SQL> exec borra_datos 
BEGIN borra_datos; END; 

* 
ERROR at line 1: 
ORA-00942: table or view does not exist 
ORA-06512: at "USUARIO_B.BORRA_DATOS", line 3 
ORA-06512: at line 1

No tiene acceso la tabla que quiero truncar.

5. Ahora pruebo con el borrado por medio de la instrucción DELETE de la tabla con otro procedimiento:

SQL> create or replace procedure borra_datos_dir is 
  2  begin 
  3    delete from usuario_a.datos; 
  4    commit; 
  5* end; 
SQL> / 

Warning: Procedure created with compilation errors. 

SQL> show errors 
Errors for PROCEDURE BORRA_DATOS_DIR: 

LINE/COL ERROR 
-------- ----------------------------------------------------------------- 
3/3      PL/SQL: SQL Statement ignored 
3/25     PL/SQL: ORA-00942: table or view does not exist

Como se puede observar, ni siquiera puedo crear el procedimiento porque no encuentra la tabla.

Es interesante el ver cómo no se puede tener acceso a la tabla a través del procedimiento, a pesar de tener el rol DBA asignado al USUARIO_B.

6. Muy bien, ahora voy a hacer otra prueba, crearé un rol especial con el permiso de borrado sobre la tabla:

SQL> create role lectura; 

Role created. 

SQL> grant delete on usuario_a.datos to lectura;

Grant succeeded.

para después asigno el rol creado al USUARIO_B:

SQL> grant lectura to usuario_b; 

Grant succeeded.

Como ya se creó el procedimiento BORRA_DATOS_DIR aunque con errores, de acuerdo al post Objetos inválidos después de un alter, vuelvo a ejecutarlo desde el USUARIO_B intentando que se compile automáticamente y se ejecute. Con esta acción, se obtiene el siguiente resultado:

SQL> exec borra_datos_dir 
BEGIN borra_datos_dir; END; 

      * 
ERROR at line 1: 
ORA-06550: line 1, column 7: 
PLS-00905: object USUARIO_B.BORRA_DATOS_DIR is invalid 
ORA-06550: line 1, column 7: 
PL/SQL: Statement ignored

Como se puede ver el borrado directo asignado a través de un rol tampoco ha funcionado al ser invocada la instrucción desde un programa almacenado.

7. Finalmente, asigno el privilegio de borrado sobre la tabla de manera directa al usuario:

SQL> grant delete on usuario_a.datos to usuario_b; 

Grant succeeded.

para después conectarme con el USUARIO_B:

SQL> conn usuario_b/prueba; 
Connected.

y siguiendo lo que comento en el post Objetos inválidos después de un alter, intento ejecutar nuevamente el procedimiento BORRA_DATOS_DIR:

SQL> exec borra_datos_dir

PL/SQL procedure successfully completed.

En cuya ejecución, se puede confirmar que se compiló automáticamente el procedimiento, y se ejecutó de manera exitosa.

Conclusiones

Desconozco por qué Oracle tiene esta característica ya que afecta a la naturaleza de los roles, porque si se desea tener manipulación sobre ciertos objetos de la base de datos, tendrán que existir los privilegios específicos asignados a cada usuario, invalidando el uso de roles.

Sin embargo, es bueno saberlo para que puedan tomar sus precauciones al momento de desarrollar sus programas.

Si la información de este post te ha sido de utilidad o quieres que agregue algo más, deja por favor un comentario, contestaré a la brevedad.

Anuncios

4 Responses to Problema al usar roles

  1. oscarlennon says:

    Hola Orlando, ya me habia topado con este tipo de detalles, en la siguiente nota de Oracle PLS-201 GRANTING PRIVILEGES THROUGH A ROLE [ID 113186.1] se explica dicho funcionamiento.

    Saludos…

  2. orlandoolguin says:

    Hola Lennon,

    Si, en efecto ese es el documento oficial de dicho problema en Oracle Support, gracias por tu contribución.

    Orlando.

  3. Irondrake says:

    Que tal Orlando!

    Agregando tu blog en mi listado de accesos, me llamó la atención esta publicación que haces, quisiera hacer la observación de que este no es como tal una anomalía en la ejecución de stored procedures, sino una característica de seguridad (que está documentada en el manual de PL/SQL)

    http://docs.oracle.com/cd/B10500_01/appdev.920/a96624/08_subs.htm#18575

    Ahí busca la parte de Using Roles with Invoker-Rights Subprograms

    Tengo un borrador al respecto en mi blog, me falta complementarlo con ejemplos para publicarlo.

    Saludos!

  4. orlandoolguin says:

    Hola Irondrake,

    ¡Muy buena e interesante aportación!, supongo que esto se complementa con lo del authid.

    Lo investigaré y compementaré.

    Orlando.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: