Me gustaría escribir una consulta en un sql 2008 que informará a todos los usuarios que tienen acceso a una base de datos específica u objetos dentro de la base de datos, como tablas, vistas y procedimientos almacenados, ya sea directamente o debido a roles, etc. Esto informe se utilizaría para fines de auditoría de seguridad. No estoy seguro si alguien tiene una consulta que satisfaga mis necesidades por completo, pero espero que sea algo que me dé un buen comienzo. Ya sea sql 2008, 2005 o 2000, probablemente pueda convertir según sea necesario.
191
Respuestas:
Esta es mi primera grieta en una consulta, basada en las sugerencias de Andomar. Esta consulta está destinada a proporcionar una lista de permisos que un usuario ha aplicado directamente a la cuenta de usuario o mediante roles que tiene el usuario.
fuente
login_token
cambiado auser_token
Aquí hay una versión completa de la consulta de Jeremy de agosto de 2011 con los cambios sugeridos por Brad (octubre de 2011) e iw.kuchin (mayo de 2012) incorporados:
[ObjectType]
y[ObjectName]
para esquemas.[ObjectType]
es mejor usarobj.type_desc
solo para laOBJECT_OR_COLUMN
clase de permiso. Para todos los demás casos, useperm.[class_desc]
.IMPERSONATE
permisos.sys.login_token
con,sys.server_principals
ya que mostrará también inicios de sesión de SQL, no solo de Windows.sys
e INFORMATION_SCHEMA.Esperemos que esto salve a alguien más una o dos horas de sus vidas.
:)
fuente
sys.login_token
tampocosys.server_principals
es compatible y necesitan ser reemplazados consys.user_token
A partir de SQL Server 2005, puede usar vistas del sistema para eso. Por ejemplo, esta consulta enumera todos los usuarios en una base de datos, con sus derechos:
Tenga en cuenta que un usuario también puede tener derechos a través de un rol. Por ejemplo, el
db_data_reader
rol otorgaselect
derechos sobre la mayoría de los objetos.fuente
select * from sys.database_principals where type_desc = 'EXTERNAL_GROUP'
), mientras que la respuesta aceptada no, incluso después de la correcciónsys.user_token
.SELECT PrincipalName = p.[name], p.[type_desc], dp.[permission_name], dp.[state_desc], CASE dp.class_desc WHEN 'DATABASE' THEN DB_NAME(dp.major_id) WHEN 'SCHEMA' THEN SCHEMA_NAME(dp.major_id) WHEN 'OBJECT_OR_COLUMN' THEN CONCAT_WS('.', OBJECT_SCHEMA_NAME(dp.major_id), OBJECT_NAME(dp.major_id), c.[name]) END FROM sys.database_principals AS p LEFT OUTER JOIN sys.database_permissions AS dp ON p.principal_id = dp.grantee_principal_id LEFT OUTER JOIN sys.columns AS c ON dp.major_id = c.[object_id] AND dp.minor_id = c.column_id
No puedo comentar sobre la respuesta aceptada, así que agregaré algunos comentarios aquí:
sys.objects
tabla de referencia de MS contiene solo objetos con ámbito de esquema. Por lo tanto, para obtener información sobre objetos de "nivel superior" (es decir, esquemas en nuestro caso) debe usar lasys.schemas
tabla.[ObjectType]
es mejor usarobj.type_desc
solo para laOBJECT_OR_COLUMN
clase de permiso. Para todos los demás casos, useperm.[class_desc]
IMPERSONATE
. Para obtener información sobre personificaciones uno debeLEFT JOIN
consys.database_principals
elperm.major_id = imp.principal_id
sys.login_token
consys.server_principals
lo que se mostrará también los inicios de sesión de SQL, no sólo los de Windows'G'
a los tipos principales permitidos para permitir grupos de Windowssys
yINFORMATION_SCHEMA
de la tabla resultante, ya que estos usuarios se usan solo para el servicioPublicaré la primera pieza del script con todas las correcciones propuestas, otras partes también deberían cambiarse:
fuente
sysadmin
+securityadmin
se asignan ya quedbo
para cada DB en el servidor + hay un permiso del servidorCONTROL SERVER
que podría otorgarse al usuario. Este permiso otorga casi los mismos derechos que el sersysadmin
.Impresionante guión Jeremy y colaboradores! ¡Gracias!
Tengo una tonelada de usuarios, por lo que ejecutar esto para todos los usuarios fue una pesadilla. No pude agregar comentarios, así que estoy publicando todo el script con los cambios. Agregué una variable + cláusula where para poder buscar cualquier cosa que coincida con hasta 5 caracteres en el nombre de usuario (o todos los usuarios cuando se deja en blanco). Nada especial, pero pensé que sería útil en algunos casos de uso.
fuente
Las otras respuestas que he visto pierden algunos permisos que son posibles en la base de datos. La primera consulta en el siguiente código obtendrá el permiso de nivel de base de datos para todo lo que no sea un objeto del sistema. También genera las declaraciones GRANT apropiadas. La segunda consulta obtiene todas las membresías de roles.
Esto debe ejecutarse para cada base de datos, pero es demasiado largo para usarlo con sp_MSforeachdb. Si desea hacerlo, deberá agregarlo a la base de datos maestra como un procedimiento almacenado del sistema.
Para cubrir todas las posibilidades, también debería tener un script que verifique los permisos a nivel de servidor.
ACTUALIZACIÓN: Las siguientes consultas recuperarán los permisos y membresías a nivel de servidor.
fuente
Aquí está mi versión, adaptada de otras. Pasé 30 minutos tratando de recordar cómo se me ocurrió esto, y la respuesta de @Jeremy parece ser la inspiración principal. No quería actualizar la respuesta de Jeremy, en caso de que introdujera errores, así que estoy publicando mi versión aquí.
Sugiero combinar el guión completo con un poco de inspiración extraída del martes T-SQL de Kenneth Fisher: ¿Qué permisos tiene un usuario específico? : Esto le permitirá responder preguntas de cumplimiento / auditoría de abajo hacia arriba, en lugar de arriba hacia abajo.
Para comprender lo que esto cubre, considere
Contoso\DB_AdventureWorks_Accounting
Windows AD Group con miembroContoso\John.Doe
. John.Doe se autentica en AdventureWorks a través de server_principalContoso\DB_AdventureWorks_Logins
Windows AD Group. Si alguien le pregunta: "¿Qué permisos tiene John.Doe?", No puede responder esa pregunta solo con el siguiente script. Luego, debe iterar a través de cada fila devuelta por el script a continuación y unirlo al script anterior. (Es posible que también deba normalizar losname
valores obsoletos al buscar el SID en su proveedor de Active Directory).Aquí está el script, sin incorporar dicha lógica de búsqueda inversa.
fuente
fuente
El procedimiento almacenado GetPermissions anterior es bueno, sin embargo, utiliza Sp_msforeachdb, lo que significa que se romperá si su instancia de SQL tiene nombres de bases de datos que incluyen espacios o guiones y otros caracteres no recomendados. He creado una versión que evita el uso de Sp_msforeachdb y también incluye dos columnas que indican 1: si el inicio de sesión es un inicio de sesión de sysadmin (IsSysAdminLogin) y 2: si el inicio de sesión es un usuario huérfano (IsEmptyRow).
fuente
you can use [] to resolve it. sp_msforeachdb ' use [?] select db_name()'
, supongo que su respuesta fue como un comentario, pero como su cuenta no llena la reputación mínima, publicó una respuesta.Probé casi todo esto, pero rápidamente noté que faltaban algunos, especialmente los usuarios de sysadmin. Tener un agujero así no se verá bien en nuestra próxima auditoría, así que esto es lo que se me ocurrió
fuente
Debido a la baja representación, no puedo responder con esto a las personas que solicitan ejecutar esto en múltiples bases de datos / Servidores SQL.
Cree un grupo de servidores registrados y consulte en todos ellos lo siguiente y simplemente pase el cursor por las bases de datos:
Este hilo me ayudó enormemente gracias a todos!
fuente
DB_NAME()
y almacenando la salida en una tabla temporal para evitar terminar con múltiples conjuntos de resultados. ¡Gracias!Muchas gracias por los increíbles scripts de auditoría.
Recomiendo encarecidamente que el usuario de auditoría use el increíble Kenneth Fisher ( procedimientos almacenados de b | t )
fuente
Una consulta simple que muestra solo si eres un SysAdmin o no:
fuente
Desafortunadamente, no pude comentar sobre la publicación de Sean Rose debido a una reputación insuficiente, sin embargo, tuve que enmendar la parte de la función "pública" del guión, ya que no mostraba los permisos de alcance SCHEMA debido a la (INNER) JOIN contra sys. objetos. Después de que se cambió a una IZQUIERDA IZQUIERDA, tuve que modificar la lógica de la cláusula WHERE para omitir los objetos del sistema. Mi consulta modificada para los permisos públicos está a continuación.
fuente
Si desea verificar el acceso a las bases de datos para un inicio de sesión particular, use este script simple como se muestra a continuación:
sys.sp_helplogins @LoginNamePattern = 'Domain \ login' - sysname
fuente
--me turno para contribuir de nuevo, disfrutar
Este encabezado del informe toma dinámicamente el nombre de la instancia SQL, la fecha y la hora y el nombre de la cuenta con la que se ejecuta el informe, todo lo que un buen auditor querrá saber. :)
Nota: si tiene una propiedad extendida llamada 'entorno' en la base de datos maestra, el valor (lo que utilice: PreProd, Desarrollo, Producción, DR, etc.) se incluirá en el encabezado del informe.
FINAL
- genial para guardar como un proceso almacenado
fuente