viernes, 22 de abril de 2016

El Privilegio DROP ANY TABLE es Peligroso

Estaba leyendo el blog de Laurent Schneider aquí. Según él, un usuario debe tener el privilegio DROP ANY TABLE para hacer un TRUNCATE en una tabla que pertenece a otro usuario. Esto me pareció extraño y por eso me decidí a probarlo en Oracle 11.2.0.1. Creé un usuario (USER1) que sería el dueño de una tabla:

SQL> create user user1
  2  identified by user1
  3  default tablespace users
  4  quota 10m on users
  5  /
 
User created.
 
SQL> grant
  2  create session,
  3  create table,
  4  select any dictionary
  5  to user1
  6  /
 
Grant succeeded.
 
SQL>

Luego creé un usuario (USER2) que intentaría emplear el privilegio DROP ANY TABLE para hacer un TRUNCATE en la tabla de USER1:

SQL> create user user2
  2  identified by user2
  3  /
 
User created.
 
SQL> grant
  2  create session,
  3  drop any table to user2
  4  /
 
Grant succeeded.
 
SQL>

El usuario USER1 creó una tabla con datos:

SQL> conn user1/user1
Connected.
SQL> create table tab1 as
  2  select * from dba_tables
  3  /
 
Table created.
 
SQL> grant select on tab1 to user2
  2  /
 
Grant succeeded.
 
SQL>

El usuario USER2 contó las líneas en la tabla, hizo el TRUNCATE y contó las líneas otra vez para verificar que el TRUNCATE había funcionado:

SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
      3192
 
SQL> truncate table user1.tab1
  2  /
 
Table truncated.
 
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
         0
 
SQL>

La idea de dar el privilegio DROP ANY TABLE al usuario USER2 me pareció peligroso y por eso lo revoqué:

SQL> conn / as sysdba
Connected.
SQL> revoke drop any table from user2
  2  /
 
Revoke succeeded.
 
SQL> grant create procedure to user1
  2  /
 
Grant succeeded.
 
SQL>

Entonces el usuario USER1 creó un procedimiento para hacer un TRUNCATE en su tabla:

SQL> conn user1/user1
Connected.
SQL> create procedure truncate_tab1 as
  2  begin
  3    execute immediate 'truncate table tab1';
  4  end;
  5  /
 
Procedure created.
 
SQL>

y le dio al usuario USER2 el derecho de ejecutarlo:

SQL> grant execute on truncate_tab1 to user2
  2  /
 
Grant succeeded.
 
SQL> insert into tab1 select * from dba_tables
  2  /
 
3193 rows created.
 
SQL>

Con este procedimiento el usuario USER2 podía todavía hacer un TRUNCATE en la tabla de USER1:

SQL> conn user2/user2
Connected.
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
      3193
 
SQL> exec user1.truncate_tab1;
 
PL/SQL procedure successfully completed.
 
SQL> select count(*) from user1.tab1
  2  /
 
  COUNT(*)
----------
         0
 
SQL> 

Pero, por supuesto, no podía borrar las tablas de los otros usuarios.

martes, 8 de septiembre de 2015

ORA-14223 (otra vez)


En Oracle 11.2.0.1 se puede crear una tabla con creación diferida. También es posible crear una tabla dividida. Pero si intentas crear una tabla dividida y con creación diferida, Oracle responde con un error ORA-14223:

Oracle 11.2.0.1 > sqlplus /
 
SQL*Plus: Release 11.2.0.1.0 Production on Lun Sep 7 18:42:12 2015
 
Copyright (c) 1982, 2009, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> create table tab1
  2  (col1 number)
  3  segment creation deferred
  4  /
 
Table created.
 
SQL> drop table tab1
  2  /
 
Table dropped.
 
SQL> create table tab1
  2  (col1 number)
  3  partition by range(col1)
  4  (partition part01
  5  values less than (maxvalue))
  6  /
 
Table created.
 
SQL> drop table tab1
  2  /
 
Table dropped.
 
SQL> create table tab1
  2  (col1 number)
  3  segment creation deferred
  4  partition by range(col1)
  5  (partition part01
  6  values less than (maxvalue))
  7  /
create table tab1
*
ERROR at line 1:
ORA-14223: No está soportada la creación de segmentos diferida para esta tabla
 
SQL> 

Si tienes que crear una table dividida y con creación diferida, es posible hacerlo en Oracle 11.2.0.2 como se puede ver en el último ejemplo bajo estas líneas:

Oracle 11.2.0.2 > sqlplus /
 
SQL*Plus: Release 11.2.0.2.0 Production on Mon Sep 7 18:46:17 2015
 
Copyright (c) 1982, 2010, Oracle.  All rights reserved.
 
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
 
SQL> create table tab1
  2  (col1 number)
  3  segment creation deferred
  4  partition by range(col1)
  5  (partition part01
  6  values less than (maxvalue))
  7  /
 
Table created.
 
SQL>