Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

284 lines
7.3 KiB

  1. //+--------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: downlvl.cxx
  7. //
  8. // Contents: Functions which return information about domains when
  9. // uplevel (Windows 2000 or later) APIs are not available
  10. // (i.e. when joined to an NT4 domain or in a workgroup).
  11. //
  12. // Functions: GetLsaAccountDomainInfo
  13. // GetDomainSid
  14. //
  15. // History: 06-22-2000 DavidMun Created
  16. //
  17. //---------------------------------------------------------------------------
  18. #include "headers.hxx"
  19. #pragma hdrstop
  20. //+--------------------------------------------------------------------------
  21. //
  22. // Function: GetLsaAccountDomainInfo
  23. //
  24. // Synopsis: Use LSA APIs to fill *[ppAccountDomainInfo].
  25. //
  26. // Arguments: [pwzServerName] - target computer
  27. // [phlsaServer] - filled with handle returned by
  28. // LsaOpenPolicy
  29. // [ppAccountDomainInfo] - filled with domain info returned
  30. // by LsaQueryInformationPolicy.
  31. //
  32. // Returns: HRESULT
  33. //
  34. // History: 06-22-2000 DavidMun Created
  35. //
  36. //---------------------------------------------------------------------------
  37. HRESULT
  38. GetLsaAccountDomainInfo(
  39. PCWSTR pwzServerName,
  40. PLSA_HANDLE phlsaServer,
  41. PPOLICY_ACCOUNT_DOMAIN_INFO *ppAccountDomainInfo)
  42. {
  43. TRACE_FUNCTION(GetLsaAccountDomainInfo);
  44. HRESULT hr = S_OK;
  45. NTSTATUS nts = ERROR_SUCCESS;
  46. LSA_OBJECT_ATTRIBUTES oa;
  47. SECURITY_QUALITY_OF_SERVICE sqos;
  48. BOOL fOk;
  49. do
  50. {
  51. //
  52. // Open the lsa policy object on the target server
  53. //
  54. ZeroMemory(&sqos, sizeof sqos);
  55. sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  56. sqos.ImpersonationLevel = SecurityImpersonation;
  57. sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  58. sqos.EffectiveOnly = FALSE;
  59. ZeroMemory(&oa, sizeof oa);
  60. oa.Length = sizeof oa;
  61. oa.SecurityQualityOfService = &sqos;
  62. UNICODE_STRING uszServerName;
  63. if (pwzServerName)
  64. {
  65. fOk = RtlCreateUnicodeString(&uszServerName, pwzServerName);
  66. if (!fOk)
  67. {
  68. hr = E_OUTOFMEMORY;
  69. DBG_OUT_HRESULT(hr);
  70. break;
  71. }
  72. }
  73. nts = LsaOpenPolicy(pwzServerName ? &uszServerName : NULL,
  74. &oa,
  75. POLICY_VIEW_LOCAL_INFORMATION,
  76. phlsaServer);
  77. if (pwzServerName)
  78. {
  79. RtlFreeUnicodeString(&uszServerName);
  80. }
  81. BREAK_ON_FAIL_NTSTATUS(nts);
  82. //
  83. // Get the domain information for the passed-in server
  84. //
  85. nts = LsaQueryInformationPolicy(*phlsaServer,
  86. PolicyAccountDomainInformation,
  87. (LPVOID *)ppAccountDomainInfo);
  88. BREAK_ON_FAIL_NTSTATUS(nts);
  89. } while (0);
  90. if (NT_ERROR(nts))
  91. {
  92. hr = E_FAIL;
  93. }
  94. return hr;
  95. }
  96. //+--------------------------------------------------------------------------
  97. //
  98. // Function: GetDomainSid
  99. //
  100. // Synopsis: Get the SID of domain with name [pwzDomainName].
  101. //
  102. // Arguments: [pwzDomainName] - name of domain for which to retrieve SID
  103. // [ppSid] - filled with pointer to domain's SID
  104. // [ppwzDC] - if non-NULL, filled with name of DC for
  105. // domain [pwzDomainName].
  106. //
  107. // Returns: HRESULT
  108. //
  109. // History: 06-22-2000 DavidMun Created
  110. //
  111. //---------------------------------------------------------------------------
  112. HRESULT
  113. GetDomainSid(
  114. PWSTR pwzDomainName,
  115. PSID *ppSid,
  116. PWSTR *ppwzDC)
  117. {
  118. Dbg(DEB_TRACE, "GetDomainSid('%ws')\n", pwzDomainName);
  119. HRESULT hr;
  120. ULONG ulResult;
  121. PWSTR pwzPDC = NULL;
  122. NTSTATUS nts;
  123. LSA_HANDLE hlsaServer = NULL;
  124. POLICY_ACCOUNT_DOMAIN_INFO *pAccountDomainInfo = NULL;
  125. SECURITY_QUALITY_OF_SERVICE sqos;
  126. LSA_OBJECT_ATTRIBUTES oa;
  127. BOOL fOk;
  128. do
  129. {
  130. //
  131. // First find a DC in the domain
  132. //
  133. ulResult = NetGetDCName(NULL, pwzDomainName, (LPBYTE *) &pwzPDC);
  134. if (ulResult != ERROR_SUCCESS)
  135. {
  136. hr = E_FAIL;
  137. Dbg(DEB_ERROR, "GetDomainSid: NetGetDCName err=%uL\n", ulResult);
  138. break;
  139. }
  140. Dbg(DEB_TRACE,
  141. "GetDomainSid: DC of domain '%ws' is '%ws'\n",
  142. pwzDomainName,
  143. pwzPDC);
  144. PWSTR pwzDCname = pwzPDC + 2;
  145. if (ppwzDC)
  146. {
  147. *ppwzDC = new WCHAR[lstrlen(pwzDCname) + 1];
  148. if (!*ppwzDC)
  149. {
  150. hr = E_OUTOFMEMORY;
  151. DBG_OUT_HRESULT(hr);
  152. break;
  153. }
  154. lstrcpy(*ppwzDC, pwzDCname);
  155. }
  156. hr = GetLsaAccountDomainInfo(pwzDCname,
  157. &hlsaServer,
  158. &pAccountDomainInfo);
  159. //
  160. // Open the lsa policy object on the DC
  161. //
  162. ZeroMemory(&sqos, sizeof sqos);
  163. sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
  164. sqos.ImpersonationLevel = SecurityImpersonation;
  165. sqos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
  166. sqos.EffectiveOnly = FALSE;
  167. ZeroMemory(&oa, sizeof oa);
  168. oa.Length = sizeof oa;
  169. oa.SecurityQualityOfService = &sqos;
  170. //
  171. // Get a handle to lsa policy for queries about domains
  172. //
  173. UNICODE_STRING uszServerName;
  174. fOk = RtlCreateUnicodeString(&uszServerName, pwzDCname);
  175. if (!fOk)
  176. {
  177. hr = E_OUTOFMEMORY;
  178. DBG_OUT_HRESULT(hr);
  179. break;
  180. }
  181. nts = LsaOpenPolicy(&uszServerName,
  182. &oa,
  183. POLICY_VIEW_LOCAL_INFORMATION,
  184. &hlsaServer);
  185. RtlFreeUnicodeString(&uszServerName);
  186. BREAK_ON_FAIL_NTSTATUS(nts);
  187. //
  188. // Get the SID for the domain
  189. //
  190. nts = LsaQueryInformationPolicy(hlsaServer,
  191. PolicyAccountDomainInformation,
  192. (LPVOID *)&pAccountDomainInfo);
  193. BREAK_ON_FAIL_NTSTATUS(nts);
  194. if (pAccountDomainInfo->DomainSid)
  195. {
  196. ULONG cbSid = GetLengthSid(pAccountDomainInfo->DomainSid);
  197. ASSERT(cbSid);
  198. *ppSid = (PSID) new BYTE[cbSid];
  199. if (!*ppSid)
  200. {
  201. hr = E_OUTOFMEMORY;
  202. DBG_OUT_HRESULT(hr);
  203. break;
  204. }
  205. CopyMemory(*ppSid, pAccountDomainInfo->DomainSid, cbSid);
  206. }
  207. else
  208. {
  209. hr = E_FAIL;
  210. Dbg(DEB_ERROR,
  211. "GetDomainSid: couldn't obtain sid for domain '%ws'\n",
  212. pwzDomainName);
  213. }
  214. } while (0);
  215. //
  216. // Release resources
  217. //
  218. if (hlsaServer)
  219. {
  220. LsaClose(hlsaServer);
  221. }
  222. if (pwzPDC)
  223. {
  224. NetApiBufferFree(pwzPDC);
  225. }
  226. if (pAccountDomainInfo)
  227. {
  228. LsaFreeMemory(pAccountDomainInfo);
  229. }
  230. return hr;
  231. }