GRANTs, ORA-01720 y VIEWs

La concesión de privilegios (‘GRANTs’) sobre vistas tiene algunas particularidades que pueden dar ciertos problemas inesperados.

Veamos un ejemplo. Empezamos con un usuario y una tabla simple:

usuario1@TEST10G> SELECT * FROM PRUEBA01;

        ID TXT
---------- -------------------------
         1 UNO
         2 DOS
         3 TRES
         4 CUATRO
         5 CINCO
         6 SEIS

6 filas seleccionadas.

usuario1@TEST10G> GRANT SELECT ON PRUEBA01 TO usuario2;

Concesión terminada correctamente.

usuario1@TEST10G> GRANT SELECT ON PRUEBA01 TO usuario3;

Concesión terminada correctamente.

Comprobamos que los usuarios 2 y 3 pueden acceder a la tabla.

El usuario2:

usuario2@TEST10G> SELECT * FROM usuario1.PRUEBA01;

        ID TXT
---------- -------------------------
         1 UNO
         2 DOS
         3 TRES
         4 CUATRO
         5 CINCO
         6 SEIS

6 filas seleccionadas.

…y el usuario3:

usuario3@TEST10G> SELECT * FROM usuario1.PRUEBA01;

        ID TXT
---------- -------------------------
         1 UNO
         2 DOS
         3 TRES
         4 CUATRO
         5 CINCO
         6 SEIS

6 filas seleccionadas.

Hasta aquí, todo correcto. El asunto se complica cuando el usuario2 crea una vista e intenta darle privilegios de lectura al usuario3:

usuario2@TEST10G> CREATE VIEW PRUEBAVW AS SELECT * FROM PRUEBA01;

Vista creada.

usuario2@TEST10G> GRANT SELECT ON PRUEBAVW TO usuario3;
GRANT SELECT ON PRUEBAVW TO usuario3
                *
ERROR en línea 1:
ORA-01720: la opción Otorgar no existe para 'USUARIO1.PRUEBA01'

Por alguna razón, el usuario2 no puede otorgar los privilegios sobre la vista al usuario3. (Recordemos que usuario3 tiene privilegios sobre la tabla base de la vista usuario1.PRUEBA01)

Ni siquiera SYSTEM puede:

system@TEST10G> GRANT SELECT ON usuario2.PRUEBAVW TO usuario3;
GRANT SELECT ON USUARIO2.PRUEBAVW TO USUARIO3
                       *
ERROR en línea 1:
ORA-01720: la opción Otorgar no existe para 'USUARIO1.PRUEBA01'

El problema está en que Oracle no verifica los ‘GRANTS’ sobre los objetos base de las vistas, sino que los debe conceder explícitamente para la ejecución de la vista. Y esto sólo se puede hacer otorgando los privilegios sobre los objetos base de la vista al propietario de la misma con la opción ‘WITH GRANT OPTION’.

Lo vemos a continuación:

usuario1@TEST10G> GRANT SELECT ON PRUEBA01 TO usuario2 WITH GRANT OPTION;

Concesión terminada correctamente.

Y ahora todo va bien:

usuario2@TEST10G>  GRANT SELECT ON PRUEBAVW TO usuario3;

Concesión terminada correctamente.

usuario2@TEST10G>

Y así:

usuario3@TEST10G> select * from usuario2.pruebavw;

        ID TXT
---------- -------------------------
         1 UNO
         2 DOS
         3 TRES
         4 CUATRO
         5 CINCO
         6 SEIS

6 filas seleccionadas.

Pero la cosa se vuelve más peliaguda si hacemos:

usuario1@TEST10G>  revoke SELECT ON PRUEBA01 from usuario2;

Revocación terminada correctamente.

usuario1@TEST10G> GRANT SELECT ON PRUEBA01 TO usuario2;

Concesión terminada correctamente.

Porque ahora el pobre usuario3, sin saber porqué, verá:

usuario3@TEST10G> select * from usuario2.pruebavw;
select * from usuario2.pruebavw
*
ERROR en línea 1:
ORA-01031: privilegios insuficientes

usuario3@TEST10G>

Así que hay que tener mucho cuidado cuando se otorgan privilegios sobre vistas si éstas hacen referencia a objetos base que pertenecen a otros esquemas. Y también si se revocan y vuelven a conceder los privilegios sobre los objetos base sin hacer caso al ‘WITH GRANT OPTION’.

Saludos.

Carlos.

12 Responses to GRANTs, ORA-01720 y VIEWs

  1. Gerardo Gaete dice:

    OK, muchas gracias…funcionó impecable.

  2. FERNANDO dice:

    gracias !!!

  3. Milber dice:

    Pues lo mejor sería crear un paquete de interfaz al otro esquema sobre el cual se le den los privilegios

  4. carlosal dice:

    Milber

    Crear un ‘paquete de interfaz’ es reinventar la rueda… y reinventarla cuadrada.

    Saludos.

    Carlos.

  5. David dice:

    Muchas gracias Carlos. Muy buena la explicación

  6. Ricardo dice:

    Gracias Carlos, el unico lugar del Internet en que encontre una explicacion perfecta a este problema.

  7. verny dice:

    Que tal Carlos,

    El procedimiento es el mismo para el grant a un rol?

    Gracias de antemano

  8. Daniel dice:

    Gracias por el artículo tan claro y conciso. Me ha sacado de un problema del que no tenía ni idea.

    Lo apunto para mi wiki. Citandote como fuente original. Si tienes algún inconveniente me envías un correo.

    Un saludo
    El enlace al artículo http://zulwiki.freehostia.com/wikimedia/index.php?title=ORA-01720

  9. RGG dice:

    Master,
    Tenia tiempo con este problema en ORACLE 7 y creia que era una limitante de la versión sin embargo tu explicación tan clara me ha hecho solucionarlo.

    Saludos.

  10. Maxi dice:

    Muy bueno! Funcion perfectamente. Gracias por la explicacion.

    Saludos

  11. anonimo dice:

    Muchas gracias, Carlos. ¡Una explicación perfecta!

Deja un comentario