Je suis programmeur, pas dba ... J'en sais juste assez pour être dangereux.
J'ai hérité d'une base de données avec un utilisateur hérité qui est un db_owner pour la base de données. Nous ne pouvons pas ajuster l'autorisation de cet utilisateur pour les tables, schémas, etc. existants, pour des raisons commerciales, mais de nouvelles tables sont en cours de création, et je souhaite uniquement que cet utilisateur dispose d'un accès SELECT sur celles-ci.
Des autorisations ont été définies pour cet utilisateur pour ces tables afin que tout soit REFUSÉ, à l'exception de SELECT, qui est défini sur GRANT.
Pourtant, lorsque cet utilisateur (dbadmin) tente d'effectuer un SELECT sur l'une de ces tables (AccountingAudit), cette erreur se produit:
The SELECT permission was denied on the object 'AccountingAudit', database 'billing', schema 'dbo'.
J'ai exécuté ce SQL pour essayer de voir quelles autorisations sont définies pour cette table / cet utilisateur:
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
Et voici ce que je récupère:
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
Il semble que cela devrait fonctionner correctement?
L'appel SELECT que je fais est un SELECT * FROM AccountingAudit très basique, depuis SSMS. Je ne fais pas de sp_executesql spécial ou quelque chose comme ça.
J'ai essayé d'accorder explicitement l'autorisation:
GRANT SELECT ON [dbo].AccountingAudit TO dbadmin
Cela n'a aucun effet (pourquoi, la requête ci-dessus montre déjà que c'est accordé! ;-)
J'ai cherché sur stackoverflow.com et ailleurs, et je ne trouve rien que je n'ai pas encore essayé. Je me demande si cela a quelque chose à voir avec la configuration des schémas. (À ce stade, je connais très peu de schémas.)
Des idées? Merci!
la source
Utilisez la
sp_DBPermissions
procédure stockée de Ken Fisher pour consulter les autorisations.DENY CONTROL
n'est pas appliquée à la table, en plus de la communeDENY SELECT
,DENY INSERT
,DENY UPDATE
,DENY DELETE
etDENY REFERENCES
.SELECT
instruction contient des fonctions table, assurez-vous qu'il y a unEXECUTE AS OWNER
sur la fonction table ou unGRANT EXECUTE
dessus (et nonDENY EXECUTE
!). Si tel est le cas, lisez le message d'erreur plus attentivement car il ne dira probablement pas que l'autorisation SELECT a été refusée sur la table, mais à la place quelque chose sur EXECUTE étant refusé.Si l'utilisateur est un utilisateur ou un groupe AD, utilisez le script suivant pour déterminer le ou les utilisateurs
login_token
:Regardez le plan d'exécution réel. Si l'erreur se trouve dans une procédure stockée avec
SET NOCOUNT ON;
, le plan d'exécution réel vous donnera un aperçu auquel vous pourriez ne pas faire attention en regardant simplement l'onglet Messages dans SSMS, car les "lignes affectées" peuvent être hors de votre contrôle.Vous pouvez compiler l'instruction en tant que procédure stockée et SSMS "View Object Dependencies", ainsi que les astuces décrites par Svetlana Golovko de différentes manières pour trouver les dépendances d'objets SQL Server
Utilisez l'événement SQL Server Profiler Security «Audit Schema Object Access Event» et les colonnes «TextData» et «Success» pour suivre les objets sur lesquels SQL Server évalue les autorisations. - J'ai vu des situations où deux lignes sont émises pour cet événement, et une valeur indique Success = 1 et l'autre indique Success = 0. Dans ce scénario, la seule solution que j'ai trouvée fonctionne est de redémarrer le serveur. Même l'exécution
repadmin /syncall
n'a pas résolu le problème, ni le démarrage et l'arrêt de l'application (et donc du pool de connexions).Déterminez les autorisations effectives pour la connexion:
Si l'utilisateur est lié à un utilisateur ou un groupe AD, pensez à exécuter
repadmin /syncall
pour forcer la synchronisation de toutes les modifications apportées à Active Directory sur vos contrôleurs de domaine. - Si quelqu'un connaît un bon moyen de comparer les valeurs actuelles de deux contrôleurs de domaine, faites-le moi savoir.Avant d'envisager un redémarrage dur de l'ensemble du système, essayez de supprimer toutes les connexions actives pour cet utilisateur. La raison en est que l'utilisateur obtient son jeton Windows du contrôleur de domaine qui inclut ses groupes. Le jeton ne sera pas mis à jour tant que l'utilisateur n'aura pas un nouveau jeton - généralement en se déconnectant puis en se reconnectant.
Redémarrez durement le système. ça a marché pour moi. Toujours pas sûr à 100% pourquoi encore. FAITES-LE UNIQUEMENT SI VOUS POUVEZ SURVIVRE AU TEMPS! SOYEZ PRUDENT DE LE FAIRE PENDANT QUE VOUS AVEZ DE GRANDES TRANSACTIONS EN COURS!
la source