Я программист, а не дба ... Я знаю достаточно, чтобы быть опасным.
Я унаследовал базу данных от старого пользователя, который является db_owner для базы данных. Мы не можем настроить разрешение этого пользователя для существующих таблиц, схем и т. Д. По деловым причинам, но создаются некоторые новые таблицы, и я только хочу, чтобы этот пользователь имел к ним доступ SELECT.
Для этих пользователей были установлены разрешения для этих таблиц, так что все ОТКАЗАНО, кроме SELECT, для которого установлено значение GRANT.
Тем не менее, когда этот пользователь (dbadmin) пытается выполнить SELECT для одной из этих таблиц (AccountingAudit), возникает эта ошибка:
The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.
Я запустил этот SQL, чтобы попытаться увидеть, какие разрешения установлены для этой таблицы / пользователя:
select object_name(major_id) as object,
user_name(grantee_principal_id) as grantee,
user_name(grantor_principal_id) as grantor,
permission_name,
state_desc
from sys.database_permissions
И вот что я получаю обратно:
AccountingAudit dbadmin dbo ALTER DENY
AccountingAudit dbadmin dbo CONTROL DENY
AccountingAudit dbadmin dbo DELETE DENY
AccountingAudit dbadmin dbo INSERT DENY
AccountingAudit dbadmin dbo REFERENCES DENY
AccountingAudit dbadmin dbo SELECT GRANT
AccountingAudit dbadmin dbo TAKE OWNERSHIP DENY
AccountingAudit dbadmin dbo UPDATE DENY
AccountingAudit dbadmin dbo VIEW DEFINITION DENY
AccountingAudit dbadmin dbo VIEW CHANGE TRACKING DENY
Похоже, это должно работать правильно?
Вызов SELECT, который я делаю, является очень простым SELECT * FROM AccountingAudit изнутри SSMS. Я не делаю никаких специальных sp_executesql или что-то в этом роде.
Я пытался явно предоставить разрешение:
GRANT SELECT ON [dbo].AccountingAudit TO dbadmin
Это не имеет никакого эффекта (почему бы, запрос выше уже показывает, что это предоставлено! ;-)
Я искал на stackoverflow.com и в других местах, и не могу найти ничего, что я еще не пробовал. Мне интересно, связано ли это с тем, как настроены схемы. (На данный момент я очень мало знаю о схемах.)
Есть идеи? Спасибо!
источник
Используйте
sp_DBPermissions
хранимую процедуру Кена Фишера для просмотра разрешений.DENY CONTROL
не применяется к таблице, в дополнение к общемуDENY SELECT
,DENY INSERT
,DENY UPDATE
,DENY DELETE
иDENY REFERENCES
.SELECT
операторе содержатся табличные функции, убедитесь, чтоEXECUTE AS OWNER
в табличной функции есть или функцияGRANT EXECUTE
on (и нетDENY EXECUTE
!). Если дело обстоит именно так, прочитайте сообщение об ошибке более внимательно, так как оно, скорее всего, не скажет, что разрешение SELECT было отклонено для таблицы, а вместо этого что-то об отказе EXECUTE.Если пользователь является пользователем или группой AD, используйте следующий сценарий для определения пользователя
login_token
(ей):Посмотрите на фактический план выполнения. Если ошибка находится внутри хранимой процедуры с
SET NOCOUNT ON;
, то фактический план выполнения даст вам понимание, на которое вы можете не обращать внимания, просто взглянув на вкладку «Сообщения» в SSMS, поскольку «Затрагиваемые строки» могут находиться вне вашего контроля.Вы можете скомпилировать оператор как хранимую процедуру и SSMS «Просмотр зависимостей объекта», а также приемы, описанные Светланой Головко в « Разных путях» для поиска зависимостей объекта SQL Server.
Используйте событие безопасности SQL Server Profiler «Событие доступа к объекту схемы аудита» и столбцы «TextData» и «Success», чтобы отслеживать, для каких объектов SQL Server оценивает разрешения. - Я видел ситуации, когда для этого события выбрасывались две строки, и одно значение указывает «Успех = 1», а другое - «Успех = 0». В этом сценарии единственное решение, которое я нашел для работы, это перезагрузить сервер. Даже выполнение
repadmin /syncall
не решило проблему, не запустило и не остановило приложение (и, следовательно, пул соединений).Определите действующие разрешения для входа в систему:
Если пользователь привязан к пользователю или группе AD, рассмотрите возможность запуска,
repadmin /syncall
чтобы принудительно синхронизировать любые изменения, сделанные в активном каталоге, между контроллерами домена. - Если кто-то знает, как можно сравнить текущие значения двух контроллеров домена, сообщите мне.Прежде чем приступить к полной перезагрузке всей системы, попробуйте убить все активные подключения для этого пользователя. Причина в том, что пользователь получает свой токен Windows от DC, который включает их группы. Токен не будет обновляться до тех пор, пока пользователь не получит новый токен - обычно после выхода из системы и повторного входа.
Тяжело перезагрузить систему. Это сработало для меня. Все еще не уверен на 100%, почему еще. ТОЛЬКО СДЕЛАЙТЕ ЭТО, ЕСЛИ ВЫ МОЖЕТЕ ВЫЖИТЬ ВНИЗ! БУДЬТЕ ОСТОРОЖНЫ, ЧТОБЫ ДЕЛАТЬ ЭТО, КОГДА У ВАС БОЛЬШИЕ ВЫДАЮЩИЕСЯ СДЕЛКИ!
источник