Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Active Directory средствами CLR  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Вашему вниманию предлагается библиотека для работы с AD.

Возможности:

1. Информация по пользователю AD
2. Список пользователей AD
3. Изменить свойство AD (узнать список всех свойств можно из первой процедуры)


Код:

using System;
using System.Data;
using System.Collections.Generic;
using Microsoft.SqlServer.Server;
using System.DirectoryServices;
using System.Collections;

namespace ADLibrary
{
    public partial class ADLibraryClass
    {
        private static DirectoryEntry GetDirectoryEntry(string domain)
        {
            return new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.Secure);
        }

        /// <summary>
        /// Получить свойства пользователя
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="domain"></param>
        /// <returns></returns>
        [SqlProcedure]
        public static int GetUserProperties(string userName, string domain)
        {
            string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", userName);
            string[] properties = new string[] { "fullname" };

            try
            {
                using (DirectoryEntry adRoot = GetDirectoryEntry(domain))
                using (DirectorySearcher searcher = new DirectorySearcher(adRoot))
                {
                    searcher.SearchScope = SearchScope.Subtree;
                    searcher.ReferralChasing = ReferralChasingOption.All;
                    searcher.PropertiesToLoad.AddRange(properties);
                    searcher.Filter = filter;
                    SearchResult result = searcher.FindOne();
                    if (result != null)
                    {
                        SqlMetaData property = new SqlMetaData("Property", SqlDbType.VarChar, 50);
                        SqlMetaData value = new SqlMetaData("Value", SqlDbType.VarChar, 1000);

                        SqlDataRecord record = new SqlDataRecord(property, value);
                        SqlContext.Pipe.SendResultsStart(record);

                        using (DirectoryEntry directoryEntry = result.GetDirectoryEntry())
                            foreach (string propName in directoryEntry.Properties.PropertyNames)
                            {
                                record.SetValue(0, propName);
                                record.SetValue(1, directoryEntry.Properties[propName][0].ToString());
                                SqlContext.Pipe.SendResultsRow(record);
                            }

                        SqlContext.Pipe.SendResultsEnd();
                    }

                }

                return 0;
            }

            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                return -1;
            }
        }

        /// <summary>
        /// Получить список пользователей
        /// </summary>
        /// <param name="domain"></param>
        /// <returns></returns>
        [SqlProcedure]
        public static int GetAllADDomainUsers(string domain)
        {
            try
            {
                List<string> allUsers = new List<string>();

                using (DirectoryEntry searchRoot = GetDirectoryEntry(domain))
                using (DirectorySearcher search = new DirectorySearcher(searchRoot))
                {
                    search.Filter = "(&(objectClass=user)(objectCategory=person))";
                    search.PropertiesToLoad.Add("samaccountname");

                    SearchResultCollection resultCol = search.FindAll();

                    if (resultCol == null)
                        return 0;

                    for (int counter = 0; counter < resultCol.Count; counter++)
                    {
                        SearchResult result = resultCol[counter];
                        if (result.Properties.Contains("samaccountname"))
                            allUsers.Add(result.Properties["samaccountname"][0].ToString());
                    }

                    allUsers.Sort();

                    SqlMetaData users = new SqlMetaData("Users", SqlDbType.VarChar, 250);
                    SqlDataRecord record = new SqlDataRecord(users);
                    SqlContext.Pipe.SendResultsStart(record);

                    foreach (string user in allUsers)
                    {
                        record.SetValue(0, user);
                        SqlContext.Pipe.SendResultsRow(record);
                    }

                    SqlContext.Pipe.SendResultsEnd();
                    return 1;
                }
            }
            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                return -1;
            }
        }

        /// <summary>
        /// Изменить свойство AD
        /// </summary>
        /// <param name="domain"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <param name="property"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        [SqlProcedure]
        public static int SetADProperty(string domain, string userName, string password, string property, string value)
        {
            string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "person", userName);
            string[] properties = new string[] { "fullname" };

            try
            {
                using (DirectoryEntry adRoot = GetDirectoryEntry(domain))
                using (DirectorySearcher searcher = new DirectorySearcher(adRoot))
                {
                    adRoot.Username = userName;
                    adRoot.Password = password;
                    searcher.Filter = filter;
                    searcher.PropertiesToLoad.AddRange(properties);
                    searcher.SearchScope = SearchScope.Subtree;

                    SearchResult results = searcher.FindOne();

                    if (results != null)
                        using (DirectoryEntry updateEntry = results.GetDirectoryEntry())
                        {
                            updateEntry.Properties[property].Value = value;
                            updateEntry.CommitChanges();
                        }
                }

                return 0;
            }

            catch (Exception ex)
            {
                SqlContext.Pipe.Send(ex.Message);
                return -1;
            }
        }
    }
}

Регистрация:


ALTER DATABASE Test SET TRUSTWORTHY ON
GO

CREATE ASSEMBLY [DirectoryServices]
FROM 'C:\WINNT\Microsoft.NET\Framework\v2.0.50727\System.DirectoryServices.dll'
WITH PERMISSION_SET = UNSAFE
GO

CREATE ASSEMBLY [ADLibrary] 
FROM 'C:\ADLibrary.dll'
WITH PERMISSION_SET = UNSAFE 
GO

CREATE PROCEDURE GetUserProperties (@userName sysname, @domain sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[GetUserProperties]
GO

CREATE PROCEDURE GetAllADDomainUsers (@domain sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[GetAllADDomainUsers]
GO

CREATE PROCEDURE SetADProperty (@domain sysname, @userName sysname, @password sysname, @property sysname, @value sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[SetADProperty]
GO


-- Примеры:
declare @user sysname, @domain sysname
select @domain = SUBSTRING(SYSTEM_USER, 1, PATINDEX ('%\%', SYSTEM_USER) - 1),
       @user = SUBSTRING(SYSTEM_USER, PATINDEX ('%\%', SYSTEM_USER) + 1, LEN(SYSTEM_USER))

-- Получить инфрорамцию по пользователю AD
exec GetUserProperties @user, @domain
-- Получить список пользователей
exec GetAllADDomainUsers @domain
-- Изменить свойсство AD (узнать список свойств можно из поля Property ХП GetUserProperties)
exec SetADProperty @domain, @user, 'pass', 'mobile', '+79039999999'


Скомпилированная библиотка прилагается. Проверено на Microsoft SQL Server 2005 - 9.00.3042.00 (Intel X86) Feb 9 2007 22:47:07 Copyright (c) 1988-2005 Microsoft Corporation Developer Edition on Windows NT 5.1 (Build 2600: Service Pack 2)

Замечания и пожелания по добавлению функционала принимаются

К сообщению приложен файл (ADLibrary.dll - 20Kb) cкачать
14 авг 08, 18:16    [6068930]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Добавил 2 полезные процедуры:

CREATE PROCEDURE GetAllADDomainGroups (@domain sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[GetAllADDomainGroups]
GO

CREATE PROCEDURE GetAllADUsersInGroup (@domain sysname, @groupName sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[GetAllADUsersInGroup]
GO


-- Получить список групп
exec GetAllADDomainGroups @domain

-- Получить список пользователей, которые входят в заданную группу
exec GetAllADUsersInGroup @domain, 'support'

P.S. Скомпилированная библиотека прилагается.

К сообщению приложен файл (ADLibrary.dll - 20Kb) cкачать
15 авг 08, 13:04    [6071762]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
Добавил 1 процедуру:

CREATE PROCEDURE GetAllADGroupsInUser (@domain sysname, @userName sysname)
AS EXTERNAL NAME [ADLibrary].[ADLibrary.ADLibraryClass].[GetAllADGroupsInUser]
GO

-- Получить список групп, в которые входит пользователь
exec GetAllADGroupsInUser @domain, @user


К сообщению приложен файл (ADLibrary.dll - 20Kb) cкачать
15 авг 08, 15:52    [6073024]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
reno
Member

Откуда:
Сообщений: 7
Спасибо за CLR!!!!! нужная вещь
А будет ли продолжение этой dll?
27 сен 08, 14:18    [6235941]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
reno
Спасибо за CLR!!!!! нужная вещь
А будет ли продолжение этой dll?


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

27 сен 08, 19:14    [6236264]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
reno
А будет ли продолжение этой dll?

А что хотелось бы еще вдовесок?
27 сен 08, 21:52    [6236433]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ
Member [заблокирован]

Откуда: http://codearticles.ru
Сообщений: 31089
+ OFF
Winnipuh
должно быть, просто обязано!
мы недавно обсуждали к примеру функцию получить всех юзеров для казанной группы включая неявных, т.е. тех, которые входят в указанную группу через членство в подгруппах этой группы



Винни, тот урок по AD прошел Вам на пользу? ;)

28 сен 08, 01:50    [6236765]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Sergey_M
Member

Откуда:
Сообщений: 35
Подскажите плиз при запуске

CREATE ASSEMBLY [DirectoryServices]
FROM 'C:\WINDOWS\microsoft.net\Framework\v2.0.50727\System.DirectoryServices.dll'
WITH PERMISSION_SET = UNSAFE
GO

выдает ошибку

Msg 10327, Level 14, State 1, Line 2
CREATE ASSEMBLY for assembly 'System.DirectoryServices' failed because assembly 'System.DirectoryServices' is not authorized for PERMISSION_SET = UNSAFE. The assembly is authorized when either of the following is true: the database owner (DBO) has UNSAFE ASSEMBLY permission and the database has the TRUSTWORTHY database property on; or the assembly is signed with a certificate or an asymmetric key that has a corresponding login with UNSAFE ASSEMBLY permission.

какие и где нужно прописывать права. ведь я делаю под SA.
подскажите плиз что нужно сделать?
16 окт 08, 15:57    [6316192]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
tpg
Member

Откуда: Novosibirsk
Сообщений: 23902
Sergey_M
выдает ошибку

Msg 10327, Level 14, State 1, Line 2
https://www.sql.ru/forum/actualtopics.aspx?search=10327&bid=1
17 окт 08, 06:28    [6318599]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Alex Shulg
Member

Откуда:
Сообщений: 227
Хорошая штука, еще бы возможность получать SID пользователя по его имени и наоборот (или добавить данный атрибут как еще одно свойство в GetUserProperties)
20 окт 08, 14:39    [6329811]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Sergey_M
Member

Откуда:
Сообщений: 35
Спасибо вроде получилось. но запуск
exec GetAllADDomainUsers 'apollon'
Выдает
The specified directory service attribute or value does not exist.

наверное что еще не хватает.
не подскажите чего именно
20 окт 08, 15:29    [6330163]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Maxx
Member [скрыт]

Откуда:
Сообщений: 24290
наверное домена Апполо:)
-------------------------------------
Jedem Das Seine
20 окт 08, 16:02    [6330466]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Богдан Гоцкий
Member

Откуда: Львов
Сообщений: 504
Извините, просто интересно, а зачем CLR, если с AD можно и OPENROWSET-ом доставать данные?
20 окт 08, 18:29    [6331577]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Domninsky
Member

Откуда: Москва
Сообщений: 655
А возможно ли переделать процедуру SetADProperty так чтобы для поиска использовалось только имя пользователя, а для коннекта к АД некий фиксированный пользователь АД с паролем.

Просто в данной процедуре чтобы изменить атрибут пользователя в АД нужно знать его имя и пароль.
Это здорово, но хотелось бы иметь возможность фильтроваться только по имени.
А коннектится к АД по юзером администратором домена.

Спасибо!
13 ноя 08, 16:28    [6436338]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ фбане
Guest
Domninsky
А возможно ли переделать процедуру SetADProperty так чтобы для поиска использовалось только имя пользователя, а для коннекта к АД некий фиксированный пользователь АД с паролем.

Не совсем понял. Что Вы понимаете под поиском? SetADProperty устанавливает любой указанной проперти AD значение. Для доступа к проперти необходима учетка, наделенная правом изменять эту эту проперть. В процедуре как раз и есть возможность указать, от какой учетки будут происходить измнения. Если хотите использовать текущий лонин/пароль, смотрите в сторону имперсонации. Но, имхо, это уже никак не относится к SetADProperty. Итак, имперсонируетесь под нужным пользователем и входите в SetADProperty.
Domninsky
Просто в данной процедуре чтобы изменить атрибут пользователя в АД нужно знать его имя и пароль.

Верно. А Вы как хотели? ;)
Domninsky
Это здорово, но хотелось бы иметь возможность фильтроваться только по имени.
А коннектится к АД по юзером администратором домена.

Спасибо!

Что такое "фильтроваться только по имени"? Это инициализация проперти. О какой фильтровке идет речь?

Чтобы коннектиться к АД под юзером администратора домена, Вам нужно знать его пароль. Если пароль известен, в чем проблема использовать приведенные выше процедуры?

Возможно, я Вас не так понял. Поясните, пожалуйста.
1 дек 08, 22:07    [6511328]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ фбане
Guest
Богдан Гоцкий
Извините, просто интересно, а зачем CLR, если с AD можно и OPENROWSET-ом доставать данные?

Дело в гибкости и инкапсуляции логики. С CLR вы юзаете готовые методы, управляющие всей рутиной, сокрытой от разработчика. Считайте это объектным подходом по работе с АД.
Альтернативы есть всегда, просто каждый выбирает то, что ему ближе и проще. Если есть желание поднимать отдельную службу SQL Server Active Directory Helper и ковыряться в рекордсетах черех оперновсеты - никто против не будет :)
1 дек 08, 22:14    [6511346]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
YaNN
Member

Откуда: N.Novgorod
Сообщений: 162
МСУ фбане,

трапается с ComException. Сталкивался, какие могут быть проблемы?
8 дек 08, 15:00    [6539655]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
YaNN
Member

Откуда: N.Novgorod
Сообщений: 162
или у тебя Контроллер домена на одном серваке с sql? %)
8 дек 08, 15:50    [6540147]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Cheerful Calf
Member

Откуда: Lithuania
Сообщений: 6994
1. Что такое "трапается"?
2. ComException - ни о чем не говорит. Приведите полное сообщение об ошибке.
3. Сиквел у меня разнесен от контроллера.
8 дек 08, 17:00    [6540795]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
Winnipuh
Member [заблокирован]

Откуда: Київ
Сообщений: 10428
Cheerful Calf
1. Что такое "трапается"?

трайкэтчится ?

2. ComException - ни о чем не говорит. Приведите полное сообщение об ошибке.
3. Сиквел у меня разнесен от контроллера.
8 дек 08, 17:21    [6541004]     Ответить | Цитировать Сообщить модератору
 Нихрена не понял :)  [new]
МСУ фбане
Guest
YaNN, а поподробней, в чём трабла?

P.S. FW в системе залит? :))
8 дек 08, 23:25    [6542187]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
YaNN
Member

Откуда: N.Novgorod
Сообщений: 162
Трапается - throwns an exception.

фреймворк есть, разумеется.
я использую в некоторых местах clr фунции.
После явной передачи в DirectoryEntry пароля и имени пользователя под которыми авторизуемся в AD все заработало, но такой вариант не устраивает по понятным причинам.

Что что свазанное с делегированием, у вас Керберос поднят? делегирование настроено?

если нет, то интересует, что же я неправильно делаю, судя по листингу, никаких бубнов с имперсонализацией автор не делает.
8 дек 08, 23:34    [6542221]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
МСУ фбане
Guest
YaNN
Трапается - throwns an exception.

Ну у Вас и сленг...
YaNN
После явной передачи в DirectoryEntry пароля и имени пользователя под которыми авторизуемся в AD все заработало, но такой вариант не устраивает по понятным причинам.

Т.е., Вы хотите авторизоваться в АД силой мысли? :)
YaNN
Что что свазанное с делегированием, у вас Керберос поднят? делегирование настроено?

Керберос не юзаю, не нужен он мне. Что Вы понимаете под делегированием?
YaNN
если нет, то интересует, что же я неправильно делаю, судя по листингу, никаких бубнов с имперсонализацией автор не делает.

Имперсонации нет. Да и не нужна она, еще раз говорю.
8 дек 08, 23:44    [6542260]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
YaNN
Member

Откуда: N.Novgorod
Сообщений: 162
[quot МСУ фбане]
private static DirectoryEntry GetDirectoryEntry(string domain)
{
return new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.Secure);
}
где у вас явно в либе происходит авторизация?
я скачал вашу либу, сделал как описано выше - не работает. генерируется ComException.

У меня на sql виндовая авторизация.
Если юзер зашел в сеанс то хорошо бы, если AD понимала это, но к сожалению AD не понимает.
все что я нашел - описание проблемы с имперсонализацией.

Вопрос возник из отсутствия в вашем коде явной авторизации.
может я что-то не так делаю? или код не полный? у вас на SQL какая авторизация?
9 дек 08, 09:39    [6542865]     Ответить | Цитировать Сообщить модератору
 Re: Active Directory средствами CLR  [new]
YaNN
Member

Откуда: N.Novgorod
Сообщений: 162
МСУ фбане

Т.е., Вы хотите авторизоваться в АД силой мысли? :)

я хочу авторизовываться так же как из консолного или winforms приложения - там не надо явно указывать авторизационные данные - все работает.
9 дек 08, 09:43    [6542888]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить