DCOM: как правильно подключаться к серверу по паролю?
От: djandy_spb  
Дата: 22.01.04 09:36
Оценка:
Вопрос такой, есть ком объект на одном компе, к нему подключается клиент с другого компа с помощью CoCreateInstanceEx, там в COSERVERINFO забиты мои логин и пароль, под которыми я — админ на сервере. В DCOMCNFG на сервере выставлен полный доступ к объекту для everyone. Все подключается прекрасно, с любого компа. Но запустить методы я могу только залогинившись под своим логином и паролем на клиентском компе, т.е. я должен быть на нем зарегистрирован. А нужно добиться, чтобы клиент с любого компа мог подрубиться к серверу без каких либо изменений в настройках. В идеале — в клиенте пользователь вводит имя компа-сервера, логин и пароль, и клиент подключается к СОМ-объекту.
Как это лучше сделать? В факе не нашел, либо не понял что нашел
Re: DCOM: как правильно подключаться к серверу по паролю?
От: Tom Россия http://www.RSDN.ru
Дата: 22.01.04 12:22
Оценка:
_>Вопрос такой, есть ком объект на одном компе, к нему подключается клиент с другого компа с помощью CoCreateInstanceEx, там в COSERVERINFO забиты мои логин и пароль, под которыми я — админ на сервере. В DCOMCNFG на сервере выставлен полный доступ к объекту для everyone. Все подключается прекрасно, с любого компа. Но запустить методы я могу только залогинившись под своим логином и паролем на клиентском компе, т.е. я должен быть на нем зарегистрирован. А нужно добиться, чтобы клиент с любого компа мог подрубиться к серверу без каких либо изменений в настройках. В идеале — в клиенте пользователь вводит имя компа-сервера, логин и пароль, и клиент подключается к СОМ-объекту.
_>Как это лучше сделать? В факе не нашел, либо не понял что нашел

COSERVERINFO заполнить нужно. Этого хватит.
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[2]: DCOM: как правильно подключаться к серверу по паролю?
От: djandy_spb  
Дата: 23.01.04 08:47
Оценка:
Tom>COSERVERINFO заполнить нужно. Этого хватит.

Заполняю вот так:
  COSERVERINFO csInfo;
  COAUTHINFO caInfo;
  COAUTHIDENTITY caId;
  LPWSTR pcServName;
  pcServName = m_sServName.AllocSysString();
  csInfo.pwszName = pcServName;
  csInfo.pAuthInfo = &caInfo;
  csInfo.dwReserved1 = 0;
  csInfo.dwReserved2 = 0;

  caInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  caInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
  caInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
  caInfo.dwCapabilities = EOAC_NONE;
  caInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  caInfo.pAuthIdentityData = &caId;
  caInfo.pwszServerPrincName = NULL;

  caId.User = SysAllocString(L"login");
  caId.Password = SysAllocString(L"password");
  caId.Domain = SysAllocString(L"");
  caId.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  caId.UserLength = 5;
  caId.PasswordLength = 8;
  caId.DomainLength = 0;


Этого не хватает! Работает только если и в комп залогиниться под login и password. Но если при этом в COSERVERINFO заменить пароль или логин, то перестает даже просто комобъект создавать, т.е COSERVERINFO тоже имеет значение.
Re[3]: DCOM: как правильно подключаться к серверу по паролю?
От: Tom Россия http://www.RSDN.ru
Дата: 23.01.04 09:06
Оценка: 9 (1)
_>Этого не хватает! Работает только если и в комп залогиниться под login и password. Но если при этом в COSERVERINFO заменить пароль или логин, то перестает даже просто комобъект создавать, т.е COSERVERINFO тоже имеет значение.

Блин стареть начинаю. Забыл совсем То, что ты указываешь в COSERVERINFO — это параметры безопастности активации (запуска) обьекта. Т.е эти параметры действуют только на создание обьекта. Есть ещё защита вызовов. Её параметры нужно установить при помощи IClientSecurity или врапера над ней — CoSetProxyBlanket.
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[4]: DCOM: как правильно подключаться к серверу по паролю?
От: djandy_spb  
Дата: 23.01.04 12:06
Оценка:
Tom>Блин стареть начинаю. Забыл совсем То, что ты указываешь в COSERVERINFO — это параметры безопастности активации (запуска) обьекта. Т.е эти параметры действуют только на создание обьекта. Есть ещё защита вызовов. Её параметры нужно установить при помощи IClientSecurity или врапера над ней — CoSetProxyBlanket.

Значит делаю так, с помощью IMyInterface->QI получаю IUnknown и IClientSecurity, дальше вызываю SetBlanket:
SetBlanket(piUnk,RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CONNECT,
           RPC_C_IMP_LEVEL_IMPERSONATE, &caId, EOAC_NONE);

здесь caID такое же как и при CoCreateInstanceEx.

Результат не изменился
Re[5]: DCOM: как правильно подключаться к серверу по паролю?
От: Tom Россия http://www.RSDN.ru
Дата: 23.01.04 12:54
Оценка:
_>Значит делаю так, с помощью IMyInterface->QI получаю IUnknown и IClientSecurity, дальше вызываю SetBlanket:
_>
_>SetBlanket(piUnk,RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CONNECT,
_>           RPC_C_IMP_LEVEL_IMPERSONATE, &caId, EOAC_NONE);
_>

_>здесь caID такое же как и при CoCreateInstanceEx.

_>Результат не изменился


ну вообще это странно. т.е ты

1. создал обьект
2. вызвал SetBlanket (hr проверил?)

получаешь E_ACCESS...

Единственное, что могу посоветовать — перестартовать сервер
А так должно всё работать
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[6]: DCOM: как правильно подключаться к серверу по паролю?
От: djandy_spb  
Дата: 23.01.04 13:28
Оценка:
Tom>ну вообще это странно. т.е ты
Tom>1. создал обьект
Tom>2. вызвал SetBlanket (hr проверил?)

Hr везде 0

Tom>получаешь E_ACCESS...

Т.е. 0x80070005 получаю. И только при вызове метода объекта.

Сейчас читал статью comsec... У меня клиент на вин98 стоит, а сервер на вин2к, доменов нету. Может из-за этого?
Win 9x как DCOM клиент - список граблей
От: Tom Россия http://www.RSDN.ru
Дата: 23.01.04 14:01
Оценка: 38 (5)
#Имя: FAQ.dcom.win9x
_>Сейчас читал статью comsec... У меня клиент на вин98 стоит, а сервер на вин2к, доменов нету. Может из-за этого?

Ну так с win98 надо было начинать. Итак список граблей на которые можно наступить при использовании win 9x как DCOM клиента:

0. Проверить что у пользователя, указываемого в COSERVERINFO есть права на запуск и на вызов методов обьекта (смотреть в dcomcnfg.exe)
1. Для серверов exe проверить вызывается ли CoInitializeSecurity и её параметры (см. статью )
2. Убедится, что в dcomcnfg.exe для сервера указана не "Launching User" а "Interactive user" или "This User" (из за проблеммы call backs)
3. Так как win95 поддерживает проверку целостности пакетов уровня только RPC_C_AUTHN_LEVEL_CONNECT, то на сервере для обьекта должна быть задана настройка не выше чем RPC_C_AUTHN_LEVEL_CONNECT. Иначе вызов метода будет обламыватся с ошибкой E_ACCESSDENIED
4. Если ничего не помогло, то можно посмотреть Event Log, там иногда бывает полезная информация.

Ссылки:
Q174024
Q158508
Защита в DCOM/COM+
Автор(ы): Владислав Чистяков
Дата: 28.01.2002
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[8]: DCOM: как правильно подключаться к серверу по паролю?
От: Аноним  
Дата: 26.01.04 10:09
Оценка:
Tom>0. Проверить что у пользователя, указываемого в COSERVERINFO есть права на запуск и на вызов методов обьекта (смотреть в dcomcnfg.exe)
Везде everyone
Tom>1. Для серверов exe проверить вызывается ли CoInitializeSecurity и её параметры (см. статью )
Запускается строка из статьи, отключающая защиту, и в клиенте и в сервере.

Tom>2. Убедится, что в dcomcnfg.exe для сервера указана не "Launching User" а "Interactive user" или "This User" (из за проблеммы call backs)

Сервер оформлен в виде сервиса, и при попытке выбрать This User и задать верного пользователя с паролем пишет "неправильный параметр". А изначально вообще стоит system.

Tom>3. Так как win95 поддерживает проверку целостности пакетов уровня только RPC_C_AUTHN_LEVEL_CONNECT, то на сервере для обьекта должна быть задана настройка не выше чем RPC_C_AUTHN_LEVEL_CONNECT. Иначе вызов метода будет обламыватся с ошибкой E_ACCESSDENIED

Везде NONE!

Tom>4. Если ничего не помогло, то можно посмотреть Event Log, там иногда бывает полезная информация.

Тоже пусто

Tom>Ссылки:

Tom>Q174024
Tom>Q158508
Tom>Защита в DCOM/COM+
Автор(ы): Владислав Чистяков
Дата: 28.01.2002


В общем пора садиться на Win2000 Спасибо за инфу!
Re[9]: DCOM: как правильно подключаться к серверу по паролю?
От: Tom Россия http://www.RSDN.ru
Дата: 26.01.04 14:20
Оценка:
Tom>>0. Проверить что у пользователя, указываемого в COSERVERINFO есть права на запуск и на вызов методов обьекта (смотреть в dcomcnfg.exe)
А>Везде everyone
Tom>>1. Для серверов exe проверить вызывается ли CoInitializeSecurity и её параметры (см. статью )
А>Запускается строка из статьи, отключающая защиту, и в клиенте и в сервере.
Вот с этого места по подробнее. В общем показывай код инициализации защиты на сервере и клиенте.

Tom>>2. Убедится, что в dcomcnfg.exe для сервера указана не "Launching User" а "Interactive user" или "This User" (из за проблеммы call backs)

А>Сервер оформлен в виде сервиса, и при попытке выбрать This User и задать верного пользователя с паролем пишет "неправильный параметр". А изначально вообще стоит system.
гм. Это не есть правильно. В SCM можно указать если что...

Tom>>3. Так как win95 поддерживает проверку целостности пакетов уровня только RPC_C_AUTHN_LEVEL_CONNECT, то на сервере для обьекта должна быть задана настройка не выше чем RPC_C_AUTHN_LEVEL_CONNECT. Иначе вызов метода будет обламыватся с ошибкой E_ACCESSDENIED

А>Везде NONE!
Не важно что у сервера там прописано, если ты защиту не правильно инициализируешь.

Tom>>4. Если ничего не помогло, то можно посмотреть Event Log, там иногда бывает полезная информация.

А>Тоже пусто

Tom>>Ссылки:

Tom>>Q174024
Tom>>Q158508
Tom>>Защита в DCOM/COM+
Автор(ы): Владислав Чистяков
Дата: 28.01.2002


А>В общем пора садиться на Win2000 Спасибо за инфу!

Это да. Это давно пора
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[10]: DCOM: как правильно подключаться к серверу по паролю
От: djandy_spb  
Дата: 02.02.04 11:40
Оценка:
Приветствую! Пардон, инета не было, не отвечал.
Tom>Вот с этого места по подробнее. В общем показывай код инициализации защиты на сервере и клиенте.
Как только я перестал запускать сервер как сервис — без защиты подключиться получилось, удалось выбрать This User в DCOMCNFG.
Сейчас я пытаюсь сделать так, чтобы защита появилась, и по логину-паролю позволяла проге с любого компа и из-под любого пользователя запускать сервер и работать с его методами.

Как делаю:
Сервер:

в DCOMCNFG установлено authentication level = Connect, все разрешено администраторам, "This User" — Log:Tester Pw: test. Tester — администратор в винде 2000.

Инициализация
    SOLE_AUTHENTICATION_SERVICE sasInfo;
    sasInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
    sasInfo.dwAuthzSvc = RPC_C_AUTHN_NONE;
    sasInfo.pPrincipalName = NULL;
    hr = CoInitializeSecurity(NULL, 1, &sasInfo, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);

Подозреваю, что нужно в первом параметре слать не NULL а правильно заполненный security_descriptor, но не очень понятно как именно это делается.

Клиент:

инициализация
  HRESULT hr = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_CONNECT,RPC_C_IMP_LEVEL_IMPERSONATE, NULL,EOAC_NONE, NULL);


работа
  MULTI_QI mqiInfo;
  IID iid = IID_IMyObj;
  mqiInfo.pIID = &iid;
  mqiInfo.pItf = NULL;

  COSERVERINFO csInfo;
  COAUTHINFO caInfo;
  COAUTHIDENTITY caId;
  LPWSTR pcServName = SysAllocString(L"Server");
  csInfo.pwszName = pcServName;
  csInfo.pAuthInfo = &caInfo;
  csInfo.dwReserved1 = 0;
  csInfo.dwReserved2 = 0;

  caInfo.dwAuthnLevel = RPC_C_AUTHN_LEVEL_CONNECT;
  caInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
  caInfo.dwAuthzSvc = RPC_C_AUTHZ_NONE;
  caInfo.dwCapabilities = EOAC_NONE;
  caInfo.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
  caInfo.pAuthIdentityData = &caId;
  caInfo.pwszServerPrincName = NULL;

  caId.User = SysAllocString(L"Tester");
  caId.Password = SysAllocString(L"test");
  caId.Domain = SysAllocString(L"");
  caId.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
  caId.UserLength = 6;
  caId.PasswordLength = 4;
  caId.DomainLength = 0;

  HRESULT hr = CoCreateInstanceEx(CLSID_MyObj,NULL,CLSCTX_REMOTE_SERVER,&csInfo,1,&mqiInfo);

  IMyObj * pMyObj = reinterpret_cast<IMyObj *>(mqiInfo.pItf);
  mqiInfo.pItf = NULL;
  IClientSecurity *piClSec = NULL;
  hr = pMyObj->QueryInterface(IID_IClientSecurity, (void **) &piClSec);
  IUnknown *piUnk = NULL;
  hr = pMyObj->QueryInterface(IID_IUnknown, (void **) &piUnk);
  hr = piClSec->SetBlanket(piUnk,RPC_C_AUTHN_WINNT,RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, &caId, EOAC_NONE);

  hr = pMyObj->Procedure1();


Ну и естественно, ошибка 0x80070005, Access Deinied.
В любом случае, хотелось бы посмотреть на пример инициализации security_descriptor!
Re[11]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 02.02.04 12:31
Оценка:
_>В любом случае, хотелось бы посмотреть на пример инициализации security_descriptor!
Плохо читал статью. Вот цитата от туда:

Чтобы заставить ATL-сервер работать так, как написано в большинстве книг по COM, т.е. чтобы правами доступа можно было управлять через dcomcnfg, нужно изменить инициализацию защиты так, чтобы настройки считывались из ветки реестра, соответствующей AppID. Для этого нужно заменить приведенные выше строки кода на следующие:

struct __declspec(uuid("8030105E-9B2A-4758-9AF9-12CCC4507468")) CAppID;
GUID gAppID = __uuidof(CAppID);
hr = CoInitializeSecurity(&gAppID, -1, NULL, NULL, NULL, NULL, NULL, 
                          EOAC_APPID, NULL);


Здесь 8030105E-9B2A-4758-9AF9-12CCC4507468 – AppID. Это значение генерирует ATL-визард, его можно найти в коде функции _tWinMain и RegisterServer.

... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[12]: DCOM: как правильно подключаться к серверу по паролю
От: djandy_spb  
Дата: 02.02.04 12:58
Оценка:
Tom>Чтобы заставить ATL-сервер работать так, как написано в большинстве книг по COM, т.е. чтобы правами доступа можно было управлять через dcomcnfg, нужно изменить инициализацию защиты так, чтобы настройки считывались из ветки реестра, соответствующей AppID. Для этого нужно заменить приведенные выше строки кода на следующие:

Заменил инициализацию в сервере на этот код — объект перестал даже создаваться, с той же ошибкой Значит наверно надо ещё и клиент изменять.
Re[13]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 02.02.04 13:27
Оценка:
_>Заменил инициализацию в сервере на этот код — объект перестал даже создаваться, с той же ошибкой Значит наверно надо ещё и клиент изменять.

Нет. Клиент не надо, но инициализацию надо проверить.

Попробуй SEC_WINNT_AUTH_IDENTITY_ANSI и 0 вместо -1
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[14]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 02.02.04 13:54
Оценка:
И после каждого изменения сервера/клиента/настроек надо убить сервер из таск мэнеджера. Сам он умрёт не скоро, а если не убивать то настройки сервера будут работать старые.

PS: заглядывай в EventsLog на сервере
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[15]: DCOM: как правильно подключаться к серверу по паролю
От: djandy_spb  
Дата: 03.02.04 12:14
Оценка:
Запустил через AppID, объект создается(раньше была ошибка в uuid ), но все также не позволяет запускать методы. Если unicode заменить на ansi я думаю ничего не изменится, так как если сделать ошибку в пароле или имени, то объект перестает создаваться — access denied, т.е. в юникоде строки нормально воспринимаются. Под виндой 2000 абсолютно аналогично все работает, так что это не из-за 98 Если в CoInitializeSecurity в клиенте вместо -1 во втором параметре вставить 0 то получаем 80050057 — e_InvalidArg.. Ломаю голову. Кстати, организовался вопрос, когда я переносил клиента на другой комп, пришлось скопировать описание интерфейса и typelib из реестра, и вместе с exe передать файл tlb. Так делается всегда? Или есть способ сделать переносимого безо всяких усилий клиента?
Re[16]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 03.02.04 13:02
Оценка:
_>Запустил через AppID, объект создается(раньше была ошибка в uuid ), но все также не позволяет запускать методы. Если unicode заменить на ansi я думаю ничего не изменится, так как если сделать ошибку в пароле или имени, то объект перестает создаваться — access denied, т.е. в юникоде строки нормально воспринимаются. Под виндой 2000 абсолютно аналогично все работает, так что это не из-за 98 Если в CoInitializeSecurity в клиенте вместо -1 во втором параметре вставить 0 то получаем 80050057 — e_InvalidArg.. Ломаю голову. Кстати, организовался вопрос, когда я переносил клиента на другой комп, пришлось скопировать описание интерфейса и typelib из реестра, и вместе с exe передать файл tlb. Так делается всегда? Или есть способ сделать переносимого безо всяких усилий клиента?

В общем так:
Если обьект создаётся нормально, CoSetProxyBlanket проходит без ошибок и на сервере разрешено вызывать методы порльзователю, а у тебя всё равно не работает, то я не знаю почему. Скорее всего что то ты пропустил. Перепроверь всё заново.
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[17]: DCOM: как правильно подключаться к серверу по паролю
От: djandy_spb  
Дата: 03.02.04 14:31
Оценка:
Tom>Если обьект создаётся нормально, CoSetProxyBlanket проходит без ошибок и на сервере разрешено вызывать методы порльзователю,
Стоп, а как это делается?

Tom>а у тебя всё равно не работает, то я не знаю почему. Скорее всего что то ты пропустил. Перепроверь всё заново.

Как у меня происходит вызов SetBlanket я написал в Re(10), там все правильно? Создается объект, вызывается его QI 2 раза и получаем IUnknown и IClientSecurity, потом у IClientSecurity вызывается SetBlanket в которую параметром передается указатель на IUnknown. Идеология правильная или напутал? И насчет tlb файла тоже интересно узнать, так всегда делается?
Re[18]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 03.02.04 15:37
Оценка: 16 (3)
Tom>>а у тебя всё равно не работает, то я не знаю почему. Скорее всего что то ты пропустил. Перепроверь всё заново.
_>Как у меня происходит вызов SetBlanket я написал в Re(10), там все правильно? Создается объект, вызывается его QI 2 раза и получаем IUnknown и IClientSecurity, потом у IClientSecurity вызывается SetBlanket в которую параметром передается указатель на IUnknown. Идеология правильная или напутал? И насчет tlb файла тоже интересно узнать, так всегда делается?

Похоже напутал маленько.
Когда ты делаешь QI для IUnknown то ты получаешь реально IUnknown не обьекта или прокси а менеджера проксей, по этому ему бессмысленно делать SetBlanket. Тебе надо спросить по QI именно твой интерфейс (не IUnknown или IDispatch), тогда ты получишь указатель на прокси, который потом нужно передать в SetBlanket, а затем уже использовать (вызывать методы именно для указателя кот. ты передал в SetBlanket)

ps: сделай это, а если не поможет то показывай весь код
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[19]: DCOM: как правильно подключаться к серверу по паролю
От: djandy_spb  
Дата: 04.02.04 09:10
Оценка:
УРААААА!!!!!!!!! Заработало сразу. Все, огромное спасибо, в остальном ошибок значит не было!
И все-таки, насчет tlb файла бы узнать ещё..
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.