请问WMI远程访问有关问题
请教WMI远程访问问题.
程序运行在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
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);