读书人

请问WMI远程访问有关问题

发布时间: 2012-09-19 13:43:53 作者: rapoo

请教WMI远程访问问题.

C/C++ code
HRESULT hres;IEnumWbemClassObject* pEnumerator = NULL;    IWbemClassObject * pObject = NULL;    ULONG uReturn = 0;TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH+1]=L"Administrator";TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1]=L"1234567890";hres =  CoInitializeEx(0, COINIT_MULTITHREADED); ZeroMemory(&sID,sizeof(SOLE_AUTHENTICATION_INFO));cID.User = (USHORT *)pszName;cID.UserLength = _tcslen(pszName);cID.Password = (USHORT *)pszPwd;cID.PasswordLength = _tcslen(pszPwd);cID.Domain = (USHORT *)L"";cID.DomainLength = _tcslen(L"");cID.Flags=SEC_WINNT_AUTH_IDENTITY_UNICODE;sID.dwAuthnSvc=RPC_C_AUTHN_LEVEL_DEFAULT;sID.dwAuthzSvc=RPC_C_AUTHZ_DEFAULT;sID.pAuthInfo=&cID;hres =  CoInitializeSecurity(    NULL,     -1,                          // COM negotiates service    NULL,                        // Authentication services    NULL,                        // Reserved    RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication     RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation      &sID,                        // Authentication info    EOAC_NONE,                   // Additional capabilities     NULL                         // Reserved    );hres = CoCreateInstance(CLSID_WbemLocator,    0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *) &pLoc);hres = pLoc->ConnectServer(    _bstr_t(L"\\\\192.168.1.28\\root\\cimv2"),    _bstr_t(pszName),                 // User name    _bstr_t(pszPwd),                  // User password    _bstr_t(L"MS_409"),               // Locale                 NULL,                             // Security flags    _bstr_t(L""),//_bstr_t(L"ntlmdomain:domain"),    // Authority            0,                                // Context object     &pSvc                             // IWbemServices proxy    );hres = CoSetProxyBlanket(    pSvc,                        // Indicates the proxy to set    RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx     RPC_C_AUTHZ_DEFAULT,         // RPC_C_AUTHZ_xxx     NULL,                        // Server principal name     RPC_C_AUTHN_LEVEL_DEFAULT,      // RPC_C_AUTHN_LEVEL_xxx     RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx    &cID,                        // client identity    EOAC_NONE                   // proxy capabilities     );    hres = pSvc->ExecQuery(bstr_t("WQL"),bstr_t("SELECT * FROM Win32_Processor"),         WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY,NULL,&pEnumerator);        while (pEnumerator)    {           hres = pEnumerator->Next(WBEM_INFINITE, 1,  &pObject, &uReturn);            if(0 == uReturn)        ///hres == E_ACCESSDENIED             break;    // WBEM_E_FAILED    }

程序运行在A电脑上面,我需要连接到B电脑上面.
当前A电脑上面登陆的用户不是(Administrator),这里假设登陆用户为 UserA

TCHAR pszName[CREDUI_MAX_USERNAME_LENGTH+1]=L"Administrator";
TCHAR pszPwd[CREDUI_MAX_PASSWORD_LENGTH+1]=L"1234567890";
这个是B电脑的账号,具有管理员权限.

现在的问题是.
在code hres = pEnumerator->Next(WBEM_INFINITE, 1, &pObject, &uReturn); 之前,一切都是正常的,连接也是以pszName指定的用户连接.
但hres = pEnumerator->Next(WBEM_INFINITE, 1, &pObject, &uReturn);这句执行的时候,发现返回值是 E_ACCESSDENIED
,觉得很奇怪,然后去B电脑查看日志,发现 A电脑在这时使用的是UserA,而不是pszName指定的(怎么看?日志记录全打开,在事件查看器的安全性里面)

请问各位有没有遇到过吗.

[解决办法]
IWbemServices 设置权限验证
构建COAUTHIDENTITY, 获取IClientSecurity接口 调用SetBlanket
参考

C/C++ code
BOOL    WbemAllocAuthIdentity(CHAR *pUser, CHAR *pUserPwd, CHAR *pDomain, COAUTHIDENTITY **ppAuth){    COAUTHIDENTITY *        pNewAuth;    _bstr_t        bStrServer;    _bstr_t        bStrUser;    _bstr_t        bStrUserPwd;    WCHAR *        pwUser;    WCHAR *        pwUserPwd;    WCHAR *        pwDomain;    pNewAuth = (COAUTHIDENTITY *)CoTaskMemAlloc(sizeof(COAUTHIDENTITY));    bStrUser = pUser;    bStrUserPwd = pUserPwd;    bStrServer = pDomain;    pwUser = (WCHAR *)CoTaskMemAlloc((bStrUser.length() + 1)*sizeof(WCHAR));    pwUserPwd = (WCHAR *)CoTaskMemAlloc((bStrUserPwd.length() + 1)*sizeof(WCHAR));    pwDomain = (WCHAR *)CoTaskMemAlloc((bStrServer.length() + 1)*sizeof(WCHAR));    wcscpy(pwUser, bStrUser);    wcscpy(pwUserPwd, bStrUserPwd);    wcscpy(pwDomain, bStrServer);    pNewAuth->User = (USHORT *)pwUser;    pNewAuth->UserLength = bStrUser.length();    pNewAuth->Password = (USHORT *)pwUserPwd;    pNewAuth->PasswordLength = bStrUserPwd.length();    pNewAuth->Domain = (USHORT *)pwDomain;    pNewAuth->DomainLength = bStrServer.length();    pNewAuth->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;    *ppAuth = pNewAuth;    return TRUE;}BOOL    SetProxyBlanket(IUnknown *pInterface, DWORD dwAuthnSvc, DWORD dwAuthzSvc, BSTR pServerPrincName, DWORD dwAuthnLevel,                         DWORD dwImpLevel, VOID *pAuthInfo, DWORD dwCapabilities){    IUnknown *            pUnknow;    IClientSecurity *    pClientSecurity;    HRESULT                hr;    pUnknow = NULL;    pClientSecurity = NULL;    hr = pInterface->QueryInterface(IID_IUnknown, (VOID **)&pUnknow);    if(FAILED(hr))        goto SetProxyBlanket_end;    hr = pInterface->QueryInterface(IID_IClientSecurity, (VOID **)&pClientSecurity);    if(FAILED(hr))        goto SetProxyBlanket_end;    hr = pClientSecurity->SetBlanket(pInterface, dwAuthnSvc, dwAuthzSvc, pServerPrincName,         dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);    if(FAILED(hr))        goto SetProxyBlanket_end;    if(pAuthInfo)    {        pClientSecurity->Release();        pClientSecurity = NULL;        hr = pUnknow->QueryInterface(IID_IClientSecurity, (VOID **)&pClientSecurity);        if(FAILED(hr))            goto SetProxyBlanket_end;        hr = pClientSecurity->SetBlanket(pInterface, dwAuthnSvc, dwAuthzSvc, pServerPrincName,             dwAuthnLevel, dwImpLevel, pAuthInfo, dwCapabilities);    }SetProxyBlanket_end:    if(pUnknow)        pUnknow->Release();    if(pClientSecurity)        pClientSecurity->Release();    if(FAILED(hr))        return FALSE;    return TRUE;}BOOL    SetInterfaceSecurity(IUnknown *pInterface, CHAR *pServer, CHAR *pUser, CHAR *pUserPwd, COAUTHIDENTITY **ppAuth){    BOOL        bRetVal;    if(m_bChgAuth == FALSE)        return TRUE;    if(pInterface == NULL)        //WBEM_E_INVALID_PARAMETER        return FALSE;    if(*ppAuth)    {        bRetVal = SetInterfaceSecurity(pInterface, *ppAuth);        return bRetVal;    }    if(pUser && pUserPwd)        bRetVal = WbemAllocAuthIdentity(pUser, pUserPwd, pServer, ppAuth);    bRetVal = SetProxyBlanket(pInterface, RPC_C_AUTHN_WINNT, 0, NULL, 0, RPC_C_IMP_LEVEL_IMPERSONATE, *ppAuth, NULL);    return bRetVal;}SetInterfaceSecurity(pWbemServices, bStrServer, bStrUser, bStrUserPwd, ppAuth); 


[解决办法]
可能需要这个用户有登陆,你把UserA也登陆到B机器等,然后看能否连接上.
估计微软做了一些安全限制等,查看一下策略管理中是否有对应的一些设置

读书人网 >VC/MFC

热点推荐