Today, episode 1:
The scenario is very simple. I have two nice users: TALEK and SIM. TALEK has a table and gives UPDATE rights to SIM.
SQL> connect talek
Enter password:
Connected.
SQL> create table muci (col1 varchar2(10));
Table created.
SQL> insert into muci values ('abc')
2 /
1 row created.
SQL> commit;
Commit complete.
SQL> grant update on muci to sim;
Grant succeeded.
SQL> connect sim
Enter password:
Connected.
SQL> update talek.muci set col1='xyz' where col1='abc';
update talek.muci set col1='xyz' where col1='abc'
*
ERROR at line 1:
ORA-01031: insufficient privileges
Of course, this is the WTF moment. Why the UPDATE failed? The first thing to do is to check the DBA_TAB_PRIVS view for a confirmation that the UPDATE privilege is still there. (I'm pretty sure that no one was so fast to revoke meanwhile the granted privilege but, just in case...)
SQL> select grantee, owner, table_name, privilege
from dba_tab_privs where table_name='MUCI' and owner='TALEK';
GRANT OWNER TABLE_NAM PRIVILEGE
----- ----- --------- ----------
SIM TALEK MUCI UPDATE
And yes, the privilege is there. Hmmm... what's next? Usually the next thought is that another Oracle bug makes fun of me. But, this sounds too scary to be true. Finally, the stupid answer comes to light.
SQL> show parameter sql92_security
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
sql92_security boolean TRUE
The database reference documentation says the following:
"The SQL92 standards specify that security administrators should be able to require that users have SELECT privilege on a table when executing an UPDATE or DELETE statement that references table column values in a WHERE or SET clause. SQL92_SECURITY specifies whether users must have been granted the SELECT object privilege in order to execute such UPDATE or DELETE statements."
With the above sql92_security parameter set, actually the "where col1='abc'" filter from the UPDATE statement complains about "insufficient privileges" and not the UPDATE itself. Without a filter the update executes as expected:
SQL> update talek.muci set col1='xyz';
1 row updated.
Ok, another lesson has been learned!
No comments:
Post a Comment