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.

609 lines
21 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1999.
  5. //
  6. // File: ChkDeleg.cpp
  7. //
  8. // Contents: CheckDelegation and support methods
  9. //
  10. //
  11. //----------------------------------------------------------------------------
  12. #include "stdafx.h"
  13. #include <conio.h>
  14. #include <aclapi.h>
  15. #include "adutils.h"
  16. #include <util.h>
  17. #include "ChkDeleg.h"
  18. #include <deltempl.h>
  19. #include <tempcore.h>
  20. #include "SecDesc.h"
  21. #include <sddl.h>
  22. #include <dscmn.h> // from the admin\display project (CrackName)
  23. #ifndef ARRAYSIZE
  24. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  25. #endif
  26. #include <_util.cpp>
  27. #include <_tempcor.cpp>
  28. #include <_deltemp.cpp>
  29. class CTemplateAccessPermissionsHolderManagerVerify : public CTemplateAccessPermissionsHolderManager
  30. {
  31. public:
  32. HRESULT ProcessTemplates (); // for ACLDiag - process each template in turn
  33. HRESULT ProcessPermissions(
  34. const wstring& strObjectClass,
  35. CTemplate* pTemplate,
  36. PACL pAccessList,
  37. CPrincipalList& principalList);
  38. };
  39. HRESULT CheckDelegation ()
  40. {
  41. _TRACE (1, L"Entering CheckDelegation\n");
  42. HRESULT hr = S_OK;
  43. wstring str;
  44. if ( !_Module.DoTabDelimitedOutput () )
  45. {
  46. LoadFromResource (str, IDS_DELEGATION_TEMPLATE_DIAGNOSIS);
  47. MyWprintf (str.c_str ());
  48. }
  49. CTemplateAccessPermissionsHolderManagerVerify templateAccessPermissionsHolderManager;
  50. if ( templateAccessPermissionsHolderManager.LoadTemplates() )
  51. {
  52. hr = templateAccessPermissionsHolderManager.ProcessTemplates ();
  53. }
  54. else
  55. {
  56. LoadFromResource (str, IDS_FAILED_TO_LOAD_TEMPLATES);
  57. MyWprintf (str.c_str ());
  58. hr = E_FAIL;
  59. }
  60. _TRACE (-1, L"Leaving CheckDelegation: 0x%x\n", hr);
  61. return hr;
  62. }
  63. PTOKEN_USER EfspGetTokenUser ()
  64. {
  65. _TRACE (1, L"Entering EfspGetTokenUser\n");
  66. HANDLE hToken = 0;
  67. DWORD dwReturnLength = 0;
  68. PTOKEN_USER pTokenUser = NULL;
  69. BOOL bResult = ::OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &hToken);
  70. if ( bResult )
  71. {
  72. bResult = ::GetTokenInformation (
  73. hToken,
  74. TokenUser,
  75. NULL,
  76. 0,
  77. &dwReturnLength
  78. );
  79. if ( !bResult && dwReturnLength > 0 )
  80. {
  81. pTokenUser = (PTOKEN_USER) malloc (dwReturnLength);
  82. if (pTokenUser)
  83. {
  84. bResult = GetTokenInformation (
  85. hToken,
  86. TokenUser,
  87. pTokenUser,
  88. dwReturnLength,
  89. &dwReturnLength
  90. );
  91. if ( !bResult)
  92. {
  93. DWORD dwErr = GetLastError ();
  94. _TRACE (0, L"GetTokenInformation () failed: 0x%x\n", dwErr);
  95. free (pTokenUser);
  96. pTokenUser = NULL;
  97. }
  98. }
  99. }
  100. else
  101. {
  102. DWORD dwErr = GetLastError ();
  103. _TRACE (0, L"GetTokenInformation () failed: 0x%x\n", dwErr);
  104. }
  105. ::CloseHandle (hToken);
  106. }
  107. else
  108. {
  109. DWORD dwErr = GetLastError ();
  110. _TRACE (0, L"OpenProcessToken () failed: 0x%x\n", dwErr);
  111. }
  112. _TRACE (-1, L"Leaving EfspGetTokenUser\n");
  113. return pTokenUser;
  114. }
  115. HRESULT CTemplateAccessPermissionsHolderManagerVerify::ProcessTemplates ()
  116. {
  117. HRESULT hr = S_OK;
  118. DWORD dwErr = 0;
  119. // the access list is read in, modified, written back
  120. // If /fixdeleg is on, this list will be populated from the DS,
  121. // will receive the permissions associated with selected templates is the
  122. // user chooses to fix delegation, and then will be written back to the DS.
  123. PACL pFixDACL = NULL;
  124. PSECURITY_DESCRIPTOR pSD = NULL;
  125. LPCWSTR lpszObjectLdapPath = _Module.m_adsiObject.GetLdapPath();
  126. // get the security info
  127. if ( _Module.FixDelegation () && !_Module.DoTabDelimitedOutput () )
  128. {
  129. _TRACE (0, L"calling GetSDForDsObjectPath(%s, ...)\n", lpszObjectLdapPath);
  130. HRESULT hr1 = ::GetSDForDsObjectPath ((LPWSTR) lpszObjectLdapPath, // name of the object
  131. &pFixDACL, // receives a pointer to the DACL
  132. &pSD);
  133. if (FAILED(hr1))
  134. {
  135. _TRACE (0, L"failed on GetSDForDsObjectPath(): hr1 = 0x%x\n", hr1);
  136. wstring str;
  137. LoadFromResource (str, IDS_DELEGWIZ_ERR_GET_SEC_INFO);
  138. MyWprintf (str.c_str ());
  139. _Module.TurnOffFixDelegation ();
  140. }
  141. }
  142. CPrincipal principal; // a dummy placeholder for us to get
  143. // the incremental rights associated
  144. // with each template
  145. // We will use the current logged-in user as a placeholder only.
  146. PTOKEN_USER pTokenUser = ::EfspGetTokenUser ();
  147. if ( pTokenUser )
  148. {
  149. hr = principal.Initialize (pTokenUser->User.Sid);
  150. free (pTokenUser);
  151. }
  152. if ( SUCCEEDED (hr) )
  153. {
  154. CTemplateList* pList = m_templateManager.GetTemplateList();
  155. for (CTemplateList::iterator itr = pList->begin(); itr != pList->end(); itr++)
  156. {
  157. CTemplate* pTemplate = *itr;
  158. ASSERT(pTemplate != NULL);
  159. // Select the templates one at a time to get the
  160. // permissions representing them
  161. pTemplate->m_bSelected = TRUE;
  162. if ( InitPermissionHoldersFromSelectedTemplates (
  163. &_Module.m_classInfoArray,
  164. &_Module.m_adsiObject) )
  165. {
  166. // This access list will contain only the access control values
  167. // associated with the selected template
  168. PACL pAccessList = 0; //(PACL) ::LocalAlloc (LMEM_ZEROINIT, sizeof (ACL));
  169. if ( 1 ) //pAccessList )
  170. {
  171. dwErr = UpdateAccessList (
  172. &principal,
  173. _Module.m_adsiObject.GetServerName(),
  174. _Module.m_adsiObject.GetPhysicalSchemaNamingContext(),
  175. &pAccessList
  176. );
  177. if ( 0 == dwErr )
  178. {
  179. CPrincipalList principalList;
  180. PSID pSid = principal.GetSid ();
  181. SID_NAME_USE sne = SidTypeUnknown;
  182. wstring strPrincipalName;
  183. hr = GetNameFromSid (pSid, strPrincipalName, 0, sne);
  184. if ( SUCCEEDED (hr) )
  185. {
  186. hr = ProcessPermissions (_Module.m_adsiObject.GetClass (),
  187. pTemplate, pAccessList, principalList);
  188. if ( SUCCEEDED (hr) && _Module.FixDelegation () && !_Module.DoTabDelimitedOutput () )
  189. {
  190. // loop thru all the principals and classes
  191. CPrincipalList::iterator i;
  192. for (i = principalList.begin(); i != principalList.end(); ++i)
  193. {
  194. CPrincipal* pCurrPrincipal = (*i);
  195. dwErr = UpdateAccessList(
  196. pCurrPrincipal,
  197. _Module.m_adsiObject.GetServerName(),
  198. _Module.m_adsiObject.GetPhysicalSchemaNamingContext(),
  199. &pFixDACL);
  200. if (dwErr != 0)
  201. break;
  202. } // for pCurrPrincipal
  203. }
  204. }
  205. }
  206. ::LocalFree (pAccessList);
  207. }
  208. else
  209. {
  210. hr = E_OUTOFMEMORY;
  211. break;
  212. }
  213. }
  214. pTemplate->m_bSelected = FALSE;
  215. }
  216. if ( _Module.FixDelegation () && !_Module.DoTabDelimitedOutput () )
  217. {
  218. // commit changes
  219. _TRACE (0, L"calling SetNamedSecurityInfo(%s, ...)\n", lpszObjectLdapPath);
  220. dwErr = ::SetNamedSecurityInfoW(
  221. (LPWSTR) lpszObjectLdapPath,
  222. SE_DS_OBJECT_ALL,
  223. DACL_SECURITY_INFORMATION,
  224. NULL,
  225. NULL,
  226. pFixDACL,
  227. 0);
  228. if (dwErr != ERROR_SUCCESS)
  229. {
  230. _TRACE (0, L"failed on SetNamedSecurityInfo(): dwErr = 0x%x\n", dwErr);
  231. wstring str;
  232. LoadFromResource (str, IDS_DELEGWIZ_ERR_SET_SEC_INFO);
  233. MyWprintf (str.c_str ());
  234. }
  235. }
  236. }
  237. if ( pSD )
  238. ::LocalFree (pSD);
  239. return hr;
  240. }
  241. class CTemplateStatus
  242. {
  243. public:
  244. CTemplateStatus () :
  245. m_nACECnt (1),
  246. m_bApplies (false),
  247. m_bInherited (false)
  248. {
  249. }
  250. ULONG m_nACECnt;
  251. bool m_bApplies;
  252. bool m_bInherited;
  253. wstring m_strObjName;
  254. PSID m_psid;
  255. };
  256. typedef list<CTemplateStatus*> CStatusList;
  257. HRESULT CTemplateAccessPermissionsHolderManagerVerify::ProcessPermissions(
  258. const wstring& strObjectClass,
  259. CTemplate* pTemplate,
  260. PACL pDacl,
  261. CPrincipalList& principalList)
  262. {
  263. if ( !pTemplate )
  264. return E_POINTER;
  265. HRESULT hr = S_OK;
  266. CStatusList statusList; // This list will contain 1 entry for each
  267. // SidStart/bInherited/bApplies triplet.
  268. // The counter for each item will incremented
  269. // each time an ACE is found that belongs to
  270. // the object pointed to by the SidStart.
  271. ULONG nExpectedCnt = 0;
  272. bool bApplies = pTemplate->AppliesToClass(strObjectClass.c_str ()) ? true : false;
  273. ACE_SAMNAME* pAceSAMName = 0;
  274. // Look in global DACL for each right
  275. PACCESS_ALLOWED_ACE pAllowedAce = 0;
  276. // iterate through the template ACES
  277. for (int i = 0; i < pDacl->AceCount; i++)
  278. {
  279. if ( GetAce (pDacl, i, (void **)&pAllowedAce) )
  280. {
  281. PSID AceSid = 0;
  282. if ( IsObjectAceType ( pAllowedAce ) )
  283. {
  284. AceSid = RtlObjectAceSid( pAllowedAce );
  285. }
  286. else
  287. {
  288. AceSid = &( ( PKNOWN_ACE )pAllowedAce )->SidStart;
  289. }
  290. ASSERT (IsValidSid (AceSid));
  291. if ( !IsValidSid (AceSid) )
  292. continue;
  293. // wstring strPrincipalName;
  294. // SID_NAME_USE sne = SidTypeUnknown;
  295. // hr = GetNameFromSid (AceSid, strPrincipalName, 0, sne);
  296. // if ( SUCCEEDED (hr) )
  297. {
  298. ACE_SAMNAME* pAceTemplate = new ACE_SAMNAME;
  299. if ( pAceTemplate )
  300. {
  301. pAceTemplate->m_AceType = pAllowedAce->Header.AceType;
  302. switch (pAceTemplate->m_AceType)
  303. {
  304. case ACCESS_ALLOWED_ACE_TYPE:
  305. pAceTemplate->m_pAllowedAce = pAllowedAce;
  306. break;
  307. case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
  308. pAceTemplate->m_pAllowedObjectAce =
  309. reinterpret_cast <PACCESS_ALLOWED_OBJECT_ACE> (pAllowedAce);
  310. break;
  311. case ACCESS_DENIED_ACE_TYPE:
  312. pAceTemplate->m_pDeniedAce =
  313. reinterpret_cast <PACCESS_DENIED_ACE> (pAllowedAce);
  314. break;
  315. case ACCESS_DENIED_OBJECT_ACE_TYPE:
  316. pAceTemplate->m_pDeniedObjectAce =
  317. reinterpret_cast <PACCESS_DENIED_OBJECT_ACE> (pAllowedAce);
  318. break;
  319. default:
  320. break;
  321. }
  322. // pAceTemplate->m_SAMAccountName = strPrincipalName;
  323. pAceTemplate->DebugOut ();
  324. nExpectedCnt++;
  325. ACE_SAMNAME_LIST::iterator itr = _Module.m_DACLList.begin ();
  326. for (; itr != _Module.m_DACLList.end () && SUCCEEDED (hr); itr++)
  327. {
  328. pAceSAMName = *itr;
  329. // to neutralize Sid differences
  330. pAceTemplate->m_SAMAccountName = pAceSAMName->m_SAMAccountName;
  331. if ( *pAceSAMName == *pAceTemplate )
  332. {
  333. bool bFound = false;
  334. CTemplateStatus* pStatus = 0;
  335. CStatusList::iterator itr1 = statusList.begin ();
  336. wstring strObjName;
  337. PSID psid = 0;
  338. if ( ACCESS_ALLOWED_OBJECT_ACE_TYPE == pAceSAMName->m_AceType )
  339. {
  340. psid = RtlObjectAceSid (pAceSAMName->m_pAllowedObjectAce);
  341. }
  342. else
  343. {
  344. psid = &( ( PKNOWN_ACE )pAceSAMName->m_pAllowedAce )->SidStart;
  345. }
  346. SID_NAME_USE sne = SidTypeUnknown;
  347. hr = GetNameFromSid (psid, strObjName, 0, sne);
  348. if ( SUCCEEDED (hr) )
  349. {
  350. for (; itr1 != statusList.end (); itr1++)
  351. {
  352. pStatus = *itr1;
  353. if ( (pStatus->m_bApplies == bApplies) &&
  354. ( pStatus->m_bInherited == pAceSAMName->IsInherited () ) &&
  355. ( !_wcsicmp (
  356. pStatus->m_strObjName.c_str (),
  357. strObjName.c_str ())) )
  358. {
  359. bFound = true;
  360. break;
  361. }
  362. }
  363. if ( bFound )
  364. {
  365. pStatus->m_nACECnt++;
  366. }
  367. else
  368. {
  369. pStatus = new CTemplateStatus;
  370. if ( pStatus )
  371. {
  372. pStatus->m_strObjName = strObjName;
  373. pStatus->m_bApplies = bApplies;
  374. pStatus->m_bInherited = pAceSAMName->IsInherited ();
  375. pStatus->m_psid = psid;
  376. statusList.push_back (pStatus);
  377. }
  378. else
  379. {
  380. hr = E_OUTOFMEMORY;
  381. break;
  382. }
  383. }
  384. }
  385. }
  386. }
  387. }
  388. else
  389. {
  390. hr = E_OUTOFMEMORY;
  391. break;
  392. }
  393. }
  394. }
  395. }
  396. // Now, iterate thru status list and evaluate each item
  397. // If the list is empty, then this template is not present.
  398. // Otherwise, for each present item, if the class and attr count is less than the required count
  399. // the template is partial for the item.
  400. // Otherwise, it is OK.
  401. CStatusList::iterator itr = statusList.begin ();
  402. CTemplateStatus* pStatus = 0;
  403. wstring str;
  404. wstring strStatus;
  405. for (; itr != statusList.end () && SUCCEEDED (hr); itr++)
  406. {
  407. pStatus = *itr;
  408. // Print template description
  409. bool bMisconfigured = false;
  410. if ( _Module.DoTabDelimitedOutput () )
  411. {
  412. FormatMessage (str, IDS_DELEGATION_TITLE_CDO, pTemplate->GetDescription (),
  413. pStatus->m_strObjName.c_str ());
  414. }
  415. else
  416. {
  417. FormatMessage (str, IDS_DELEGATION_TITLE, pTemplate->GetDescription (),
  418. pStatus->m_strObjName.c_str ());
  419. }
  420. MyWprintf (str.c_str ());
  421. // Print "Status: OK/MISCONFIGURED"
  422. if ( pStatus->m_nACECnt < nExpectedCnt )
  423. {
  424. LoadFromResource (strStatus, IDS_MISCONFIGURED);
  425. bMisconfigured = true;
  426. }
  427. else
  428. LoadFromResource (strStatus, IDS_OK);
  429. if ( _Module.DoTabDelimitedOutput () )
  430. FormatMessage (str, IDS_DELTEMPL_STATUS_CDO, strStatus.c_str ());
  431. else
  432. FormatMessage (str, IDS_DELTEMPL_STATUS, strStatus.c_str ());
  433. MyWprintf (str.c_str ());
  434. // Print "Applies on this object: YES/NO"
  435. if ( pStatus->m_bApplies )
  436. {
  437. LoadFromResource (strStatus,
  438. _Module.DoTabDelimitedOutput () ? IDS_APPLIES : IDS_YES);
  439. }
  440. else
  441. {
  442. LoadFromResource (strStatus,
  443. _Module.DoTabDelimitedOutput () ? IDS_DOES_NOT_APPLY : IDS_NO);
  444. }
  445. if ( _Module.DoTabDelimitedOutput () )
  446. FormatMessage (str, IDS_APPLIES_ON_THIS_OBJECT_CDO, strStatus.c_str ());
  447. else
  448. FormatMessage (str, IDS_APPLIES_ON_THIS_OBJECT, strStatus.c_str ());
  449. MyWprintf (str.c_str ());
  450. // Print "Inherited from parent: YES/NO"
  451. if ( pStatus->m_bInherited )
  452. {
  453. LoadFromResource (strStatus,
  454. _Module.DoTabDelimitedOutput () ? IDS_INHERITED : IDS_YES);
  455. }
  456. else
  457. {
  458. LoadFromResource (strStatus,
  459. _Module.DoTabDelimitedOutput () ? IDS_EXPLICIT : IDS_NO);
  460. }
  461. if ( _Module.DoTabDelimitedOutput () )
  462. FormatMessage (str, IDS_INHERITED_FROM_PARENT_CDO, strStatus.c_str ());
  463. else
  464. FormatMessage (str, IDS_INHERITED_FROM_PARENT, strStatus.c_str ());
  465. MyWprintf (str.c_str ());
  466. if ( bMisconfigured && _Module.FixDelegation () && !_Module.DoTabDelimitedOutput () )
  467. {
  468. LoadFromResource (str, IDS_FIX_DELEGATION_QUERY);
  469. while (1)
  470. {
  471. MyWprintf (str.c_str ());
  472. int ch = _getche ();
  473. if ( 'y' == ch )
  474. {
  475. CPrincipal* pPrincipal = new CPrincipal;
  476. if ( pPrincipal )
  477. {
  478. if ( SUCCEEDED (pPrincipal->Initialize (pStatus->m_psid)) )
  479. principalList.push_back (pPrincipal);
  480. else
  481. delete pPrincipal;
  482. }
  483. else
  484. hr = E_OUTOFMEMORY;
  485. MyWprintf (L"\n\n");
  486. break;
  487. }
  488. else if ( 'n' == ch )
  489. {
  490. MyWprintf (L"\n\n");
  491. break;
  492. }
  493. else
  494. {
  495. MyWprintf (L"\n");
  496. continue;
  497. }
  498. }
  499. }
  500. }
  501. if ( !pStatus ) // None found
  502. {
  503. // Print template description
  504. if ( _Module.DoTabDelimitedOutput () )
  505. {
  506. FormatMessage (str, IDS_DELEGATION_NOT_FOUND_CDO,
  507. pTemplate->GetDescription ());
  508. MyWprintf (str.c_str ());
  509. }
  510. else
  511. {
  512. FormatMessage (str, L"\t%1\n\n", pTemplate->GetDescription ());
  513. MyWprintf (str.c_str ());
  514. LoadFromResource (strStatus, IDS_NOT_PRESENT);
  515. FormatMessage (str, IDS_DELTEMPL_STATUS, strStatus.c_str ());
  516. MyWprintf (str.c_str ());
  517. }
  518. }
  519. if ( !_Module.DoTabDelimitedOutput () )
  520. MyWprintf (L"\n");
  521. return hr;
  522. }