Имя: Пароль:
1C
1С v8
1с + AD
0 Наська72
 
15.04.13
13:01
Добрый день!
Возникла проблема:
Есть некий домен "А.ru" он дружит с доменом "B.ru".
В домене А есть группа "GroupA", в нее вложена группа из домена В "GroupB".
Задача: Средствами 1с получить членов группы "GroupB".

Проблема: вместо дружественных вложений получаю контейнер ForeignSecurityPrincipals.
Читаю в интернете "Это контейнер по умолчанию для объектов из внешних доверяемых доменов." Да так и есть, но как получить оттуда участников Users?


Мой код:
//Подключимся к AD
Попытка
       oConnect = ПолучитьCOMОбъект("","ADODB.Connection");
   oConnect.Provider = "ADSDSOObject";
       oConnect.Properties("User ID").Value = "учетка домена B.ru";
   oConnect.Properties("Password").Value = "пароль домена B.ru";            
   oConnect.Properties("Encrypt Password").Value = True;    
   oConnect.Open("Active Directory Provider");
Исключение
   #Если Клиент Тогда
   Сообщить("Не удалось подключиться к AD. " + ОписаниеОшибки());
   #КонецЕсли

   Возврат;
КонецПопытки;


Query1 = "SELECT * FROM 'LDAP://ДоменА/DC=доменА,DC=ru' WHERE objectCategory='Group' And name = '" + GroupA + "' And member='*'";
       Попытка
           RecordSet1 = oConnect.Execute(query1);
           Пока Не RecordSet1.EOF Цикл
               obj = ПолучитьCOMОбъект(RecordSet1.Fields(0).Value);
               Если obj.Class = "group" Тогда
                   Сообщить("Группа " + obj.Name);
                   Для Каждого Элемент Из obj.member Цикл
                       obj1 = ПолучитьCOMОбъект("LDAP://ДоменА/" + Элемент);
                       Если obj1.Class = "user" Тогда
                           Сообщить("Пользователь " + obj1.sn);    
                       ИначеЕсли obj1.Class = "group" Тогда
                           Сообщить("Группа1 " + obj1.Name);
                       ИначеЕсли obj1.Class = "ForeignSecurityPrincipals" Тогда
                           obj2 = ????????????????????
                       КонецЕсли;
                   КонецЦикла;
               Иначе
                   Сообщить("Пользователь " + obj.sn);
               КонецЕсли;
               RecordSet1.MoveNext();
           КонецЦикла;


Будьте добры, помогите пожалуйста, с решением получения членов контейнера! Я не админ, но путем долгого копания поняла, что другими способами пользователей оттуда никак не взять.
1 zladenuw
 
15.04.13
13:26
2 Наська72
 
16.04.13
06:22
(1) Спасибо за ссылки. Получилось пока вот что
strComputer    = ".";
                           objWMIService    = ПолучитьCOMОбъект("winmgmts:\\" + strComputer + "\root\cimv2");
objAccount        = objWMIService.Get("Win32_SID.SID='S-1-5-21-1670766961-3854722118-3510669582-6106'");
Имя            = objAccount.AccountName;
Сообщить("Имя " + Имя);

Но выдает пустое ("") Имя.
Мой компьютер находится в другом С.ru, дружественном A.ru. Может быть вместо strComputer вставить ip компа из домена F.ru???
3 Наська72
 
16.04.13
06:23
*прошу прощения за очепятки:
Мой компьютер находится в другом домене С.ru, дружественном A.ru. Может быть вместо strComputer вставить ip компа из домена A.ru???
4 Наська72
 
16.04.13
06:27
Спасибо за помощь!
Вставила ip сервака 1с из дружественного домена А.ru и всё взлетело.
5 Наська72
 
16.04.13
07:00
А есть ли возможность узнать у objAccount другие поля кроме AccountName и ReferencedDomainName?

Пытаюсь через запрос получить объект не получается:

Имя            = objAccount.AccountName;
                               Сообщить("Имя " + Имя);
                               Домен            = objAccount.ReferencedDomainName;
                               Сообщить("Домен " + Домен);
                               //Ищем в пользователях
                               Query2 = "SELECT * FROM 'LDAP://"+Домен+"/DC="+Домен+",DC=ru' WHERE objectCategory='User' And AccountName = '" + Имя + "'";
                               Попытка
                                   RecordSet2 = oConnect.Execute(query2);

бла-бла
                               Исключение
                                   //Ищем в группах
                                   Query2 = "SELECT * FROM 'LDAP://"+Домен+"/DC="+Домен+",DC=ru' WHERE objectCategory='Group' And name = '" + Имя + "' And member='*'";
                                    Попытка
                                        RecordSet2 = oConnect.Execute(query2);
                                        бла-бла
                                    Исключение
                                    КонецПопытки;
                               КонецПопытки;
6 Наська72
 
16.04.13
07:32
Пишут "The big difference here is that instead of getting an instance of the Win32_UserAccount class we get an instance of the Win32_SID class (and note that we pass the SID as the parameter to the Get method). As soon as we’ve retrieved that instance, we echo the account name and domain name, and we’re off and running." То есть мы получаем не Win32_UserAccount class, а Win32_SID class, а мне очень нужно узнать некое поле у пользователя, а в случае с группой еще и ее членов.
Запрос вида SELECT * FROM 'LDAP://"+Домен+"/DC="+Домен+",DC=ru' WHERE... не проходит видимо потому, что я не в том домене. Хотя использую учетку того домена.

Как же быть?
7 vde69
 
16.04.13
08:06
8 Наська72
 
16.04.13
08:16
(7) Не вижу там ответов на свои вопросы. К примеру беру такую процедурку:

Функция ПолучитьСписокПользователейВГруппеДомена (ИмяДомена, ИмяГруппы) Экспорт....


Результат = Новый Массив();
                               objNameSpace = "";  
                               Попытка  
                                   objNameSpace = ПолучитьCOMОбъект("WinNT://" + СокрЛП(ИмяДомена) + "/" + СокрЛП(Имя) + ", Group");  
                                   Для каждого item Из objNameSpace.Members() Цикл  
                                       Результат.Добавить(item.Name);  
                                   КонецЦикла;
                               Исключение  
                                   Результат.Очистить();
                                   Сообщить("Проблема с запросом к AD. " + ОписаниеОшибки());
                               КонецПопытки;  


А в ответ мне: "Ошибка при вызове метода контекста (ПолучитьCOMОбъект): Ошибка получения объекта COM: Не найден сетевой путь."
Мой компьютер находится в другом домене С.ru, дружественном A.ru, обращаюсь к домену B.ru
9 Наська72
 
16.04.13
08:25
Дело в том, что через WinNT я не вижу домена B.ru.
Какие еще могут быть варианты получения любого другого поля кроме AccountName и ReferencedDomainName?
10 vde69
 
16.04.13
08:28
чего выдает ПолучитьСписокДоменов()  ???
11 Наська72
 
16.04.13
08:44
Мой домен в котором сейчас работает учетка (С.ru), домен А.ru с которым дружит + Workgroup, а вот домен В.ru, к которому надо достучаться не показывает.
12 Наська72
 
16.04.13
08:52
При этом пинг с моей машины на В.ru идет
13 vde69
 
16.04.13
08:53
(11) значит действительно провайдер NT не прокатит,

причины может быть
1. Контолер удаленого домена не поддерживает провайдера NT (NT - считается устаревшим)
2. сетевые проблеммы (блочится)

по сабжу

           Попытка        
               query = "SELECT ADsPath FROM 'LDAP://DC="+СокрЛП(Домен.Код);    
               rs = conn.Execute(query);    
               Пока НЕ rs.EOF() Цикл    
                   obj = ПолучитьCOMОбъект(rs.Fields(0).Value);    
                   Если obj.Class="user" Тогда      
               
//*----- здесь смотри свойства    obj

   КонецЕсли;    
                   КонецЕсли;    
                   rs.MoveNext();    
               КонецЦикла;  
           Исключение
               Сообщить("Ошибка получения почты для логина :"+Стр.Логин);
14 Наська72
 
16.04.13
08:54
Вот такой запрос Query1 = "SELECT * FROM 'LDAP://Домен/DC=домен,DC=ru' WHERE objectCategory='Group' And name = 'ИмяГруппы' And member='*'";
Выдает ошибку при выполнении Query1 = "SELECT * FROM 'LDAP://TESELL/DC=tesell,DC=ru' WHERE objectCategory='Group' And name = 'YAL_SUENCO_Proximity' And member='*'";
15 vde69
 
16.04.13
09:00
(13) блин, не прочитал все :)

у тебя там сиды, в 1с из них нифига не получишь.

определить сид к учетке можно только на контролере домена,


попробуй так
               query = "SELECT ADsPath FROM 'LDAP://'А.ru'/DC='Б.ru'/";
16 Наська72
 
16.04.13
09:02
По SIDу я получаю AccountName и ReferencedDomainName! Но по этим данным не могу больше ничего узнать на различные запросы ошибки сыпятся
17 Наська72
 
16.04.13
09:05
(15) Какой-то странный запрос...
"Произошла одна или несколько ошибок во время обработки команды."
18 vde69
 
16.04.13
09:07
(16) это хранится в домене А (из-за дружбы), а остальные данные лежат в контролере домена Б.

как вариант
сделайте локально доступный дополнительный контроллер домена Б и на нем провайдер NT и репликация с основным...

для админов то-же плюс будет уменьшение трафика между А и Б
19 vde69
 
16.04.13
09:08
(17) запрос просит контроллер А запросить данные у контроллера Б... может там кавычки лишние :)
20 Наська72
 
16.04.13
09:13
(19) Ой, тысяча извинений, и правда кавычек лишка.
Теперь пишет: "Был передан недопустимый путь службы каталогов" =)
Насчет (18) даже не знаю, админы злые и не захотят такое наверное.
21 vde69
 
16.04.13
09:21
(20) ну хз, разбиратся нужно... я-бы копал в сторону прав, по тому что если права кривые - то LDAP выдает пусто.

query = "SELECT ADsPath FROM 'LDAP://A.RU/DC=Б.ru/";

можно попробовать по IP контроллеров

query = "SELECT ADsPath FROM 'LDAP://IP_A/DC=Б.ru/";

и подключение поменяй

       oConnect = ПолучитьCOMОбъект("","ADODB.Connection");
   oConnect.Provider = "ADSDSOObject";
       oConnect.Properties("User ID").Value = "учетка домена А.ru";
   oConnect.Properties("Password").Value = "пароль домена А.ru";            
   oConnect.Properties("Encrypt Password").Value = True;    
   oConnect.Open("Active Directory Provider");


ps
ушел работать
22 Наська72
 
16.04.13
12:03
Пробую еще из Имени и Домена получить пользователя:

strComputer1    = "ip_доменаB.ru";
                               objWMIService1    = ПолучитьCOMОбъект("winmgmts:\\" + strComputer1 + "\root\cimv2");
                               objAccount1    = objWMIService.Get("Win32_UserAccount.Domain='" + СокрЛП(Домен) + ".ru', Name = '" + СокрЛП(Имя) + "'");

Соответственно раз я в другом домене "Ошибка получения объекта COM: Отказано в доступе.". Кто знает как тут учетку другого домена прописать?
23 Наська72
 
16.04.13
13:18
Попробовала зайти под доменной учеткой B.ru весь запрос отлично отрабатывает.
Т.е. выявилась такая закономерность: к какому домену хочешь обращаться с Ldap такая доменная учетка у тебя должна быть. Причем в коннекте(oConnect) абсолютно все равно какая учетка будет.

Как такое можно обойти? Ввиду того, что это будет фоновое задание, то это довольно критично.
24 vde69
 
16.04.13
13:46
на память не помню но вроде вот так

objWMIService1     = ПолучитьCOMОбъект("winmgmts:\\" + strComputer1 + ".ИмяПользователя.Пароль\root\cimv2");
25 Наська72
 
16.04.13
14:05
(24) Спасибо, но уже не актуально.
Как обойти тот факт, что запрос по домену работает только под учеткой из этого же домена?
26 vde69
 
16.04.13
14:06
(25) так я и написал... после имени хоста через точку логин и пароль
27 zladenuw
 
16.04.13
14:41
закладка :).
28 Наська72
 
17.04.13
07:32
(26) Не работает =( Похоже ошибка в синтаксисе
objWMIService = ПолучитьCOMОбъект("winmgmts:\\" + strComputer + ".доменB\ИмяПользователя.12345678\root\cimv2");
29 Наська72
 
17.04.13
07:33
(28) "Ошибка получения объекта COM: IDispatch error #3617"
30 Наська72
 
17.04.13
07:37
(28) Если пишу так:
strComputer    = "ДоменВ.ru";
objWMIService = ПолучитьCOMОбъект("winmgmts:\\" + strComputer + ".ИмяПользователя.12345678\root\cimv2");
Получаю ошибку: "Сервер RPC недоступен."
31 Наська72
 
18.04.13
14:17
В общем ситуация такая: все мои запросы работают, если зайти под доменной учеткой домена A.ru (т.к. А дружит с В и А дружит с С).
Вопрос к знатокам: как запускать регламентное задание из под определенной учетки? Под кем она обычно запускается? System?
32 vde69
 
18.04.13
14:29
(31) под кем запущена служба 1с под тем и все процессы сервера висят.

служба 1с требует спец прав, если админы разрешат то тебе нужно службу запустить под правами любого админа домена А, если заортачатся - пусть права настраивают, там ДКОМ нужно прописывать и отдельно файловые права курить...