Leaked source code of windows server 2003
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.

650 lines
15 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 = (DWORD)(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. if (wcslen(szAccountName)>=MAX_PATH)
  192. {
  193. hr = E_ADS_BAD_PARAMETER;
  194. BAIL_ON_FAILURE(hr);
  195. }
  196. wcscpy(pszAccountName, szAccountName);
  197. }
  198. }
  199. if (FAILED(hr)) {
  200. hr = ConvertSidToString(
  201. pSid,
  202. szAccountName
  203. );
  204. BAIL_ON_FAILURE(hr);
  205. pszAccountName = AllocADsStr(szAccountName);
  206. if (!pszAccountName) {
  207. hr = E_OUTOFMEMORY;
  208. BAIL_ON_FAILURE(hr);
  209. }
  210. }
  211. *ppszAccountName = pszAccountName;
  212. error:
  213. RRETURN(hr);
  214. }
  215. HRESULT
  216. ConvertACLToVariant(
  217. PACL pACL,
  218. PVARIANT pvarACL
  219. )
  220. {
  221. IADsAccessControlList * pAccessControlList = NULL;
  222. IDispatch * pDispatch = NULL;
  223. VARIANT varAce;
  224. DWORD dwAclSize = 0;
  225. DWORD dwAclRevision = 0;
  226. DWORD dwAceCount = 0;
  227. ACL_SIZE_INFORMATION AclSize;
  228. ACL_REVISION_INFORMATION AclRevision;
  229. DWORD dwStatus = 0;
  230. DWORD i = 0;
  231. DWORD dwNewAceCount = 0;
  232. HRESULT hr = S_OK;
  233. LPBYTE pAceAddress = NULL;
  234. memset(&AclSize, 0, sizeof(ACL_SIZE_INFORMATION));
  235. memset(&AclRevision, 0, sizeof(ACL_REVISION_INFORMATION));
  236. dwStatus = GetAclInformation(
  237. pACL,
  238. &AclSize,
  239. sizeof(ACL_SIZE_INFORMATION),
  240. AclSizeInformation
  241. );
  242. dwStatus = GetAclInformation(
  243. pACL,
  244. &AclRevision,
  245. sizeof(ACL_REVISION_INFORMATION),
  246. AclRevisionInformation
  247. );
  248. dwAceCount = AclSize.AceCount;
  249. dwAclRevision = AclRevision.AclRevision;
  250. VariantInit(pvarACL);
  251. hr = CoCreateInstance(
  252. CLSID_AccessControlList,
  253. NULL,
  254. CLSCTX_INPROC_SERVER,
  255. IID_IADsAccessControlList,
  256. (void **)&pAccessControlList
  257. );
  258. BAIL_ON_FAILURE(hr);
  259. for (i = 0; i < dwAceCount; i++) {
  260. dwStatus = GetAce(pACL, i, (void **)&pAceAddress);
  261. hr = ConvertAceToVariant(
  262. pAceAddress,
  263. (PVARIANT)&varAce
  264. );
  265. hr = pAccessControlList->AddAce(V_DISPATCH(&varAce));
  266. if (SUCCEEDED(hr)) {
  267. dwNewAceCount++;
  268. }
  269. VariantClear(&varAce);
  270. }
  271. pAccessControlList->put_AclRevision(dwAclRevision);
  272. pAccessControlList->put_AceCount(dwNewAceCount);
  273. hr = pAccessControlList->QueryInterface(
  274. IID_IDispatch,
  275. (void **)&pDispatch
  276. );
  277. V_VT(pvarACL) = VT_DISPATCH;
  278. V_DISPATCH(pvarACL) = pDispatch;
  279. error:
  280. if (pAccessControlList) {
  281. pAccessControlList->Release();
  282. }
  283. RRETURN(hr);
  284. }
  285. /* INTRINSA suppress=null_pointers, uninitialized */
  286. HRESULT
  287. ConvertAceToVariant(
  288. PBYTE pAce,
  289. PVARIANT pvarAce
  290. )
  291. {
  292. IADsAccessControlEntry * pAccessControlEntry = NULL;
  293. IDispatch * pDispatch = NULL;
  294. DWORD dwAceType = 0;
  295. DWORD dwAceFlags = 0;
  296. DWORD dwAccessMask = 0;
  297. LPWSTR pszAccountName = NULL;
  298. PACE_HEADER pAceHeader = NULL;
  299. LPBYTE pSidAddress = NULL;
  300. LPBYTE pOffset = NULL;
  301. DWORD dwFlags = 0;
  302. GUID ObjectGUID;
  303. GUID InheritedObjectGUID;
  304. WCHAR szObjectGUID[MAX_PATH];
  305. WCHAR szInheritedObjectGUID[MAX_PATH];
  306. HRESULT hr = S_OK;
  307. szObjectGUID[0] = L'\0';
  308. szInheritedObjectGUID[0] = L'\0';
  309. VariantInit(pvarAce);
  310. hr = CoCreateInstance(
  311. CLSID_AccessControlEntry,
  312. NULL,
  313. CLSCTX_INPROC_SERVER,
  314. IID_IADsAccessControlEntry,
  315. (void **)&pAccessControlEntry
  316. );
  317. BAIL_ON_FAILURE(hr);
  318. pAceHeader = (ACE_HEADER *)pAce;
  319. dwAceType = pAceHeader->AceType;
  320. dwAceFlags = pAceHeader->AceFlags;
  321. dwAccessMask = *(PACCESS_MASK)((LPBYTE)pAceHeader + sizeof(ACE_HEADER));
  322. switch (dwAceType) {
  323. case ACCESS_ALLOWED_ACE_TYPE:
  324. case ACCESS_DENIED_ACE_TYPE:
  325. case SYSTEM_AUDIT_ACE_TYPE:
  326. case SYSTEM_ALARM_ACE_TYPE:
  327. pSidAddress = (LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK);
  328. break;
  329. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  330. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  331. case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
  332. case SYSTEM_ALARM_OBJECT_ACE_TYPE:
  333. pOffset = (LPBYTE)((LPBYTE)pAceHeader + sizeof(ACE_HEADER) + sizeof(ACCESS_MASK));
  334. dwFlags = (DWORD)(*(PDWORD)pOffset);
  335. //
  336. // Now advance by the size of the flags
  337. //
  338. pOffset += sizeof(ULONG);
  339. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  340. memcpy(&ObjectGUID, pOffset, sizeof(GUID));
  341. StringFromGUID2(ObjectGUID, szObjectGUID, MAX_PATH);
  342. pOffset += sizeof (GUID);
  343. }
  344. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  345. memcpy(&InheritedObjectGUID, pOffset, sizeof(GUID));
  346. StringFromGUID2(InheritedObjectGUID, szInheritedObjectGUID, MAX_PATH);
  347. pOffset += sizeof (GUID);
  348. }
  349. pSidAddress = pOffset;
  350. break;
  351. default:
  352. break;
  353. }
  354. hr = ConvertSidToFriendlyName(
  355. pSidAddress,
  356. &pszAccountName
  357. );
  358. if (FAILED(hr)){
  359. pszAccountName = AllocADsStr(L"Unknown Trustee");
  360. }
  361. //
  362. // Now set all the information in the Access Control Entry
  363. //
  364. hr = pAccessControlEntry->put_AccessMask(dwAccessMask);
  365. hr = pAccessControlEntry->put_AceFlags(dwAceFlags);
  366. hr = pAccessControlEntry->put_AceType(dwAceType);
  367. //
  368. // Extended ACE information
  369. //
  370. hr = pAccessControlEntry->put_Flags(dwFlags);
  371. if (dwFlags & ACE_OBJECT_TYPE_PRESENT) {
  372. //
  373. // Add in the Object Type GUID
  374. //
  375. hr = pAccessControlEntry->put_ObjectType(szObjectGUID);
  376. }
  377. if (dwFlags & ACE_INHERITED_OBJECT_TYPE_PRESENT) {
  378. //
  379. // Add in the Inherited Object Type GUID
  380. //
  381. hr = pAccessControlEntry->put_InheritedObjectType(szInheritedObjectGUID);
  382. }
  383. hr = pAccessControlEntry->put_Trustee(pszAccountName);
  384. hr = pAccessControlEntry->QueryInterface(
  385. IID_IDispatch,
  386. (void **)&pDispatch
  387. );
  388. BAIL_ON_FAILURE(hr);
  389. V_DISPATCH(pvarAce) = pDispatch;
  390. V_VT(pvarAce) = VT_DISPATCH;
  391. cleanup:
  392. if (pszAccountName) {
  393. FreeADsStr(pszAccountName);
  394. }
  395. if (pAccessControlEntry) {
  396. pAccessControlEntry->Release();
  397. }
  398. RRETURN(hr);
  399. error:
  400. if (pDispatch) {
  401. pDispatch->Release();
  402. }
  403. goto cleanup;
  404. }
  405. HRESULT
  406. ConvertSidToString(
  407. PSID pSid,
  408. LPWSTR String
  409. )
  410. /*++
  411. Routine Description:
  412. This function generates a printable unicode string representation
  413. of a SID.
  414. The resulting string will take one of two forms. If the
  415. IdentifierAuthority value is not greater than 2^32, then
  416. the SID will be in the form:
  417. S-1-281736-12-72-9-110
  418. ^ ^^ ^^ ^ ^^^
  419. | | | | |
  420. +-----+--+-+--+---- Decimal
  421. Otherwise it will take the form:
  422. S-1-0x173495281736-12-72-9-110
  423. ^^^^^^^^^^^^^^ ^^ ^^ ^ ^^^
  424. Hexidecimal | | | |
  425. +--+-+--+---- Decimal
  426. Arguments:
  427. pSid - opaque pointer that supplies the SID that is to be
  428. converted to Unicode.
  429. Return Value:
  430. If the Sid is successfully converted to a Unicode string, a
  431. pointer to the Unicode string is returned, else NULL is
  432. returned.
  433. --*/
  434. {
  435. WCHAR Buffer[256];
  436. UCHAR i;
  437. ULONG Tmp;
  438. HRESULT hr = S_OK;
  439. SID_IDENTIFIER_AUTHORITY *pSidIdentifierAuthority;
  440. PUCHAR pSidSubAuthorityCount;
  441. if (!IsValidSid( pSid )) {
  442. *String= L'\0';
  443. hr = HRESULT_FROM_WIN32(ERROR_INVALID_SID);
  444. RRETURN(hr);
  445. }
  446. wsprintf(Buffer, L"S-%u-", (USHORT)(((PISID)pSid)->Revision ));
  447. wcscpy(String, Buffer);
  448. pSidIdentifierAuthority = GetSidIdentifierAuthority(pSid);
  449. if ( (pSidIdentifierAuthority->Value[0] != 0) ||
  450. (pSidIdentifierAuthority->Value[1] != 0) ){
  451. wsprintf(Buffer, L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
  452. (USHORT)pSidIdentifierAuthority->Value[0],
  453. (USHORT)pSidIdentifierAuthority->Value[1],
  454. (USHORT)pSidIdentifierAuthority->Value[2],
  455. (USHORT)pSidIdentifierAuthority->Value[3],
  456. (USHORT)pSidIdentifierAuthority->Value[4],
  457. (USHORT)pSidIdentifierAuthority->Value[5] );
  458. wcscat(String, Buffer);
  459. } else {
  460. Tmp = (ULONG)pSidIdentifierAuthority->Value[5] +
  461. (ULONG)(pSidIdentifierAuthority->Value[4] << 8) +
  462. (ULONG)(pSidIdentifierAuthority->Value[3] << 16) +
  463. (ULONG)(pSidIdentifierAuthority->Value[2] << 24);
  464. wsprintf(Buffer, L"%lu", Tmp);
  465. wcscat(String, Buffer);
  466. }
  467. pSidSubAuthorityCount = GetSidSubAuthorityCount(pSid);
  468. for (i=0;i< *(pSidSubAuthorityCount);i++ ) {
  469. wsprintf(Buffer, L"-%lu", *(GetSidSubAuthority(pSid, i)));
  470. wcscat(String, Buffer);
  471. }
  472. RRETURN(S_OK);
  473. }