Как определить, есть ли у меня права на выполнение БД программно? - PullRequest
1 голос
/ 13 октября 2009

У меня есть служба Windows, требующая разрешения на выполнение в БД SQL Server 2005. При запуске я проверяю, могу ли я подключиться к БД и остановить службу, если не могу. Я также хочу проверить, могу ли я выполнить хранимую процедуру, используя это соединение. Есть ли способ сделать это без фактической попытки выполнения sproc и проверки исключения, если оно произошло?

Ответы [ 4 ]

11 голосов
/ 14 октября 2009

SQL 2005 и вы можете проверить любое разрешение с помощью HAS_PERM_BY_NAME:

SELECT HAS_PERMS_BY_NAME('sp_foo', 'OBJECT', 'EXECUTE');
3 голосов
/ 14 октября 2009

вы можете выполнить запрос, подобный этому:

SELECT
    o.NAME,COALESCE(p.state_desc,'?permission_command?')+' '+COALESCE(p.permission_name,'?permission_name?')+' ON ['+SCHEMA_NAME(o.schema_id)+'].['+COALESCE(o.Name,'?object_name?')+'] TO ['+COALESCE(dp.Name,'?principal_name?')+']' COLLATE SQL_Latin1_General_CP1_CI_AS AS GrantCommand
    FROM sys.all_objects                          o
        INNER JOIN sys.database_permissions       p ON o.OBJECT_ID=p.major_id
        LEFT OUTER JOIN sys.database_principals  dp ON p.grantee_principal_id = dp.principal_id
    where p.state_desc='GRANT' AND p.permission_name='EXECUTE'
        AND o.NAME='YourProcedureName'
        AND dp.Name='YourSecurityName'

... и удалите причудливое форматирование команды grant, оно есть только для справки

это тоже хорошо ...

SELECT * FROM fn_my_permissions('YourTable', 'OBJECT') 
SELECT * FROM fn_my_permissions('YourProcedure', 'OBJECT') 
SELECT * FROM fn_my_permissions (NULL, 'DATABASE')
SELECT * FROM fn_my_permissions(NULL, 'SERVER')

Чтобы узнать, какие разрешения есть у кого-то другого, вы можете сделать это:

EXECUTE AS user = 'loginToTest'
GO
PRINT 'SELECT permissions on tables:'
SELECT
    HAS_PERMS_BY_NAME(    QUOTENAME(SCHEMA_NAME(schema_id))+'.' + QUOTENAME(name)
                          ,'OBJECT','SELECT'
                     ) AS have_select
        , * 
    FROM sys.tables;

PRINT 'EXECUTE permissions on stored procedures:'
SELECT
    HAS_PERMS_BY_NAME(    QUOTENAME(SCHEMA_NAME(schema_id)) + '.' + QUOTENAME(name)
        ,'OBJECT', 'EXECUTE') AS have_execute
        , * 
    FROM sys.procedures;
GO
REVERT;
GO
1 голос
/ 20 октября 2014

В первой части этого ответа показано, как можно проверить права в T-SQL , во второй части приведен пример, как использовать это в Entity Framework (обратите внимание, что различия между версиями EF - приведен пример EF 4, но его можно легко изменить на более новую версию):


Первая часть (SQL):

Я использую следующий T-SQL скрипт для проверки разрешений. Сначала он проверяет, есть ли у вас какие-либо права, затем он проверяет разрешения на выполнение для SP, наконец, выбирает разрешения для таблиц. См. эту ссылку для получения дополнительной информации.

-- 1. Do I have any permissions?
SELECT HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;

-- 2. create list of schemas
declare @SchemaList table (schema_id int, name nvarchar(max));

PRINT 'Schemas regarded:'

insert into @SchemaList
select distinct schema_id, name FROM sys.schemas
where name in ('dbo') -- enter the schemas you like to check comma-separated

SELECT s.name, s.schema_id FROM sys.schemas s
join @SchemaList sl on s.schema_id=sl.schema_id

-- 3. check execute permissions
PRINT 'EXECUTE permissions on stored procedures:'
SELECT 
    HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)
        ,'OBJECT', 'EXECUTE') AS [have execute]
        ,'['+s.name +'].['+ t.name+']' as [object]
        --, * 
    FROM sys.procedures t
    join @SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;

-- 4. check select permissions
PRINT 'SELECT permissions on tables:'
SELECT 
    HAS_PERMS_BY_NAME(QUOTENAME(SCHEMA_NAME(t.schema_id))+'.' + QUOTENAME(t.name)
        ,'OBJECT','SELECT') AS [have select]
        ,'['+s.name +'].['+ t.name+']' as [object]
        --, * 
    FROM sys.tables t
    join @SchemaList s on t.schema_id=s.schema_id
order by s.name, t.name;

С базой данных Northwind , например, это дает следующий результат:

Query_results

Обратите внимание , что вы можете настроить схемы, рассмотренные на шаге 2. Если вам не требуется проверять ограниченный набор схем, вы можете просто закомментировать предложение where в операторе insert into @SchemaList чтобы получить все схемы.


Вторая часть (Entity Framework):

В этом разделе я хотел бы показать вам, как вы можете получить результаты в Entity Framework. Предположим, вы хотите проверить, есть ли у вас какие-либо права до , используя любую из таблиц в ваших запросах LINQ. Посмотрите на этот пример (для простоты я сделал это в LinqPad , пожалуйста, добавьте System.Data.Entity.dll и его пространства имен через F4, прежде чем запускать его):

void Main()
{
    var dc=this;
    var sql="SELECT TOP 1 "
              + "HAS_PERMS_BY_NAME(db_name(), 'DATABASE', 'ANY') DoIHaveAnyRights;";
    var result=dc.ExecuteStoreQuery<Rights>(sql);
    if (result1.DoIHaveAnyRights==1)
    {
        Console.WriteLine("OK"); // ok
    }
    else
    {
        // no rights: Show error etc.
        Console.WriteLine("No rights"); // ok
    }
}

public class Rights
{
    public Int32 DoIHaveAnyRights { get; set; }
}

Точно так же вы можете использовать запрос из первой части моего ответа, например ::

var sql="select top 1 case when cnt.NoRightsCount=0 then 1 else 0 end "
+"as DoIHaveAnyRights "
+"from (SELECT count(1) NoRightsCount FROM sys.procedures t "
+"where HAS_PERMS_BY_NAME("
+"QUOTENAME(SCHEMA_NAME(t.schema_id)) + '.' + QUOTENAME(t.name)"
+",'OBJECT', 'EXECUTE')<>1) cnt";

Этот запрос проверит, есть ли в вашей базе данных хранимые процедуры, для которых у вас нет прав на выполнение - в этом случае возвращаемое значение будет result1.DoIHaveAnyRights!=1.

Я думаю, что вы поняли идею, поэкспериментируете с возможностями: имейте в виду, что EF требует доступа ко всем таблицам базы данных, хранимым процедурам и т. Д., К которым вы привязываетесь - вы можете использовать приведенный выше код для проверки перед доступом их. К сожалению, в настоящее время нет более простого способа сделать это.

0 голосов
/ 13 октября 2009

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...