Регенерация грантов для ролей в разных схемах - PullRequest
6 голосов
/ 20 января 2010

Подобно этому вопросу , я хотел бы знать, как сгенерировать все операторы GRANT, выданные всем ролям в наборе схем, и список ролей, имена которых заканчиваются на "PROXY". Я хочу воссоздать утверждения вроде:

GRANT SELECT ON TABLE_NAME TO ROLE_NAME;
GRANT EXECUTE ON PACKAGE_NAME TO ROLE_NAME;

Цель - помочь перейти с базы данных разработки на тестовую базу данных (Oracle 11g). Есть некоторые инструменты, которые пытаются сделать это автоматически, но часто терпят неудачу.

Есть идеи?

Ответы [ 4 ]

8 голосов
/ 21 января 2010

Этот скрипт генерирует список всех привилегий таблицы, предоставленных ролям ...

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
order by grantee, owner
/

Обратите внимание, что я не ограничиваю роли грантополучателя, потому что ваш вопрос неясен в этом вопросе. Вам может понадобиться добавить фильтр в sub_query на dba_roles. Если у вас есть роли, предоставленные другим ролям, вы тоже захотите их подобрать ...

select 'grant '||granted_role||' to '||grantee
         ||case when admin_option = 'YES' then ' with admin option' else null end
         ||';'
from dba_role_privs
where grantee in ( select role from dba_roles )
order by grantee, granted_role
/

Чтобы получить список ролей ...

select 'create role '||role ||';'
from dba_roles
where role like '%PROXY'
/

Обратите внимание, что эти сценарии не генерируют гранты для системных привилегий. Кроме того, жизнь немного усложняется, если вы используете объекты каталога, потому что для этого требуется дополнительное ключевое слово ...

select 'grant '||privilege||' on '||owner||'.'||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where owner in ('A', 'B')
and grantee in ( select role from dba_roles )
and table_name not in ( select directory_name from dba_directories )
union all
select 'grant '||privilege||' on directory '||table_name||' to '||grantee
         ||case when grantable = 'YES' then ' with grant option' else null end
         ||';'
from dba_tab_privs
where grantee in ( select role from dba_roles )
and table_name  in ( select directory_name from dba_directories )
/

редактировать

В 9i Oracle представила пакет DBMS_METADATA, который объединяет множество запросов такого рода в простой PL / SQL API. Например, этот вызов создаст CLOB со всеми объектными привилегиями, предоставленными A ...

select dbms_metadata.get_granted_ddl('OBJECT_GRANT', 'A') from dual
/

Это, очевидно, намного проще, чем сворачивать нашу собственную.

1 голос
/ 20 января 2010

Вы можете сделать это с помощью некоторого кода PL / SQL:

TYPE obj_name_type is TABLE OF ALL_OBJECTS%OBJECT_NAME INDEX BY BINARY_INTEGER;
object_names obj_name_type;
i INTEGER;
BEGIN
   SELECT object_name BULK COLLECT INTO object_names FROM ALL_OBJECTS WHERE OWNER = 'whatever' AND object_type = 'PROCEDURE';
   FOR i IN 1 .. object_names.last LOOP
         EXECUTE IMMEDIATE 'GRANT EXECUTE ON ' object_names(i) ' TO ' role_name
   END LOOP;
END;

Вы можете сделать более универсальным сопоставление типов разрешений с типами объектов или с тем, что у вас есть, но это основная идея.

Вы должны использовать EXECUTE IMMEDIATE, потому что вы не можете статически запускать DDL внутри процедурного кода.

0 голосов
/ 05 июля 2015

Я хотел решить проблему, очень похожую на эту. Единственное отличие состоит в том, что мне нужен более универсальный инструмент, а также независимый от СУБД. Я хотел иметь возможность применять инструмент в производственных средах, и некоторые из целевых баз данных не были Oracle.

Я придумал функцию Powershell, которая выполняет подстановку параметров и генерирует повторяющийся сценарий, содержащий последовательность операторов GRANT. Выход выглядит как

grant ALL 
   on Employees 
   to DBA;




grant READ 
   on Employees 
   to Analyst;




grant READ, WRITE 
   on Employees 
   to Application;




grant ALL 
   on Departments 
   to DBA;




grant READ 
   on Departments 
   to Analyst, Application;

Для моего инструмента есть два входа: файл шаблона и файл csv. Файл шаблона выглядит следующим образом:

grant $privs 
   on $table 
   to $user;

И CSV-файл выглядит так:

privs,table,user
ALL,Employees,DBA
READ,Employees,Analyst
"READ, WRITE", Employees, Application
ALL,Departments,DBA
READ,Departments,"Analyst, Application"

Инструмент расширения выглядит следующим образом:

<#  This function is a table driven template tool. 
    It's a refinement of an earlier attempt.

    It generates output from a template and
    a driver table.  The template file contains plain
    text and embedded variables.  The driver table 
    (in a csv file) has one column for each variable, 
    and one row for each expansion to be generated.

    5/13/2015

#>

function Expand-csv {
   [CmdletBinding()]
   Param(
      [Parameter(Mandatory=$true)]
      [string] $driver,
      [Parameter(Mandatory=$true)]
      [string] $template
   )
   Process
   {
      $OFS = "`r`n"
      $list = Import-Csv $driver
      [string]$pattern = Get-Content $template

      foreach ($item in $list) {
         foreach ($key in $item.psobject.properties) {
            Set-variable -name $key.name -value $key.value
            }
         $ExecutionContext.InvokeCommand.ExpandString($pattern) 
         }
   }
}

Наконец, пример вызова инструмента выглядит так:

Expand-csv demo.csv demo.tem > demo.sql

обратите внимание, что спецификация файла csv стоит первой, а спецификация файла шаблона - второй. обратите внимание, что «формальные параметры», используемые в файле шаблона, выглядят как переменные Powershell. Это то, что они есть. обратите внимание, что имена, используемые в шаблоне, соответствуют именам, указанным в заголовке файла CSV.

На самом деле я использовал предшественник этого инструмента с различными диалектами SQL, а также с целевыми языками, отличными от SQL. Я даже использовал его для генерации повторяющегося скрипта Powershell, который делает не что иное, как многократный вызов другого скрипта .ps1 с разными фактическими параметрами.

Это не самый элегантный инструмент в мире, но он хорошо мне подходит.

0 голосов
/ 20 января 2010

Это соответствует нашим потребностям:

SELECT
  'GRANT ' || p.privilege || ' ON ' || p.table_name || ' TO ' ||
  p.grantee || ';' AS generated_grant
FROM
  dba_tab_privs p
WHERE
  p.grantor IN ( 'SCHEMA_NAME_01', 'SCHEMA_NAME_02' ) AND
  p.grantee IN (
    SELECT DISTINCT
      granted_role
    FROM
      dba_role_privs
    WHERE
      grantee LIKE '%PROXY' AND
      granted_role NOT IN ('CONNECT','AQ_ADMINISTRATOR_ROLE','RESOURCE')
  ) AND
  p.table_name NOT LIKE 'BIN%' AND
  p.table_name NOT LIKE '%$%'
ORDER BY
  p.table_name, p.grantee, p.privilege;
...