Jogosultságok Oracle DB-ben

2008. augusztus 10., vasárnap, 12:15

A minap szembesültem egy jogosultági problémával Oracle-ben, s mivel régen volt már az OCP vizsga, és én gyorsan felejtek, kénytelen voltam felfrissíteni ismereteimet a témában. Ha már így jártam, s mivel ketten is Oracle-ös posztokra nyilvánították ki igényüket a nyitóbejegyzés kommentjeiben, gondoltam írok a témáról.

Jogosultságok típusai

Két fajta jogosultság létezik Oracle-ben: objektum szintű (object privileges), és rendszer szintű (system privileges). A műveletet, amivel jogot adunk egy user-nek bizonyos dologra szép magyarul grantolásnak nevezzük, és meglepő mód a GRANT utasítással lehet elvégezni. Visszavonni a REVOKE-kal lehet.

Rendszer szintű privilégiumok: ilyen bizonyos műveletek végrehajtásának joga (pl.: csatlakozás az adatbázishoz, vagy táblatér létrehozása), és idetartoznak azon jogosultságok amik egy séma összes azonos típusú objektumára vonatkoznak (pl.: lekérdezés egy séma bármelyik táblájából).

Objektum szintű privilégiumok: egy bizonyos művelet végrehajtásának joga egy bizonyos séma egy bizonyos objektumán (pl.: sorok törlésének joga a HR user DEPARTMENTS tábláján). Bizonyos típusú objektumokhoz (CLUSTER, INDEX, TRIGGER, DATABASE LINK) nem tartoznak objektumszintű privilégiumok, hanem csak rendszer szintűek. Ha egy szinonímára grantolunk objektum szintű privilégiumot, akkor az egyenértékű azzal, mintha a szinoníma által hivatkozott objektumra grantolnánk. A szinoníma eldobása után a jog nem is fog elveszni.

Szerepek

Jogosultságokat adhatunk felhasználóknak (user) és szerepeknek (role). Mire jók a szerepek? Segítségükkel összefoghatunk privilégiumokat, és ezeket egyszerre oszthatjuk ki felhasználóknak, sőt akár más szerepeknek is, így egyszerűsíthetjük az adiminsztrációt.

Szerepek munkamenet (session) szinten lehetnek ki- és bekapcsolt állapotban. SET ROLE utasítással tudjuk ezt megtenni. Fontos tudni, hogy Oracle-ön belüli programoknak (függvények, eljárások, csomagok) közvetlenül kell kiosztani a jogosultságokat, szerepeken keresztül kiosztott jogosultságot nem használhatnak. Hiszen fordítási időben nem tudhatja az adatbázis, hogy mikor majd a program futni fog, a szükséges szerep aktív állapotban lesz-e.

WITH ADMIN OPTION, WITH GRANT OPTION

Rendszer szintű privilégium és szerep esetén a WITH ADMIN OPTION megadásával megengedhetjük, hogy a felhasználó, aki kapta a jogot vagy szerepet, tovább is adhassa azt másoknak. Objektum szintű privilégiumok esetén a WITH GRANT OPTION-t kell használnunk, ha azt akarjuk, hogy tovább lehessen adni szerepeknek vagy felhasználóknak.

Ha WITH ADMIN OPTION-nel jogot adtunk Bobónak, majd visszavonjuk, de ő addigra már tovább grantolta Benőnek, akkor a továbbadott jogot Benő nem fogja elveszíteni. Viszont objektum szintű privilégium esetén, ha WITH GRANT OPTION-nel kiosztottuk Bobónak valami, aki továbbadta Benőnek, ezután visszavonjuk Bobótól, akkor ezzel a mozdulattal Benőtől is visszavontuk. Fincsi mi?

Jogosultságok kiosztása

Objektum szintű jogosultságot adunk Bobo nevű kollégának, hogy módosíthassa a departments tábla department_name oszlopát.

SQL> GRANT UPDATE (department_name) ON departments TO bobo ;

A looser_privs szerepnek jogot adunk, hogy bármilyen táblát eldobhasson, majd Bobo megkapja a looser_privs-t.

SQL> GRANT DROP ANY TABLE TO looser_privs;
SQL> GRANT looser_privs TO bobo;

Majd rájövünk, hogy inkább visszavonunk mindent

SQL> REVOKE UPDATE ON departments FROM bobo;
SQL> REVOKE DROP ANY TABLE FROM looser_privs;

Jogosultságok lekérdezése

A következő nézetekből tudjuk lekérdezni, hogy kinek milyen jogosultságai vannak:

  • DBA_USERS: adatbázisban található felhasználók.
  • DBA_ROLES: adatbázisban található szerepek.
  • DBA_TAB_PRIVS: felhasználóknak és szerepeknek kiosztott objektum szintű jogosultságok. Ne zavarjon meg senkit a tábla neve, az összes objektumra vonatkozó jogosultság ebben van. Az objektum neve a TABLE_NAME mezőben található.
  • DBA_SYS_PRIVS felhasználóknak és szerepeknek kiosztott rendszer szintű jogosultságok.
  • DBA_ROLE_PRIVS felhasználóknak és szerepeknek kiosztott szerepek.

A végére pedig jöjjön három trükkös lekérdezés (forrás). Az első megadja, hogy egy user-nek, milyen szerepei vannak (rekurzívan) és a szerepeken keresztül milyen rendszerszintű privilégiumokkal rendelkezik.

select
  lpad(' ', 2*level) || granted_role "User, his roles and privileges"
from
  (
  /* THE USERS */
    select 
      null     grantee, 
      username granted_role
    from 
      dba_users
    where
      username like upper('%&enter_username%')
  /* THE ROLES TO ROLES RELATIONS */ 
  union
    select 
      grantee,
      granted_role
    from
      dba_role_privs
  /* THE ROLES TO PRIVILEGE RELATIONS */ 
  union
    select
      grantee,
      privilege
    from
      dba_sys_privs
  )
start with grantee is null
connect by grantee = prior granted_role;

Megkeresi egy adott rendszer szintű privilégiumhoz, hogy milyen szerepek rendelkeznek vele (rekurzívan) és ezek a szerepek milyen felhasználókhoz tartoznak.

select
  lpad(' ', 2*level) || c "Privilege, Roles and Users"
from
  (
  /* THE PRIVILEGES */
    select 
      null   p, 
      name   c
    from 
      system_privilege_map
    where
      name like upper('%&enter_privliege%')
  /* THE ROLES TO ROLES RELATIONS */ 
  union
    select 
      granted_role  p,
      grantee       c
    from
      dba_role_privs
  /* THE ROLES TO PRIVILEGE RELATIONS */ 
  union
    select
      privilege     p,
      grantee       c
    from
      dba_sys_privs
  )
start with p is null
connect by p = prior c;

Megkeresi, hogy adott séma adott objektumára milyen objektumszintű privilégiumok vannak kiosztva közvetlenül vagy szerepeken keresztül (rekurzívan).

select
  case when level = 1 then own || '.' || obj || ' (' || typ || ')' else
  lpad (' ', 2*(level-1)) || obj || nvl2 (typ, ' (' || typ || ')', null)
  end
from
  (
  /* THE OBJECTS */
    select 
      null          p1, 
      null          p2,
      object_name   obj,
      owner         own,
      object_type   typ
    from 
      dba_objects
    where
       owner like upper('%&enter_owner_name%')    
       and object_name like upper('%&enter_object_name%')
       
  /* THE OBJECT TO PRIVILEGE RELATIONS */ 
  union
    select
      table_name p1,
      owner      p2,
      grantee,
      grantee,
      privilege
    from
      dba_tab_privs
  /* THE ROLES TO ROLES/USERS RELATIONS */ 
  union
    select 
      granted_role  p1,
      granted_role  p2,
      grantee,
      grantee,
      null
    from
      dba_role_privs
  )
start with p1 is null and p2 is null
connect by p1 = prior obj and p2 = prior own;

Nincsenek megjegyzések:

Megjegyzés küldése