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.

1043 lines
36 KiB

  1. #include "stdafx.h"
  2. #include <ole2.h>
  3. #include <aclapi.h>
  4. #include "iadmw.h"
  5. #include "iiscnfg.h"
  6. #include "log.h"
  7. #include "mdkey.h"
  8. #include "dcomperm.h"
  9. #include "other.h"
  10. #include "mdacl.h"
  11. #include <sddl.h> // ConvertSidToStringSid
  12. extern int g_GlobalDebugCrypto;
  13. #ifndef _CHICAGO_
  14. BOOL CleanAdminACL(SECURITY_DESCRIPTOR *pSD)
  15. {
  16. // iisDebugOut((LOG_TYPE_TRACE, _T("CleanAdminACL(): Start.\n")));
  17. BOOL fSetData = FALSE;
  18. BOOL b= FALSE, bDaclPresent = FALSE, bDaclDefaulted = FALSE;;
  19. PACL pDacl = NULL;
  20. LPVOID pAce = NULL;
  21. int i = 0;
  22. ACE_HEADER *pAceHeader;
  23. ACCESS_MASK dwOldMask, dwNewMask, dwExtraMask, dwMask;
  24. dwMask = (MD_ACR_READ |
  25. MD_ACR_WRITE |
  26. MD_ACR_RESTRICTED_WRITE |
  27. MD_ACR_UNSECURE_PROPS_READ |
  28. MD_ACR_ENUM_KEYS |
  29. MD_ACR_WRITE_DAC);
  30. b = GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDacl, &bDaclDefaulted);
  31. if (NULL == pDacl)
  32. {
  33. return FALSE;
  34. }
  35. if (b) {
  36. //iisDebugOut((LOG_TYPE_TRACE, _T("CleanAdminACL:ACE count: %d\n"), (int)pDacl->AceCount));
  37. for (i=0; i<(int)pDacl->AceCount; i++) {
  38. b = GetAce(pDacl, i, &pAce);
  39. if (b) {
  40. pAceHeader = (ACE_HEADER *)pAce;
  41. switch (pAceHeader->AceType) {
  42. case ACCESS_ALLOWED_ACE_TYPE:
  43. dwOldMask = ((ACCESS_ALLOWED_ACE *)pAce)->Mask;
  44. dwExtraMask = dwOldMask & (~dwMask);
  45. if (dwExtraMask) {
  46. fSetData = TRUE;
  47. dwNewMask = dwOldMask & dwMask;
  48. ((ACCESS_ALLOWED_ACE *)pAce)->Mask = dwNewMask;
  49. }
  50. break;
  51. case ACCESS_DENIED_ACE_TYPE:
  52. dwOldMask = ((ACCESS_DENIED_ACE *)pAce)->Mask;
  53. dwExtraMask = dwOldMask & (~dwMask);
  54. if (dwExtraMask) {
  55. fSetData = TRUE;
  56. dwNewMask = dwOldMask & dwMask;
  57. ((ACCESS_DENIED_ACE *)pAce)->Mask = dwNewMask;
  58. }
  59. break;
  60. case SYSTEM_AUDIT_ACE_TYPE:
  61. dwOldMask = ((SYSTEM_AUDIT_ACE *)pAce)->Mask;
  62. dwExtraMask = dwOldMask & (~dwMask);
  63. if (dwExtraMask) {
  64. fSetData = TRUE;
  65. dwNewMask = dwOldMask & dwMask;
  66. ((SYSTEM_AUDIT_ACE *)pAce)->Mask = dwNewMask;
  67. }
  68. break;
  69. default:
  70. break;
  71. }
  72. } else {
  73. //iisDebugOut((LOG_TYPE_TRACE, _T("CleanAdminACL:GetAce:err=%x\n"), GetLastError()));
  74. }
  75. }
  76. } else {
  77. //iisDebugOut((LOG_TYPE_TRACE, _T("CleanAdminACL:GetSecurityDescriptorDacl:err=%x\n"), GetLastError()));
  78. }
  79. //iisDebugOut_End(_T("CleanAdminACL"),LOG_TYPE_TRACE);
  80. return (fSetData);
  81. }
  82. void FixAdminACL(LPTSTR szKeyPath)
  83. {
  84. // iisDebugOutSafeParams((LOG_TYPE_TRACE, _T("FixAdminACL Path=%1!s!. Start.\n"), szKeyPath));
  85. BOOL bFound = FALSE, b = FALSE;
  86. DWORD attr, uType, dType, cbLen;
  87. CMDKey cmdKey;
  88. BUFFER bufData;
  89. CString csName, csValue;
  90. PBYTE pData;
  91. int BufSize;
  92. SECURITY_DESCRIPTOR *pSD;
  93. cmdKey.OpenNode(szKeyPath);
  94. if ( (METADATA_HANDLE)cmdKey )
  95. {
  96. pData = (PBYTE)(bufData.QueryPtr());
  97. BufSize = bufData.QuerySize();
  98. cbLen = 0;
  99. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  100. if (!bFound && (cbLen > 0))
  101. {
  102. if ( ! (bufData.Resize(cbLen)) )
  103. {
  104. cmdKey.Close();
  105. return; // insufficient memory
  106. }
  107. else
  108. {
  109. pData = (PBYTE)(bufData.QueryPtr());
  110. BufSize = cbLen;
  111. cbLen = 0;
  112. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  113. }
  114. }
  115. cmdKey.Close();
  116. if (bFound && (dType == BINARY_METADATA))
  117. {
  118. pSD = (SECURITY_DESCRIPTOR *)pData;
  119. b = CleanAdminACL(pSD);
  120. if (b)
  121. {
  122. // need to reset the data
  123. DWORD dwLength = GetSecurityDescriptorLength(pSD);
  124. cmdKey.OpenNode(szKeyPath);
  125. if ( (METADATA_HANDLE)cmdKey )
  126. {
  127. cmdKey.SetData(MD_ADMIN_ACL,METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE,IIS_MD_UT_SERVER,BINARY_METADATA,dwLength,(LPBYTE)pSD);
  128. cmdKey.Close();
  129. }
  130. }
  131. }
  132. }
  133. //iisDebugOut_End1(_T("FixAdminACL"),szKeyPath,LOG_TYPE_TRACE);
  134. return;
  135. }
  136. #endif //_CHICAGO_
  137. #ifndef _CHICAGO_
  138. DWORD SetAdminACL(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount)
  139. {
  140. iisDebugOut_Start1(_T("SetAdminACL"), szKeyPath, LOG_TYPE_TRACE);
  141. int iErr=0;
  142. DWORD dwErr=0;
  143. DWORD dwRetCode = ERROR_SUCCESS;
  144. BOOL b = FALSE;
  145. DWORD dwLength = 0;
  146. PSECURITY_DESCRIPTOR pSD = NULL;
  147. PSECURITY_DESCRIPTOR outpSD = NULL;
  148. DWORD cboutpSD = 0;
  149. PACL pACLNew = NULL;
  150. DWORD cbACL = 0;
  151. PSID pAdminsSID = NULL, pEveryoneSID = NULL;
  152. BOOL bWellKnownSID = FALSE;
  153. // Initialize a new security descriptor
  154. pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);
  155. if (!pSD)
  156. {
  157. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:LocalAlloc FAILED.out of memory. GetLastError()= 0x%x\n"), ERROR_NOT_ENOUGH_MEMORY));
  158. dwRetCode = ERROR_OUTOFMEMORY;
  159. goto Cleanup;
  160. }
  161. iErr = InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION);
  162. if (iErr == 0)
  163. {
  164. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:InitializeSecurityDescriptor FAILED. GetLastError()= 0x%x\n"), GetLastError() ));
  165. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  166. goto Cleanup;
  167. }
  168. // Get Local Admins Sid
  169. dwErr = GetPrincipalSID (_T("Administrators"), &pAdminsSID, &bWellKnownSID);
  170. if (dwErr != ERROR_SUCCESS)
  171. {
  172. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:GetPrincipalSID(Administrators) FAILED. Return Code = 0x%x\n"), dwErr));
  173. dwRetCode = dwErr;
  174. goto Cleanup;
  175. }
  176. // Get everyone Sid
  177. dwErr = GetPrincipalSID (_T("Everyone"), &pEveryoneSID, &bWellKnownSID);
  178. if (dwErr != ERROR_SUCCESS)
  179. {
  180. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:GetPrincipalSID(Everyone) FAILED. Return Code = 0x%x\n"), dwErr));
  181. dwRetCode = dwErr;
  182. goto Cleanup;
  183. }
  184. // Calculate the length needed for the ACL
  185. cbACL = sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pAdminsSID) - sizeof(DWORD));
  186. if ( dwAccessForEveryoneAccount != 0x00 )
  187. {
  188. // Add room for everyone ACL
  189. cbACL += sizeof(ACCESS_ALLOWED_ACE) + GetLengthSid(pEveryoneSID) - sizeof(DWORD);
  190. }
  191. pACLNew = (PACL) LocalAlloc(LPTR, cbACL);
  192. if ( !pACLNew )
  193. {
  194. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:pACLNew LocalAlloc(LPTR, FAILED. size = %u GetLastError()= 0x%x\n"), cbACL, GetLastError()));
  195. dwRetCode = ERROR_OUTOFMEMORY;
  196. goto Cleanup;
  197. }
  198. if (!InitializeAcl(pACLNew, cbACL, ACL_REVISION))
  199. {
  200. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:InitializeAcl FAILED. GetLastError()= 0x%x\n"), GetLastError));
  201. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  202. goto Cleanup;
  203. }
  204. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,(MD_ACR_READ |MD_ACR_WRITE |MD_ACR_RESTRICTED_WRITE |MD_ACR_UNSECURE_PROPS_READ |MD_ACR_ENUM_KEYS |MD_ACR_WRITE_DAC),pAdminsSID))
  205. {
  206. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:AddAccessAllowedAce(pAdminsSID) FAILED. GetLastError()= 0x%x\n"), GetLastError));
  207. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  208. goto Cleanup;
  209. }
  210. if ( dwAccessForEveryoneAccount != 0x00 )
  211. {
  212. if (!AddAccessAllowedAce(pACLNew,ACL_REVISION,dwAccessForEveryoneAccount,pEveryoneSID))
  213. {
  214. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:AddAccessAllowedAce(pEveryoneSID) FAILED. GetLastError()= 0x%x\n"), GetLastError()));
  215. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  216. goto Cleanup;
  217. }
  218. }
  219. // Add the ACL to the security descriptor
  220. b = SetSecurityDescriptorDacl(pSD, TRUE, pACLNew, FALSE);
  221. if (!b)
  222. {
  223. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:SetSecurityDescriptorDacl(pACLNew) FAILED. GetLastError()= 0x%x\n"), GetLastError()));
  224. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  225. goto Cleanup;
  226. }
  227. b = SetSecurityDescriptorOwner(pSD, pAdminsSID, TRUE);
  228. if (!b)
  229. {
  230. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:SetSecurityDescriptorOwner(pAdminsSID) FAILED. GetLastError()= 0x%x\n"), GetLastError()));
  231. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  232. goto Cleanup;
  233. }
  234. b = SetSecurityDescriptorGroup(pSD, pAdminsSID, TRUE);
  235. if (!b)
  236. {
  237. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:SetSecurityDescriptorGroup(pAdminsSID) FAILED. GetLastError()= 0x%x\n"), GetLastError()));
  238. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  239. goto Cleanup;
  240. }
  241. // Security descriptor blob must be self relative
  242. b = MakeSelfRelativeSD(pSD, outpSD, &cboutpSD);
  243. outpSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(GPTR, cboutpSD);
  244. if ( !outpSD )
  245. {
  246. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:GlobalAlloc FAILED. cboutpSD = %u GetLastError()= 0x%x\n"), cboutpSD, GetLastError()));
  247. dwRetCode = ERROR_OUTOFMEMORY;
  248. goto Cleanup;
  249. }
  250. b = MakeSelfRelativeSD( pSD, outpSD, &cboutpSD );
  251. if (!b)
  252. {
  253. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:MakeSelfRelativeSD() FAILED. cboutpSD = %u GetLastError()= 0x%x\n"),cboutpSD, GetLastError()));
  254. dwRetCode = GetLastError() != ERROR_SUCCESS ? GetLastError() : ERROR_OUTOFMEMORY;
  255. goto Cleanup;
  256. }
  257. if (outpSD)
  258. {
  259. if (IsValidSecurityDescriptor(outpSD))
  260. {
  261. // Apply the new security descriptor to the metabase
  262. iisDebugOut_Start(_T("SetAdminACL:Write the new security descriptor to the Metabase"),LOG_TYPE_TRACE);
  263. iisDebugOut((LOG_TYPE_TRACE, _T("SetAdminACL: At this point we have already been able to write basic entries to the metabase, so...")));
  264. iisDebugOut((LOG_TYPE_TRACE, _T("SetAdminACL: If this has a problem then there is a problem with setting up encryption for the metabase (Crypto).")));
  265. //DoesAdminACLExist(szKeyPath);
  266. if (g_GlobalDebugCrypto == 2)
  267. {
  268. // if we want to call this over and over...
  269. do
  270. {
  271. dwRetCode = WriteSDtoMetaBase(outpSD, szKeyPath);
  272. if (FAILED(dwRetCode))
  273. {
  274. OutputDebugString(_T("\nCalling WriteSDtoMetaBase again...Set iis!g_GlobalDebugCrypto to 0 to stop looping on failure."));
  275. OutputDebugString(_T("\nSet iis!g_GlobalDebugCrypto to 0 to stop looping on crypto failure.\n"));
  276. }
  277. } while (FAILED(dwRetCode) && g_GlobalDebugCrypto == 2);
  278. }
  279. else
  280. {
  281. dwRetCode = WriteSDtoMetaBase(outpSD, szKeyPath);
  282. }
  283. //DoesAdminACLExist(szKeyPath);
  284. iisDebugOut_End(_T("SetAdminACL:Write the new security descriptor to the Metabase"),LOG_TYPE_TRACE);
  285. }
  286. else
  287. {
  288. iisDebugOut((LOG_TYPE_ERROR, _T("SetAdminACL:IsValidSecurityDescriptor.4.SelfRelative(%u) FAILED!"),outpSD));
  289. }
  290. }
  291. if (outpSD){GlobalFree(outpSD);outpSD=NULL;}
  292. Cleanup:
  293. // both of Administrators and Everyone are well-known SIDs, use FreeSid() to free them.
  294. if (pAdminsSID){FreeSid(pAdminsSID);}
  295. if (pEveryoneSID){FreeSid(pEveryoneSID);}
  296. if (pSD){LocalFree((HLOCAL) pSD);}
  297. if (pACLNew){LocalFree((HLOCAL) pACLNew);}
  298. iisDebugOut_End1(_T("SetAdminACL"),szKeyPath,LOG_TYPE_TRACE);
  299. return (dwRetCode);
  300. }
  301. DWORD SetAdminACL_wrap(LPCTSTR szKeyPath, DWORD dwAccessForEveryoneAccount, BOOL bDisplayMsgOnErrFlag)
  302. {
  303. int bFinishedFlag = FALSE;
  304. UINT iMsg = NULL;
  305. DWORD dwReturn = ERROR_SUCCESS;
  306. LogHeapState(FALSE, __FILE__, __LINE__);
  307. do
  308. {
  309. dwReturn = SetAdminACL(szKeyPath, dwAccessForEveryoneAccount);
  310. LogHeapState(FALSE, __FILE__, __LINE__);
  311. if (FAILED(dwReturn))
  312. {
  313. if (bDisplayMsgOnErrFlag == TRUE)
  314. {
  315. iMsg = MyMessageBox( NULL, IDS_RETRY, MB_ABORTRETRYIGNORE | MB_SETFOREGROUND );
  316. switch ( iMsg )
  317. {
  318. case IDIGNORE:
  319. dwReturn = ERROR_SUCCESS;
  320. goto SetAdminACL_wrap_Exit;
  321. case IDABORT:
  322. dwReturn = ERROR_OPERATION_ABORTED;
  323. goto SetAdminACL_wrap_Exit;
  324. case IDRETRY:
  325. break;
  326. default:
  327. break;
  328. }
  329. }
  330. else
  331. {
  332. // return whatever err happened
  333. goto SetAdminACL_wrap_Exit;
  334. }
  335. }
  336. else
  337. {
  338. break;
  339. }
  340. } while ( FAILED(dwReturn) );
  341. SetAdminACL_wrap_Exit:
  342. return dwReturn;
  343. }
  344. #endif
  345. #ifndef _CHICAGO_
  346. DWORD WriteSDtoMetaBase(PSECURITY_DESCRIPTOR outpSD, LPCTSTR szKeyPath)
  347. {
  348. iisDebugOut_Start(_T("WriteSDtoMetaBase"), LOG_TYPE_TRACE);
  349. DWORD dwReturn = ERROR_ACCESS_DENIED;
  350. DWORD dwLength = 0;
  351. DWORD dwMDFlags = 0;
  352. CMDKey cmdKey;
  353. HRESULT hReturn = E_FAIL;
  354. int iSavedFlag = 0;
  355. dwMDFlags = METADATA_INHERIT | METADATA_REFERENCE | METADATA_SECURE,IIS_MD_UT_SERVER,BINARY_METADATA;
  356. iSavedFlag = g_GlobalDebugCrypto;
  357. if (!outpSD)
  358. {
  359. dwReturn = ERROR_INVALID_SECURITY_DESCR;
  360. goto WriteSDtoMetaBase_Exit;
  361. }
  362. // Apply the new security descriptor to the metabase
  363. dwLength = GetSecurityDescriptorLength(outpSD);
  364. // open the metabase
  365. // stick it into the metabase. warning those hoses a lot because
  366. // it uses encryption. rsabase.dll
  367. // Check for special debug flag in metabase to break right before this call!
  368. if (g_GlobalDebugCrypto != 0)
  369. {
  370. // special flag to say... hey "stop setup so that the crypto team can debug they're stuff"
  371. iisDebugOut((LOG_TYPE_TRACE, _T("Breakpoint enabled thru setup (to debug crypto api). look at debugoutput.")));
  372. OutputDebugString(_T("\n\nBreakpoint enabled thru setup (to debug crypto api)"));
  373. OutputDebugString(_T("\n1.in this process:"));
  374. OutputDebugString(_T("\n set breakpoint on admwprox!IcpGetContainerHelper"));
  375. OutputDebugString(_T("\n set breakpoint on advapi32!CryptAcquireContextW"));
  376. OutputDebugString(_T("\n IcpGetKeyHelper will call CryptAcquireContext and try to open an existing key container,"));
  377. OutputDebugString(_T("\n if it doesn't exist it will return NTE_BAD_KEYSET, and IcpGetContainerHelper will try to create the container."));
  378. OutputDebugString(_T("\n2.in the inetinfo process:"));
  379. OutputDebugString(_T("\n set breakpoint on admwprox!IcpGetContainerHelper"));
  380. OutputDebugString(_T("\n set breakpoint on advapi32!CryptAcquireContextW\n"));
  381. }
  382. hReturn = cmdKey.CreateNode(METADATA_MASTER_ROOT_HANDLE, szKeyPath);
  383. if ( (METADATA_HANDLE)cmdKey )
  384. {
  385. TCHAR szErrorString[50];
  386. iisDebugOut((LOG_TYPE_TRACE, _T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), dwdata = %d; outpSD = %x, Start\n"), dwLength, (DWORD_PTR) outpSD ));
  387. if (g_GlobalDebugCrypto != 0)
  388. {
  389. OutputDebugString(_T("\nCalling SetData....\n"));
  390. DebugBreak();
  391. }
  392. dwReturn = cmdKey.SetData(MD_ADMIN_ACL,dwMDFlags,IIS_MD_UT_SERVER,BINARY_METADATA,dwLength,(LPBYTE)outpSD);
  393. if (FAILED(dwReturn))
  394. {
  395. iisDebugOut((LOG_TYPE_ERROR, _T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), FAILED. Code=0x%x.End.\n"), dwReturn));
  396. if (g_GlobalDebugCrypto != 0)
  397. {
  398. _stprintf(szErrorString, _T("\r\nSetData Failed. code=0x%x\r\n\r\n"), dwReturn);
  399. OutputDebugString(szErrorString);
  400. }
  401. }
  402. else
  403. {
  404. dwReturn = ERROR_SUCCESS;
  405. iisDebugOut((LOG_TYPE_TRACE, _T("WriteSDtoMetaBase:cmdKey():SetData(MD_ADMIN_ACL), Success.End.\n")));
  406. if (g_GlobalDebugCrypto != 0)
  407. {
  408. _stprintf(szErrorString, _T("\r\nSetData Succeeded. code=0x%x\r\n\r\n"), dwReturn);
  409. OutputDebugString(szErrorString);
  410. }
  411. }
  412. cmdKey.Close();
  413. }
  414. else
  415. {
  416. dwReturn = hReturn;
  417. }
  418. WriteSDtoMetaBase_Exit:
  419. g_GlobalDebugCrypto = iSavedFlag;
  420. iisDebugOut((LOG_TYPE_TRACE, _T("WriteSDtoMetaBase:End. Return=0x%x"), dwReturn));
  421. return dwReturn;
  422. }
  423. DWORD WriteSessiontoMetaBase(LPCTSTR szKeyPath)
  424. {
  425. iisDebugOut_Start(_T("WriteSessiontoMetaBase"), LOG_TYPE_TRACE);
  426. DWORD dwReturn = ERROR_ACCESS_DENIED;
  427. CMDKey cmdKey;
  428. HRESULT hReturn = E_FAIL;
  429. hReturn = cmdKey.CreateNode(METADATA_MASTER_ROOT_HANDLE, szKeyPath);
  430. if ( (METADATA_HANDLE)cmdKey )
  431. {
  432. dwReturn = cmdKey.SetData(9999,METADATA_NO_ATTRIBUTES,IIS_MD_UT_SERVER,BINARY_METADATA,0,(LPBYTE)"");
  433. if (FAILED(dwReturn))
  434. {
  435. iisDebugOut((LOG_TYPE_ERROR, _T("WriteSessiontoMetaBase:cmdKey():SetData(), FAILED. Code=0x%x.End.\n"), dwReturn));
  436. }
  437. else
  438. {
  439. dwReturn = ERROR_SUCCESS;
  440. iisDebugOut((LOG_TYPE_TRACE, _T("WriteSessiontoMetaBase:cmdKey():SetData(), Success.End.\n")));
  441. }
  442. cmdKey.Close();
  443. }
  444. else
  445. {
  446. dwReturn = hReturn;
  447. }
  448. iisDebugOut((LOG_TYPE_TRACE, _T("WriteSessiontoMetaBase:End. Return=0x%x"), dwReturn));
  449. return dwReturn;
  450. }
  451. #endif
  452. //----------------------------------------------------------------------------
  453. // Test if the given account name is an account on the local machine or not.
  454. //----------------------------------------------------------------------------
  455. BOOL IsLocalAccount(LPCTSTR pAccnt, DWORD *dwErr )
  456. {
  457. BOOL fIsLocalAccount = FALSE;
  458. CString csDomain, csComputer;
  459. DWORD cbDomain = 0;
  460. PSID pSid = NULL;
  461. DWORD cbSid = 0;
  462. SID_NAME_USE snu;
  463. // get the computer name
  464. cbDomain = _MAX_PATH;
  465. GetComputerName(
  466. csComputer.GetBuffer( cbDomain ), // address of name buffer
  467. &cbDomain // address of size of name buffer
  468. );
  469. csComputer.ReleaseBuffer();
  470. cbDomain = 0;
  471. // have security look up the account name and get the domain name. We dont' care about
  472. // the other stuff it can return, so pass in nulls
  473. BOOL fLookup = LookupAccountName(
  474. NULL, // address of string for system name
  475. pAccnt, // address of string for account name
  476. NULL, // address of security identifier
  477. &cbSid, // address of size of security identifier
  478. NULL,// address of string for referenced domain
  479. &cbDomain, // address of size of domain string
  480. &snu // address of SID-type indicator
  481. );
  482. // check the error - it should be insufficient buffer
  483. *dwErr = GetLastError();
  484. if (*dwErr != ERROR_INSUFFICIENT_BUFFER)
  485. return FALSE;
  486. // allocate the sid
  487. pSid = (PSID) malloc (cbSid);
  488. if (!pSid )
  489. {
  490. *dwErr = GetLastError();
  491. return FALSE;
  492. }
  493. // do the real lookup
  494. fLookup = LookupAccountName (NULL,pAccnt,pSid,&cbSid,csDomain.GetBuffer(cbDomain+2),&cbDomain,&snu);
  495. csDomain.ReleaseBuffer();
  496. // free the pSid we allocated above and set the final error code
  497. *dwErr = GetLastError();
  498. free( pSid );
  499. pSid = NULL;
  500. // compare the domain to the machine name, if it is the same, then set the sub auth
  501. if ( fLookup && (csDomain.CompareNoCase(csComputer) == 0) )
  502. fIsLocalAccount = TRUE;
  503. // return the answer
  504. return fIsLocalAccount;
  505. }
  506. // pDomainUserName can be one of the following:
  507. //
  508. // domainname\username <-- this function returns true
  509. // computername\username <-- this function returns false
  510. // username <-- this function returns false
  511. //
  512. int IsDomainSpecifiedOtherThanLocalMachine(LPCTSTR pDomainUserName)
  513. {
  514. int iReturn = TRUE;
  515. TCHAR szTempDomainUserName[_MAX_PATH];
  516. iisDebugOut_Start1(_T("IsDomainSpecifiedOtherThanLocalMachine"),pDomainUserName);
  517. CString csComputer;
  518. DWORD cbDomain = 0;
  519. // Make a copy to be sure not to move the pointer around.
  520. _tcscpy(szTempDomainUserName, pDomainUserName);
  521. // Check if there is a "\" in there.
  522. LPTSTR pch = NULL;
  523. pch = _tcschr(szTempDomainUserName, _T('\\'));
  524. if (!pch)
  525. {
  526. // no '\' found so, they must be specifying only the username, return false
  527. iReturn = FALSE;
  528. goto IsDomainSpecifiedOtherThanLocalMachine_Exit;
  529. }
  530. // We have at least a '\' in there, so set default return to true.
  531. // let's check if the name is the local computername!
  532. // get the computer name
  533. cbDomain = _MAX_PATH;
  534. if (0 == GetComputerName(csComputer.GetBuffer( cbDomain ),&cbDomain) )
  535. {
  536. // failed to get computername so, let's bail
  537. iReturn = TRUE;
  538. csComputer.ReleaseBuffer();
  539. goto IsDomainSpecifiedOtherThanLocalMachine_Exit;
  540. }
  541. csComputer.ReleaseBuffer();
  542. cbDomain = 0;
  543. // trim off the '\' character to leave just the domain\computername so we can check against it.
  544. *pch = _T('\0');
  545. // Compare the domainname with the computername
  546. // if they match then it's the local system account.
  547. iReturn = TRUE;
  548. iisDebugOut((LOG_TYPE_TRACE, _T("IsDomainSpecifiedOtherThanLocalMachine(): %s -- %s.\n"), szTempDomainUserName, csComputer));
  549. if ( 0 == csComputer.CompareNoCase(szTempDomainUserName) )
  550. {
  551. // The domain name and the computername are the same.
  552. // it is the same place.
  553. iReturn = FALSE;
  554. }
  555. IsDomainSpecifiedOtherThanLocalMachine_Exit:
  556. iisDebugOut((LOG_TYPE_TRACE, _T("IsDomainSpecifiedOtherThanLocalMachine():%s.End.Ret=%d.\n"), pDomainUserName,iReturn));
  557. return iReturn;
  558. }
  559. #ifndef _CHICAGO_
  560. void DumpAdminACL(HANDLE hFile,PSECURITY_DESCRIPTOR pSD)
  561. {
  562. BOOL b= FALSE, bDaclPresent = FALSE, bDaclDefaulted = FALSE;;
  563. PACL pDacl = NULL;
  564. ACCESS_ALLOWED_ACE* pAce;
  565. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:Start\n")));
  566. b = GetSecurityDescriptorDacl(pSD, &bDaclPresent, &pDacl, &bDaclDefaulted);
  567. if (NULL == pDacl)
  568. {
  569. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:No Security.\n")));
  570. return;
  571. }
  572. if (b)
  573. {
  574. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:ACE count: %d\n"), (int)pDacl->AceCount));
  575. // get dacl length
  576. DWORD cbDacl = pDacl->AclSize;
  577. // now check if SID's ACE is there
  578. for (int i = 0; i < pDacl->AceCount; i++)
  579. {
  580. if (!GetAce(pDacl, i, (LPVOID *) &pAce))
  581. {
  582. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:GetAce failed with 0x%x\n"),GetLastError()));
  583. }
  584. if (IsValidSid( (PSID) &(pAce->SidStart) ) )
  585. {
  586. LPTSTR pszSid;
  587. LPCTSTR ServerName = NULL; // local machine
  588. DWORD cbName = UNLEN+1;
  589. TCHAR ReferencedDomainName[200];
  590. DWORD cbReferencedDomainName = sizeof(ReferencedDomainName);
  591. SID_NAME_USE sidNameUse = SidTypeUser;
  592. TCHAR szUserName[UNLEN + 1];
  593. // dump out the sid in string format
  594. if (ConvertSidToStringSid( (PSID) &(pAce->SidStart) , &pszSid))
  595. {
  596. _tcscpy(szUserName, _T("(unknown...)"));
  597. if (LookupAccountSid(ServerName, (PSID) &(pAce->SidStart), szUserName, &cbName, ReferencedDomainName, &cbReferencedDomainName, &sidNameUse))
  598. {
  599. // Get the rights for this user.
  600. // pAce->Mask
  601. DWORD dwBytesWritten = 0;
  602. TCHAR szBuf[UNLEN+1 + 20 + 20];
  603. memset(szBuf, 0, _tcslen(szBuf) * sizeof(TCHAR));
  604. /*
  605. typedef struct _ACCESS_ALLOWED_ACE {
  606. ACE_HEADER Header;
  607. ACCESS_MASK Mask;
  608. ULONG SidStart;
  609. } ACCESS_ALLOWED_ACE;
  610. typedef struct _ACE_HEADER {
  611. UCHAR AceType;
  612. UCHAR AceFlags;
  613. USHORT AceSize;
  614. } ACE_HEADER;
  615. typedef ACE_HEADER *PACE_HEADER;
  616. typedef ULONG ACCESS_MASK;
  617. */
  618. _stprintf(szBuf, _T("%s,%s,0x%x,0x%x,0x%x,0x%x\r\n"),
  619. szUserName,
  620. pszSid,
  621. pAce->Header.AceType,
  622. pAce->Header.AceFlags,
  623. pAce->Header.AceSize,
  624. pAce->Mask
  625. );
  626. if (hFile != NULL && hFile != INVALID_HANDLE_VALUE)
  627. {
  628. if (WriteFile(hFile, szBuf, _tcslen(szBuf) * sizeof(TCHAR), &dwBytesWritten, NULL ) == FALSE )
  629. {iisDebugOut((LOG_TYPE_WARN, _T("WriteFile Failed=0x%x.\n"), GetLastError()));}
  630. }
  631. else
  632. {
  633. // echo to logfile
  634. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:Sid[%i]=%s,%s,0x%x,0x%x,0x%x,0x%x\n"),i,
  635. pszSid,
  636. szUserName,
  637. pAce->Header.AceType,
  638. pAce->Header.AceFlags,
  639. pAce->Header.AceSize,
  640. pAce->Mask
  641. ));
  642. }
  643. }
  644. else
  645. {
  646. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:Sid[%i]=%s='%s'\n"),i,pszSid,szUserName));
  647. }
  648. LocalFree(LocalHandle(pszSid));
  649. }
  650. }
  651. else
  652. {
  653. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:IsVAlidSid failed with 0x%x\n"),GetLastError()));
  654. }
  655. }
  656. }
  657. iisDebugOut((LOG_TYPE_TRACE, _T("DumpAdminACL:End\n")));
  658. return;
  659. }
  660. #endif
  661. DWORD MDDumpAdminACL(CString csKeyPath)
  662. {
  663. DWORD dwReturn = ERROR_ACCESS_DENIED;
  664. BOOL bFound = FALSE;
  665. DWORD attr, uType, dType, cbLen;
  666. CMDKey cmdKey;
  667. BUFFER bufData;
  668. PBYTE pData;
  669. int BufSize;
  670. PSECURITY_DESCRIPTOR pOldSd = NULL;
  671. cmdKey.OpenNode(csKeyPath);
  672. if ( (METADATA_HANDLE) cmdKey )
  673. {
  674. pData = (PBYTE)(bufData.QueryPtr());
  675. BufSize = bufData.QuerySize();
  676. cbLen = 0;
  677. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  678. if (!bFound)
  679. {
  680. if (cbLen > 0)
  681. {
  682. if ( ! (bufData.Resize(cbLen)) )
  683. {
  684. iisDebugOut((LOG_TYPE_ERROR, _T("MDDumpAdminACL(): cmdKey.GetData. failed to resize to %d.!\n"), cbLen));
  685. }
  686. else
  687. {
  688. pData = (PBYTE)(bufData.QueryPtr());
  689. BufSize = cbLen;
  690. cbLen = 0;
  691. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  692. }
  693. }
  694. }
  695. cmdKey.Close();
  696. if (bFound)
  697. {
  698. // dump out the info
  699. // We've got the acl
  700. pOldSd = (PSECURITY_DESCRIPTOR) pData;
  701. if (IsValidSecurityDescriptor(pOldSd))
  702. {
  703. #ifndef _CHICAGO_
  704. DumpAdminACL(INVALID_HANDLE_VALUE,pOldSd);
  705. dwReturn = ERROR_SUCCESS;
  706. #endif
  707. }
  708. }
  709. else
  710. {
  711. dwReturn = ERROR_PATH_NOT_FOUND;
  712. }
  713. }
  714. return dwReturn;
  715. }
  716. // function: AddUserToMetabaseACL_Rec
  717. //
  718. // Add a user to a metabase acl recursively. This will add them
  719. // directly to the location you specify, and then to any other
  720. // location that is a child of it, that has an ACL set
  721. //
  722. DWORD AddUserToMetabaseACL_Rec(CString csKeyPath, LPTSTR szUserToAdd, DWORD dwAccessMask )
  723. {
  724. CMDKey cmdKey;
  725. DWORD dwRet;
  726. CStringList AclList;
  727. POSITION pos;
  728. CString csPath;
  729. CString csFullPath;
  730. CString csNewPath;
  731. dwRet = AddUserToMetabaseACL( csKeyPath, szUserToAdd, dwAccessMask );
  732. if ( dwRet != ERROR_SUCCESS )
  733. {
  734. // Failed, so lets exit
  735. return dwRet;
  736. }
  737. if ( FAILED( cmdKey.OpenNode(csKeyPath) ) ||
  738. FAILED( cmdKey.GetDataPaths( MD_ADMIN_ACL,
  739. BINARY_METADATA,
  740. AclList ) )
  741. )
  742. {
  743. return ERROR_ACCESS_DENIED;
  744. }
  745. // Close Metabase
  746. cmdKey.Close();
  747. pos = AclList.GetHeadPosition();
  748. while ( NULL != pos )
  749. {
  750. csPath = AclList.GetNext( pos );
  751. if ( ( _tcscmp( csPath.GetBuffer(0), _T("/") ) == 0 ) ||
  752. ( _tcsnicmp( csPath.GetBuffer(0),
  753. METABASEPATH_SCHEMA,
  754. _tcslen( METABASEPATH_SCHEMA ) ) == 0 )
  755. )
  756. {
  757. // If we are at the root of where we set it, then skip this one,
  758. // since this is already set. Or if we are in the schema, it
  759. // should not be changed
  760. continue;
  761. }
  762. if ( _tcscmp( csKeyPath.GetBuffer(0), _T("/") ) == 0 )
  763. {
  764. // If the root of the acl we are at is the root, then don't
  765. // add '/' to it, since it already starts with a '/'
  766. csFullPath = csPath;
  767. }
  768. else
  769. {
  770. csFullPath = csKeyPath + csPath;
  771. }
  772. dwRet = AddUserToMetabaseACL( csFullPath, szUserToAdd, dwAccessMask );
  773. if ( dwRet != ERROR_SUCCESS )
  774. {
  775. return dwRet;
  776. }
  777. }
  778. return dwRet;
  779. }
  780. DWORD AddUserToMetabaseACL(CString csKeyPath, LPTSTR szUserToAdd, DWORD dwAccessMask )
  781. {
  782. DWORD dwReturn = ERROR_ACCESS_DENIED;
  783. BOOL bFound = FALSE;
  784. DWORD attr, uType, dType, cbLen;
  785. CMDKey cmdKey;
  786. BUFFER bufData;
  787. PBYTE pData;
  788. int BufSize;
  789. PSECURITY_DESCRIPTOR pOldSd = NULL;
  790. PSECURITY_DESCRIPTOR pNewSd = NULL;
  791. cmdKey.OpenNode(csKeyPath);
  792. if ( (METADATA_HANDLE) cmdKey )
  793. {
  794. pData = (PBYTE)(bufData.QueryPtr());
  795. BufSize = bufData.QuerySize();
  796. cbLen = 0;
  797. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  798. if (!bFound)
  799. {
  800. if (cbLen > 0)
  801. {
  802. if ( ! (bufData.Resize(cbLen)) )
  803. {
  804. iisDebugOut((LOG_TYPE_ERROR, _T("AddUserToMetabaseACL(): cmdKey.GetData. failed to resize to %d.!\n"), cbLen));
  805. }
  806. else
  807. {
  808. pData = (PBYTE)(bufData.QueryPtr());
  809. BufSize = cbLen;
  810. cbLen = 0;
  811. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  812. }
  813. }
  814. }
  815. cmdKey.Close();
  816. if (bFound)
  817. {
  818. // We've got the acl
  819. // so now we want to add a user to it.
  820. pOldSd = (PSECURITY_DESCRIPTOR) pData;
  821. if (IsValidSecurityDescriptor(pOldSd))
  822. {
  823. PSID principalSID = NULL;
  824. BOOL bWellKnownSID = FALSE;
  825. if ( dwAccessMask == 0x00 )
  826. {
  827. // If accessmask is not set, then lets set it
  828. dwAccessMask = ( MD_ACR_READ |
  829. MD_ACR_WRITE |
  830. MD_ACR_RESTRICTED_WRITE |
  831. MD_ACR_UNSECURE_PROPS_READ |
  832. MD_ACR_ENUM_KEYS |
  833. MD_ACR_WRITE_DAC );
  834. }
  835. // Get the SID for the certain string (administrator or everyone or whoever)
  836. dwReturn = GetPrincipalSID(szUserToAdd, &principalSID, &bWellKnownSID);
  837. if (dwReturn != ERROR_SUCCESS)
  838. {
  839. iisDebugOut((LOG_TYPE_WARN, _T("AddUserToMetabaseACL:GetPrincipalSID(%s) FAILED. Error()= 0x%x\n"), szUserToAdd, dwReturn));
  840. return dwReturn;
  841. }
  842. #ifndef _CHICAGO_
  843. if (FALSE == AddUserAccessToSD(pOldSd,principalSID,dwAccessMask,ACCESS_ALLOWED_ACE_TYPE,&pNewSd))
  844. {
  845. iisDebugOut((LOG_TYPE_ERROR, _T("AddUserToMetabaseACL:AddUserAccessToSD FAILED\n")));
  846. return dwReturn;
  847. }
  848. if (pNewSd)
  849. {
  850. // We have a new self relative SD
  851. // lets write it to the metabase.
  852. if (IsValidSecurityDescriptor(pNewSd))
  853. {
  854. dwReturn = WriteSDtoMetaBase(pNewSd, csKeyPath);
  855. }
  856. }
  857. #endif
  858. }
  859. }
  860. else
  861. {
  862. dwReturn = ERROR_PATH_NOT_FOUND;
  863. }
  864. }
  865. if (pNewSd){GlobalFree(pNewSd);}
  866. iisDebugOut((LOG_TYPE_TRACE, _T("AddUserToMetabaseACL():End. Return=0x%x.\n"), dwReturn));
  867. return dwReturn;
  868. }
  869. DWORD DoesAdminACLExist(CString csKeyPath)
  870. {
  871. DWORD dwReturn = FALSE;
  872. BOOL bFound = FALSE;
  873. DWORD attr, uType, dType, cbLen;
  874. CMDKey cmdKey;
  875. BUFFER bufData;
  876. PBYTE pData;
  877. int BufSize;
  878. cmdKey.OpenNode(csKeyPath);
  879. if ( (METADATA_HANDLE) cmdKey )
  880. {
  881. pData = (PBYTE)(bufData.QueryPtr());
  882. BufSize = bufData.QuerySize();
  883. cbLen = 0;
  884. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  885. if (bFound)
  886. {
  887. dwReturn = TRUE;
  888. }
  889. else
  890. {
  891. if (cbLen > 0)
  892. {
  893. if ( ! (bufData.Resize(cbLen)) )
  894. {
  895. iisDebugOut((LOG_TYPE_ERROR, _T("DoesAdminACLExist(): cmdKey.GetData. failed to resize to %d.!\n"), cbLen));
  896. }
  897. else
  898. {
  899. pData = (PBYTE)(bufData.QueryPtr());
  900. BufSize = cbLen;
  901. cbLen = 0;
  902. bFound = cmdKey.GetData(MD_ADMIN_ACL, &attr, &uType, &dType, &cbLen, pData, BufSize);
  903. if (bFound)
  904. {
  905. dwReturn = TRUE;
  906. }
  907. }
  908. }
  909. }
  910. cmdKey.Close();
  911. }
  912. if (dwReturn != TRUE)
  913. {
  914. //No the acl Does not exist
  915. }
  916. iisDebugOut((LOG_TYPE_TRACE, _T("DoesAdminACLExist():End. Return=0x%x.\n"), dwReturn));
  917. return dwReturn;
  918. }