_>УРААААА!!!!!!!!! Заработало сразу. Все, огромное спасибо, в остальном ошибок значит не было!
Welcome
_>И все-таки, насчет tlb файла бы узнать ещё..
Ну надо за собой таскать. Или регистри интерфейс сам. Там не сложно. Надо только стандартный сурогат указать...
А вообще в deployment-те exe я не силён
... << RSDN@Home 1.1.0 stable >>
Здравствуйте, 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?
Просвятите плз
Здравствуйте.
Я не четко сформулировал вопрос в предыдущем сообщение или ни кто не знает(во что верится с трудом)?
С надеждой на ответ, Глиндор.
Здравствуйте, 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, не смогут ни запускать сервер, ни пользоваться его методами.
Если у Вас что-то не получилось, могу выслать код тестового клиента и сервера. Но за основу был взят Ваш проект, никаких существенных изменений в нём я не делал.
Успехов!