powered by simpleCommunicator - 2.0.52     © 2025 Programmizd 02
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как выбрать все database roles указанного юзера?
21 сообщений из 21, страница 1 из 1
Как выбрать все database roles указанного юзера?
    #40025959
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Может ли другой юзер выбрать список датабазе ролей другого юзера?
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40025984
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

права на просмотр метаданных должны быть.

а так:
Код: sql
1.
2.
3.
select user_name([role_principal_id]) 
from sys.database_role_members
where [member_principal_id] = user_id('otheruser');
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40025990
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

права на просмотр метаданных должны быть.

а так:
Код: sql
1.
2.
3.
select user_name([role_principal_id]) 
from sys.database_role_members
where [member_principal_id] = user_id('otheruser');



В частном случае - да.
Фигня начинается, когда domain\user входит в domain\group, а сам domain\user явно не включен в назначения ролей.

Код: sql
1.
2.
3.
4.
5.
6.
select user_name([role_principal_id]), *
from sys.database_role_members rm
RIGHT OUTER JOIN sys.database_principals AS dp  
    ON rm.role_principal_id = dp.principal_id 
LEFT OUTER JOIN sys.database_principals AS dp2   ON rm.member_principal_id = dp2.principal_id  
where [member_principal_id] = user_id('domain\group'); --user_id('domain\group');
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026004
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
felix_ff
Ролг Хупин,

права на просмотр метаданных должны быть.

а так:
Код: sql
1.
2.
3.
select user_name([role_principal_id]) 
from sys.database_role_members
where [member_principal_id] = user_id('otheruser');



В частном случае - да.
Фигня начинается, когда domain\user входит в domain\group, а сам domain\user явно не включен в назначения ролей.

Код: sql
1.
2.
3.
4.
5.
6.
select user_name([role_principal_id]), *
from sys.database_role_members rm
RIGHT OUTER JOIN sys.database_principals AS dp  
    ON rm.role_principal_id = dp.principal_id 
LEFT OUTER JOIN sys.database_principals AS dp2   ON rm.member_principal_id = dp2.principal_id  
where [member_principal_id] = user_id('domain\group'); --user_id('domain\group');



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

Что Вы в итоге хотите видеть? опишите ситуацию более конкретно.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026008
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин
пропущено...


В частном случае - да.
Фигня начинается, когда domain\user входит в domain\group, а сам domain\user явно не включен в назначения ролей.

Код: sql
1.
2.
3.
4.
5.
6.
select user_name([role_principal_id]), *
from sys.database_role_members rm
RIGHT OUTER JOIN sys.database_principals AS dp  
    ON rm.role_principal_id = dp.principal_id 
LEFT OUTER JOIN sys.database_principals AS dp2   ON rm.member_principal_id = dp2.principal_id  
where [member_principal_id] = user_id('domain\group'); --user_id('domain\group');



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

Что Вы в итоге хотите видеть? опишите ситуацию более конкретно.



я заустил приложение, коннектнулся к среднеуровневому сервису, передал ему имя юзера Юзер101, хотелось бы, чтоб сервис сходил на SQL Server и узнал список ролей, которые получил бы Юзер101, если бы коннектнулся напрямую к серверу базы.
При этом
Юзер101 может быть SQL Server-ным юзером, доменным юзером, у которого явно в базе указаны его роли или членом группы
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026011
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

на мой взгляд самый простой вариант это процедура обертка, которая повышает права сервисного пользователя внутри себя до возможности олицетворения нужного контекста пользователя.

олицетворяете пользователя, вычитываете инфу токена базы данных, возвращаете требуемый набор.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026013
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

на мой взгляд самый простой вариант это процедура обертка, которая повышает права сервисного пользователя внутри себя до возможности олицетворения нужного контекста пользователя.

олицетворяете пользователя, вычитываете инфу токена базы данных, возвращаете требуемый набор.


Т.е. все-таки то, во что я не хотел в 2020 г поверить снова: только юзер сам может вычитать список своих ролей
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026014
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

нет, вам по сути хватит VIEW DEFINITION права, и потом гемороится с sys.database_role_members
на предмет "ой, а доменный ли это пользователь" "ой а не входит ли он в доменную группу" и.т.д

вычитать разову инфу с sys.user_token sys.login_token намного проще.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026022
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

нет, вам по сути хватит VIEW DEFINITION права, и потом гемороится с sys.database_role_members
на предмет "ой, а доменный ли это пользователь" "ой а не входит ли он в доменную группу" и.т.д

вычитать разову инфу с sys.user_token sys.login_token намного проще.


так все-таки - процедуру? как? пример можно чисто штрихами, как художник художнику
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026027
Фотография komrad
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин

так все-таки - процедуру? как? пример можно чисто штрихами, как художник художнику


для AD\account можно так:
- выбрать все пути входа в сиквел
- найти пересечение с результатом sp_helprolemember (выполнять в нужной бд)
Код: sql
1.
2.
exec xp_logininfo 'AD\account','all'
exec sp_helprolemember 



для SQL логина можно просто вторую процедуру
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026047
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин
felix_ff
Ролг Хупин,

нет, вам по сути хватит VIEW DEFINITION права, и потом гемороится с sys.database_role_members
на предмет "ой, а доменный ли это пользователь" "ой а не входит ли он в доменную группу" и.т.д

вычитать разову инфу с sys.user_token sys.login_token намного проще.


так все-таки - процедуру? как? пример можно чисто штрихами, как художник художнику


ну примерно так, там еще поиграться с условностями входа в public оно для dbo к примеру никогда не показывает что он туда входит, думаю допилить под себя сможете.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
use master;
create certificate [cert01] encryption by password = 'liuwqer;qwb42;u4y21;421jk!E' with subject = 'certificate for [dbo].[usp_getRolesByLogin]';

create login [cert01_login] from certificate [cert01];
grant impersonate any login to [cert01_login];
go

--перенос сертификата на целевую бд
declare @sql nvarchar(max) = N'';
declare @pub nvarchar(max) = N'';
declare @pvk nvarchar(max) = N'';
declare @pwd nvarchar(255) = N'liuwqer;qwb42;u4y21;421jk!E';

set @pub = convert(nvarchar(max), certencoded(cert_id('cert01')), 1);
set @pvk = convert(nvarchar(max), certprivatekey(cert_id('cert01'), @pwd, @pwd), 1);
set @pwd = quotename(@pwd, nchar(39));
set @sql = 'create certificate [cert01] from binary = ' + @pub + ' with private key (binary = ' + @pvk + ', decryption by password = ' + @pwd + ', encryption by password = ' + @pwd + ');';
exec [database].sys.sp_executesql @stmt = @sql;
go
--//перенос сертификата на целевую бд

use [database];
go

create or alter procedure [usp_getRolesByLogin]
      @login_name sysname
as
if original_login() <> 'service_account_name' throw 50000, 'procedure can be invoked only from web-service', 16;

if has_perms_by_name(@login_name, 'LOGIN', 'IMPERSONATE') = 0 throw 50000, 'You dont have permissions for impersonate this context', 16;

execute as login = @login_name;

select user_name(rm.[role_principal_id]) as [name], 'DBO_ACCESS' as [usage], 'DATABASE' as [level] 
from sys.server_principals sp
    join sys.database_principals dp on dp.[sid] = sp.[sid]
        join sys.database_role_members rm on rm.[member_principal_id] = dp.[principal_id]
where sp.[name] = @login_name
  and user_name() = 'dbo'
union
select [name], [usage], 'DATABASE' from sys.user_token where [type] = 'ROLE'
union
select [name], [usage], 'SERVER' from sys.login_token where [type] = 'SERVER ROLE';

revert;
go

add signature to [dbo].[usp_getRolesByLogin] by certificate [cert01] with password = 'liuwqer;qwb42;u4y21;421jk!E';


...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026308
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин
пропущено...


так все-таки - процедуру? как? пример можно чисто штрихами, как художник художнику


ну примерно так, там еще поиграться с условностями входа в public оно для dbo к примеру никогда не показывает что он туда входит, думаю допилить под себя сможете.

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
use master;
create certificate [cert01] encryption by password = 'liuwqer;qwb42;u4y21;421jk!E' with subject = 'certificate for [dbo].[usp_getRolesByLogin]';

create login [cert01_login] from certificate [cert01];
grant impersonate any login to [cert01_login];
go

--перенос сертификата на целевую бд
declare @sql nvarchar(max) = N'';
declare @pub nvarchar(max) = N'';
declare @pvk nvarchar(max) = N'';
declare @pwd nvarchar(255) = N'liuwqer;qwb42;u4y21;421jk!E';

set @pub = convert(nvarchar(max), certencoded(cert_id('cert01')), 1);
set @pvk = convert(nvarchar(max), certprivatekey(cert_id('cert01'), @pwd, @pwd), 1);
set @pwd = quotename(@pwd, nchar(39));
set @sql = 'create certificate [cert01] from binary = ' + @pub + ' with private key (binary = ' + @pvk + ', decryption by password = ' + @pwd + ', encryption by password = ' + @pwd + ');';
exec [database].sys.sp_executesql @stmt = @sql;
go
--//перенос сертификата на целевую бд

use [database];
go

create or alter procedure [usp_getRolesByLogin]
      @login_name sysname
as
if original_login() <> 'service_account_name' throw 50000, 'procedure can be invoked only from web-service', 16;

if has_perms_by_name(@login_name, 'LOGIN', 'IMPERSONATE') = 0 throw 50000, 'You dont have permissions for impersonate this context', 16;

execute as login = @login_name;

select user_name(rm.[role_principal_id]) as [name], 'DBO_ACCESS' as [usage], 'DATABASE' as [level] 
from sys.server_principals sp
    join sys.database_principals dp on dp.[sid] = sp.[sid]
        join sys.database_role_members rm on rm.[member_principal_id] = dp.[principal_id]
where sp.[name] = @login_name
  and user_name() = 'dbo'
union
select [name], [usage], 'DATABASE' from sys.user_token where [type] = 'ROLE'
union
select [name], [usage], 'SERVER' from sys.login_token where [type] = 'SERVER ROLE';

revert;
go

add signature to [dbo].[usp_getRolesByLogin] by certificate [cert01] with password = 'liuwqer;qwb42;u4y21;421jk!E';




спасибо, пытаюсь адаптировать, всё сработало, но на последнем дает ошибку, выполняю из-под sa

Код: sql
1.
add signature to [dbo].[usp_getRolesByLogin] by certificate [cert01] with password = 'liuwqer;qwb42;u4y21;421jk!E';


авторMsg 15151, Level 16, State 1, Line 48
Cannot find the certificate 'cert01', because it does not exist or you do not have permission.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026355
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,


проверьте что сертификат мигрировал с master в вашу целевую базу:

Код: sql
1.
2.
3.
use <имя вашей бд>;

select * from sys.certificates where name = 'cert01';



если строки нет значит криво выполнилась эта инструкция:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
declare @sql nvarchar(max) = N'';
declare @pub nvarchar(max) = N'';
declare @pvk nvarchar(max) = N'';
declare @pwd nvarchar(255) = N'liuwqer;qwb42;u4y21;421jk!E';

set @pub = convert(nvarchar(max), certencoded(cert_id('cert01')), 1);
set @pvk = convert(nvarchar(max), certprivatekey(cert_id('cert01'), @pwd, @pwd), 1);
set @pwd = quotename(@pwd, nchar(39));
set @sql = 'create certificate [cert01] from binary = ' + @pub + ' with private key (binary = ' + @pvk + ', decryption by password = ' + @pwd + ', encryption by password = ' + @pwd + ');';
exec [database].sys.sp_executesql @stmt = @sql;



там где выделено тоже нужно заменить на вашу БД
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026383
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,


проверьте что сертификат мигрировал с master в вашу целевую базу:

Код: sql
1.
2.
3.
use <имя вашей бд>;

select * from sys.certificates where name = 'cert01';



если строки нет значит криво выполнилась эта инструкция:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
declare @sql nvarchar(max) = N'';
declare @pub nvarchar(max) = N'';
declare @pvk nvarchar(max) = N'';
declare @pwd nvarchar(255) = N'liuwqer;qwb42;u4y21;421jk!E';

set @pub = convert(nvarchar(max), certencoded(cert_id('cert01')), 1);
set @pvk = convert(nvarchar(max), certprivatekey(cert_id('cert01'), @pwd, @pwd), 1);
set @pwd = quotename(@pwd, nchar(39));
set @sql = 'create certificate [cert01] from binary = ' + @pub + ' with private key (binary = ' + @pvk + ', decryption by password = ' + @pwd + ', encryption by password = ' + @pwd + ');';
exec [database].sys.sp_executesql @stmt = @sql;



там где выделено тоже нужно заменить на вашу БД


во втором случае я исправил на мою базу, иначе была бы ошибка, причина была в том, что сертификат не мигрировал. Сейчас ошибка ушла.

Теперь осталось: при выполнении процедуры получаю естественно:

exec [dbo].[usp_getRolesByLogin] 'юзер'

Msg 50000, Level 16, State 16, Procedure dbo.usp_getRolesByLogin, Line 7 [Batch Start Line 53]
You dont have permissions for impersonate this context
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026395
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

ну а теперь подписать надо, иначе права от сертификата не добавятся
Код: sql
1.
add signature to [dbo].[usp_getRolesByLogin] by certificate [cert01] with password = 'liuwqer;qwb42;u4y21;421jk!E';
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026397
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

ну а теперь подписать надо, иначе права от сертификата не добавятся
Код: sql
1.
add signature to [dbo].[usp_getRolesByLogin] by certificate [cert01] with password = 'liuwqer;qwb42;u4y21;421jk!E';



подписал, все ок, вот здесь нет имперсонизации

if has_perms_by_name(@login_name, 'LOGIN', 'IMPERSONATE') = 0 throw 50000, 'You dont have permissions for impersonate this context', 16;
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026398
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

а право impersonate any login для логина сертификата выдали?

измените немного процедуру:

перед проверками if

добавьте
Код: sql
1.
2.
select * from sys.login_token
select * from sys.fn_my_permissions(null, null);



и заново подписать только не забудьте.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026411
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

а право impersonate any login для логина сертификата выдали?

измените немного процедуру:

перед проверками if

добавьте
Код: sql
1.
2.
select * from sys.login_token
select * from sys.fn_my_permissions(null, null);



и заново подписать только не забудьте.


добавил, переподписал, запросы выдали результаты

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
sa	SQL LOGIN
public	SERVER ROLE
sysadmin	SERVER ROLE
cert01_login	LOGIN MAPPED TO CERTIFICATE
cert01	CERTIFICATE

------------------------
CONNECT SQL
SHUTDOWN
CREATE ENDPOINT
CREATE ANY DATABASE
CREATE AVAILABILITY GROUP
ALTER ANY LOGIN
ALTER ANY CREDENTIAL
ALTER ANY ENDPOINT
ALTER ANY LINKED SERVER
ALTER ANY CONNECTION
ALTER ANY DATABASE
ALTER RESOURCES
ALTER SETTINGS
ALTER TRACE
ALTER ANY AVAILABILITY GROUP
ADMINISTER BULK OPERATIONS
AUTHENTICATE SERVER
EXTERNAL ACCESS ASSEMBLY
VIEW ANY DATABASE
VIEW ANY DEFINITION
VIEW SERVER STATE
CREATE DDL EVENT NOTIFICATION
CREATE TRACE EVENT NOTIFICATION
ALTER ANY EVENT NOTIFICATION
ALTER SERVER STATE
UNSAFE ASSEMBLY
ALTER ANY SERVER AUDIT
CREATE SERVER ROLE
ALTER ANY SERVER ROLE
ALTER ANY EVENT SESSION
CONNECT ANY DATABASE
IMPERSONATE ANY LOGIN
SELECT ALL USER SECURABLES
CONTROL SERVER
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026413
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

О так вы вообще под sa процу запускаете у него даже без сертификата права будут.

В любом случае сертификат виден и право тоже, по сути проверку на if has_perms_by_name(login, 'login', 'impersonate') должно проходить на ура.

вы в параметр @login_name точно указываете именно имя логина? и такой логин представляет именно отдельного пользователя, не доменную группу какую нибудь?
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026419
Ролг Хупин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
felix_ff
Ролг Хупин,

О так вы вообще под sa процу запускаете у него даже без сертификата права будут.

В любом случае сертификат виден и право тоже, по сути проверку на if has_perms_by_name(login, 'login', 'impersonate') должно проходить на ура.

вы в параметр @login_name точно указываете именно имя логина? и такой логин представляет именно отдельного пользователя, не доменную группу какую нибудь?


Пробовал из-под разных, решил кардинально попробовать - sa
Но там возможно проблема в том, что тестовая база когда-то от кустомера получена, его домена у меня нет, групп и доменных юзеров тоже.
Сейчас сделаю руками юзера, попробую.
...
Рейтинг: 0 / 0
Как выбрать все database roles указанного юзера?
    #40026421
felix_ff
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ролг Хупин,

если домена нет конечно под таким логином олицетворение не пройдет, но по сути вы и подключиться от такого логина никогда и не сможете.

пробуйте дать на вход или реальный sql логин, или реальный доменный логин.
касатально доменных логинов важная особенность: он реально должен иметь возможность подключаться к инстансу (или быть отмаплен в логины или иметь возможность аутентифицироваться через доменные группы)

если к примеру у вас в домене три пользователя:
mydomain\vasya
mydomain\petya
mydomain\igor


mydomain\vasya реально отмаплен логином в инстанс
mydomain\petya входит в доменную группу mydomain\sql_access которая отмаплена в инстанс

то для васи и пети процедура отработает, а для igor будет ругаться, потому что данный логин не имеет доступа к сиквелу.
...
Рейтинг: 0 / 0
21 сообщений из 21, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Как выбрать все database roles указанного юзера?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]