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.

2263 lines
58 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. azstore.cxx
  5. Abstract:
  6. Routines implementing the Authorization Store object
  7. Author:
  8. Cliff Van Dyke (cliffv) 11-Apr-2001
  9. History:
  10. Chaitanya D. Upadhyay (chaitu) 28-May-2002
  11. Changed all references to AdminManager to AzAuthorizationStore
  12. --*/
  13. #include "pch.hxx"
  14. //
  15. // Global Data
  16. //
  17. //
  18. // Global list of all AzAuthorizationStores for this process
  19. // Access serialized by AzGlResource
  20. //
  21. GENERIC_OBJECT_HEAD AzGlAzStores;
  22. SAFE_RESOURCE AzGlResource;
  23. SAFE_RESOURCE AzGlCloseApplication;
  24. BOOL ResourceInitialized = FALSE;
  25. BOOL AzIsDC = FALSE;
  26. UCHAR SidBuffer[SECURITY_MAX_SID_SIZE] = {0};
  27. PSID AzAccountDomainSid = (PSID) SidBuffer;
  28. BOOL AzAccountDomainSidInitialized = FALSE;
  29. GUID AzGlZeroGuid;
  30. //
  31. // Well known sids
  32. //
  33. PSID AzGlCreatorOwnerSid;
  34. PSID AzGlWorldSid;
  35. PSID AzGlCreatorGroupSid;
  36. ULONG AzGlWorldSidSize;
  37. //
  38. // Define the default values for all scalar attributes
  39. //
  40. ULONG AzGlDefDomainTimeout = AZ_AZSTORE_DEFAULT_DOMAIN_TIMEOUT;
  41. ULONG AzGlDefScriptEngineTimeout = AZ_AZSTORE_DEFAULT_SCRIPT_ENGINE_TIMEOUT;
  42. ULONG AzGlDefMaxScriptEngines = AZ_AZSTORE_DEFAULT_MAX_SCRIPT_ENGINES;
  43. ULONG AzGlCurrAzRolesMajorVersion = 1;
  44. ULONG AzGlCurrAzRolesMinorVersion = 0;
  45. AZP_DEFAULT_VALUE AzGlAzStoreDefaultValues[] = {
  46. { AZ_PROP_AZSTORE_DOMAIN_TIMEOUT, AZ_DIRTY_AZSTORE_DOMAIN_TIMEOUT, &AzGlDefDomainTimeout },
  47. { AZ_PROP_AZSTORE_SCRIPT_ENGINE_TIMEOUT, AZ_DIRTY_AZSTORE_SCRIPT_ENGINE_TIMEOUT, &AzGlDefScriptEngineTimeout },
  48. { AZ_PROP_AZSTORE_MAX_SCRIPT_ENGINES, AZ_DIRTY_AZSTORE_MAX_SCRIPT_ENGINES, &AzGlDefMaxScriptEngines },
  49. { AZ_PROP_AZSTORE_MAJOR_VERSION, AZ_DIRTY_AZSTORE_MAJOR_VERSION, &AzGlCurrAzRolesMajorVersion},
  50. { AZ_PROP_AZSTORE_MINOR_VERSION, AZ_DIRTY_AZSTORE_MINOR_VERSION, &AzGlCurrAzRolesMinorVersion},
  51. { 0, 0, NULL }
  52. };
  53. AZP_STRING AzGEmptyString = {0};
  54. #if DBG
  55. BOOL CritSectInitialized = FALSE;
  56. #endif // DBG
  57. #ifdef AZROLESDBG
  58. BOOL LogFileCritSectInitialized = FALSE;
  59. DWORD
  60. myatolx(
  61. char const *psz)
  62. {
  63. DWORD dw = 0;
  64. while (isxdigit(*psz))
  65. {
  66. char ch = *psz++;
  67. if (isdigit(ch))
  68. {
  69. ch -= '0';
  70. }
  71. else if (isupper(ch))
  72. {
  73. ch += 10 - 'A';
  74. }
  75. else
  76. {
  77. ch += 10 - 'a';
  78. }
  79. dw = (dw << 4) | ch;
  80. }
  81. return(dw);
  82. }
  83. #endif //AZROLESDBG
  84. DWORD
  85. AzpInitializeAccountDomainSid( VOID )
  86. /*++
  87. Routine description:
  88. This routine reads whether this machine is a DC and reads the AccountDomain
  89. sid if it is not.
  90. Arguments: None
  91. Return Value:
  92. Returns ERROR_SUCCESS on success, appropriate failure value otherwise.
  93. --*/
  94. {
  95. DWORD WinStatus;
  96. NTSTATUS Status;
  97. PDSROLE_PRIMARY_DOMAIN_INFO_BASIC BasicInfo = NULL;
  98. LSA_HANDLE hPolicy = NULL;
  99. OBJECT_ATTRIBUTES obja = {0};
  100. PPOLICY_ACCOUNT_DOMAIN_INFO pAccountInfo = NULL;
  101. //
  102. // Get the information about the local machine.
  103. //
  104. WinStatus = DsRoleGetPrimaryDomainInformation(
  105. NULL,
  106. DsRolePrimaryDomainInfoBasic,
  107. (PBYTE *) &BasicInfo );
  108. if ( WinStatus != NO_ERROR )
  109. {
  110. return WinStatus;
  111. }
  112. switch(BasicInfo->MachineRole)
  113. {
  114. case DsRole_RolePrimaryDomainController:
  115. case DsRole_RoleBackupDomainController:
  116. //
  117. // If the local machine is a DC then the client account must be a domain
  118. // account. The only workgroup accounts that can be authenticated are
  119. // local machine accounts.
  120. // Note that in this case we do not read the AccountDomainSid.
  121. //
  122. AzIsDC = TRUE;
  123. DsRoleFreeMemory( BasicInfo );
  124. return NO_ERROR;
  125. default:
  126. DsRoleFreeMemory( BasicInfo );
  127. break;
  128. }
  129. //
  130. // This may be a member server or a standalone machine. We need to get the
  131. // AccountDomainSid.
  132. //
  133. // open LSA policy
  134. //
  135. Status = LsaOpenPolicy(
  136. 0,
  137. &obja,
  138. POLICY_VIEW_LOCAL_INFORMATION,
  139. &hPolicy );
  140. if (!NT_SUCCESS(Status))
  141. {
  142. WinStatus = LsaNtStatusToWinError(Status);
  143. goto Cleanup;
  144. }
  145. //
  146. // Read the AccountDomainOformation.
  147. //
  148. Status = LsaQueryInformationPolicy(
  149. hPolicy,
  150. PolicyAccountDomainInformation,
  151. (PVOID*)&pAccountInfo
  152. );
  153. if ( !NT_SUCCESS( Status ) )
  154. {
  155. WinStatus = LsaNtStatusToWinError( Status );
  156. goto Cleanup;
  157. }
  158. ASSERT( RtlLengthSid( pAccountInfo->DomainSid ) < SECURITY_MAX_SID_SIZE );
  159. //
  160. // Copy the AccountDomainSid into global buffer.
  161. //
  162. Status = RtlCopySid(
  163. RtlLengthSid( pAccountInfo->DomainSid ),
  164. AzAccountDomainSid,
  165. pAccountInfo->DomainSid );
  166. if ( !NT_SUCCESS( Status ) )
  167. {
  168. WinStatus = LsaNtStatusToWinError( Status );
  169. goto Cleanup;
  170. }
  171. AzAccountDomainSidInitialized = TRUE;
  172. Cleanup:
  173. if ( hPolicy != NULL )
  174. {
  175. LsaClose( hPolicy );
  176. }
  177. if ( pAccountInfo != NULL )
  178. {
  179. LsaFreeMemory(pAccountInfo);
  180. }
  181. return WinStatus;
  182. }
  183. PSID
  184. AzpAllocateWellKnownSid(
  185. IN WELL_KNOWN_SID_TYPE WellKnownSidType
  186. )
  187. /*++
  188. Routine Description:
  189. This routine allocate the SID of a well known security principal
  190. Arguments:
  191. WellKnownSidType - the well known account sid that the caller desires
  192. Return Values:
  193. A pointer to the allocated SID. The caller must call AzpFreeHeap to free the sid.
  194. NULL - buffer couldn't be allocated
  195. --*/
  196. {
  197. DWORD WinStatus;
  198. DWORD SidSize;
  199. PSID Sid = NULL;
  200. //
  201. // Determine the size of the buffer
  202. //
  203. SidSize = 0;
  204. if (!CreateWellKnownSid( WellKnownSidType, NULL, NULL, &SidSize)) {
  205. WinStatus = GetLastError();
  206. if ( WinStatus != ERROR_INSUFFICIENT_BUFFER ) {
  207. return NULL;
  208. }
  209. } else {
  210. return NULL;
  211. }
  212. //
  213. // Allocate the buffer
  214. //
  215. Sid = AzpAllocateHeap( SidSize, "UTILWSID" );
  216. if ( Sid == NULL ) {
  217. return NULL;
  218. }
  219. //
  220. // Fill in the SID
  221. //
  222. if (!CreateWellKnownSid( WellKnownSidType, NULL, Sid, &SidSize)) {
  223. AzpFreeHeap( Sid );
  224. Sid = NULL;
  225. }
  226. return Sid;
  227. }
  228. BOOL
  229. AzDllInitialize(VOID)
  230. /*++
  231. Routine Description
  232. This initializes global events and variables for the DLL.
  233. Arguments
  234. none
  235. Return Value
  236. Boolean: TRUE on success, FALSE on fail.
  237. --*/
  238. {
  239. #ifdef DBG
  240. NTSTATUS Status;
  241. #endif // DBG
  242. BOOL RetVal = TRUE;
  243. DWORD WinStatus;
  244. //
  245. // Initialize global constants
  246. //
  247. RtlZeroMemory( &AzGlZeroGuid, sizeof(AzGlZeroGuid) );
  248. //
  249. // Initialize the safe lock subsystem
  250. //
  251. #ifdef DBG
  252. Status = SafeLockInit( SAFE_MAX_LOCK, TRUE );
  253. if ( !NT_SUCCESS( Status )) {
  254. RetVal = FALSE;
  255. KdPrint(("AzRoles.dll: SafeLockInit failed: 0x%lx\n",
  256. Status ));
  257. goto Cleanup;
  258. }
  259. #endif
  260. //
  261. // Initialize the resource
  262. //
  263. __try {
  264. SafeInitializeResource( &AzGlCloseApplication, SAFE_CLOSE_APPLICATION );
  265. SafeInitializeResource( &AzGlResource, SAFE_GLOBAL_LOCK );
  266. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  267. RetVal = FALSE;
  268. KdPrint(("AzRoles.dll: RtlInitializeResource failed: 0x%lx\n",
  269. GetExceptionCode() ));
  270. goto Cleanup;
  271. }
  272. ResourceInitialized = TRUE;
  273. //
  274. // Initialize the root of the tree of objects
  275. //
  276. AzpLockResourceExclusive( &AzGlResource );
  277. ObInitGenericHead( &AzGlAzStores, OBJECT_TYPE_AZAUTHSTORE, NULL, NULL );
  278. AzpUnlockResource( &AzGlResource );
  279. //
  280. // Initialize the stack allocator
  281. //
  282. SafeAllocaInitialize(
  283. SAFEALLOCA_USE_DEFAULT,
  284. SAFEALLOCA_USE_DEFAULT,
  285. AzpAllocateHeapSafe,
  286. AzpFreeHeap
  287. );
  288. WinStatus = AzpInitializeAccountDomainSid();
  289. if ( WinStatus != NO_ERROR ) {
  290. RetVal = FALSE;
  291. KdPrint(("AzRoles.dll: AzpInitializeAccountDomainSid failed: 0x%lx\n",
  292. WinStatus ));
  293. goto Cleanup;
  294. }
  295. #if DBG
  296. //
  297. // Initialize the allocator
  298. //
  299. InitializeListHead ( &AzGlAllocatedBlocks );
  300. Status = SafeInitializeCriticalSection( &AzGlAllocatorCritSect, SAFE_ALLOCATOR );
  301. if ( !NT_SUCCESS( Status )) {
  302. RetVal = FALSE;
  303. KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlAllocatorCritSect) failed: 0x%lx\n",
  304. Status ));
  305. goto Cleanup;
  306. }
  307. CritSectInitialized = TRUE;
  308. #endif // DBG
  309. #ifdef AZROLESDBG
  310. //
  311. // Initialize debugging
  312. //
  313. Status = SafeInitializeCriticalSection( &AzGlLogFileCritSect, SAFE_LOGFILE );
  314. if ( !NT_SUCCESS( Status )) {
  315. RetVal = FALSE;
  316. KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlLogFileCritSect) failed: 0x%lx\n",
  317. Status ));
  318. goto Cleanup;
  319. }
  320. LogFileCritSectInitialized = TRUE;
  321. //
  322. // Get debug flag from environment variable AZDBG
  323. //
  324. char const *pszAzDbg;
  325. pszAzDbg = getenv("AZDBG");
  326. if (NULL != pszAzDbg)
  327. {
  328. AzGlDbFlag |= myatolx(pszAzDbg);
  329. }
  330. #endif // AZROLESDBG
  331. //
  332. // Initialize Global variables
  333. //
  334. AzGlCreatorOwnerSid = AzpAllocateWellKnownSid( WinCreatorOwnerSid );
  335. if ( AzGlCreatorOwnerSid == NULL ) {
  336. RetVal = FALSE;
  337. KdPrint(("AzRoles.dll: Cannot allocate creator owner sid\n" ));
  338. goto Cleanup;
  339. }
  340. AzGlCreatorGroupSid = AzpAllocateWellKnownSid( WinCreatorGroupSid );
  341. if ( AzGlCreatorGroupSid == NULL ) {
  342. RetVal = FALSE;
  343. KdPrint(("AzRoles.dll: Cannot allocate creator group sid\n" ));
  344. goto Cleanup;
  345. }
  346. AzGlWorldSid = AzpAllocateWellKnownSid( WinWorldSid );
  347. if ( AzGlWorldSid == NULL ) {
  348. RetVal = FALSE;
  349. KdPrint(("AzRoles.dll: Cannot allocate world sid\n" ));
  350. goto Cleanup;
  351. }
  352. AzGlWorldSidSize = GetLengthSid( AzGlWorldSid );
  353. Cleanup:
  354. if ( !RetVal ) {
  355. AzDllUnInitialize();
  356. }
  357. return RetVal;
  358. }
  359. BOOL
  360. AzDllUnInitialize(VOID)
  361. /*++
  362. Routine Description
  363. This uninitializes global events and variables for the DLL.
  364. Arguments
  365. none
  366. Return Value
  367. Boolean: TRUE on success, FALSE on fail.
  368. --*/
  369. {
  370. BOOL RetVal = TRUE;
  371. //
  372. // Free any global resources
  373. //
  374. if ( AzGlCreatorOwnerSid != NULL ) {
  375. AzpFreeHeap( AzGlCreatorOwnerSid );
  376. AzGlCreatorOwnerSid = NULL;
  377. }
  378. if ( AzGlCreatorGroupSid != NULL ) {
  379. AzpFreeHeap( AzGlCreatorGroupSid );
  380. AzGlCreatorGroupSid = NULL;
  381. }
  382. if ( AzGlWorldSid != NULL ) {
  383. AzpFreeHeap( AzGlWorldSid );
  384. AzGlWorldSid = NULL;
  385. }
  386. //
  387. // Delete the resource
  388. //
  389. if ( ResourceInitialized ) {
  390. SafeDeleteResource( &AzGlResource );
  391. SafeDeleteResource( &AzGlCloseApplication );
  392. ResourceInitialized = FALSE;
  393. }
  394. #if DBG
  395. //
  396. // Done with the allocator
  397. //
  398. if ( CritSectInitialized ) {
  399. ASSERT( IsListEmpty( &AzGlAllocatedBlocks ));
  400. SafeDeleteCriticalSection ( &AzGlAllocatorCritSect );
  401. CritSectInitialized = FALSE;
  402. }
  403. #endif // DBG
  404. #ifdef AZROLESDBG
  405. //
  406. // Done with debugging
  407. //
  408. if ( LogFileCritSectInitialized ) {
  409. SafeDeleteCriticalSection ( &AzGlLogFileCritSect );
  410. LogFileCritSectInitialized = FALSE;
  411. }
  412. #endif // AZROLESDBG
  413. return RetVal;
  414. }
  415. VOID
  416. AzpAzStoreCleanupAuditSystem(
  417. IN OUT PAZP_AZSTORE AzAuthorizationStore
  418. )
  419. /*++
  420. Routine Description:
  421. This routines deregisters the event types with Authz audit system.
  422. Arguments:
  423. AzAuthorizationStore - Authorization Store for which the audit handles will be deregistered.
  424. Return Value:
  425. NO_ERROR - The operation was successful
  426. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  427. Other exception status codes
  428. --*/
  429. {
  430. //
  431. // Free the audit handles
  432. //
  433. if ( AzAuthorizationStore->hClientContextCreateAuditEventType != NULL )
  434. {
  435. AuthziFreeAuditEventType( AzAuthorizationStore->hClientContextCreateAuditEventType );
  436. AzAuthorizationStore->hClientContextCreateAuditEventType = NULL;
  437. }
  438. if ( AzAuthorizationStore->hClientContextDeleteAuditEventType != NULL )
  439. {
  440. AuthziFreeAuditEventType( AzAuthorizationStore->hClientContextDeleteAuditEventType );
  441. AzAuthorizationStore->hClientContextDeleteAuditEventType = NULL;
  442. }
  443. if ( AzAuthorizationStore->hAccessCheckAuditEventType != NULL )
  444. {
  445. AuthziFreeAuditEventType( AzAuthorizationStore->hAccessCheckAuditEventType );
  446. AzAuthorizationStore->hAccessCheckAuditEventType = NULL;
  447. }
  448. if ( AzAuthorizationStore->hApplicationInitializationAuditEventType != NULL)
  449. {
  450. AuthziFreeAuditEventType( AzAuthorizationStore->hApplicationInitializationAuditEventType );
  451. AzAuthorizationStore->hApplicationInitializationAuditEventType = NULL;
  452. }
  453. if ( AzAuthorizationStore->hClientContextCreateNameAuditEventType != NULL )
  454. {
  455. AuthziFreeAuditEventType( AzAuthorizationStore->hClientContextCreateNameAuditEventType );
  456. AzAuthorizationStore->hClientContextCreateNameAuditEventType = NULL;
  457. }
  458. if ( AzAuthorizationStore->hClientContextDeleteNameAuditEventType != NULL )
  459. {
  460. AuthziFreeAuditEventType( AzAuthorizationStore->hClientContextDeleteNameAuditEventType );
  461. AzAuthorizationStore->hClientContextDeleteNameAuditEventType = NULL;
  462. }
  463. if ( AzAuthorizationStore->hAccessCheckNameAuditEventType != NULL )
  464. {
  465. AuthziFreeAuditEventType( AzAuthorizationStore->hAccessCheckNameAuditEventType );
  466. AzAuthorizationStore->hAccessCheckNameAuditEventType = NULL;
  467. }
  468. return;
  469. }
  470. DWORD
  471. AzpAzStoreInitializeAuditSystem(
  472. IN OUT PAZP_AZSTORE AzAuthorizationStore
  473. )
  474. /*++
  475. Routine Description:
  476. This routines registers the event types with Authz audit system. We need
  477. one event handle per type of event generated.
  478. Arguments:
  479. AzAuthorizationStore - Authorization Store for which the audit handles will be registered.
  480. Return Value:
  481. NO_ERROR - The operation was successful
  482. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  483. Other exception status codes
  484. --*/
  485. {
  486. BOOL b;
  487. HANDLE hToken = NULL;
  488. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hClientContextCreateNameAuditEventType = NULL;
  489. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hClientContextDeleteNameAuditEventType = NULL;
  490. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hAccessCheckNameAuditEventType = NULL;
  491. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hClientContextCreateAuditEventType = NULL;
  492. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hClientContextDeleteAuditEventType = NULL;
  493. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hAccessCheckAuditEventType = NULL;
  494. AUTHZ_AUDIT_EVENT_TYPE_HANDLE hApplicationInitializationAuditEventType = NULL;
  495. TOKEN_PRIVILEGES NewPrivilegeState = {0};
  496. DWORD WinStatus;
  497. TOKEN_PRIVILEGES OldPrivilegeState = {0};
  498. BOOL PrivilegeAdjusted = FALSE;
  499. //
  500. // Set the values to Zero.
  501. //
  502. AzAuthorizationStore->hAccessCheckAuditEventType = NULL;
  503. AzAuthorizationStore->hApplicationInitializationAuditEventType = NULL;
  504. AzAuthorizationStore->hClientContextCreateAuditEventType = NULL;
  505. AzAuthorizationStore->hClientContextDeleteAuditEventType = NULL;
  506. AzAuthorizationStore->hAccessCheckNameAuditEventType = NULL;
  507. AzAuthorizationStore->hClientContextCreateNameAuditEventType = NULL;
  508. AzAuthorizationStore->hClientContextDeleteNameAuditEventType = NULL;
  509. //
  510. // Get the current token to adjust the Audit privilege.
  511. //
  512. WinStatus = AzpGetCurrentToken( &hToken );
  513. if ( WinStatus != NO_ERROR ) {
  514. return WinStatus;
  515. }
  516. //
  517. // Enable the audit privilege
  518. // If the initialize flag has the audit_is_critical bit set, then fail
  519. // if privilege is not held. If the bit is not set, then simply return
  520. // w/o initializing any audit handles.
  521. //
  522. WinStatus = AzpChangeSinglePrivilege(
  523. SE_AUDIT_PRIVILEGE,
  524. hToken,
  525. &NewPrivilegeState,
  526. &OldPrivilegeState );
  527. if ( WinStatus != NO_ERROR ) {
  528. CloseHandle( hToken );
  529. if ( (AzAuthorizationStore->InitializeFlag & AZ_AZSTORE_FLAG_AUDIT_IS_CRITICAL) == 0 ) {
  530. //
  531. // Audit is not critical
  532. //
  533. WinStatus = NO_ERROR;
  534. }
  535. return WinStatus;
  536. }
  537. PrivilegeAdjusted = TRUE;
  538. //
  539. // Get audit handles for the event types we are interested in.
  540. //
  541. // Audit handle for Client context creation audit.
  542. b = AuthziInitializeAuditEventType( 0,
  543. SE_CATEGID_OBJECT_ACCESS,
  544. SE_AUDITID_AZ_CLIENTCONTEXT_CREATION,
  545. AZP_CLIENTCREATE_AUDITPARAMS_NO,
  546. &hClientContextCreateAuditEventType );
  547. if ( !b ) {
  548. WinStatus = GetLastError();
  549. goto Cleanup;
  550. }
  551. // Audit handle for Client context deletion audit.
  552. b = AuthziInitializeAuditEventType( 0,
  553. SE_CATEGID_OBJECT_ACCESS,
  554. SE_AUDITID_AZ_CLIENTCONTEXT_DELETION,
  555. AZP_CLIENTDELETE_AUDITPARAMS_NO,
  556. &hClientContextDeleteAuditEventType );
  557. if ( !b ) {
  558. WinStatus = GetLastError();
  559. goto Cleanup;
  560. }
  561. // Audit handle for access check audit.
  562. b = AuthziInitializeAuditEventType( 0,
  563. SE_CATEGID_OBJECT_ACCESS,
  564. SE_AUDITID_AZ_ACCESSCHECK,
  565. AZP_ACCESSCHECK_AUDITPARAMS_NO,
  566. &hAccessCheckAuditEventType );
  567. if ( !b ) {
  568. WinStatus = GetLastError();
  569. goto Cleanup;
  570. }
  571. // Audit handle for app initialization audit.
  572. b = AuthziInitializeAuditEventType( 0,
  573. SE_CATEGID_OBJECT_ACCESS,
  574. SE_AUDITID_AZ_APPLICATION_INITIALIZATION,
  575. AZP_APPINIT_AUDITPARAMS_NO,
  576. &hApplicationInitializationAuditEventType );
  577. if ( !b ) {
  578. WinStatus = GetLastError();
  579. goto Cleanup;
  580. }
  581. // Audit handle for Client context name creation audit.
  582. b = AuthziInitializeAuditEventType( 0,
  583. SE_CATEGID_OBJECT_ACCESS,
  584. SE_AUDITID_AZ_CLIENTCONTEXT_CREATION,
  585. AZP_CLIENTCREATE_AUDITPARAMS_NO+2,
  586. &hClientContextCreateNameAuditEventType );
  587. if ( !b ) {
  588. WinStatus = GetLastError();
  589. goto Cleanup;
  590. }
  591. // Audit handle for Client context name deletion audit.
  592. b = AuthziInitializeAuditEventType( 0,
  593. SE_CATEGID_OBJECT_ACCESS,
  594. SE_AUDITID_AZ_CLIENTCONTEXT_DELETION,
  595. AZP_CLIENTDELETE_AUDITPARAMS_NO+2,
  596. &hClientContextDeleteNameAuditEventType );
  597. if ( !b ) {
  598. WinStatus = GetLastError();
  599. goto Cleanup;
  600. }
  601. // Audit handle for access check name audit.
  602. b = AuthziInitializeAuditEventType( 0,
  603. SE_CATEGID_OBJECT_ACCESS,
  604. SE_AUDITID_AZ_ACCESSCHECK,
  605. AZP_ACCESSCHECK_AUDITPARAMS_NO+2,
  606. &hAccessCheckNameAuditEventType );
  607. if ( !b ) {
  608. WinStatus = GetLastError();
  609. goto Cleanup;
  610. }
  611. //
  612. // Set the handles in the authorization store structure.
  613. //
  614. AzAuthorizationStore->hAccessCheckAuditEventType = hAccessCheckAuditEventType;
  615. AzAuthorizationStore->hApplicationInitializationAuditEventType = hApplicationInitializationAuditEventType;
  616. AzAuthorizationStore->hClientContextCreateAuditEventType =hClientContextCreateAuditEventType;
  617. AzAuthorizationStore->hClientContextDeleteAuditEventType = hClientContextDeleteAuditEventType;
  618. AzAuthorizationStore->hAccessCheckNameAuditEventType = hAccessCheckNameAuditEventType;
  619. AzAuthorizationStore->hClientContextCreateNameAuditEventType = hClientContextCreateNameAuditEventType;
  620. AzAuthorizationStore->hClientContextDeleteNameAuditEventType = hClientContextDeleteNameAuditEventType;
  621. WinStatus = NO_ERROR;
  622. Cleanup:
  623. //
  624. // In case of errors, free all the audit handles that were created.
  625. //
  626. if ( WinStatus != NO_ERROR ) {
  627. if ( hClientContextCreateAuditEventType != NULL ) {
  628. AuthziFreeAuditEventType( hClientContextCreateAuditEventType );
  629. }
  630. if ( hClientContextDeleteAuditEventType != NULL ) {
  631. AuthziFreeAuditEventType( hClientContextDeleteAuditEventType );
  632. }
  633. if ( hAccessCheckAuditEventType != NULL ) {
  634. AuthziFreeAuditEventType( hAccessCheckAuditEventType );
  635. }
  636. if ( hClientContextCreateNameAuditEventType != NULL ) {
  637. AuthziFreeAuditEventType( hClientContextCreateNameAuditEventType );
  638. }
  639. if ( hClientContextDeleteNameAuditEventType != NULL ) {
  640. AuthziFreeAuditEventType( hClientContextDeleteNameAuditEventType );
  641. }
  642. if ( hAccessCheckNameAuditEventType != NULL ) {
  643. AuthziFreeAuditEventType( hAccessCheckNameAuditEventType );
  644. }
  645. if ( hApplicationInitializationAuditEventType != NULL) {
  646. AuthziFreeAuditEventType( hApplicationInitializationAuditEventType );
  647. }
  648. }
  649. //
  650. // If we had adjusted the audit privilege, revert to the original state.
  651. //
  652. if ( PrivilegeAdjusted ) {
  653. WinStatus = AzpChangeSinglePrivilege(
  654. 0, // This is ignored since OldState is NULL.
  655. hToken,
  656. &OldPrivilegeState,
  657. NULL ); // This should be set to NULL to specify REVERT.
  658. ASSERT( WinStatus == NO_ERROR );
  659. }
  660. if ( hToken != NULL ) {
  661. CloseHandle( hToken );
  662. }
  663. return WinStatus;
  664. }
  665. DWORD
  666. AzpAzStoreInit(
  667. IN PGENERIC_OBJECT ParentGenericObject,
  668. IN PGENERIC_OBJECT ChildGenericObject
  669. )
  670. /*++
  671. Routine Description:
  672. This routine is a worker routine for AzInitialize. It does any object specific
  673. initialization that needs to be done.
  674. On entry, AzGlResource must be locked exclusively.
  675. Arguments:
  676. ParentGenericObject - Specifies the parent object to add the child object onto.
  677. The reference count has been incremented on this object.
  678. ChildGenericObject - Specifies the newly allocated child object.
  679. The reference count has been incremented on this object.
  680. Return Value:
  681. NO_ERROR - The operation was successful
  682. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  683. Other exception status codes
  684. --*/
  685. {
  686. DWORD WinStatus;
  687. PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) ChildGenericObject;
  688. NTSTATUS Status;
  689. //
  690. // Initialization
  691. //
  692. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  693. //
  694. // Initialize the lists of child objects
  695. // Let the generic object manager know all of the types of children we support
  696. //
  697. ASSERT( ParentGenericObject == NULL );
  698. UNREFERENCED_PARAMETER( ParentGenericObject );
  699. ChildGenericObject->ChildGenericObjectHead = &AzAuthorizationStore->Applications;
  700. // List of child applications
  701. ObInitGenericHead( &AzAuthorizationStore->Applications,
  702. OBJECT_TYPE_APPLICATION,
  703. ChildGenericObject,
  704. &AzAuthorizationStore->Groups );
  705. // List of child groups
  706. ObInitGenericHead( &AzAuthorizationStore->Groups,
  707. OBJECT_TYPE_GROUP,
  708. ChildGenericObject,
  709. &ChildGenericObject->AzpSids );
  710. // List of child AzpSids
  711. ObInitGenericHead( &ChildGenericObject->AzpSids,
  712. OBJECT_TYPE_SID,
  713. ChildGenericObject,
  714. NULL );
  715. //
  716. // Initialize the Domain list.
  717. //
  718. Status = SafeInitializeCriticalSection( &AzAuthorizationStore->DomainCritSect,
  719. SAFE_DOMAIN_LIST );
  720. if ( !NT_SUCCESS( Status )) {
  721. WinStatus = RtlNtStatusToDosError( Status );
  722. goto Cleanup;
  723. }
  724. AzAuthorizationStore->DomainCritSectInitialized = TRUE;
  725. InitializeListHead( &AzAuthorizationStore->Domains );
  726. //
  727. // Initialize Crit sect that serializes Persist engine operations
  728. //
  729. Status = SafeInitializeCriticalSection( &AzAuthorizationStore->FreeScriptCritSect,
  730. SAFE_FREE_SCRIPT_LIST );
  731. if ( !NT_SUCCESS( Status )) {
  732. WinStatus = RtlNtStatusToDosError( Status );
  733. goto Cleanup;
  734. }
  735. AzAuthorizationStore->FreeScriptCritSectInitialized = TRUE;
  736. InitializeListHead( &AzAuthorizationStore->LruFreeScriptHead );
  737. //
  738. // Initialize AzAuthStore mode
  739. //
  740. Status = SafeInitializeCriticalSection(
  741. &AzAuthorizationStore->PersistCritSect,
  742. SAFE_PERSIST_LOCK );
  743. if ( !NT_SUCCESS( Status ))
  744. {
  745. WinStatus = RtlNtStatusToDosError( Status );
  746. goto Cleanup;
  747. }
  748. AzAuthorizationStore->PersistCritSectInitialized = TRUE;
  749. InitializeListHead( &AzAuthorizationStore->NewNames );
  750. //
  751. // Initialize the script engine timer queue
  752. //
  753. AzAuthorizationStore->ScriptEngineTimerQueue = CreateTimerQueue();
  754. if ( AzAuthorizationStore->ScriptEngineTimerQueue == NULL ) {
  755. WinStatus = GetLastError();
  756. goto Cleanup;
  757. }
  758. //
  759. // By default generate audits
  760. //
  761. AzAuthorizationStore->GenericObject.IsGeneratingAudits = TRUE;
  762. WinStatus = NO_ERROR;
  763. Cleanup:
  764. if ( WinStatus != NO_ERROR ) {
  765. AzpAzStoreCleanupAuditSystem( AzAuthorizationStore );
  766. AzpAzStoreFree( ChildGenericObject );
  767. }
  768. return WinStatus;
  769. }
  770. VOID
  771. AzpAzStoreFree(
  772. IN PGENERIC_OBJECT GenericObject
  773. )
  774. /*++
  775. Routine Description:
  776. This routine is a worker routine for AzAuthorizationStore object free. It does any object specific
  777. cleanup that needs to be done.
  778. On entry, AzGlResource must be locked exclusively.
  779. Arguments:
  780. GenericObject - Specifies a pointer to the object to be deleted.
  781. Return Value:
  782. None
  783. --*/
  784. {
  785. PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) GenericObject;
  786. //
  787. // Initialization
  788. //
  789. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  790. //
  791. // Close the database store
  792. //
  793. AzPersistClose( AzAuthorizationStore );
  794. //
  795. // Free any local strings
  796. //
  797. AzpFreeString( &AzAuthorizationStore->PolicyUrl );
  798. //
  799. // Free any local strings
  800. //
  801. AzpFreeString( &AzAuthorizationStore->TargetMachine );
  802. //
  803. // Free the domain list
  804. //
  805. if ( AzAuthorizationStore->DomainCritSectInitialized ) {
  806. // Free the list itself
  807. AzpUnlinkDomains( AzAuthorizationStore );
  808. // Free the crit sect protecting the list
  809. SafeDeleteCriticalSection( &AzAuthorizationStore->DomainCritSect );
  810. AzAuthorizationStore->DomainCritSectInitialized = FALSE;
  811. }
  812. //
  813. // Free the free script list
  814. //
  815. if ( AzAuthorizationStore->FreeScriptCritSectInitialized ) {
  816. //
  817. // The LRU FreeScriptList should have been flushed as each task object
  818. // was freed.
  819. // So we shouldn't be here unless the free script list is empty.
  820. ASSERT( IsListEmpty( &AzAuthorizationStore->LruFreeScriptHead ));
  821. ASSERT( AzAuthorizationStore->LruFreeScriptCount == 0 );
  822. // Free the crit sect protecting the list
  823. SafeDeleteCriticalSection( &AzAuthorizationStore->FreeScriptCritSect );
  824. AzAuthorizationStore->FreeScriptCritSectInitialized = FALSE;
  825. }
  826. //
  827. // Free the timer queue
  828. //
  829. if ( AzAuthorizationStore->ScriptEngineTimerQueue != NULL ) {
  830. DeleteTimerQueueEx( AzAuthorizationStore->ScriptEngineTimerQueue,
  831. INVALID_HANDLE_VALUE ); // Wait for operation to finish
  832. AzAuthorizationStore->ScriptEngineTimerQueue = NULL;
  833. }
  834. // Free persistence engine critical section
  835. if (AzAuthorizationStore->PersistCritSectInitialized)
  836. {
  837. SafeDeleteCriticalSection( &AzAuthorizationStore->PersistCritSect );
  838. AzAuthorizationStore->PersistCritSectInitialized = FALSE;
  839. ASSERT( IsListEmpty( &AzAuthorizationStore->NewNames ));
  840. }
  841. //
  842. // Cleanup the audit system handles.
  843. //
  844. AzpAzStoreCleanupAuditSystem( AzAuthorizationStore );
  845. //
  846. // Free the provider dll
  847. //
  848. if ( AzAuthorizationStore->ProviderDll != NULL ) {
  849. FreeLibrary( AzAuthorizationStore->ProviderDll );
  850. AzAuthorizationStore->ProviderDll = NULL;
  851. }
  852. }
  853. DWORD
  854. AzpAzStoreGetProperty(
  855. IN PGENERIC_OBJECT GenericObject,
  856. IN ULONG Flags,
  857. IN ULONG PropertyId,
  858. OUT PVOID *PropertyValue
  859. )
  860. /*++
  861. Routine Description:
  862. This routine is the AzAuthorizationStore specific worker routine for AzGetProperty.
  863. It does any object specific property gets.
  864. On entry, AzGlResource must be locked shared.
  865. Arguments:
  866. GenericObject - Specifies a pointer to the object to be queried
  867. Flags - Specifies internal flags
  868. AZP_FLAGS_BY_GUID - name lists should be returned as GUID lists
  869. AZP_FLAGS_PERSIST_* - Call is from the persistence provider
  870. PropertyId - Specifies which property to return.
  871. PropertyValue - Specifies a pointer to return the property in.
  872. The returned pointer must be freed using AzFreeMemory.
  873. The returned value and type depends in PropertyId. The valid values are:
  874. AZ_PROP_AZSTORE_DOMAIN_TIMEOUT PULONG - Domain timeout (in milliseconds)
  875. AZ_PROP_AZSTORE_SCRIPT_ENGINE_TIMEOUT PULONG - Script timeout (in milliseconds)
  876. AZ_PROP_AZSTORE_MAX_SCRIPT_ENGINES PULONG - Max number of cached scripts
  877. AZ_PROP_AZSTORE_MAJOR_VERSION PLONG - Major version
  878. AZ_PROP_AZSTORE_MINOR_VERSION PLONG - Minor version
  879. Return Value:
  880. Status of the operation
  881. --*/
  882. {
  883. DWORD WinStatus = NO_ERROR;
  884. PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) GenericObject;
  885. UNREFERENCED_PARAMETER( Flags );
  886. //
  887. // Initialization
  888. //
  889. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  890. //
  891. // Return any object specific attribute
  892. //
  893. // Return the domain timeout to the caller
  894. //
  895. switch ( PropertyId ) {
  896. case AZ_PROP_AZSTORE_DOMAIN_TIMEOUT:
  897. *PropertyValue = AzpGetUlongProperty( AzAuthorizationStore->DomainTimeout );
  898. if ( *PropertyValue == NULL ) {
  899. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  900. }
  901. break;
  902. //
  903. // Return the script engine timeout to the caller
  904. //
  905. case AZ_PROP_AZSTORE_SCRIPT_ENGINE_TIMEOUT:
  906. *PropertyValue = AzpGetUlongProperty( AzAuthorizationStore->ScriptEngineTimeout );
  907. if ( *PropertyValue == NULL ) {
  908. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  909. }
  910. break;
  911. //
  912. // Return max number of cached scripted engines
  913. //
  914. case AZ_PROP_AZSTORE_MAX_SCRIPT_ENGINES:
  915. *PropertyValue = AzpGetUlongProperty( AzAuthorizationStore->MaxScriptEngines );
  916. if ( *PropertyValue == NULL ) {
  917. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  918. }
  919. break;
  920. //
  921. // Return store's major version
  922. //
  923. case AZ_PROP_AZSTORE_MAJOR_VERSION:
  924. *PropertyValue = AzpGetUlongProperty( AzAuthorizationStore->MajorVersion );
  925. if ( *PropertyValue == NULL ) {
  926. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  927. }
  928. break;
  929. //
  930. // Return store's minor version
  931. //
  932. case AZ_PROP_AZSTORE_MINOR_VERSION:
  933. *PropertyValue = AzpGetUlongProperty( AzAuthorizationStore->MinorVersion );
  934. if ( *PropertyValue == NULL ) {
  935. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  936. }
  937. break;
  938. //
  939. // Return store's target machine for resolving accounts
  940. //
  941. case AZ_PROP_AZSTORE_TARGET_MACHINE:
  942. *PropertyValue = AzpGetStringProperty( &AzAuthorizationStore->TargetMachine );
  943. if ( *PropertyValue == NULL ) {
  944. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  945. }
  946. break;
  947. default:
  948. AzPrint(( AZD_INVPARM, "AzpAzStoreGetProperty: invalid prop id %ld\n", PropertyId ));
  949. WinStatus = ERROR_INVALID_PARAMETER;
  950. break;
  951. }
  952. return WinStatus;
  953. }
  954. DWORD
  955. AzpAzStoreSetProperty(
  956. IN PGENERIC_OBJECT GenericObject,
  957. IN ULONG Flags,
  958. IN ULONG PropertyId,
  959. IN PVOID PropertyValue
  960. )
  961. /*++
  962. Routine Description:
  963. This routine is the AzAuthorizationStore object specific worker routine for AzSetProperty.
  964. It does any object specific property sets.
  965. On entry, AzGlResource must be locked exclusive.
  966. Arguments:
  967. GenericObject - Specifies a pointer to the object to be modified
  968. Flags - Specifies flags controlling to operation of the routine
  969. AZP_FLAGS_SETTING_TO_DEFAULT - Property is being set to default value
  970. AZP_FLAGS_PERSIST_* - Call is from the persistence provider
  971. PropertyId - Specifies which property to set.
  972. PropertyValue - Specifies a pointer to the property.
  973. The specified value and type depends in PropertyId. The valid values are:
  974. AZ_PROP_AZSTORE_DOMAIN_TIMEOUT PULONG - Domain timeout (in milliseconds)
  975. AZ_PROP_AZSTORE_SCRIPT_ENGINE_TIMEOUT PULONG - Script timeout (in milliseconds)
  976. AZ_PROP_AZSTORE_MAX_SCRIPT_ENGINES PULONG - Max number of cached scripts
  977. AZ_PROP_AZSTORE_MAJOR_VERSION PLONG - Major version
  978. AZ_PROP_AZSTORE_MINOR_VERSION PLONG - Minor version
  979. Return Value:
  980. Status of the operation
  981. --*/
  982. {
  983. DWORD WinStatus;
  984. PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) GenericObject;
  985. LONG TempLong;
  986. BOOL bHasChanged = TRUE;
  987. //
  988. // Initialization
  989. //
  990. UNREFERENCED_PARAMETER( Flags );
  991. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  992. //
  993. // Set any object specific attribute
  994. //
  995. // Set domain timeout
  996. //
  997. switch ( PropertyId ) {
  998. case AZ_PROP_AZSTORE_DOMAIN_TIMEOUT:
  999. BEGIN_SETPROP( &WinStatus, AzAuthorizationStore, Flags, AZ_DIRTY_AZSTORE_DOMAIN_TIMEOUT ) {
  1000. WinStatus = AzpCaptureLong( PropertyValue, &TempLong );
  1001. if ( WinStatus != NO_ERROR ) {
  1002. goto Cleanup;
  1003. }
  1004. //
  1005. // Do parameter validity checking
  1006. //
  1007. BEGIN_VALIDITY_CHECKING( Flags ) {
  1008. if ( TempLong < AZ_AZSTORE_MIN_DOMAIN_TIMEOUT && TempLong != -1 ) {
  1009. AzPrint(( AZD_INVPARM, "AzpAzStoreManagerSetProperty: domain timeout too small %ld\n", TempLong ));
  1010. WinStatus = ERROR_INVALID_PARAMETER;
  1011. goto Cleanup;
  1012. }
  1013. } END_VALIDITY_CHECKING;
  1014. AzAuthorizationStore->DomainTimeout = TempLong;
  1015. } END_SETPROP(bHasChanged);
  1016. break;
  1017. //
  1018. // Set script engine timeout
  1019. //
  1020. case AZ_PROP_AZSTORE_SCRIPT_ENGINE_TIMEOUT:
  1021. BEGIN_SETPROP( &WinStatus, AzAuthorizationStore, Flags, AZ_DIRTY_AZSTORE_SCRIPT_ENGINE_TIMEOUT ) {
  1022. WinStatus = AzpCaptureLong( PropertyValue, &TempLong );
  1023. if ( WinStatus != NO_ERROR ) {
  1024. goto Cleanup;
  1025. }
  1026. //
  1027. // Do parameter validity checking
  1028. //
  1029. BEGIN_VALIDITY_CHECKING( Flags ) {
  1030. if ( TempLong < AZ_AZSTORE_MIN_SCRIPT_ENGINE_TIMEOUT && TempLong != -1 && TempLong != 0 ) {
  1031. AzPrint(( AZD_INVPARM, "AzpAzStoreManagerSetProperty: script engine timeout too small %ld\n", TempLong ));
  1032. WinStatus = ERROR_INVALID_PARAMETER;
  1033. goto Cleanup;
  1034. }
  1035. } END_VALIDITY_CHECKING;
  1036. AzAuthorizationStore->ScriptEngineTimeout = TempLong;
  1037. } END_SETPROP(bHasChanged);
  1038. break;
  1039. //
  1040. // Set max number of cached scripted engines
  1041. //
  1042. case AZ_PROP_AZSTORE_MAX_SCRIPT_ENGINES:
  1043. BEGIN_SETPROP( &WinStatus, AzAuthorizationStore, Flags, AZ_DIRTY_AZSTORE_MAX_SCRIPT_ENGINES ) {
  1044. WinStatus = AzpCaptureLong( PropertyValue, &TempLong );
  1045. if ( WinStatus != NO_ERROR ) {
  1046. goto Cleanup;
  1047. }
  1048. //
  1049. // Do parameter validity checking
  1050. //
  1051. BEGIN_VALIDITY_CHECKING( Flags ) {
  1052. if ( TempLong < 0) {
  1053. AzPrint(( AZD_INVPARM, "AzpAzStoreManagerSetProperty: max script engines too small %ld\n", TempLong ));
  1054. WinStatus = ERROR_INVALID_PARAMETER;
  1055. goto Cleanup;
  1056. }
  1057. } END_VALIDITY_CHECKING;
  1058. AzAuthorizationStore->MaxScriptEngines = TempLong;
  1059. } END_SETPROP(bHasChanged);
  1060. break;
  1061. //
  1062. // Major version. These are hidden from out side clients. Howeveer, in order
  1063. // for it to work with our cache model, we still have to implement this code.
  1064. //
  1065. case AZ_PROP_AZSTORE_MAJOR_VERSION:
  1066. BEGIN_SETPROP( &WinStatus, AzAuthorizationStore, Flags, AZ_DIRTY_AZSTORE_MAJOR_VERSION ) {
  1067. WinStatus = AzpCaptureLong( PropertyValue, &TempLong );
  1068. if (WinStatus != NO_ERROR)
  1069. {
  1070. goto Cleanup;
  1071. }
  1072. AzAuthorizationStore->MajorVersion = TempLong;
  1073. } END_SETPROP(bHasChanged);
  1074. break;
  1075. //
  1076. // Minor version These are hidden from out side clients. Howeveer, in order
  1077. // for it to work with our cache model, we still have to implement this code.
  1078. //
  1079. case AZ_PROP_AZSTORE_MINOR_VERSION:
  1080. BEGIN_SETPROP( &WinStatus, AzAuthorizationStore, Flags, AZ_DIRTY_AZSTORE_MINOR_VERSION ) {
  1081. WinStatus = AzpCaptureLong( PropertyValue, &TempLong );
  1082. if (WinStatus != NO_ERROR)
  1083. {
  1084. goto Cleanup;
  1085. }
  1086. AzAuthorizationStore->MinorVersion = TempLong;
  1087. } END_SETPROP(bHasChanged);
  1088. break;
  1089. default:
  1090. AzPrint(( AZD_INVPARM, "AzpAzStoreManagerSetProperty: invalid prop id %ld\n", PropertyId ));
  1091. WinStatus = ERROR_INVALID_PARAMETER;
  1092. break;
  1093. }
  1094. Cleanup:
  1095. return WinStatus;
  1096. }
  1097. DWORD
  1098. WINAPI
  1099. AzInitialize(
  1100. IN LPCWSTR PolicyUrl,
  1101. IN DWORD Flags,
  1102. IN DWORD Reserved,
  1103. OUT PAZ_HANDLE AzStoreHandle
  1104. )
  1105. /*++
  1106. Routine Description:
  1107. This routine initializes the authorization store. This routine must be called before any other
  1108. routine.
  1109. Arguments:
  1110. PolicyUrl - Specifies the location of the policy store
  1111. Flags - Specifies flags that control the behavior of AzInitialize
  1112. AZ_AZSTORE_FLAG_CREATE: Create the policy database
  1113. AZ_AZSTORE_FLAG_MANAGE_STORE_ONLY: Open the store for administrative purposes only. There
  1114. will be no runtime functions performed.
  1115. AZ_AZSTORE_FLAG_BATCH_UPDATE: When this flag is set, we will not update
  1116. the authorization store object for the purpuse of quick
  1117. discovery of store modification. For those clients who know
  1118. that they will do massive number of updates within a short
  1119. period of time on an AD store, then they should use this
  1120. flag to reduce network traffic.
  1121. AZ_AZSTORE_FLAG_AUDIT_IS_CRITICAL: If this flag is specified, the calling process needs to have
  1122. SE_AUDIT_PRIVILEGE, else error will be returned.
  1123. Reserved - Reserved. Must by zero.
  1124. AzStoreHandle - Return a handle to the AzAuthorizationStore.
  1125. The caller must close this handle by calling AzCloseHandle.
  1126. Return Value:
  1127. NO_ERROR - The operation was successful
  1128. ERROR_ALREADY_EXISTS - AZ_AZSTORE_FLAG_CREATE flag was specified and the policy already exists
  1129. ERROR_FILE_NOT_FOUND - AZ_AZSTORE_FLAG_CREATE flag was not specified and the policy does not already exist
  1130. --*/
  1131. {
  1132. DWORD WinStatus;
  1133. PGENERIC_OBJECT AzAuthorizationStore = NULL;
  1134. AZP_STRING AzStoreName;
  1135. AZP_STRING PolicyUrlString;
  1136. //
  1137. // Grab the global lock
  1138. //
  1139. AzpLockResourceExclusive( &AzGlResource );
  1140. AzpInitString( &AzStoreName, NULL );
  1141. AzpInitString( &PolicyUrlString, NULL );
  1142. //
  1143. // Initialization
  1144. //
  1145. __try {
  1146. *AzStoreHandle = NULL;
  1147. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  1148. WinStatus = RtlNtStatusToDosError( GetExceptionCode());
  1149. goto Cleanup;
  1150. }
  1151. //
  1152. // Validate the input parameters
  1153. //
  1154. if ( Reserved != 0 ) {
  1155. AzPrint(( AZD_INVPARM, "AzInitialize: Reserved != 0\n" ));
  1156. WinStatus = ERROR_INVALID_PARAMETER;
  1157. goto Cleanup;
  1158. }
  1159. if ( Flags & ~AZ_AZSTORE_FLAG_VALID ) {
  1160. AzPrint(( AZD_INVPARM, "AzInitialize: Invalid flags 0x%lx\n", Flags ));
  1161. WinStatus = ERROR_INVALID_FLAGS;
  1162. goto Cleanup;
  1163. }
  1164. //
  1165. // Capture the Policy URL
  1166. //
  1167. WinStatus = AzpCaptureString( &PolicyUrlString,
  1168. (LPWSTR) PolicyUrl,
  1169. AZ_MAX_POLICY_URL_LENGTH,
  1170. FALSE ); // NULL is not OK
  1171. if ( WinStatus != NO_ERROR ) {
  1172. goto Cleanup;
  1173. }
  1174. //
  1175. // Create the object. If this succeeds, then AzAuthorizationStore is holding
  1176. // two ref count: one for global list and one for AzAuthorizationStore itself.
  1177. // Therefore, if for any reason we fail to return the requested handle,
  1178. // we must decrement one extra ref count because the global list ref
  1179. // count relies on the handle's close to go down to 0.
  1180. //
  1181. WinStatus = ObCreateObject(
  1182. NULL, // There is no parent object
  1183. &AzGlAzStores,
  1184. OBJECT_TYPE_AZAUTHSTORE,
  1185. &AzStoreName,
  1186. NULL, // Guid not known
  1187. 0, // No special flags
  1188. &AzAuthorizationStore );
  1189. if ( WinStatus != NO_ERROR ) {
  1190. goto Cleanup;
  1191. }
  1192. //
  1193. // Set authorization store specific fields
  1194. //
  1195. AzpSwapStrings( &PolicyUrlString, &((PAZP_AZSTORE)AzAuthorizationStore)->PolicyUrl );
  1196. AzpInitString(&((PAZP_AZSTORE)AzAuthorizationStore)->TargetMachine, NULL);
  1197. ((PAZP_AZSTORE)AzAuthorizationStore)->InitializeFlag = Flags;
  1198. //
  1199. // Initialize the audit system if not in manage store mode
  1200. //
  1201. if ( !AzpOpenToManageStore((PAZP_AZSTORE)AzAuthorizationStore) ) {
  1202. WinStatus = AzpAzStoreInitializeAuditSystem( (PAZP_AZSTORE)AzAuthorizationStore );
  1203. if ( WinStatus != NO_ERROR ) {
  1204. //
  1205. // Bug 591762: We will fail Initialization if SeAuditPrivilege is not held,
  1206. // or if the Audit System failed to initialize for some other reason. This is
  1207. // because the user specifically asked for Initialization with runtime audits
  1208. // being generated.
  1209. //
  1210. ObDereferenceObject( AzAuthorizationStore );
  1211. AzPrint(( AZD_CRITICAL,
  1212. "AzInitialize: Failed to Initialize Audit system: %ld\n",
  1213. WinStatus
  1214. ));
  1215. goto Cleanup;
  1216. }
  1217. }
  1218. //
  1219. // Load the objects for the database store
  1220. //
  1221. WinStatus = AzPersistOpen(
  1222. (PAZP_AZSTORE)AzAuthorizationStore,
  1223. (Flags & AZ_AZSTORE_FLAG_CREATE) != 0 );
  1224. if ( WinStatus != NO_ERROR ) {
  1225. ObDereferenceObject( AzAuthorizationStore );
  1226. goto Cleanup;
  1227. }
  1228. //
  1229. // Return the handle to the caller
  1230. //
  1231. ObIncrHandleRefCount( AzAuthorizationStore );
  1232. *AzStoreHandle = AzAuthorizationStore;
  1233. WinStatus = NO_ERROR;
  1234. //
  1235. // Free locally used resources
  1236. //
  1237. Cleanup:
  1238. if ( AzAuthorizationStore != NULL ) {
  1239. ObDereferenceObject( AzAuthorizationStore );
  1240. }
  1241. AzpFreeString( &PolicyUrlString );
  1242. //
  1243. // Drop the global lock
  1244. //
  1245. AzpUnlockResource( &AzGlResource );
  1246. return WinStatus;
  1247. }
  1248. DWORD
  1249. WINAPI
  1250. AzUpdateCache(
  1251. IN AZ_HANDLE AzStoreHandle
  1252. )
  1253. /*++
  1254. Routine Description:
  1255. This routine updates the cache to match the underlying store.
  1256. Arguments:
  1257. AzStoreHandle - Specifies a handle to the AzAuthorizationStore.
  1258. Return Value:
  1259. NO_ERROR - The operation was successful
  1260. --*/
  1261. {
  1262. DWORD WinStatus;
  1263. PGENERIC_OBJECT ReferencedGenericObject = NULL;
  1264. //
  1265. // Grab the global lock
  1266. //
  1267. AzpLockResourceExclusive( &AzGlResource );
  1268. //
  1269. // Validate the passed in handle
  1270. //
  1271. WinStatus = ObReferenceObjectByHandle( (PGENERIC_OBJECT)AzStoreHandle,
  1272. FALSE, // Don't allow deleted objects
  1273. FALSE, // No need to refresh the cache here
  1274. OBJECT_TYPE_AZAUTHSTORE );
  1275. if ( WinStatus != NO_ERROR ) {
  1276. goto Cleanup;
  1277. }
  1278. ReferencedGenericObject = (PGENERIC_OBJECT) AzStoreHandle;
  1279. WinStatus = AzPersistUpdateCache( (PAZP_AZSTORE)ReferencedGenericObject );
  1280. //
  1281. // Free locally used resources
  1282. //
  1283. Cleanup:
  1284. if ( ReferencedGenericObject != NULL ) {
  1285. ObDereferenceObject( ReferencedGenericObject );
  1286. }
  1287. //
  1288. // Drop the global lock
  1289. //
  1290. AzpUnlockResource( &AzGlResource );
  1291. return WinStatus;
  1292. }
  1293. DWORD
  1294. WINAPI
  1295. AzGetProperty(
  1296. IN AZ_HANDLE AzHandle,
  1297. IN ULONG PropertyId,
  1298. IN DWORD Reserved,
  1299. OUT PVOID *PropertyValue
  1300. )
  1301. /*++
  1302. Routine Description:
  1303. Returns the specified property for an Authz object
  1304. Arguments:
  1305. AzHandle - Specifies a handle to the object to get the property for
  1306. PropertyId - Specifies which property to return.
  1307. Reserved - Reserved. Must by zero.
  1308. PropertyValue - Specifies a pointer to return the property in.
  1309. The returned pointer must be freed using AzFreeMemory.
  1310. The returned value and type depends in PropertyId.
  1311. The PropertyId is one of the AZ_PROP_* values.
  1312. Return Value:
  1313. NO_ERROR - The operation was successful
  1314. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  1315. --*/
  1316. {
  1317. //
  1318. // Call the common routine to do most of the work
  1319. //
  1320. return ObCommonGetProperty(
  1321. (PGENERIC_OBJECT) AzHandle,
  1322. 0, // No flags
  1323. PropertyId,
  1324. Reserved,
  1325. PropertyValue );
  1326. }
  1327. DWORD
  1328. WINAPI
  1329. AzSetProperty(
  1330. IN AZ_HANDLE AzHandle,
  1331. IN ULONG PropertyId,
  1332. IN DWORD Reserved,
  1333. IN PVOID PropertyValue
  1334. )
  1335. /*++
  1336. Routine Description:
  1337. Sets the specified property for an AzAuthorizationStore.
  1338. Arguments:
  1339. AzHandle - Specifies a handle to the object to set the property for
  1340. PropertyId - Specifies which property to set
  1341. Reserved - Reserved. Must by zero.
  1342. PropertyValue - Specifies a pointer to the property.
  1343. The specified value and type depends in PropertyId.
  1344. The PropertyId is one of the AZ_PROP_* values.
  1345. Return Value:
  1346. NO_ERROR - The operation was successful
  1347. ERROR_INVALID_PARAMETER - PropertyId isn't valid
  1348. --*/
  1349. {
  1350. //
  1351. // Call the common routine to do most of the work
  1352. //
  1353. return ObCommonSetProperty(
  1354. (PGENERIC_OBJECT) AzHandle,
  1355. PropertyId,
  1356. Reserved,
  1357. PropertyValue );
  1358. }
  1359. DWORD
  1360. WINAPI
  1361. AzAuthorizationStoreDelete(
  1362. IN AZ_HANDLE AzStoreHandle,
  1363. IN DWORD Reserved
  1364. )
  1365. /*++
  1366. Routine Description:
  1367. This routine deletes the authorization store object specified by the passed in handle
  1368. Also deletes any child objects of ApplicationName and the underlying store.
  1369. Arguments:
  1370. AzStoreHandle - Specifies a handle to the AzAuthorizationStore.
  1371. Reserved - Reserved. Must by zero.
  1372. Return Value:
  1373. NO_ERROR - The operation was successful
  1374. --*/
  1375. {
  1376. DWORD WinStatus;
  1377. PGENERIC_OBJECT ReferencedGenericObject = NULL;
  1378. //
  1379. // Grab the global lock
  1380. //
  1381. AzpLockResourceExclusive( &AzGlResource );
  1382. //
  1383. // Validate the input parameters
  1384. //
  1385. if ( Reserved != 0 ) {
  1386. AzPrint(( AZD_INVPARM, "AzAuthorizationStoreDelete: Reserved != 0\n" ));
  1387. WinStatus = ERROR_INVALID_PARAMETER;
  1388. goto Cleanup;
  1389. }
  1390. //
  1391. // Validate the passed in handle
  1392. //
  1393. WinStatus = ObReferenceObjectByHandle( (PGENERIC_OBJECT)AzStoreHandle,
  1394. FALSE, // Don't allow deleted objects
  1395. FALSE, // No need to refresh the cache on a delete
  1396. OBJECT_TYPE_AZAUTHSTORE );
  1397. if ( WinStatus != NO_ERROR ) {
  1398. goto Cleanup;
  1399. }
  1400. ReferencedGenericObject = (PGENERIC_OBJECT) AzStoreHandle;
  1401. //
  1402. // Actually, delete the object
  1403. //
  1404. WinStatus = AzPersistSubmit( ReferencedGenericObject, TRUE );
  1405. if ( WinStatus != NO_ERROR ) {
  1406. goto Cleanup;
  1407. }
  1408. //
  1409. // Mark the entry (and its child objects) as deleted
  1410. // We do this since other threads may have references to the objects.
  1411. // We want to ensure those threads know the objects are deleted.
  1412. //
  1413. ObMarkObjectDeleted( ReferencedGenericObject );
  1414. //
  1415. // Return to the caller
  1416. //
  1417. WinStatus = NO_ERROR;
  1418. //
  1419. // Free locally used resources
  1420. //
  1421. Cleanup:
  1422. if ( ReferencedGenericObject != NULL ) {
  1423. ObDereferenceObject( ReferencedGenericObject );
  1424. }
  1425. //
  1426. // Drop the global lock
  1427. //
  1428. AzpUnlockResource( &AzGlResource );
  1429. return WinStatus;
  1430. }
  1431. DWORD
  1432. WINAPI
  1433. AzCloseHandle(
  1434. IN AZ_HANDLE AzHandle,
  1435. IN DWORD Reserved
  1436. )
  1437. /*++
  1438. Routine Description:
  1439. Close a handle returned from any of the Az* routines
  1440. Arguments:
  1441. AzHandle - Passes in the handle to be closed.
  1442. Reserved - Reserved. Must by zero.
  1443. Return Value:
  1444. NO_ERROR - The operation was successful.
  1445. ERROR_INVALID_HANDLE - The passed in handle was invalid
  1446. --*/
  1447. {
  1448. DWORD WinStatus;
  1449. PGENERIC_OBJECT ReferencedGenericObject = NULL;
  1450. PGENERIC_OBJECT GenericObject = (PGENERIC_OBJECT) AzHandle;
  1451. PGENERIC_OBJECT AzStoreGenericObject = NULL;
  1452. DWORD ObjectType;
  1453. //
  1454. // Grab the global lock
  1455. //
  1456. AzpLockResourceShared( &AzGlResource );
  1457. //
  1458. // Validate the input parameters
  1459. //
  1460. if ( Reserved != 0 ) {
  1461. AzPrint(( AZD_INVPARM, "AzCloseHandle: Reserved != 0\n" ));
  1462. WinStatus = ERROR_INVALID_PARAMETER;
  1463. goto Cleanup;
  1464. }
  1465. //
  1466. // Determine the type of the object
  1467. //
  1468. WinStatus = ObGetHandleType( GenericObject,
  1469. TRUE, // Ok to close handle for deleted object
  1470. &ObjectType );
  1471. if ( WinStatus != NO_ERROR ) {
  1472. goto Cleanup;
  1473. }
  1474. //
  1475. // Grab the lock exclusively if we're going to change the database
  1476. //
  1477. if ( ObjectType == OBJECT_TYPE_AZAUTHSTORE ) {
  1478. AzpLockResourceSharedToExclusive( &AzGlResource );
  1479. }
  1480. //
  1481. // Validate the passed in handle
  1482. //
  1483. WinStatus = ObReferenceObjectByHandle( GenericObject,
  1484. TRUE, // Allow deleted objects
  1485. FALSE, // No need to refresh cache on a close
  1486. ObjectType );
  1487. if ( WinStatus != NO_ERROR ) {
  1488. goto Cleanup;
  1489. }
  1490. ReferencedGenericObject = GenericObject;
  1491. //
  1492. // Grab a reference to the root of the core cache
  1493. //
  1494. // This might be the last handle open. Closing the last handle removes
  1495. // the last reference to the object at the root of the core cache.
  1496. // We need to ensure that there are no other references to children objects.
  1497. // We do that by grabing our own reference here so that our dereference will
  1498. // be the final dereference
  1499. //
  1500. AzStoreGenericObject = &GenericObject->AzStoreObject->GenericObject;
  1501. InterlockedIncrement( &AzStoreGenericObject->ReferenceCount );
  1502. AzpDumpGoRef( "AzAuthorizationStore in AzCloseHandle ref", AzStoreGenericObject );
  1503. //
  1504. // If the object is dirty,
  1505. // and we're closing the last handle,
  1506. // abort the changes.
  1507. //
  1508. if ( GenericObject->DirtyBits != 0 &&
  1509. GenericObject->HandleReferenceCount == 1 ) {
  1510. //
  1511. // We need an exclusive lock to delete the object.
  1512. //
  1513. // If this is the AzAuthorizationStore object, the we already
  1514. // have the glock held exclusively
  1515. //
  1516. if ( ObjectType != OBJECT_TYPE_AZAUTHSTORE ) {
  1517. AzpLockResourceSharedToExclusive( &AzGlResource );
  1518. }
  1519. //
  1520. // Ensure things haven't changed
  1521. //
  1522. if ( GenericObject->DirtyBits != 0 &&
  1523. GenericObject->HandleReferenceCount == 1 ) {
  1524. AzPersistAbort( GenericObject );
  1525. }
  1526. }
  1527. //
  1528. // Handle close of AzAuthorizationStore handles
  1529. //
  1530. if ( ObjectType == OBJECT_TYPE_AZAUTHSTORE ) {
  1531. //
  1532. // If the object hasn't been deleted,
  1533. // remove the reference representing being in the global list.
  1534. //
  1535. if ( (GenericObject->Flags & GENOBJ_FLAGS_DELETED) == 0 ) {
  1536. //
  1537. // Make sure the caller doesn't re-use the handle
  1538. //
  1539. GenericObject->Flags |= GENOBJ_FLAGS_DELETED;
  1540. // No longer in the global list
  1541. ObDereferenceObject( GenericObject );
  1542. }
  1543. //
  1544. // For a client context,
  1545. // remove the link from the parent when the handle closes
  1546. //
  1547. } else if ( ObjectType == OBJECT_TYPE_CLIENT_CONTEXT ) {
  1548. ASSERT( GenericObject->HandleReferenceCount == 1 );
  1549. // One from ObReferenceObjectByHandle,
  1550. // one for being in the global list,
  1551. // one because the handle itself isn't closed yet.
  1552. //ASSERT( GenericObject->ReferenceCount == 3 );
  1553. // No longer in the global list
  1554. ObDereferenceObject( GenericObject );
  1555. }
  1556. //
  1557. // Actually close the handle
  1558. //
  1559. WinStatus = ObDecrHandleRefCount( GenericObject );
  1560. if ( WinStatus != NO_ERROR ) {
  1561. goto Cleanup;
  1562. }
  1563. //
  1564. // Done
  1565. //
  1566. WinStatus = NO_ERROR;
  1567. //
  1568. // Free locally used resources
  1569. //
  1570. Cleanup:
  1571. if ( ReferencedGenericObject != NULL ) {
  1572. ObDereferenceObject( ReferencedGenericObject );
  1573. }
  1574. if ( AzStoreGenericObject != NULL ) {
  1575. // This dereference might delete the entire cache
  1576. ObDereferenceObject( AzStoreGenericObject );
  1577. }
  1578. //
  1579. // Drop the global lock
  1580. //
  1581. AzpUnlockResource( &AzGlResource );
  1582. return WinStatus;
  1583. }
  1584. VOID
  1585. WINAPI
  1586. AzFreeMemory(
  1587. IN OUT PVOID Buffer
  1588. )
  1589. /*++
  1590. Routine Description
  1591. Free memory returned from AzGetProperty
  1592. Arguments
  1593. Buffer - address of buffer to free
  1594. Return Value
  1595. None
  1596. --*/
  1597. {
  1598. if ( Buffer != NULL ) {
  1599. AzpFreeHeap( Buffer);
  1600. }
  1601. }
  1602. inline BOOL
  1603. AzpAzStoreVersionAllowWrite(
  1604. IN PAZP_AZSTORE AzAuthorizationStore
  1605. )
  1606. /*++
  1607. Routine Description:
  1608. This routine tests if the current azroles.dll verion can support
  1609. writing of the store created by a potentially different version
  1610. of adroles.dll. The version of the dll that wrote the dll is captured
  1611. by the major and minor verions of the AzAuthStore object.
  1612. Arguments:
  1613. AzAuthorizationStore - the auth store object
  1614. Return Values:
  1615. TRUE if it supports the action
  1616. FALSE if not.
  1617. Note:
  1618. MajorVersion (DWORD) - Specifies the major version of the azroles.dll
  1619. that wrote this policy. An azroles.dll with an older major version
  1620. number cannot read nor write a database with a newer major version number.
  1621. The version 1 value of this DWORD is 1. We hope to never have to
  1622. change this value in future releases.
  1623. MinorVersion (DWORD) - Specifies the minor version of the azroles.dll
  1624. that wrote this policy. An azroles.dll with an older minor version
  1625. number can read but cannot write a database with a newer minor version number.
  1626. The version 1 value of this DWORD is 0.
  1627. --*/
  1628. {
  1629. return ( AzAuthorizationStore->MajorVersion == AzGlCurrAzRolesMajorVersion &&
  1630. AzAuthorizationStore->MinorVersion <= AzGlCurrAzRolesMinorVersion );
  1631. }