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.

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