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.

644 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1997.
  5. //
  6. // File: sec2var.cxx
  7. //
  8. // Contents:
  9. //
  10. // Functions:
  11. //
  12. // History: 25-Apr-97 KrishnaG Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "iis.hxx"
  16. #pragma hdrstop
  17. HRESULT
  18. ConvertSidToString(
  19. PSID pSid,
  20. LPWSTR String
  21. );
  22. HRESULT
  23. ConvertSecDescriptorToVariant(
  24. PSECURITY_DESCRIPTOR pSecurityDescriptor,
  25. VARIANT * pVarSec
  26. )
  27. {
  28. IADsSecurityDescriptor * pSecDes = NULL;
  29. IDispatch * pDispatch = NULL;
  30. LPWSTR pszGroup = NULL;
  31. LPWSTR pszOwner = NULL;
  32. BOOL fOwnerDefaulted = 0;
  33. BOOL fGroupDefaulted = 0;
  34. BOOL fDaclDefaulted = 0;
  35. BOOL fSaclDefaulted = 0;
  36. BOOL fSaclPresent = 0;
  37. BOOL fDaclPresent = 0;
  38. LPBYTE pOwnerSidAddress = NULL;
  39. LPBYTE pGroupSidAddress = NULL;
  40. LPBYTE pDACLAddress = NULL;
  41. LPBYTE pSACLAddress = NULL;
  42. DWORD dwRet = 0;
  43. VARIANT varDACL;
  44. VARIANT varSACL;
  45. HRESULT hr = S_OK;
  46. DWORD dwRevision = 0;
  47. WORD wControl = 0;
  48. VariantInit(pVarSec);
  49. memset(&varSACL, 0, sizeof(VARIANT));
  50. memset(&varDACL, 0, sizeof(VARIANT));
  51. if (!pSecurityDescriptor) {
  52. RRETURN(E_FAIL);
  53. }
  54. dwRet = GetSecurityDescriptorControl(
  55. pSecurityDescriptor,
  56. &wControl,
  57. &dwRevision
  58. );
  59. if (!dwRet){
  60. hr = HRESULT_FROM_WIN32(GetLastError());
  61. BAIL_ON_FAILURE(hr);
  62. }
  63. dwRet = GetSecurityDescriptorOwner(
  64. pSecurityDescriptor,
  65. (PSID *)&pOwnerSidAddress,
  66. &fOwnerDefaulted
  67. );
  68. if (!dwRet){
  69. hr = HRESULT_FROM_WIN32(GetLastError());
  70. BAIL_ON_FAILURE(hr);
  71. }
  72. hr = ConvertSidToFriendlyName(
  73. pOwnerSidAddress,
  74. &pszOwner
  75. );
  76. BAIL_ON_FAILURE(hr);
  77. dwRet = GetSecurityDescriptorGroup(
  78. pSecurityDescriptor,
  79. (PSID *)&pGroupSidAddress,
  80. &fGroupDefaulted
  81. );
  82. if (!dwRet){
  83. hr = HRESULT_FROM_WIN32(GetLastError());
  84. BAIL_ON_FAILURE(hr);
  85. }
  86. hr = ConvertSidToFriendlyName(
  87. pGroupSidAddress,
  88. &pszGroup
  89. );
  90. BAIL_ON_FAILURE(hr);
  91. dwRet = GetSecurityDescriptorDacl(
  92. pSecurityDescriptor,
  93. &fDaclPresent,
  94. (PACL*)&pDACLAddress,
  95. &fDaclDefaulted
  96. );
  97. if (pDACLAddress) {
  98. hr = ConvertACLToVariant(
  99. (PACL)pDACLAddress,
  100. &varDACL
  101. );
  102. BAIL_ON_FAILURE(hr);
  103. }
  104. dwRet = GetSecurityDescriptorSacl(
  105. pSecurityDescriptor,
  106. &fSaclPresent,
  107. (PACL *)&pSACLAddress,
  108. &fSaclDefaulted
  109. );
  110. if (!dwRet){
  111. hr = HRESULT_FROM_WIN32(GetLastError());
  112. BAIL_ON_FAILURE(hr);
  113. }
  114. if (pSACLAddress) {
  115. hr = ConvertACLToVariant(
  116. (PACL)pSACLAddress,
  117. &varSACL
  118. );
  119. BAIL_ON_FAILURE(hr);
  120. }
  121. hr = CoCreateInstance(
  122. CLSID_SecurityDescriptor,
  123. NULL,
  124. CLSCTX_INPROC_SERVER,
  125. IID_IADsSecurityDescriptor,
  126. (void **)&pSecDes
  127. );
  128. BAIL_ON_FAILURE(hr);
  129. hr = pSecDes->put_Owner(pszOwner);
  130. hr = pSecDes->put_Group(pszGroup);
  131. hr = pSecDes->put_Revision(dwRevision);
  132. hr = pSecDes->put_Control((DWORD)wControl);
  133. hr = pSecDes->put_DiscretionaryAcl(V_DISPATCH(&varDACL));
  134. hr = pSecDes->put_SystemAcl(V_DISPATCH(&varSACL));
  135. hr = pSecDes->QueryInterface(IID_IDispatch, (void**)&pDispatch);
  136. BAIL_ON_FAILURE(hr);
  137. V_VT(pVarSec) = VT_DISPATCH;
  138. V_DISPATCH(pVarSec) = pDispatch;
  139. error:
  140. VariantClear(&varSACL);
  141. VariantClear(&varDACL);
  142. if (pszOwner) {
  143. FreeADsStr(pszOwner);
  144. }
  145. if (pszGroup) {
  146. FreeADsStr(pszGroup);
  147. }
  148. if (pSecDes) {
  149. pSecDes->Release();
  150. }
  151. RRETURN(hr);
  152. }
  153. HRESULT
  154. ConvertSidToFriendlyName(
  155. PSID pSid,
  156. LPWSTR * ppszAccountName
  157. )
  158. {
  159. HRESULT hr = S_OK;
  160. SID_NAME_USE eUse;
  161. WCHAR szAccountName[MAX_PATH];
  162. WCHAR szDomainName[MAX_PATH];
  163. DWORD dwLen = 0;
  164. DWORD dwRet = 0;
  165. LPWSTR pszAccountName = NULL;
  166. DWORD dwAcctLen = 0;
  167. DWORD dwDomainLen = 0;
  168. dwAcctLen = sizeof(szAccountName);
  169. dwDomainLen = sizeof(szDomainName);
  170. dwRet = LookupAccountSid(
  171. NULL,
  172. pSid,
  173. szAccountName,
  174. &dwAcctLen,
  175. szDomainName,
  176. &dwDomainLen,
  177. (PSID_NAME_USE)&eUse
  178. );
  179. if (!dwRet) {
  180. hr = HRESULT_FROM_WIN32(GetLastError());
  181. }else {
  182. dwLen = wcslen(szAccountName) + wcslen(szDomainName) + 1 + 1;
  183. pszAccountName = (LPWSTR)AllocADsMem(dwLen * sizeof(WCHAR));
  184. if (!pszAccountName) {
  185. hr = E_OUTOFMEMORY;
  186. BAIL_ON_FAILURE(hr);
  187. }
  188. if (szDomainName[0] && szAccountName[0]) {
  189. wsprintf(pszAccountName,L"%s\\%s",szDomainName, szAccountName);
  190. }else if (szAccountName[0]) {
  191. wsprintf(pszAccountName,L"%s", szAccountName);
  192. }
  193. }
  194. if (FAILED(hr)) {
  195. hr = ConvertSidToString(
  196. pSid,
  197. szAccountName
  198. );
  199. BAIL_ON_FAILURE(hr);
  200. pszAccountName = AllocADsStr(szAccountName);
  201. if (!pszAccountName) {
  202. hr = E_OUTOFMEMORY;
  203. BAIL_ON_FAILURE(hr);
  204. }
  205. }
  206. *ppszAccountName = pszAccountName;
  207. error:
  208. RRETURN(hr);
  209. }
  210. HRESULT
  211. ConvertACLToVariant(
  212. PACL pACL,
  213. PVARIANT pvarACL
  214. )
  215. {
  216. IADsAccessControlList * pAccessControlList = NULL;
  217. IDispatch * pDispatch = NULL;
  218. VARIANT varAce;
  219. DWORD dwAclSize = 0;
  220. DWORD dwAclRevision = 0;
  221. DWORD dwAceCount = 0;
  222. ACL_SIZE_INFORMATION AclSize;
  223. ACL_REVISION_INFORMATION AclRevision;
  224. DWORD dwStatus = 0;
  225. DWORD i = 0;
  226. DWORD dwNewAceCount = 0;
  227. HRESULT hr = S_OK;
  228. LPBYTE pAceAddress = NULL;
  229. memset(&AclSize, 0, sizeof(ACL_SIZE_INFORMATION));
  230. memset(&AclRevision, 0, sizeof(ACL_REVISION_INFORMATION));
  231. dwStatus = GetAclInformation(
  232. pACL,
  233. &AclSize,
  234. sizeof(ACL_SIZE_INFORMATION),
  235. AclSizeInformation
  236. );
  237. dwStatus = GetAclInformation(
  238. pACL,
  239. &AclRevision,
  240. sizeof(ACL_REVISION_INFORMATION),
  241. AclRevisionInformation
  242. );
  243. dwAceCount = AclSize.AceCount;
  244. dwAclRevision = AclRevision.AclRevision;
  245. VariantInit(pvarACL);
  246. hr = CoCreateInstance(
  247. CLSID_AccessControlList,
  248. NULL,
  249. CLSCTX_INPROC_SERVER,
  250. IID_IADsAccessControlList,
  251. (void **)&pAccessControlList
  252. );
  253. BAIL_ON_FAILURE(hr);
  254. for (i = 0; i < dwAceCount; i++) {
  255. dwStatus = GetAce(pACL, i, (void **)&pAceAddress);
  256. hr = ConvertAceToVariant(
  257. pAceAddress,
  258. (PVARIANT)&varAce
  259. );
  260. hr = pAccessControlList->AddAce(V_DISPATCH(&varAce));
  261. if (SUCCEEDED(hr)) {
  262. dwNewAceCount++;
  263. }
  264. VariantClear(&varAce);
  265. }
  266. pAccessControlList->put_AclRevision(dwAclRevision);
  267. pAccessControlList->put_AceCount(dwNewAceCount);
  268. hr = pAccessControlList->QueryInterface(
  269. IID_IDispatch,
  270. (void **)&pDispatch
  271. );
  272. V_VT(pvarACL) = VT_DISPATCH;
  273. V_DISPATCH(pvarACL) = pDispatch;
  274. error:
  275. if (pAccessControlList) {
  276. pAccessControlList->Release();
  277. }
  278. RRETURN(hr);
  279. }
  280. /* INTRINSA suppress=null_pointers, uninitialized */
  281. HRESULT
  282. ConvertAceToVariant(
  283. PBYTE pAce,
  284. PVARIANT pvarAce
  285. )
  286. {
  287. IADsAccessControlEntry * pAccessControlEntry = NULL;
  288. IDispatch * pDispatch = NULL;
  289. DWORD dwAceType = 0;
  290. DWORD dwAceFlags = 0;
  291. DWORD dwAccessMask = 0;
  292. LPWSTR pszAccountName = NULL;
  293. PACE_HEADER pAceHeader = NULL;
  294. LPBYTE pSidAddress = NULL;
  295. LPBYTE pOffset = NULL;
  296. DWORD dwFlags = 0;
  297. GUID ObjectGUID;
  298. GUID InheritedObjectGUID;
  299. WCHAR szObjectGUID[MAX_PATH];
  300. WCHAR szInheritedObjectGUID[MAX_PATH];
  301. HRESULT hr = S_OK;
  302. szObjectGUID[0] = L'\0';
  303. szInheritedObjectGUID[0] = L'\0';
  304. VariantInit(pvarAce);
  305. hr = CoCreateInstance(
  306. CLSID_AccessControlEntry,
  307. NULL,
  308. CLSCTX_INPROC_SERVER,
  309. IID_IADsAccessControlEntry,
  310. (void **)&pAccessControlEntry
  311. );
  312. BAIL_ON_FAILURE(hr);
  313. pAceHeader = (ACE_HEADER *)pAce;
  314. dwAceType = pAceHeader->AceType;
  315. dwAceFlags = pAceHeader->AceFlags;
  316. dwAccessMask = *(PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  317. switch (dwAceType) {
  318. case ACCESS_ALLOWED_ACE_TYPE:
  319. case ACCESS_DENIED_ACE_TYPE:
  320. case SYSTEM_AUDIT_ACE_TYPE:
  321. case SYSTEM_ALARM_ACE_TYPE:
  322. pSidAddress = (LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK);
  323. break;
  324. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  325. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  326. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  327. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  328. pOffset = (LPBYTE)((LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
  329. dwFlags = (DWORD)(*(PDWORD)pOffset);
  330. //
  331. // Now advance by the size of the flags
  332. //
  333. pOffset += sizeof(ULONG);
  334. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  335. memcpy(&ObjectGUID, pOffset, sizeof(GUID));
  336. StringFromGUID2(ObjectGUID, szObjectGUID, MAX_PATH);
  337. pOffset += sizeof (GUID);
  338. }
  339. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  340. memcpy(&InheritedObjectGUID, pOffset, sizeof(GUID));
  341. StringFromGUID2(InheritedObjectGUID, szInheritedObjectGUID, MAX_PATH);
  342. pOffset += sizeof (GUID);
  343. }
  344. pSidAddress = pOffset;
  345. break;
  346. default:
  347. break;
  348. }
  349. hr = ConvertSidToFriendlyName(
  350. pSidAddress,
  351. &pszAccountName
  352. );
  353. if (FAILED(hr)){
  354. pszAccountName = AllocADsStr(L"Unknown Trustee");
  355. }
  356. //
  357. // Now set all the information in the Access Control Entry
  358. //
  359. hr = pAccessControlEntry->put_AccessMask(dwAccessMask);
  360. hr = pAccessControlEntry->put_AceFlags(dwAceFlags);
  361. hr = pAccessControlEntry->put_AceType(dwAceType);
  362. //
  363. // Extended ACE information
  364. //
  365. hr = pAccessControlEntry->put_Flags(dwFlags);
  366. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  367. //
  368. // Add in the Object Type GUID
  369. //
  370. hr = pAccessControlEntry->put_ObjectType(szObjectGUID);
  371. }
  372. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  373. //
  374. // Add in the Inherited Object Type GUID
  375. //
  376. hr = pAccessControlEntry->put_InheritedObjectType(szInheritedObjectGUID);
  377. }
  378. hr = pAccessControlEntry->put_Trustee(pszAccountName);
  379. hr = pAccessControlEntry->QueryInterface(
  380. IID_IDispatch,
  381. (void **)&pDispatch
  382. );
  383. BAIL_ON_FAILURE(hr);
  384. V_DISPATCH(pvarAce) = pDispatch;
  385. V_VT(pvarAce) = VT_DISPATCH;
  386. cleanup:
  387. if (pszAccountName) {
  388. FreeADsStr(pszAccountName);
  389. }
  390. if (pAccessControlEntry) {
  391. pAccessControlEntry->Release();
  392. }
  393. RRETURN(hr);
  394. error:
  395. if (pDispatch) {
  396. pDispatch->Release();
  397. }
  398. goto cleanup;
  399. }
  400. HRESULT
  401. ConvertSidToString(
  402. PSID pSid,
  403. LPWSTR String
  404. )
  405. /*++
  406. Routine Description:
  407. This function generates a printable unicode string representation
  408. of a SID.
  409. The resulting string will take one of two forms. If the
  410. IdentifierAuthority value is not greater than 2^32, then
  411. the SID will be in the form:
  412. S-1-281736-12-72-9-110
  413. ^ ^^ ^^ ^ ^^^
  414. | | | | |
  415. +-----+--+-+--+---- Decimal
  416. Otherwise it will take the form:
  417. S-1-0x173495281736-12-72-9-110
  418. ^^^^^^^^^^^^^^ ^^ ^^ ^ ^^^
  419. Hexidecimal | | | |
  420. +--+-+--+---- Decimal
  421. Arguments:
  422. pSid - opaque pointer that supplies the SID that is to be
  423. converted to Unicode.
  424. Return Value:
  425. If the Sid is successfully converted to a Unicode string, a
  426. pointer to the Unicode string is returned, else NULL is
  427. returned.
  428. --*/
  429. {
  430. WCHAR Buffer[256];
  431. UCHAR i;
  432. ULONG Tmp;
  433. HRESULT hr = S_OK;
  434. SID_IDENTIFIER_AUTHORITY *pSidIdentifierAuthority;
  435. PUCHAR pSidSubAuthorityCount;
  436. if (!IsValidSid( pSid )) {
  437. *String= L'\0';
  438. hr = HRESULT_FROM_WIN32(ERROR_INVALID_SID);
  439. RRETURN(hr);
  440. }
  441. wsprintf(Buffer, L"S-%u-", (USHORT)(((PISID)pSid)->Revision ));
  442. wcscpy(String, Buffer);
  443. pSidIdentifierAuthority = GetSidIdentifierAuthority(pSid);
  444. if ( (pSidIdentifierAuthority->Value[0] != 0) ||
  445. (pSidIdentifierAuthority->Value[1] != 0) ){
  446. wsprintf(Buffer, L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
  447. (USHORT)pSidIdentifierAuthority->Value[0],
  448. (USHORT)pSidIdentifierAuthority->Value[1],
  449. (USHORT)pSidIdentifierAuthority->Value[2],
  450. (USHORT)pSidIdentifierAuthority->Value[3],
  451. (USHORT)pSidIdentifierAuthority->Value[4],
  452. (USHORT)pSidIdentifierAuthority->Value[5] );
  453. wcscat(String, Buffer);
  454. } else {
  455. Tmp = (ULONG)pSidIdentifierAuthority->Value[5] +
  456. (ULONG)(pSidIdentifierAuthority->Value[4] << 8) +
  457. (ULONG)(pSidIdentifierAuthority->Value[3] << 16) +
  458. (ULONG)(pSidIdentifierAuthority->Value[2] << 24);
  459. wsprintf(Buffer, L"%lu", Tmp);
  460. wcscat(String, Buffer);
  461. }
  462. pSidSubAuthorityCount = GetSidSubAuthorityCount(pSid);
  463. for (i=0;i< *(pSidSubAuthorityCount);i++ ) {
  464. wsprintf(Buffer, L"-%lu", *(GetSidSubAuthority(pSid, i)));
  465. wcscat(String, Buffer);
  466. }
  467. RRETURN(S_OK);
  468. }