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.

1180 lines
33 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, 1024, &(*i)->Guid );
  699. wsprintf(szTempBuffer, lpszConfigGuidFilter,szTempString);
  700. nCurrentFilterSize += wcslen(szTempBuffer);
  701. }
  702. else if( (*i)->resolve == RESOLVE_NAME &&
  703. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  704. {
  705. wsprintf( szTempBuffer, lpszConfigNameFilter,(*i)->pszName );
  706. nCurrentFilterSize += wcslen(szTempBuffer);
  707. }
  708. if( nCurrentFilterSize > nTotalFilterSize )
  709. {
  710. nTotalFilterSize = nTotalFilterSize * 2;
  711. lpszFilterTemp = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize * sizeof( WCHAR ) );
  712. if( lpszFilterTemp == NULL )
  713. {
  714. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  715. goto FAILURE_RETURN;
  716. }
  717. wcscpy( lpszFilterTemp, lpszFilter );
  718. LocalFree(lpszFilter);
  719. lpszFilter = lpszFilterTemp;
  720. lpszFilterTemp = NULL;
  721. }
  722. wcscat(lpszFilter,szTempBuffer);
  723. }
  724. wcscat(lpszFilter,L")");
  725. //We have Filter Now
  726. //Search in Configuration Contianer
  727. hr = ::ADsOpenObject( g_szConfigurationNamingContext,
  728. NULL,
  729. NULL,
  730. ADS_SECURE_AUTHENTICATION,
  731. IID_IDirectorySearch,
  732. (void **)&IDs );
  733. if( hr != S_OK )
  734. {
  735. dwErr = HRESULT_CODE( hr );
  736. }
  737. hr = IDs->ExecuteSearch(lpszFilter,
  738. pszAttr,
  739. 3,
  740. &hSearchHandle );
  741. if( hr != S_OK )
  742. {
  743. dwErr = HRESULT_CODE( hr );
  744. goto FAILURE_RETURN;
  745. }
  746. hr = IDs->GetFirstRow(hSearchHandle);
  747. if( hr == S_OK )
  748. {
  749. while( hr != S_ADS_NOMORE_ROWS )
  750. {
  751. pCacheItem = (PDSACL_CACHE_ITEM) LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  752. if( pCacheItem == NULL )
  753. {
  754. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  755. goto FAILURE_RETURN;
  756. }
  757. //Get Guid
  758. hr = IDs->GetColumn( hSearchHandle, pszAttr[0], &col );
  759. if( hr != S_OK )
  760. {
  761. dwErr = HRESULT_CODE( hr );
  762. goto FAILURE_RETURN;
  763. }
  764. GuidFromString( &pCacheItem->Guid, col.pADsValues->CaseIgnoreString);
  765. IDs->FreeColumn( &col );
  766. //Get Display Name
  767. hr = IDs->GetColumn( hSearchHandle, pszAttr[1], &col1 );
  768. if( hr != S_OK )
  769. {
  770. dwErr = HRESULT_CODE( hr );
  771. goto FAILURE_RETURN;
  772. }
  773. uLen = wcslen( (LPWSTR) col1.pADsValues->CaseIgnoreString );
  774. pCacheItem->pszName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( uLen + 1 ) * sizeof( WCHAR) );
  775. if( pCacheItem->pszName == NULL )
  776. {
  777. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  778. goto FAILURE_RETURN;
  779. }
  780. wcscpy( pCacheItem->pszName, col1.pADsValues->CaseIgnoreString );
  781. IDs->FreeColumn( &col1 );
  782. //Get validAccesses
  783. hr = IDs->GetColumn( hSearchHandle, pszAttr[2], &col2 );
  784. if( hr != S_OK )
  785. {
  786. dwErr = HRESULT_CODE( hr );
  787. goto FAILURE_RETURN;
  788. }
  789. pCacheItem->ObjectTypeType = GetObjectTypeType( col2.pADsValues->Integer );
  790. IDs->FreeColumn( &col2 );
  791. //Add item to cache
  792. m_listCache.push_back( pCacheItem );
  793. pCacheItem = NULL;
  794. hr = IDs->GetNextRow(hSearchHandle);
  795. }
  796. }
  797. if( hr == S_ADS_NOMORE_ROWS )
  798. dwErr = ERROR_SUCCESS;
  799. FAILURE_RETURN:
  800. if( lpszFilter )
  801. LocalFree( lpszFilter );
  802. if( IDs )
  803. {
  804. if( hSearchHandle )
  805. IDs->CloseSearchHandle( hSearchHandle );
  806. IDs->Release();
  807. }
  808. if( pCacheItem )
  809. LocalFree( pCacheItem );
  810. return dwErr;
  811. }
  812. DWORD CCache::SearchSchema()
  813. {
  814. ULONG nTotalFilterSize = 1024;
  815. ULONG nCurrentFilterSize = 0;
  816. LPWSTR lpszFilter = NULL;
  817. LPWSTR lpszFilterTemp = NULL;
  818. WCHAR szTempBuffer[1024];
  819. WCHAR szTempString[1024];
  820. LPWSTR pszDestData = NULL;
  821. DWORD dwErr = 0;
  822. HRESULT hr = S_OK;
  823. IDirectorySearch * IDs = NULL;
  824. ADS_SEARCH_HANDLE hSearchHandle=NULL;
  825. LPWSTR lpszSchemaGuidFilter = L"(schemaIdGuid=%s)";
  826. LPWSTR lpszSchemaNameFilter = L"(LDAPdisplayName=%s)";
  827. LPWSTR pszAttr[] = {L"schemaIdGuid",L"LDAPdisplayName", L"objectClass"};
  828. ADS_SEARCH_COLUMN col,col1,col2;
  829. ULONG uLen = 0;
  830. list<PDSACL_CACHE_ITEM>::iterator i;
  831. PDSACL_CACHE_ITEM pCacheItem = NULL;
  832. if( m_listItem.empty() )
  833. return ERROR_SUCCESS;
  834. lpszFilter = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize*sizeof(WCHAR) );
  835. if( lpszFilter == NULL )
  836. {
  837. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  838. goto FAILURE_RETURN;
  839. }
  840. wcscpy(lpszFilter, L"(|" );
  841. nCurrentFilterSize = 4; //One for closing (
  842. for ( i = m_listItem.begin(); i != m_listItem.end(); i++ )
  843. {
  844. if( (*i)->resolve == RESOLVE_GUID &&
  845. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  846. {
  847. ADsEncodeBinaryData( (PBYTE)&((*i)->Guid),
  848. sizeof(GUID),
  849. &pszDestData );
  850. wsprintf(szTempBuffer, lpszSchemaGuidFilter,pszDestData);
  851. nCurrentFilterSize += wcslen(szTempBuffer);
  852. LocalFree( pszDestData );
  853. pszDestData = NULL;
  854. }
  855. else if( (*i)->resolve == RESOLVE_NAME &&
  856. ( ( (*i)->searchIn == BOTH ) || ( (*i)->searchIn == SCHEMA ) ) )
  857. {
  858. wsprintf( szTempBuffer, lpszSchemaNameFilter,(*i)->pszName );
  859. nCurrentFilterSize += wcslen(szTempBuffer);
  860. }
  861. if( nCurrentFilterSize > nTotalFilterSize )
  862. {
  863. nTotalFilterSize = nTotalFilterSize * 2;
  864. lpszFilterTemp = (LPWSTR)LocalAlloc( LMEM_FIXED, nTotalFilterSize * sizeof( WCHAR ) );
  865. if( lpszFilterTemp == NULL )
  866. {
  867. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  868. goto FAILURE_RETURN;
  869. }
  870. wcscpy( lpszFilterTemp, lpszFilter );
  871. LocalFree( lpszFilter );
  872. lpszFilter = lpszFilterTemp;
  873. lpszFilterTemp = NULL;
  874. }
  875. wcscat(lpszFilter,szTempBuffer);
  876. }
  877. wcscat(lpszFilter,L")");
  878. //We have Filter Now
  879. //Search in Configuration Contianer
  880. hr = ::ADsOpenObject( g_szSchemaNamingContext,
  881. NULL,
  882. NULL,
  883. ADS_SECURE_AUTHENTICATION,
  884. IID_IDirectorySearch,
  885. (void **)&IDs );
  886. if( hr != S_OK )
  887. {
  888. dwErr = HRESULT_CODE( hr );
  889. }
  890. hr = IDs->ExecuteSearch(lpszFilter,
  891. pszAttr,
  892. 3,
  893. &hSearchHandle );
  894. if( hr != S_OK )
  895. {
  896. dwErr = HRESULT_CODE( hr );
  897. goto FAILURE_RETURN;
  898. }
  899. hr = IDs->GetFirstRow(hSearchHandle);
  900. if( hr == S_OK )
  901. {
  902. while( hr != S_ADS_NOMORE_ROWS )
  903. {
  904. pCacheItem = (PDSACL_CACHE_ITEM) LocalAlloc( LMEM_FIXED, sizeof( DSACL_CACHE_ITEM ) );
  905. if( pCacheItem == NULL )
  906. {
  907. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  908. goto FAILURE_RETURN;
  909. }
  910. //Get Guid
  911. hr = IDs->GetColumn( hSearchHandle, pszAttr[0], &col );
  912. if( hr != S_OK )
  913. {
  914. dwErr = HRESULT_CODE( hr );
  915. goto FAILURE_RETURN;
  916. }
  917. memcpy( &pCacheItem->Guid,
  918. col.pADsValues->OctetString.lpValue,
  919. col.pADsValues->OctetString.dwLength);
  920. IDs->FreeColumn( &col );
  921. //Get Display Name
  922. hr = IDs->GetColumn( hSearchHandle, pszAttr[1], &col1 );
  923. if( hr != S_OK )
  924. {
  925. dwErr = HRESULT_CODE( hr );
  926. goto FAILURE_RETURN;
  927. }
  928. uLen = wcslen( (LPWSTR) col1.pADsValues->CaseIgnoreString );
  929. pCacheItem->pszName = (LPWSTR)LocalAlloc( LMEM_FIXED, ( uLen + 1 ) * sizeof( WCHAR) );
  930. if( pCacheItem->pszName == NULL )
  931. {
  932. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  933. goto FAILURE_RETURN;
  934. }
  935. wcscpy( pCacheItem->pszName, col1.pADsValues->CaseIgnoreString );
  936. IDs->FreeColumn( &col1 );
  937. //Get Object Class
  938. hr = IDs->GetColumn( hSearchHandle, pszAttr[2], &col2 );
  939. if( hr != S_OK )
  940. {
  941. dwErr = HRESULT_CODE( hr );
  942. goto FAILURE_RETURN;
  943. }
  944. pCacheItem->ObjectTypeType = GetObjectTypeType( col2.pADsValues[1].CaseIgnoreString );
  945. IDs->FreeColumn( &col2 );
  946. //Add item to cache
  947. m_listCache.push_back( pCacheItem );
  948. pCacheItem = NULL;
  949. hr = IDs->GetNextRow(hSearchHandle);
  950. }
  951. }
  952. if( hr == S_ADS_NOMORE_ROWS )
  953. dwErr = ERROR_SUCCESS;
  954. FAILURE_RETURN:
  955. if( lpszFilter )
  956. LocalFree( lpszFilter );
  957. if( IDs )
  958. {
  959. if( hSearchHandle )
  960. IDs->CloseSearchHandle( hSearchHandle );
  961. IDs->Release();
  962. }
  963. if( pCacheItem )
  964. LocalFree( pCacheItem );
  965. return dwErr;
  966. }
  967. PDSACL_CACHE_ITEM CCache::LookUp( LPWSTR pszName )
  968. {
  969. if( m_listCache.empty() )
  970. return NULL;
  971. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  972. {
  973. if( wcscmp( (*i)->pszName, pszName ) == 0 )
  974. return (*i);
  975. }
  976. return NULL;
  977. }
  978. PDSACL_CACHE_ITEM CCache::LookUp( GUID *pGuid )
  979. {
  980. if( m_listCache.empty() )
  981. return NULL;
  982. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  983. {
  984. if( IsEqualGUID( (*i)->Guid, *pGuid ) )
  985. return (*i);
  986. }
  987. return NULL;
  988. }
  989. CCache::~CCache()
  990. {
  991. for( list<PDSACL_CACHE_ITEM>::iterator i = m_listCache.begin(); i != m_listCache.end(); ++i )
  992. {
  993. if( (*i)->pszName )
  994. LocalFree( (*i)->pszName );
  995. LocalFree(*i);
  996. }
  997. for( i = m_listItem.begin(); i != m_listItem.end(); ++i )
  998. {
  999. if( (*i)->pszName )
  1000. LocalFree( (*i)->pszName );
  1001. LocalFree(*i);
  1002. }
  1003. }
  1004. //Some Utility Functions
  1005. DSACLS_OBJECT_TYPE_TYPE GetObjectTypeType( INT validAccesses )
  1006. {
  1007. if( FLAG_ON( validAccesses , ACTRL_DS_READ_PROP | ACTRL_DS_WRITE_PROP ) )
  1008. return DSACLS_PROPERTY;
  1009. if( FLAG_ON( validAccesses , ACTRL_DS_CONTROL_ACCESS ) )
  1010. return DSACLS_EXTENDED_RIGHTS;
  1011. if( FLAG_ON( validAccesses , ACTRL_DS_SELF ) )
  1012. return DSACLS_VALIDATED_RIGHTS;
  1013. return DSACLS_UNDEFINED;
  1014. }
  1015. DSACLS_OBJECT_TYPE_TYPE GetObjectTypeType( LPWSTR szObjectCategory )
  1016. {
  1017. if( wcscmp( szObjectCategory, L"attributeSchema" ) == 0 )
  1018. return DSACLS_PROPERTY;
  1019. if( wcscmp( szObjectCategory, L"classSchema" ) == 0 )
  1020. return DSACLS_CHILD_OBJECTS;
  1021. return DSACLS_UNDEFINED;
  1022. }