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.

1230 lines
36 KiB

  1. #include "stdafx.h"
  2. #include "utils.h"
  3. #include "dsace.h"
  4. #include "dsacls.h"
  5. //This constructor is used to initialize from an Ace
  6. CAce::CAce( )
  7. :m_AceFlags( 0 ),
  8. m_AceType( ALLOW ),
  9. m_ObjectTypeType( DSACLS_SELF),
  10. m_Flags( 0 ),
  11. m_Mask( 0 ),
  12. m_pSid( NULL ),
  13. m_szObjectType( NULL ),
  14. m_szTrusteeName( NULL ),
  15. m_szInheritedObjectType( NULL ),
  16. m_bErased( FALSE ),
  17. m_GuidObjectType( GUID_NULL ),
  18. m_GuidInheritedObjectType( GUID_NULL )
  19. {}
  20. CAce::~CAce()
  21. {
  22. if( m_pSid )
  23. LocalFree( m_pSid );
  24. if( m_szTrusteeName )
  25. LocalFree( m_szTrusteeName );
  26. if( m_szInheritedObjectType )
  27. LocalFree( m_szInheritedObjectType );
  28. if( m_szObjectType )
  29. LocalFree( m_szObjectType );
  30. }
  31. DWORD CAce::Initialize( PACE_HEADER pAceHeader, UINT nAllowDeny, UINT nAudit )
  32. {
  33. DWORD dwErr = ERROR_SUCCESS;
  34. ASSERT( pAceHeader != NULL );
  35. m_nAllowDeny = nAllowDeny;
  36. m_nAudit = nAudit;
  37. m_AceFlags = pAceHeader->AceFlags;
  38. m_Mask = ((PKNOWN_ACE)pAceHeader)->Mask;
  39. MapGeneric(&m_Mask);
  40. // Is this an object ACE?
  41. if (IsObjectAceType(pAceHeader))
  42. {
  43. GUID *pGuid;
  44. // Copy the object type guid if present
  45. pGuid = RtlObjectAceObjectType(pAceHeader);
  46. if (pGuid)
  47. {
  48. m_Flags |= ACE_OBJECT_TYPE_PRESENT;
  49. m_GuidObjectType = *pGuid;
  50. }
  51. // Copy the inherit type guid if present
  52. pGuid = RtlObjectAceInheritedObjectType(pAceHeader);
  53. if (pGuid)
  54. {
  55. m_Flags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
  56. m_GuidInheritedObjectType = *pGuid;
  57. }
  58. }
  59. // Copy the SID
  60. PSID psidT = GetAceSid(pAceHeader);
  61. DWORD nSidLength = GetLengthSid(psidT);
  62. m_pSid = (PSID)LocalAlloc(LPTR, nSidLength);
  63. if (m_pSid)
  64. CopyMemory(m_pSid, psidT, nSidLength);
  65. else
  66. return ERROR_NOT_ENOUGH_MEMORY;
  67. //Get the Trustee Name from the SID
  68. dwErr = GetAccountNameFromSid( g_szServerName, m_pSid, &m_szTrusteeName );
  69. if( dwErr != ERROR_SUCCESS )
  70. return dwErr;
  71. m_AceType = GetAceType( pAceHeader );
  72. if( m_AceType == ALLOW )
  73. m_AccessMode = GRANT_ACCESS;
  74. else
  75. m_AccessMode = DENY_ACCESS;
  76. //Get LDAP display name of ObjectType
  77. if( FlagOn( m_Flags, ACE_OBJECT_TYPE_PRESENT) )
  78. {
  79. PDSACL_CACHE_ITEM pItemCache = NULL;
  80. pItemCache = g_Cache->LookUp( &m_GuidObjectType );
  81. //Found in Cache, copy the name
  82. if( pItemCache )
  83. {
  84. if( ( dwErr = CopyUnicodeString( &m_szObjectType, pItemCache->pszName ) ) != ERROR_SUCCESS )
  85. return dwErr;
  86. m_ObjectTypeType = pItemCache->ObjectTypeType;
  87. }
  88. //Add to cache, Guid will be resolved when cache is build
  89. else
  90. g_Cache->AddItem( &m_GuidObjectType );
  91. }
  92. //Get the LDAP display name for the InheriteObjectType
  93. if( FlagOn( m_Flags, ACE_INHERITED_OBJECT_TYPE_PRESENT ) )
  94. {
  95. PDSACL_CACHE_ITEM pItemCache = NULL;
  96. pItemCache = g_Cache->LookUp( &m_GuidInheritedObjectType );
  97. if( pItemCache )
  98. {
  99. if( ( dwErr = CopyUnicodeString( &m_szInheritedObjectType, pItemCache->pszName ) ) != ERROR_SUCCESS )
  100. return ERROR_SUCCESS;
  101. }
  102. else
  103. g_Cache->AddItem( &m_GuidInheritedObjectType );
  104. }
  105. return ERROR_SUCCESS;
  106. }
  107. DWORD CAce::Initialize( LPWSTR pszTrustee,
  108. LPWSTR pszObjectId,
  109. LPWSTR pszInheritId,
  110. ACCESS_MODE AccessMode,
  111. ACCESS_MASK Access,
  112. BYTE Inheritance
  113. )
  114. {
  115. DWORD dwErr = ERROR_SUCCESS;
  116. m_AceFlags = Inheritance;
  117. m_Mask = Access;
  118. MapGeneric(&m_Mask);
  119. m_AccessMode = AccessMode;
  120. // Is this an object ACE?
  121. if ( pszObjectId || pszInheritId )
  122. {
  123. if ( pszObjectId )
  124. {
  125. m_Flags |= ACE_OBJECT_TYPE_PRESENT;
  126. dwErr = CopyUnicodeString( &m_szObjectType,pszObjectId );
  127. if( dwErr != ERROR_SUCCESS )
  128. return dwErr;
  129. }
  130. // Copy the inherit type guid if present
  131. if ( pszInheritId )
  132. {
  133. m_Flags |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
  134. dwErr = CopyUnicodeString( &m_szInheritedObjectType ,pszInheritId);
  135. if( dwErr != ERROR_SUCCESS )
  136. return dwErr;
  137. }
  138. }
  139. if( ( dwErr = CopyUnicodeString( &m_szTrusteeName, pszTrustee ) ) != ERROR_SUCCESS )
  140. return dwErr;
  141. if( ( dwErr = GetSidFromAccountName( g_szServerName,
  142. &m_pSid,
  143. m_szTrusteeName ) ) != ERROR_SUCCESS )
  144. {
  145. DisplayMessageEx( 0, MSG_DSACLS_NO_MATCHING_SID, m_szTrusteeName );
  146. return dwErr;
  147. }
  148. //AceType
  149. if( m_AccessMode == GRANT_ACCESS )
  150. m_AceType = ALLOW;
  151. else if ( m_AccessMode == DENY_ACCESS )
  152. m_AceType = DENY;
  153. //else Doesn't Matter
  154. //Get LDAP display name of ObjectType
  155. if( FlagOn( m_Flags, ACE_OBJECT_TYPE_PRESENT) )
  156. {
  157. PDSACL_CACHE_ITEM pItemCache = NULL;
  158. pItemCache = g_Cache->LookUp( m_szObjectType );
  159. if( pItemCache )
  160. {
  161. m_GuidObjectType = pItemCache->Guid;
  162. }
  163. else
  164. g_Cache->AddItem( m_szObjectType );
  165. }
  166. //Get the LDAP display name for the InheriteObjectType
  167. if( FlagOn( m_Flags, ACE_INHERITED_OBJECT_TYPE_PRESENT ) )
  168. {
  169. PDSACL_CACHE_ITEM pItemCache = NULL;
  170. pItemCache = g_Cache->LookUp( m_szInheritedObjectType );
  171. if( pItemCache )
  172. {
  173. m_GuidInheritedObjectType = pItemCache->Guid;
  174. }
  175. else
  176. g_Cache->AddItem( m_szInheritedObjectType );
  177. }
  178. return ERROR_SUCCESS;
  179. }
  180. GUID* CAce::GetGuidObjectType()
  181. {
  182. if( !IsEqualGUID( m_GuidObjectType, GUID_NULL ) )
  183. return &m_GuidObjectType;
  184. return NULL;
  185. }
  186. GUID* CAce::GetGuidInheritType()
  187. {
  188. if( !IsEqualGUID( m_GuidInheritedObjectType, GUID_NULL ) )
  189. return &m_GuidInheritedObjectType;
  190. return NULL;
  191. }
  192. VOID CAce::Display( UINT nMaxTrusteeLength )
  193. {
  194. WCHAR szLoadBuffer[1024];
  195. WCHAR szDisplayBuffer[1024];
  196. HMODULE hInstance = GetModuleHandle(NULL);
  197. DWORD err=0;
  198. UINT nAccessDisplayLen = 0;
  199. UINT uID = 0;
  200. UINT nLen = 0;
  201. switch ( m_AceType )
  202. {
  203. case ALLOW:
  204. uID = MSG_DSACLS_ALLOW;
  205. break;
  206. case DENY:
  207. uID = MSG_DSACLS_DENY;
  208. break;
  209. case AUDIT_SUCCESS:
  210. uID = MSG_DSACLS_AUDIT_SUCCESS;
  211. break;
  212. case AUDIT_FAILURE:
  213. uID = MSG_DSACLS_AUDIT_FAILURE;
  214. break;
  215. case AUDIT_ALL:
  216. uID = MSG_DSACLS_AUDIT_ALL;
  217. break;
  218. }
  219. nLen = LoadStringW( hInstance, uID, szLoadBuffer, 1023 );
  220. if( m_AceType == ALLOW || m_AceType == DENY )
  221. nLen = m_nAllowDeny - nLen;
  222. else
  223. nLen = m_nAudit - nLen;
  224. wcscpy(szDisplayBuffer,szLoadBuffer );
  225. StringWithNSpace(1 + nLen ,szLoadBuffer );
  226. wcscat( szDisplayBuffer, szLoadBuffer );
  227. wcscat( szDisplayBuffer, m_szTrusteeName );
  228. nLen = wcslen( m_szTrusteeName );
  229. StringWithNSpace(2 + ( nMaxTrusteeLength - nLen ), szLoadBuffer );
  230. wcscat( szDisplayBuffer, szLoadBuffer );
  231. if( m_ObjectTypeType == DSACLS_EXTENDED_RIGHTS )
  232. {
  233. wcscat( szDisplayBuffer, GetObjectType() );
  234. }
  235. else
  236. {
  237. nAccessDisplayLen = wcslen( szDisplayBuffer );
  238. ConvertAccessMaskToGenericString( m_Mask, szLoadBuffer, 1023 );
  239. if( m_ObjectTypeType == DSACLS_CHILD_OBJECTS ||
  240. m_ObjectTypeType == DSACLS_PROPERTY ||
  241. m_ObjectTypeType == DSACLS_VALIDATED_RIGHTS )
  242. {
  243. LPWSTR szTemp = NULL;
  244. if( ERROR_SUCCESS == ( err = LoadMessage( MSG_DSACLS_ACCESS_FOR, &szTemp, szLoadBuffer, GetObjectType() ) ) )
  245. {
  246. wcscat( szDisplayBuffer, szTemp );
  247. LocalFree(szTemp);
  248. }
  249. }
  250. else
  251. wcscat( szDisplayBuffer, szLoadBuffer );
  252. }
  253. if( IsInheritedFromParent() )
  254. {
  255. StringWithNSpace(3, szLoadBuffer );
  256. wcscat( szDisplayBuffer, szLoadBuffer );
  257. LoadString( hInstance, MSG_DSACLS_INHERITED_FROM_PARENT, szLoadBuffer, 1023 );
  258. wcscat( szDisplayBuffer, szLoadBuffer );
  259. }
  260. DisplayStringWithNewLine(0, szDisplayBuffer );
  261. if( m_ObjectTypeType != DSACLS_EXTENDED_RIGHTS &&
  262. ( GENERIC_ALL_MAPPING != ( m_Mask & GENERIC_ALL_MAPPING ) ) )
  263. DisplayAccessRights( nAccessDisplayLen, m_Mask );
  264. }
  265. CAcl::~CAcl()
  266. {
  267. CAce *pAce= NULL;
  268. for( list<CAce*>::iterator i = listAces.begin(); i != listAces.end(); ++i )
  269. {
  270. pAce = (*i);
  271. pAce->~CAce();
  272. //delete (*i);
  273. }
  274. }
  275. DWORD CAcl::Initialize( BOOL bProtected, PACL pAcl, UINT nAllowDeny, UINT nAudit )
  276. {
  277. DWORD dwErr = ERROR_SUCCESS;
  278. bAclProtected = bProtected;
  279. if( pAcl == NULL )
  280. return ERROR_SUCCESS;
  281. UINT nMaxTrusteeLength = 0;
  282. PACE_HEADER pAceHeader = (PACE_HEADER) FirstAce(pAcl);
  283. for ( int j = 0; j < pAcl->AceCount; j++, pAceHeader = (PACE_HEADER) NextAce(pAceHeader))
  284. {
  285. CAce * pAce = new CAce();
  286. if( !pAce )
  287. return ERROR_NOT_ENOUGH_MEMORY;
  288. dwErr = pAce->Initialize( pAceHeader, nAllowDeny, nAudit );
  289. if( dwErr != ERROR_SUCCESS )
  290. {
  291. delete pAce;
  292. return dwErr;
  293. }
  294. if( nMaxTrusteeLength < pAce->GetTrusteeLength() )
  295. nMaxTrusteeLength = pAce->GetTrusteeLength();
  296. listAces.push_back( pAce );
  297. if( pAce->IsEffective() )
  298. listEffective.push_back( pAce );
  299. if( pAce->IsInheritedToAll() )
  300. listInheritedAll.push_back( pAce );
  301. if( pAce->IsInheritedToSpecific() )
  302. listInheritedSpecific.push_back( pAce );
  303. }
  304. m_nMaxTrusteeLength = nMaxTrusteeLength;
  305. return ERROR_SUCCESS;
  306. }
  307. VOID CAcl::AddAce( CAce *pAce )
  308. {
  309. listAces.push_back(pAce);
  310. }
  311. VOID CAcl::MergeAcl( CAcl * pAcl )
  312. {
  313. for( list<CAce*>::iterator i = pAcl->listAces.begin(); i != pAcl->listAces.end(); ++i )
  314. {
  315. if( (*i)->GetAccessMode() == REVOKE_ACCESS )
  316. {
  317. //Remove all Aces from this->listAces which have same sid
  318. for( list<CAce*>::iterator j = listAces.begin(); j != listAces.end(); ++j )
  319. {
  320. if( EqualSid( (*i)->GetSID(), (*j)->GetSID() ) )
  321. (*j)->SetErased(TRUE);
  322. }
  323. }
  324. else
  325. {
  326. AddAce( (*i) );
  327. }
  328. }
  329. //After Merging pAcl should be empty()
  330. for( i = pAcl->listAces.begin(); i != pAcl->listAces.end(); ++i )
  331. {
  332. if( (*i)->GetAccessMode() == REVOKE_ACCESS )
  333. {
  334. delete (*i);
  335. }
  336. }
  337. while( !pAcl->listAces.empty() )
  338. {
  339. pAcl->listAces.pop_back();
  340. }
  341. }
  342. DWORD CAcl::BuildAcl( PACL *ppAcl )
  343. {
  344. ULONG cAceCount = 0;
  345. PEXPLICIT_ACCESS pListOfExplicitEntries = NULL;
  346. DWORD dwErr = ERROR_SUCCESS;
  347. for( list<CAce*>::iterator j = listAces.begin(); j != listAces.end(); ++j )
  348. {
  349. if( !(*j)->IsErased() )
  350. ++cAceCount;
  351. }
  352. pListOfExplicitEntries = (PEXPLICIT_ACCESS)LocalAlloc( LMEM_FIXED | LMEM_ZEROINIT,
  353. cAceCount * sizeof( EXPLICIT_ACCESS ) );
  354. if ( pListOfExplicitEntries == NULL )
  355. {
  356. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  357. return dwErr;
  358. }
  359. cAceCount = 0;
  360. for( j = listAces.begin(); j != listAces.end(); ++j )
  361. {
  362. if( !(*j)->IsErased() )
  363. {
  364. dwErr = BuildExplicitAccess( (*j)->GetSID(),
  365. (*j)->GetGuidObjectType(),
  366. (*j)->GetGuidInheritType(),
  367. (*j)->GetAccessMode(),
  368. (*j)->GetAccessMask(),
  369. (*j)->GetAceFlags(),
  370. &pListOfExplicitEntries[cAceCount] );
  371. if( dwErr != ERROR_SUCCESS )
  372. break;
  373. ++cAceCount;
  374. }
  375. }
  376. if( dwErr == ERROR_SUCCESS )
  377. {
  378. dwErr = SetEntriesInAcl( cAceCount,
  379. pListOfExplicitEntries,
  380. NULL,
  381. ppAcl );
  382. }
  383. //
  384. // Free the memory from the access entry list
  385. //
  386. for ( int i = 0; i < cAceCount; i++ )
  387. {
  388. if( pListOfExplicitEntries[i].Trustee.TrusteeForm == TRUSTEE_IS_OBJECTS_AND_SID )
  389. {
  390. POBJECTS_AND_SID pOAS = (POBJECTS_AND_SID)pListOfExplicitEntries[i].Trustee.ptstrName;
  391. if( pOAS && pOAS->pSid )
  392. LocalFree( pOAS->pSid );
  393. if( pOAS )
  394. LocalFree( pOAS );
  395. }
  396. else
  397. LocalFree( pListOfExplicitEntries[i].Trustee.ptstrName );
  398. }
  399. LocalFree( pListOfExplicitEntries );
  400. return dwErr;
  401. }
  402. VOID CAcl::GetInfoFromCache()
  403. {
  404. LPWSTR pszTemp = NULL;
  405. GUID * pGuid = NULL;
  406. PDSACL_CACHE_ITEM pItem = NULL;
  407. DWORD dwErr = ERROR_SUCCESS;
  408. WCHAR szGuid[39];
  409. for ( list<CAce*>::iterator i = listAces.begin(); i != listAces.end(); i++ )
  410. {
  411. if( (*i)->IsObjectTypePresent() )
  412. {
  413. if( (*i)->GetGuidObjectType() == NULL )
  414. {
  415. pItem = g_Cache->LookUp( (*i)->GetObjectType() );
  416. if( pItem )
  417. {
  418. (*i)->SetGuidObjectType( &pItem->Guid );
  419. (*i)->SetObjectTypeType( pItem->ObjectTypeType );
  420. }
  421. //else is fatal error since we cannot get guid this is taken care in verify
  422. }
  423. else if( (*i)->GetObjectType() == NULL )
  424. {
  425. pItem = g_Cache->LookUp( (*i)->GetGuidObjectType() );
  426. if( pItem )
  427. {
  428. (*i)->SetObjectType( pItem->pszName );
  429. (*i)->SetObjectTypeType( pItem->ObjectTypeType );
  430. }
  431. else
  432. {
  433. FormatStringGUID( szGuid, 38, (*i)->GetGuidObjectType() );
  434. (*i)->SetObjectType( szGuid );
  435. (*i)->SetObjectTypeType( DSACLS_UNDEFINED );
  436. }
  437. }
  438. }
  439. if( (*i)->IsInheritedTypePresent() )
  440. {
  441. if( (*i)->GetGuidInheritType() == NULL )
  442. {
  443. pItem = g_Cache->LookUp( (*i)->GetInheritedObjectType() );
  444. if( pItem )
  445. {
  446. (*i)->SetGuidInheritType( &pItem->Guid );
  447. }
  448. //else is fatal error since we cannot get guid this is taken care in verify
  449. }
  450. else if( (*i)->GetInheritedObjectType() == NULL )
  451. {
  452. pItem = g_Cache->LookUp( (*i)->GetGuidInheritType() );
  453. if( pItem )
  454. {
  455. (*i)->SetInheritedObjectType( pItem->pszName );
  456. }
  457. else
  458. {
  459. FormatStringGUID( szGuid, 38, (*i)->GetGuidInheritType() );
  460. (*i)->SetInheritedObjectType( szGuid );
  461. }
  462. }
  463. }
  464. }
  465. }
  466. BOOL CAcl::VerifyAllNames()
  467. {
  468. for ( list<CAce*>::iterator i = listAces.begin(); i != listAces.end(); i++ )
  469. {
  470. if( (*i)->IsObjectTypePresent() )
  471. {
  472. if( (*i)->GetGuidObjectType() == NULL )
  473. {
  474. DisplayMessageEx(0, MSG_DSACLS_NO_MATCHING_GUID, (*i)->GetObjectType() );
  475. return FALSE;
  476. }
  477. if ( (*i)->GetObjectTypeType() == DSACLS_PROPERTY &&
  478. (((*i)->GetAccessMask() & (~(ACTRL_DS_WRITE_PROP|ACTRL_DS_READ_PROP))) != 0 ) )
  479. {
  480. DisplayMessageEx(0,MSG_DSACLS_PROPERTY_PERMISSION_MISMATCH, (*i)->GetObjectType() );
  481. return FALSE;
  482. }
  483. if ( (*i)->GetObjectTypeType() == DSACLS_EXTENDED_RIGHTS &&
  484. (((*i)->GetAccessMask() & (~ACTRL_DS_CONTROL_ACCESS)) != 0 ) )
  485. {
  486. DisplayMessageEx(0,MSG_DSACLS_EXTENDED_RIGHTS_PERMISSION_MISMATCH, (*i)->GetObjectType() );
  487. return FALSE;
  488. }
  489. if ( (*i)->GetObjectTypeType() == DSACLS_VALIDATED_RIGHTS &&
  490. (((*i)->GetAccessMask() & (~ACTRL_DS_SELF)) != 0 ) )
  491. {
  492. DisplayMessageEx(0,MSG_DSACLS_VALIDATED_RIGHTS_PERMISSION_MISMATCH, (*i)->GetObjectType() );
  493. return FALSE;
  494. }
  495. if ( (*i)->GetObjectTypeType() == DSACLS_CHILD_OBJECTS &&
  496. (((*i)->GetAccessMask() & (~(ACTRL_DS_CREATE_CHILD|ACTRL_DS_DELETE_CHILD))) != 0 ) )
  497. {
  498. DisplayMessageEx(0,MSG_DSACLS_CHILD_OBJECT_PERMISSION_MISMATCH, (*i)->GetObjectType() );
  499. return FALSE;
  500. }
  501. }
  502. if( (*i)->IsInheritedTypePresent() )
  503. {
  504. if( (*i)->GetGuidInheritType() == NULL )
  505. {
  506. DisplayMessageEx(0, MSG_DSACLS_NO_MATCHING_GUID, (*i)->GetInheritedObjectType() );
  507. return FALSE;
  508. }
  509. if( (*i)->GetAceFlags() != (CONTAINER_INHERIT_ACE | INHERIT_ONLY_ACE) )
  510. {
  511. DisplayMessageEx(0, MSG_DSACLS_INCORRECT_INHERIT, (*i)->GetInheritedObjectType() );
  512. return FALSE;
  513. }
  514. }
  515. }
  516. return TRUE;
  517. }
  518. void CAcl::Display()
  519. {
  520. if( bAclProtected )
  521. DisplayMessageEx( 0, MSG_DSACLS_PROTECTED );
  522. if( listAces.empty() )
  523. {
  524. DisplayMessageEx( 0, MSG_DSACLS_NO_ACES );
  525. }
  526. //Display Effective permissons on this object
  527. if ( !listEffective.empty() )
  528. {
  529. DisplayMessageEx( 0, MSG_DSACLS_EFFECTIVE );
  530. for ( list<CAce*>::iterator i = listEffective.begin(); i != listEffective.end(); i++ )
  531. {
  532. if( !(*i)->IsObjectTypePresent() )
  533. (*i)->Display( m_nMaxTrusteeLength );
  534. }
  535. for ( i = listEffective.begin(); i != listEffective.end(); i++ )
  536. {
  537. if( (*i)->GetObjectTypeType() == DSACLS_CHILD_OBJECTS )
  538. (*i)->Display( m_nMaxTrusteeLength );
  539. }
  540. for ( i = listEffective.begin(); i != listEffective.end(); i++ )
  541. {
  542. if( (*i)->GetObjectTypeType() == DSACLS_PROPERTY )
  543. (*i)->Display( m_nMaxTrusteeLength );
  544. }
  545. for ( i = listEffective.begin(); i != listEffective.end(); i++ )
  546. {
  547. if( (*i)->GetObjectTypeType() == DSACLS_VALIDATED_RIGHTS )
  548. (*i)->Display( m_nMaxTrusteeLength );
  549. }
  550. for ( i = listEffective.begin(); i != listEffective.end(); i++ )
  551. {
  552. if( (*i)->GetObjectTypeType() == DSACLS_EXTENDED_RIGHTS )
  553. (*i)->Display( m_nMaxTrusteeLength );
  554. }
  555. DisplayNewLine();
  556. }
  557. if( !listInheritedAll.empty() || !listInheritedSpecific.empty() )
  558. DisplayMessageEx( 0, MSG_DSACLS_INHERITED );
  559. //Display permissons inherited by all subobjects
  560. if( !listInheritedAll.empty() )
  561. {
  562. DisplayMessageEx( 0, MSG_DSACLS_INHERITED_ALL );
  563. for ( list<CAce*>::iterator i = listInheritedAll.begin(); i != listInheritedAll.end(); i++ )
  564. {
  565. if( !(*i)->IsObjectTypePresent() )
  566. (*i)->Display( m_nMaxTrusteeLength );
  567. }
  568. for ( i = listInheritedAll.begin(); i != listInheritedAll.end(); i++ )
  569. {
  570. if( (*i)->GetObjectTypeType() == DSACLS_CHILD_OBJECTS )
  571. (*i)->Display( m_nMaxTrusteeLength );
  572. }
  573. for ( i = listInheritedAll.begin(); i != listInheritedAll.end(); i++ )
  574. {
  575. if( (*i)->GetObjectTypeType() == DSACLS_PROPERTY )
  576. (*i)->Display( m_nMaxTrusteeLength );
  577. }
  578. for ( i = listInheritedAll.begin(); i != listInheritedAll.end(); i++ )
  579. {
  580. if( (*i)->GetObjectTypeType() == DSACLS_VALIDATED_RIGHTS )
  581. (*i)->Display( m_nMaxTrusteeLength );
  582. }
  583. for ( i = listInheritedAll.begin(); i != listInheritedAll.end(); i++ )
  584. {
  585. if( (*i)->GetObjectTypeType() == DSACLS_EXTENDED_RIGHTS )
  586. (*i)->Display( m_nMaxTrusteeLength );
  587. }
  588. DisplayNewLine();
  589. }
  590. LPWSTR pszInherit = NULL;
  591. //Display permissons inherited to Inherited Object Class
  592. if( !listInheritedSpecific.empty() )
  593. {
  594. listInheritedSpecific.sort(CACE_SORT());
  595. for ( list<CAce*>::iterator i = listInheritedSpecific.begin(); i != listInheritedSpecific.end(); i++ )
  596. {
  597. if( !pszInherit )
  598. {
  599. pszInherit = (*i)->GetInheritedObjectType();
  600. DisplayMessageEx( 0, MSG_DSACLS_INHERITED_SPECIFIC, pszInherit );
  601. }
  602. else if( wcscmp( pszInherit,(*i)->GetInheritedObjectType() ) )
  603. {
  604. pszInherit = (*i)->GetInheritedObjectType();
  605. DisplayMessageEx( 0, MSG_DSACLS_INHERITED_SPECIFIC, pszInherit );
  606. }
  607. (*i)->Display( m_nMaxTrusteeLength );
  608. }
  609. }
  610. }
  611. DWORD CCache::AddItem( GUID *pGuid,
  612. DSACLS_SEARCH_IN s )
  613. {
  614. ASSERT( pGuid );
  615. PDSACL_CACHE_ITEM pItem = NULL;
  616. pItem = (PDSACL_CACHE_ITEM)LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  617. if( pItem == NULL )
  618. return ERROR_NOT_ENOUGH_MEMORY;
  619. pItem->Guid = *pGuid;
  620. pItem->pszName = NULL;
  621. pItem->bResolved = FALSE;
  622. pItem->resolve = RESOLVE_GUID;
  623. pItem->searchIn = s;
  624. m_listItem.push_back( pItem );
  625. return ERROR_SUCCESS;
  626. }
  627. DWORD CCache::AddItem( LPWSTR pName,
  628. DSACLS_SEARCH_IN s )
  629. {
  630. ASSERT( pName );
  631. PDSACL_CACHE_ITEM pItem = NULL;
  632. DWORD dwErr = ERROR_SUCCESS;
  633. pItem = (PDSACL_CACHE_ITEM)LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  634. if( pItem == NULL )
  635. return ERROR_NOT_ENOUGH_MEMORY;
  636. dwErr = CopyUnicodeString(&pItem->pszName, pName );
  637. if( dwErr != ERROR_SUCCESS )
  638. {
  639. LocalFree( pItem );
  640. return ERROR_NOT_ENOUGH_MEMORY;
  641. }
  642. pItem->bResolved = FALSE;
  643. pItem->resolve = RESOLVE_NAME;
  644. pItem->searchIn = s;
  645. m_listItem.push_back( pItem );
  646. return ERROR_SUCCESS;
  647. }
  648. DWORD CCache::BuildCache()
  649. {
  650. SearchConfiguration();
  651. SearchSchema();
  652. PDSACL_CACHE_ITEM pItem = NULL;
  653. //Empty m_listItem
  654. while( !m_listItem.empty() )
  655. {
  656. pItem = m_listItem.back();
  657. m_listItem.pop_back();
  658. if( pItem->pszName)
  659. LocalFree( pItem->pszName );
  660. LocalFree( pItem );
  661. }
  662. return ERROR_SUCCESS;
  663. }
  664. DWORD CCache::SearchConfiguration()
  665. {
  666. ULONG nTotalFilterSize = 1024;
  667. ULONG nCurrentFilterSize = 0;
  668. LPWSTR lpszFilter = NULL;
  669. LPWSTR lpszFilterTemp = NULL;
  670. WCHAR szTempBuffer[1024];
  671. WCHAR szTempString[1024];
  672. DWORD dwErr = 0;
  673. HRESULT hr = S_OK;
  674. IDirectorySearch * IDs = NULL;
  675. ADS_SEARCH_HANDLE hSearchHandle=NULL;
  676. LPWSTR lpszConfigGuidFilter = L"(rightsGuid=%s)";
  677. LPWSTR lpszConfigNameFilter = L"(displayName=%s)";
  678. LPWSTR pszAttr[] = { L"rightsGuid",L"displayName", L"validAccesses" };
  679. ADS_SEARCH_COLUMN col,col1,col2;
  680. ULONG uLen = 0;
  681. list<PDSACL_CACHE_ITEM>::iterator i;
  682. PDSACL_CACHE_ITEM pCacheItem = NULL;
  683. if( m_listItem.empty() )
  684. return ERROR_SUCCESS;
  685. lpszFilter = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize*sizeof(WCHAR) );
  686. if( lpszFilter == NULL )
  687. {
  688. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  689. goto FAILURE_RETURN;
  690. }
  691. wcscpy(lpszFilter, L"(|" );
  692. nCurrentFilterSize = 4; //One for closing (
  693. for ( i = m_listItem.begin(); i != m_listItem.end(); i++ )
  694. {
  695. if( (*i)->resolve == RESOLVE_GUID &&
  696. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == CONFIGURATION ) ) )
  697. {
  698. FormatStringGUID( szTempString, ARRAYSIZE(szTempString), &(*i)->Guid );
  699. hr = StringCchPrintf(szTempBuffer,ARRAYSIZE(szTempBuffer),lpszConfigGuidFilter,szTempString);
  700. if(FAILED(hr))
  701. {
  702. dwErr = HRESULT_CODE(hr);
  703. goto FAILURE_RETURN;
  704. }
  705. nCurrentFilterSize += wcslen(szTempBuffer);
  706. }
  707. else if( (*i)->resolve == RESOLVE_NAME &&
  708. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  709. {
  710. hr = StringCchPrintf(szTempBuffer,ARRAYSIZE(szTempBuffer),lpszConfigNameFilter,(*i)->pszName);
  711. if(FAILED(hr))
  712. {
  713. dwErr = HRESULT_CODE(hr);
  714. goto FAILURE_RETURN;
  715. }
  716. nCurrentFilterSize += wcslen(szTempBuffer);
  717. }
  718. if( nCurrentFilterSize > nTotalFilterSize )
  719. {
  720. nTotalFilterSize = nTotalFilterSize * 2;
  721. lpszFilterTemp = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize * sizeof( WCHAR ) );
  722. if( lpszFilterTemp == NULL )
  723. {
  724. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  725. goto FAILURE_RETURN;
  726. }
  727. wcscpy( lpszFilterTemp, lpszFilter );
  728. LocalFree(lpszFilter);
  729. lpszFilter = lpszFilterTemp;
  730. lpszFilterTemp = NULL;
  731. }
  732. hr = StringCchCat(lpszFilter,nTotalFilterSize,szTempBuffer);
  733. if(FAILED(hr))
  734. {
  735. dwErr = HRESULT_CODE(hr);
  736. goto FAILURE_RETURN;
  737. }
  738. }
  739. hr = StringCchCat(lpszFilter,nTotalFilterSize,L")");
  740. if(FAILED(hr))
  741. {
  742. dwErr = HRESULT_CODE(hr);
  743. goto FAILURE_RETURN;
  744. }
  745. //We have Filter Now
  746. //Search in Configuration Contianer
  747. hr = ::ADsOpenObject( g_szConfigurationNamingContext,
  748. NULL,
  749. NULL,
  750. ADS_SECURE_AUTHENTICATION,
  751. IID_IDirectorySearch,
  752. (void **)&IDs );
  753. if( hr != S_OK )
  754. {
  755. dwErr = HRESULT_CODE( hr );
  756. goto FAILURE_RETURN;
  757. }
  758. hr = IDs->ExecuteSearch(lpszFilter,
  759. pszAttr,
  760. 3,
  761. &hSearchHandle );
  762. if( hr != S_OK )
  763. {
  764. dwErr = HRESULT_CODE( hr );
  765. goto FAILURE_RETURN;
  766. }
  767. hr = IDs->GetFirstRow(hSearchHandle);
  768. if( hr == S_OK )
  769. {
  770. while( hr != S_ADS_NOMORE_ROWS )
  771. {
  772. pCacheItem = (PDSACL_CACHE_ITEM) LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  773. if( pCacheItem == NULL )
  774. {
  775. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  776. goto FAILURE_RETURN;
  777. }
  778. //Get Guid
  779. hr = IDs->GetColumn( hSearchHandle, pszAttr[0], &col );
  780. if( hr != S_OK )
  781. {
  782. dwErr = HRESULT_CODE( hr );
  783. goto FAILURE_RETURN;
  784. }
  785. GuidFromString( &pCacheItem->Guid, col.pADsValues->CaseIgnoreString);
  786. IDs->FreeColumn( &col );
  787. //Get Display Name
  788. hr = IDs->GetColumn( hSearchHandle, pszAttr[1], &col1 );
  789. if( hr != S_OK )
  790. {
  791. dwErr = HRESULT_CODE( hr );
  792. goto FAILURE_RETURN;
  793. }
  794. uLen = wcslen( (LPWSTR) col1.pADsValues->CaseIgnoreString );
  795. pCacheItem->pszName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( uLen + 1 ) * sizeof( WCHAR) );
  796. if( pCacheItem->pszName == NULL )
  797. {
  798. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  799. goto FAILURE_RETURN;
  800. }
  801. wcscpy( pCacheItem->pszName, col1.pADsValues->CaseIgnoreString );
  802. IDs->FreeColumn( &col1 );
  803. //Get validAccesses
  804. hr = IDs->GetColumn( hSearchHandle, pszAttr[2], &col2 );
  805. if( hr != S_OK )
  806. {
  807. dwErr = HRESULT_CODE( hr );
  808. goto FAILURE_RETURN;
  809. }
  810. pCacheItem->ObjectTypeType = GetObjectTypeType( col2.pADsValues->Integer );
  811. IDs->FreeColumn( &col2 );
  812. //Add item to cache
  813. m_listCache.push_back( pCacheItem );
  814. pCacheItem = NULL;
  815. hr = IDs->GetNextRow(hSearchHandle);
  816. }
  817. }
  818. if( hr == S_ADS_NOMORE_ROWS )
  819. dwErr = ERROR_SUCCESS;
  820. FAILURE_RETURN:
  821. if( lpszFilter )
  822. LocalFree( lpszFilter );
  823. if( IDs )
  824. {
  825. if( hSearchHandle )
  826. IDs->CloseSearchHandle( hSearchHandle );
  827. IDs->Release();
  828. }
  829. if( pCacheItem )
  830. LocalFree( pCacheItem );
  831. return dwErr;
  832. }
  833. DWORD CCache::SearchSchema()
  834. {
  835. ULONG nTotalFilterSize = 1024;
  836. ULONG nCurrentFilterSize = 0;
  837. LPWSTR lpszFilter = NULL;
  838. LPWSTR lpszFilterTemp = NULL;
  839. WCHAR szTempBuffer[1024];
  840. WCHAR szTempString[1024];
  841. LPWSTR pszDestData = NULL;
  842. DWORD dwErr = 0;
  843. HRESULT hr = S_OK;
  844. IDirectorySearch * IDs = NULL;
  845. ADS_SEARCH_HANDLE hSearchHandle=NULL;
  846. LPWSTR lpszSchemaGuidFilter = L"(schemaIdGuid=%s)";
  847. LPWSTR lpszSchemaNameFilter = L"(LDAPdisplayName=%s)";
  848. LPWSTR pszAttr[] = {L"schemaIdGuid",L"LDAPdisplayName", L"objectClass"};
  849. ADS_SEARCH_COLUMN col,col1,col2;
  850. ULONG uLen = 0;
  851. list<PDSACL_CACHE_ITEM>::iterator i;
  852. PDSACL_CACHE_ITEM pCacheItem = NULL;
  853. if( m_listItem.empty() )
  854. return ERROR_SUCCESS;
  855. lpszFilter = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize*sizeof(WCHAR) );
  856. if( lpszFilter == NULL )
  857. {
  858. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  859. goto FAILURE_RETURN;
  860. }
  861. wcscpy(lpszFilter, L"(|" );
  862. nCurrentFilterSize = 4; //One for closing (
  863. for ( i = m_listItem.begin(); i != m_listItem.end(); i++ )
  864. {
  865. if( (*i)->resolve == RESOLVE_GUID &&
  866. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  867. {
  868. ADsEncodeBinaryData( (PBYTE)&((*i)->Guid),
  869. sizeof(GUID),
  870. &pszDestData );
  871. hr = StringCchPrintf(szTempBuffer,ARRAYSIZE(szTempBuffer),lpszSchemaGuidFilter,pszDestData);
  872. LocalFree( pszDestData );
  873. pszDestData = NULL;
  874. if(FAILED(hr))
  875. {
  876. dwErr = HRESULT_CODE(hr);
  877. goto FAILURE_RETURN;
  878. }
  879. nCurrentFilterSize += wcslen(szTempBuffer);
  880. }
  881. else if( (*i)->resolve == RESOLVE_NAME &&
  882. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  883. {
  884. hr = StringCchPrintf(szTempBuffer,ARRAYSIZE(szTempBuffer),lpszSchemaNameFilter,(*i)->pszName );
  885. if(FAILED(hr))
  886. {
  887. dwErr = HRESULT_CODE(hr);
  888. goto FAILURE_RETURN;
  889. }
  890. nCurrentFilterSize += wcslen(szTempBuffer);
  891. }
  892. if( nCurrentFilterSize > nTotalFilterSize )
  893. {
  894. nTotalFilterSize = nTotalFilterSize * 2;
  895. lpszFilterTemp = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize * sizeof( WCHAR ) );
  896. if( lpszFilterTemp == NULL )
  897. {
  898. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  899. goto FAILURE_RETURN;
  900. }
  901. wcscpy( lpszFilterTemp, lpszFilter );
  902. LocalFree( lpszFilter );
  903. lpszFilter = lpszFilterTemp;
  904. lpszFilterTemp = NULL;
  905. }
  906. hr = StringCchCat(lpszFilter,nTotalFilterSize,szTempBuffer);
  907. if(FAILED(hr))
  908. {
  909. dwErr = HRESULT_CODE(hr);
  910. goto FAILURE_RETURN;
  911. }
  912. }
  913. hr = StringCchCat(lpszFilter,nTotalFilterSize,L")");
  914. if(FAILED(hr))
  915. {
  916. dwErr = HRESULT_CODE(hr);
  917. goto FAILURE_RETURN;
  918. }
  919. //We have Filter Now
  920. //Search in Configuration Contianer
  921. hr = ::ADsOpenObject( g_szSchemaNamingContext,
  922. NULL,
  923. NULL,
  924. ADS_SECURE_AUTHENTICATION,
  925. IID_IDirectorySearch,
  926. (void **)&IDs );
  927. if( hr != S_OK )
  928. {
  929. dwErr = HRESULT_CODE( hr );
  930. goto FAILURE_RETURN;
  931. }
  932. hr = IDs->ExecuteSearch(lpszFilter,
  933. pszAttr,
  934. 3,
  935. &hSearchHandle );
  936. if( hr != S_OK )
  937. {
  938. dwErr = HRESULT_CODE( hr );
  939. goto FAILURE_RETURN;
  940. }
  941. hr = IDs->GetFirstRow(hSearchHandle);
  942. if( hr == S_OK )
  943. {
  944. while( hr != S_ADS_NOMORE_ROWS )
  945. {
  946. pCacheItem = (PDSACL_CACHE_ITEM) LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  947. if( pCacheItem == NULL )
  948. {
  949. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  950. goto FAILURE_RETURN;
  951. }
  952. //Get Guid
  953. hr = IDs->GetColumn( hSearchHandle, pszAttr[0], &col );
  954. if( hr != S_OK )
  955. {
  956. dwErr = HRESULT_CODE( hr );
  957. goto FAILURE_RETURN;
  958. }
  959. if(sizeof(GUID) != col.pADsValues->OctetString.dwLength)
  960. {
  961. dwErr = ERROR_INVALID_PARAMETER;
  962. goto FAILURE_RETURN;
  963. }
  964. memcpy( &pCacheItem->Guid,
  965. col.pADsValues->OctetString.lpValue,
  966. col.pADsValues->OctetString.dwLength);
  967. IDs->FreeColumn( &col );
  968. //Get Display Name
  969. hr = IDs->GetColumn( hSearchHandle, pszAttr[1], &col1 );
  970. if( hr != S_OK )
  971. {
  972. dwErr = HRESULT_CODE( hr );
  973. goto FAILURE_RETURN;
  974. }
  975. uLen = wcslen( (LPWSTR) col1.pADsValues->CaseIgnoreString );
  976. pCacheItem->pszName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( uLen + 1 ) * sizeof( WCHAR) );
  977. if( pCacheItem->pszName == NULL )
  978. {
  979. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  980. goto FAILURE_RETURN;
  981. }
  982. wcscpy( pCacheItem->pszName, col1.pADsValues->CaseIgnoreString );
  983. IDs->FreeColumn( &col1 );
  984. //Get Object Class
  985. hr = IDs->GetColumn( hSearchHandle, pszAttr[2], &col2 );
  986. if( hr != S_OK )
  987. {
  988. dwErr = HRESULT_CODE( hr );
  989. goto FAILURE_RETURN;
  990. }
  991. pCacheItem->ObjectTypeType = GetObjectTypeType( col2.pADsValues[1].CaseIgnoreString );
  992. IDs->FreeColumn( &col2 );
  993. //Add item to cache
  994. m_listCache.push_back( pCacheItem );
  995. pCacheItem = NULL;
  996. hr = IDs->GetNextRow(hSearchHandle);
  997. }
  998. }
  999. if( hr == S_ADS_NOMORE_ROWS )
  1000. dwErr = ERROR_SUCCESS;
  1001. FAILURE_RETURN:
  1002. if( lpszFilter )
  1003. LocalFree( lpszFilter );
  1004. if( IDs )
  1005. {
  1006. if( hSearchHandle )
  1007. IDs->CloseSearchHandle( hSearchHandle );
  1008. IDs->Release();
  1009. }
  1010. if( pCacheItem )
  1011. LocalFree( pCacheItem );
  1012. return dwErr;
  1013. }
  1014. PDSACL_CACHE_ITEM CCache::LookUp( LPWSTR pszName )
  1015. {
  1016. if( m_listCache.empty() )
  1017. return NULL;
  1018. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  1019. {
  1020. if( wcscmp( (*i)->pszName, pszName ) == 0 )
  1021. return (*i);
  1022. }
  1023. return NULL;
  1024. }
  1025. PDSACL_CACHE_ITEM CCache::LookUp( GUID *pGuid )
  1026. {
  1027. if( m_listCache.empty() )
  1028. return NULL;
  1029. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  1030. {
  1031. if( IsEqualGUID( (*i)->Guid, *pGuid ) )
  1032. return (*i);
  1033. }
  1034. return NULL;
  1035. }
  1036. CCache::~CCache()
  1037. {
  1038. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  1039. {
  1040. if( (*i)->pszName )
  1041. LocalFree( (*i)->pszName );
  1042. LocalFree(*i);
  1043. }
  1044. for( i = m_listItem.begin(); i != m_listItem.end(); ++i )
  1045. {
  1046. if( (*i)->pszName )
  1047. LocalFree( (*i)->pszName );
  1048. LocalFree(*i);
  1049. }
  1050. }
  1051. //Some Utility Functions
  1052. DSACLS_OBJECT_TYPE_TYPE GetObjectTypeType( INT validAccesses )
  1053. {
  1054. if( FLAG_ON( validAccesses , ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP ) )
  1055. return DSACLS_PROPERTY;
  1056. if( FLAG_ON( validAccesses , ACTRL_DS_CONTROL_ACCESS ) )
  1057. return DSACLS_EXTENDED_RIGHTS;
  1058. if( FLAG_ON( validAccesses , ACTRL_DS_SELF ) )
  1059. return DSACLS_VALIDATED_RIGHTS;
  1060. return DSACLS_UNDEFINED;
  1061. }
  1062. DSACLS_OBJECT_TYPE_TYPE GetObjectTypeType( LPWSTR szObjectCategory )
  1063. {
  1064. if( wcscmp( szObjectCategory, L"attributeSchema" ) == 0 )
  1065. return DSACLS_PROPERTY;
  1066. if( wcscmp( szObjectCategory, L"classSchema" ) == 0 )
  1067. return DSACLS_CHILD_OBJECTS;
  1068. return DSACLS_UNDEFINED;
  1069. }