Sudo dans une base Oracle

Quand on veut exécuter une requête comme si on était un autre utilisateur, on a l’habitude de préfixer les tables. Par exemple, pour connaitre le contenu de la table EMP de SCOTT en tant que SYS, on lance la requête :

select * from scott.emp ;

Le problème que l’on peut rencontrer alors se situe au niveau des droits qui ne sont pas bien gérés et surtout le contexte. Impossible par exemple de récupérer la liste des tables de SCOTT en passant par user_tables en étant connecté en SYS ou SYSTEM car cette vue fait appel au contexte de l’utilisateur.
La suite de l’article va montrer comment se glisser dans la peau d’un autre utilisateur pour pouvoir contourner ce problème.

Pour cela il suffit d’utiliser le package dbms_sys_sql. Ainsi la requête suivante exécutée par SYS affiche la liste des tables de l’utilisateur SCOTT :
[sourcecode language= »sql »]
set serveroutput on ;
DECLARE
wSQL VARCHAR2(512);
cNum number;
cNumRow number;
res varchar2(32) ;
uid integer ;
BEGIN
select user_id into uid from dba_users where username=’SCOTT’ ;
wSQL := ‘select table_name from user_tables’ ;
cNum := dbms_sql.open_cursor;
dbms_sys_sql.parse_as_user( cNum, wSQL, dbms_sql.NATIVE,uid );
dbms_sql.define_column(cNum, 1, res,32);
cNumRow := dbms_sql.execute(cNum);
LOOP
IF dbms_sql.fetch_rows(cNum) > 0
THEN
dbms_sql.column_value(cNum, 1, res);
dbms_output.put_line(res);
ELSE
exit ;
END IF ;
END LOOP ;
dbms_sql.close_cursor(cNum) ;
END ;
[/sourcecode]
On obtient ainsi le résultat suivant :

DEPT
EMP
BONUS
SALGRADE

Cette requête utilise de manière standard le package dbms_sql. La seule différence intervient au niveau du « parsing » de l’ordre SQL : l’appel à la procédure dbms_sys_sql.parse_as_user au lieu de dbms_sql.parse permet d’exécuter la requête en tant que SCOTT.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *