2010-01-20 3 views
6

Как и для this question, я хотел бы знать, как сгенерировать все операторы GRANT, выданные всем ролям в наборе схем, и список ролей, имена которых заканчиваются на «PROXY». Я хочу воссоздать такие заявления:Регенерировать GRANT для ролей по схемам

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

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

Любые идеи?

+0

Думаю, вам нужно сделать это нелегко. Прокрутите «All_TAB_PRIVS» и сгенерируйте этот скрипт. Интересный вопрос. Я хотел бы знать, если это возможно. – Guru

ответ

7

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

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 
/

Обратите внимание, что я не ограничиваю роли GRANTEE, потому что ваш вопрос неясен в этом вопросе. Возможно, вам потребуется добавить фильтр в 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. Например, этот вызов будет prorduces в CLOB со всеми привилегиями объекта, предоставленного ...

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

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

1

Вы можете сделать это с каким-то кодом 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

Это предоставит эксклюзивные права на все процедуры вашего владельца. Насколько я понимаю, речь идет о получении фактических грантов и предоставлении сценария для воссоздания их на другой схеме. –

+0

Я просто показывал общую идею. Вы можете настроить запрос SELECT, чтобы получить правильный список. – Dan

+0

Почему бы не использовать PL/SQL? Похоже, это хороший инструмент для этой цели. – Dan

0

Это отвечает нашим требованиям:

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; 
+0

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

+0

Достаточно честный. Я просто хотел указать на потенциальные области, которые могут вызвать проблемы для будущих искателей, которые приходят в эту нить через результат поиска. – APC

0

Я хотел решить проблему, очень похожую на эту. Единственное различие заключается в том, что мне нужен инструмент, который был более общим, а также агрегированным DBMS. Я хотел использовать инструмент в производственных средах, а некоторые из целевых баз данных не были 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, снова и снова, с различными фактическими параметрами.

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

Смежные вопросы