Một truy vấn liệt kê tất cả người dùng được ánh xạ cho một lần đăng nhập nhất định


19

Khi xem các thuộc tính của một thông tin đăng nhập cụ thể, có thể thấy danh sách người dùng được ánh xạ tới thông tin đăng nhập đó: nhập mô tả hình ảnh ở đây

Tôi đã cấu hình SQL Server Management Studio (SSMS) và tôi thấy rằng SSMS kết nối với mọi cơ sở dữ liệu cùng một lúc và truy xuất thông tin từ sys.database_permissions

Có thể viết một truy vấn duy nhất lấy thông tin ánh xạ người dùng được hiển thị ở trên không hoặc tôi có bị buộc phải sử dụng một con trỏ hoặc sp_MSforeachdb hoặc một cái gì đó tương tự không?


Câu trả lời:


15

Đây là một cách sử dụng SQL động. Thực sự không có cách nào để làm điều này mà không lặp đi lặp lại nhưng cách tiếp cận này an toàn hơn nhiều so với các tùy chọn không có giấy tờ, không được hỗ trợ và lỗi như thế nàosp_MSforeachdb .

Điều này sẽ nhận được một danh sách tất cả các cơ sở dữ liệu trực tuyến, người dùng được ánh xạ (nếu nó tồn tại) cùng với tên lược đồ mặc định và danh sách các vai trò được phân tách bằng dấu phẩy.

DECLARE @name SYSNAME = N'your login name'; -- input param, presumably

DECLARE @sql NVARCHAR(MAX) = N'';

SELECT @sql += N'UNION ALL SELECT N''' + REPLACE(name,'''','''''') + ''',
  p.name, p.default_schema_name, STUFF((SELECT N'','' + r.name 
  FROM ' + QUOTENAME(name) + N'.sys.database_principals AS r
  INNER JOIN ' + QUOTENAME(name) + N'.sys.database_role_members AS rm
   ON r.principal_id = rm.role_principal_id
  WHERE rm.member_principal_id = p.principal_id
  FOR XML PATH, TYPE).value(N''.[1]'',''nvarchar(max)''),1,1,N'''')
 FROM sys.server_principals AS sp
 LEFT OUTER JOIN ' + QUOTENAME(name) + '.sys.database_principals AS p
 ON sp.sid = p.sid
 WHERE sp.name = @name '
FROM sys.databases WHERE [state] = 0;

SET @sql = STUFF(@sql, 1, 9, N'');

PRINT @sql;
EXEC master.sys.sp_executesql @sql, N'@name SYSNAME', @name;

1
lưu ý thú vị, tôi đã phải thêm các đối chiếu rõ ràng vào các cột p.name và p.default_schema_name để liên minh hoạt động bình thường
Michael J Swart

@MichaelJSwart À đúng rồi, tôi đã gặp điều này trước đây khi cơ sở dữ liệu có các đối chiếu khác nhau (một số cột siêu dữ liệu sử dụng đối chiếu máy chủ nhưng các cột khác kế thừa đối chiếu cơ sở dữ liệu). Tôi hy vọng những người duy nhất thực sự bị bỏng là những người khăng khăng sử dụng các ký tự lập dị trong các tên thực thể chỉ được hỗ trợ trong một số đối chiếu tối nghĩa ...
Aaron Bertrand

7

Kịch bản này được sửa đổi một chút từ một kịch bản được đề cập tại sẽ làm những gì bạn đang tìm kiếm. Thay thế 'Thứ năm' bằng thông tin đăng nhập bạn cần thông tin. https://www.simple-talk.com/sql/sql-tools/the-sqlcmd-workbench/

    SET NOCOUNT ON
    CREATE TABLE #temp
        (
          SERVER_name SYSNAME NULL ,
          Database_name SYSNAME NULL ,
          UserName SYSNAME ,
          GroupName SYSNAME ,
          LoginName SYSNAME NULL ,
          DefDBName SYSNAME NULL ,
          DefSchemaName SYSNAME NULL ,
          UserID INT ,
          [SID] VARBINARY(85)
        )

    DECLARE @command VARCHAR(MAX)
    --this will contain all the databases (and their sizes!)
    --on a server
    DECLARE @databases TABLE
        (
          Database_name VARCHAR(128) ,
          Database_size INT ,
          remarks VARCHAR(255)
        )
    INSERT  INTO @databases--stock the table with the list of databases
            EXEC sp_databases

    SELECT  @command = COALESCE(@command, '') + '
    USE ' + database_name + '
    insert into #temp (UserName,GroupName, LoginName,
                        DefDBName, DefSchemaName,UserID,[SID])
         Execute sp_helpuser
    UPDATE #TEMP SET database_name=DB_NAME(),
                     server_name=@@ServerName
    where database_name is null
    '
    FROM    @databases
    EXECUTE ( @command )

    SELECT  loginname ,
            UserName ,
            Database_name
    FROM    #temp
    WHERE   LoginName = 'ThursdayClass' 

Cảm ơn Taiob, điều này hoạt động tốt, (tôi sẽ gửi cột cơ sở dữ liệu trong ngoặc ('[' và ']')
Michael J Swart

5

Hãy thử sp_dbpermissions . Nó có thể sẽ cung cấp cho bạn nhiều thông tin hơn bạn cần nhưng nó sẽ làm những gì bạn muốn.

Khi nó được cài đặt, hãy chạy cái này.

sp_dbpermissions @dbname = 'All', @LoginName = 'LoginName'

Cảnh báo công bằng tại thời điểm nó thực hiện khớp "thích" vì vậy nếu các thông tin đăng nhập khác tương tự và phù hợp thì bạn cũng sẽ thấy chúng. Ví dụ MyLoginMyLoginForThiscả hai sẽ phù hợp trên MyLogin. Nếu đó là một vấn đề tôi có một phiên bản mà tôi chưa phát hành, nơi bạn có thể tắt nó đi. Hãy cho tôi biết và tôi có thể gửi email cho bạn.


4

Đây là một giải pháp quyền hạn:

import-module sqlps;

$s = new-object microsoft.sqlserver.management.smo.server '.'
foreach ($db in $s.Databases | where {$_.IsAccessible -eq $true}) {
   $u = $db.users | where {$_.Login -eq 'foobar'}
   if ($u -ne $null) { #login is mapped to a user in the db
       foreach ($role in $db.Roles) {
           if ($role.EnumMembers() -contains $u.Name) {
               $u | select parent, @{name="role";expression={$role.name}}, name
           }
       }
   }
}

4

Đáng buồn thay, bạn sẽ phải lặp qua tất cả các cơ sở dữ liệu để có được thông tin. Bạn sẽ muốn tham gia sys.database_principalsđể sys.server_principalsphù hợp với từng cơ sở dữ liệu trên SID.

Đừng sử dụng sp_msforeachdbvì đôi khi nó bị mất cơ sở dữ liệu.


1

Tôi đã tìm kiếm một câu trả lời tương tự và thấy điều này: https://www.pythian.com/blog/httpconsultingblogs-emc-comjamiethomsonarchive20070209sql-server-2005_3a00_-view-all-permissions-_2800_2_2900_-aspx/ . Và vâng, nó sử dụng sp_MSforeachDB đáng sợ, nhưng tôi nghĩ rằng anh chàng đó đôi khi có một bản rap tệ ... ;-)

Tôi sẽ đăng SQL ở đây để sao chép dễ dàng (Tôi KHÔNG lấy tín dụng cho việc này, chỉ làm cho nó dễ truy cập!):

DECLARE @DB_Users TABLE (DBName sysname, UserName sysname, LoginType sysname
, AssociatedRole varchar(max), create_date datetime, modify_date datetime)

INSERT @DB_Users
EXEC sp_MSforeachdb
'use [?]
SELECT ''?'' AS DB_Name,
case prin.name when ''dbo'' then prin.name + '' (''
    + (select SUSER_SNAME(owner_sid) from master.sys.databases where name =''?'') + '')''
    else prin.name end AS UserName,
    prin.type_desc AS LoginType,
    isnull(USER_NAME(mem.role_principal_id),'''') AS AssociatedRole, 
    create_date, modify_date
FROM sys.database_principals prin
LEFT OUTER JOIN sys.database_role_members mem
    ON prin.principal_id=mem.member_principal_id
WHERE prin.sid IS NOT NULL and prin.sid NOT IN (0x00)
and prin.is_fixed_role <> 1 AND prin.name NOT LIKE ''##%'''

SELECT dbname, username, logintype, create_date, modify_date,
    STUFF((SELECT ',' + CONVERT(VARCHAR(500), associatedrole)
        FROM @DB_Users user2
        WHERE user1.DBName=user2.DBName AND user1.UserName=user2.UserName
        FOR XML PATH('')
    ),1,1,'') AS Permissions_user
FROM @DB_Users user1
WHERE user1.UserName = N'<put your login-name here!>'
GROUP BY dbname, username, logintype, create_date, modify_date
ORDER BY DBName, username

-1

Bên dưới Truy vấn sẽ trả về ánh xạ cho DbName được yêu cầu

SELECT 'DbName', dbPri.name, dbPri1.name
FROM [DbName].sys.database_principals dbPri 
JOIN [DbName].sys.database_role_members dbRoleMem ON dbRoleMem.member_principal_id = 
dbPri.principal_id
JOIN [DbName].sys.database_principals dbPri1  ON dbPri1.principal_id = 
dbRoleMem.role_principal_id
WHERE dbPri.name != 'dbo'

Truy vấn cải tiến ở bên dưới

declare @sql varchar(Max)

 set @sql = 'use ? SELECT ''?'', dbPri.name, dbPri1.name
 FROM sys.database_principals dbPri 
 JOIN sys.database_role_members dbRoleMem ON 
 dbRoleMem.member_principal_id = 
 dbPri.principal_id
 JOIN sys.database_principals dbPri1  ON dbPri1.principal_id = 
 dbRoleMem.role_principal_id
 WHERE dbPri.name != ''dbo'''

 EXEC sp_MSforeachdb @sql

Cảm ơn bạn, mục tiêu của kịch bản này là tìm một ánh xạ cho tất cả các cơ sở dữ liệu. Kịch bản của bạn cung cấp thông tin cho chỉ một cơ sở dữ liệu cụ thể, không phải tất cả chúng.
Michael J Swart

Cảm ơn bạn đã phản hồi, tôi nghĩ rằng nó có thể được lặp đi lặp lại. Hiện được cập nhật với truy vấn được cải thiện
Dilipkumar katre

Xem câu trả lời và nhận xét của @ Aaron-Bertrand về suy nghĩ của anh ấy về sp_MSforeachdb.
Michael J Swart

-3

Thế còn EXEC master..sp_msloginmappings?


Bạn đã kiểm tra sp_msloginmappingslà không có giấy tờ và không được hỗ trợ trước khi đăng?
Kin Shah
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.