Re[20]: DCOM: как правильно подключаться к серверу по паролю
От: Tom Россия http://www.RSDN.ru
Дата: 04.02.04 10:23
Оценка:
_>УРААААА!!!!!!!!! Заработало сразу. Все, огромное спасибо, в остальном ошибок значит не было!
Welcome

_>И все-таки, насчет tlb файла бы узнать ещё..

Ну надо за собой таскать. Или регистри интерфейс сам. Там не сложно. Надо только стандартный сурогат указать...
А вообще в deployment-те exe я не силён
... << RSDN@Home 1.1.0 stable >>
Народная мудрось
всем все никому ничего(с).
Re[19]: DCOM: как правильно подключаться к серверу по паролю
От: Glindor  
Дата: 31.03.04 15:23
Оценка:
Здравствуйте, Tom, Вы писали:

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

_>>Как у меня происходит вызов SetBlanket я написал в Re(10), там все правильно? Создается объект, вызывается его QI 2 раза и получаем IUnknown и IClientSecurity, потом у IClientSecurity вызывается SetBlanket в которую параметром передается указатель на IUnknown. Идеология правильная или напутал? И насчет tlb файла тоже интересно узнать, так всегда делается?

Tom>Похоже напутал маленько.

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

Tom>ps: сделай это, а если не поможет то показывай весь код


Спасибо, очень ценная ветка и очень нужная информация, но хотелось и мне поинтересоваться:
В данном примере, который привел djandy_spb есть такой момент, что он(пример) замечательно работает, когда на серваке в настройках доступа и запуска com объекта стоит everyone. Но если задать определенного пользователя, то запуск объекта сможет осуществить только этот пользователь, а вот обращение — любой реально существующий пользователь. Как сделать, чтобы и доступ мог осуществить только указанный пользователь?

На всякий случай привозу весь кусок кода
клиент

     CoInitialize(NULL);
    HRESULT hr1 = CoInitializeSecurity(NULL,-1,NULL,NULL,RPC_C_AUTHN_LEVEL_CONNECT,RPC_C_IMP_LEVEL_IMPERSONATE, NULL,EOAC_NONE, NULL);    
    

    MULTI_QI m;
    m.pIID=&IID_ITestServer;
    m.pItf=NULL;
    m.hr=S_OK;
    

    COSERVERINFO csInfo;
    COAUTHINFO caInfo;
    COAUTHIDENTITY caId;
    LPWSTR pcServName = SysAllocString(L"192.168.80.13");
    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"User1");
    caId.Password = SysAllocString(L"Password1");
    caId.Domain = SysAllocString(L"DomainName");
    caId.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
    caId.UserLength = 5;
    caId.PasswordLength = 9;
    caId.DomainLength = 10;

    COAUTHIDENTITY caId2;
    caId2.User = SysAllocString(L"User2");
    caId2.Password = SysAllocString(L"Password2");
    caId2.Domain = SysAllocString(L"DomainName");
    caId2.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
    caId2.UserLength = 5;
    caId2.PasswordLength = 9;
    caId2.DomainLength = 10;



    DWORD errorCode;
    HRESULT hrInterface=CoCreateInstanceEx(CLSID_CoTestServer,NULL,CLSCTX_SERVER,&csInfo,1,&m);
    if( hrInterface==S_OK && SUCCEEDED( m.hr ) )
    {
        ITestServer* m_pTestServer = (ITestServer*)m.pItf;
    
        IClientSecurity *piClSec = NULL;
        HRESULT hr = m_pTestServer->QueryInterface(IID_IClientSecurity, (void **) &piClSec);
        IUnknown *piUnk = NULL;
        hr = m_pTestServer->QueryInterface(IID_ITestServer, (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, &caId2,    EOAC_NONE);

        try
        {
            if((hr=m_pTestServer->GetCode())==S_OK)
            {
                m.pItf->Release();
                return 0;
            }
            else
            {
                errorCode=GetLastError();
            }

        }
        catch( _com_error er)
        {
            errorCode=GetLastError();
            m.pItf->Release();
            return 6;    
        }
        m.pItf->Release();

    }
    else
    {
        if(hrInterface==REGDB_E_CLASSNOTREG)
            return 1;
        if(hrInterface==CLASS_E_NOAGGREGATION)
            return 2;
        if(hrInterface==CO_S_NOTALLINTERFACES)
            return 3;
        if(hrInterface==E_NOINTERFACE)
            return 4;
        if(hrInterface==0x80070005)
            return 5;
    }


на стороне сервера

    SOLE_AUTHENTICATION_SERVICE sasInfo;
    sasInfo.dwAuthnSvc = RPC_C_AUTHN_WINNT;
    sasInfo.dwAuthzSvc = RPC_C_AUTHN_NONE;
    sasInfo.pPrincipalName = NULL;
    HRESULT hr = CoInitializeSecurity(NULL, 1, &sasInfo, NULL, RPC_C_AUTHN_LEVEL_CONNECT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);


В правах на создание и доступ стоит пользователь User1 и не смотря на это срабатывает return 0; (что есть не верно)
Если в правах на доступ и создание поставить только User2, то объект даже не создастся — будет return 5;

Как сделать так, чтобы объект запускался, если в правах на запуск указан ТОЛЬКО пользователь User1, а доступ осуществлялся, когда в правах на доступ находится ТОЛЬКО User2?
Просвятите плз
Re[20]: DCOM: как правильно подключаться к серверу по паролю
От: Glindor  
Дата: 01.04.04 09:39
Оценка:
Здравствуйте.

Я не четко сформулировал вопрос в предыдущем сообщение или ни кто не знает(во что верится с трудом)?

С надеждой на ответ, Глиндор.
Re[21]: DCOM: как правильно подключаться к серверу по паролю
От: ppp  
Дата: 03.04.04 11:04
Оценка:
Здравствуйте, Glindor, Вы писали:

G>Здравствуйте.


G>Я не четко сформулировал вопрос в предыдущем сообщение или ни кто не знает(во что верится с трудом)?


G>С надеждой на ответ, Глиндор.


По-видимому, Вы невнимательно читали предыдущие сообщения. Там конечно много предположений, но основная идея там есть.


Важно:

Если Вы хотите управлять настройками сервера через утилиту dcomcnfg, Вы должны вызывать на сервере CoInitializeSecurity со след. параметрами:

HRESULT hr;
struct __declspec(uuid("025DCA86-678C-4BF6-B0CC-20B5373EFAE1")) CAppID;
GUID gAppID = __uuidof(CAppID);
hr = CoInitializeSecurity(&gAppID, -1, NULL, NULL, NULL, NULL, NULL, 
    EOAC_APPID, NULL);
return hr;


где вместо uuid ("025DCA86-678C-4BF6-B0CC-20B5373EFAE1") надо подставить реальный uuid Вашего сервера.

Далее, насколько я понял, Вы хотите, чтобы сервер мог запускать ТОЛЬКО пользователь user1, а выполнять его методы мог ТОЛЬКО пользователь user2

соответственно, запускаем dcomcnfg, в настройках Component Services/Computers/My Computer/DCOM Config находим наш сервер. Как я понял, он называется TestServer. Правой мышкой в popup-menu выбираем пункт Properties

в TAB control в разделе Security добавляем пользователя user1
в разделе Access Permissions добавляем пользователя user2

Несколько раз нажимаем OK


Далее рассмотрим следующий участок кода клиента:
HRESULT hrInterface=CoCreateInstanceEx(CLSID_CTestClass,
    NULL,CLSCTX_SERVER,&csInfo,1,&m);
if( hrInterface==S_OK && SUCCEEDED( m.hr ) )
{
        //method call
}


Если Вы всё настроили правильно, то пользователь user1 сможет только запускать сервер (hrInterface = E_ACCESSDENIED, но сервер в этот момент запускается!)
Пользователь user2 не сможет запускать сервер (если он еще не запущен, то hrInterface = E_ACCESSDENIED). Если же сервер запущен, то hrInterface = S_OK и пользователь сможет выполнять методы интерфейса.
Остальные пользователи, не указанные в настройках dcomcnfg, не смогут ни запускать сервер, ни пользоваться его методами.

Если у Вас что-то не получилось, могу выслать код тестового клиента и сервера. Но за основу был взят Ваш проект, никаких существенных изменений в нём я не делал.

Успехов!
Если ты такой умный, почему ты такой бедный?
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.