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.

1210 lines
32 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. app.cxx
  5. Abstract:
  6. Routines implementing the Application object
  7. Author:
  8. Cliff Van Dyke (cliffv) 11-Apr-2001
  9. --*/
  10. #include "pch.hxx"
  11. //
  12. // Define the default values for all scalar attributes
  13. //
  14. AZP_DEFAULT_VALUE AzGlApplicationDefaultValues[] = {
  15. { AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID, AZ_DIRTY_APPLICATION_AUTHZ_INTERFACE_CLSID, NULL },
  16. { AZ_PROP_APPLICATION_VERSION, AZ_DIRTY_APPLICATION_VERSION, NULL },
  17. { 0, 0, NULL }
  18. };
  19. DWORD
  20. AzpApplicationGenerateInitializationAudit(
  21. PAZP_APPLICATION Application,
  22. PAZP_AZSTORE AzAuthorizationStore
  23. )
  24. /*++
  25. Routine Description:
  26. This routine generates an application initialization audit.
  27. Arguments:
  28. Application - Application which just initialized.
  29. AzAuthorizationStore - Authorization Store maitaining the application.
  30. Return Value:
  31. NO_ERROR - The operation was successful
  32. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  33. Other exception status codes
  34. --*/
  35. {
  36. DWORD WinStatus = NO_ERROR;
  37. AUTHZ_AUDIT_EVENT_HANDLE hAuditEvent = NULL;
  38. PAUDIT_PARAMS pAuditParams = NULL;
  39. BOOL b;
  40. //
  41. // If audit handle is NULL, then do no generate any audits
  42. //
  43. if ( (AzAuthorizationStore->hApplicationInitializationAuditEventType == NULL) ) {
  44. return NO_ERROR;
  45. }
  46. //
  47. // The audit format will be as follows:
  48. // %tApplication Name:%t%1%n
  49. // %tApplication Instance ID:%t%2%n
  50. // %tClient Name:%t%3%n
  51. // %tClient Domain:%t%4%n
  52. // %tClient ID:%t%5%n
  53. // %tPolicy Store URL:%t%6%n
  54. //
  55. if (!AuthziAllocateAuditParams(
  56. &pAuditParams,
  57. AZP_APPINIT_AUDITPARAMS_NO
  58. )) {
  59. goto Cleanup;
  60. }
  61. //
  62. // Put the audit parameters in the array.
  63. //
  64. b = AuthziInitializeAuditParamsWithRM( APF_AuditSuccess,
  65. Application->AuthzResourceManager,
  66. AZP_APPINIT_AUDITPARAMS_NO,
  67. pAuditParams,
  68. APT_String,Application->GenericObject.ObjectName->ObjectName.String,
  69. APT_Luid, Application->InstanceId,
  70. APT_LogonId | AP_PrimaryLogonId,
  71. APT_String, AzAuthorizationStore->PolicyUrl.String );
  72. if ( !b ) {
  73. WinStatus = GetLastError();
  74. goto Cleanup;
  75. }
  76. //
  77. // Initialize the audit event handle with the audit parameters.
  78. //
  79. b = AuthziInitializeAuditEvent( 0,
  80. NULL,
  81. AzAuthorizationStore->hApplicationInitializationAuditEventType,
  82. pAuditParams,
  83. NULL,
  84. INFINITE,
  85. L"", L"", L"", L"",
  86. &hAuditEvent );
  87. if ( !b ) {
  88. WinStatus = GetLastError();
  89. goto Cleanup;
  90. }
  91. //
  92. // Send the audit to Lsa.
  93. //
  94. b = AuthziLogAuditEvent( 0,
  95. hAuditEvent,
  96. NULL );
  97. if ( !b ) {
  98. WinStatus = GetLastError();
  99. goto Cleanup;
  100. }
  101. Cleanup:
  102. //
  103. // Free the audit event handle.
  104. //
  105. if ( hAuditEvent != NULL ) {
  106. (VOID) AuthzFreeAuditEvent( hAuditEvent );
  107. }
  108. //
  109. // Free the PAUDIT_PARAMS structure
  110. //
  111. if ( pAuditParams ) {
  112. AuthziFreeAuditParams( pAuditParams );
  113. }
  114. return WinStatus;
  115. }
  116. DWORD
  117. AzpApplicationInit(
  118. IN PGENERIC_OBJECT ParentGenericObject,
  119. IN PGENERIC_OBJECT ChildGenericObject
  120. )
  121. /*++
  122. Routine Description:
  123. This routine is a worker routine for AzApplicationCreate. It does any object specific
  124. initialization that needs to be done.
  125. On entry, AzGlResource must be locked exclusively.
  126. Arguments:
  127. ParentGenericObject - Specifies the parent object to add the child object onto.
  128. The reference count has been incremented on this object.
  129. ChildGenericObject - Specifies the newly allocated child object.
  130. The reference count has been incremented on this object.
  131. Return Value:
  132. NO_ERROR - The operation was successful
  133. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  134. Other exception status codes
  135. --*/
  136. {
  137. PAZP_APPLICATION Application = (PAZP_APPLICATION) ChildGenericObject;
  138. PAZP_AZSTORE AzAuthorizationStore = (PAZP_AZSTORE) ParentGenericObject;
  139. NTSTATUS Status;
  140. DWORD WinStatus = NO_ERROR;
  141. HANDLE hToken = NULL;
  142. TOKEN_PRIVILEGES NewState = {0};
  143. TOKEN_PRIVILEGES OldState = {0};
  144. BOOL PrivilegeAdjusted = FALSE;
  145. DWORD AuthzFlags = 0;
  146. //
  147. // Initialization
  148. //
  149. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  150. //
  151. // Sanity check the parent
  152. //
  153. ASSERT( ParentGenericObject->ObjectType == OBJECT_TYPE_AZAUTHSTORE );
  154. UNREFERENCED_PARAMETER( ParentGenericObject );
  155. //
  156. // If policy store has been initialized in store manage mode only,
  157. // then we do not need to initialize the authz resource manager for auditing
  158. //
  159. if ( AzpOpenToManageStore(AzAuthorizationStore) ) {
  160. AuthzFlags = AUTHZ_RM_FLAG_NO_AUDIT;
  161. } else {
  162. //
  163. // Get the current token to adjust the Audit privilege.
  164. //
  165. WinStatus = AzpGetCurrentToken( &hToken );
  166. if ( WinStatus != NO_ERROR ) {
  167. return WinStatus;
  168. }
  169. //
  170. // Enable the audit privilege.
  171. //
  172. WinStatus = AzpChangeSinglePrivilege(
  173. SE_AUDIT_PRIVILEGE,
  174. hToken,
  175. &NewState,
  176. &OldState );
  177. if ( WinStatus == NO_ERROR ) {
  178. PrivilegeAdjusted = TRUE;
  179. } else {
  180. //
  181. // If auditing is not mandatory, then initialize the resource manager
  182. // with no audit flag
  183. //
  184. if ( (AzAuthorizationStore->InitializeFlag & AZ_AZSTORE_FLAG_AUDIT_IS_CRITICAL) == 0) {
  185. WinStatus = NO_ERROR;
  186. AuthzFlags = AUTHZ_RM_FLAG_NO_AUDIT;
  187. } else {
  188. goto Cleanup;
  189. }
  190. }
  191. }
  192. if ( !AuthzInitializeResourceManager(
  193. AuthzFlags,
  194. NULL, // No Callback ace function
  195. NULL, // We compute our own dynamic groups
  196. NULL, // " "
  197. Application->GenericObject.ObjectName->ObjectName.String,
  198. &Application->AuthzResourceManager ) ) {
  199. WinStatus = GetLastError();
  200. if ( WinStatus != NO_ERROR ) {
  201. if ( WinStatus == ERROR_ACCESS_DENIED ) {
  202. WinStatus = NO_ERROR;
  203. //
  204. // the caller may be on an impersonated thread which doesn't have
  205. // access to the process token, let's call again to initialize
  206. // resource manager on the impersonated thread
  207. //
  208. if ( !AuthzInitializeResourceManager(
  209. AuthzFlags |
  210. AUTHZ_RM_FLAG_INITIALIZE_UNDER_IMPERSONATION, // allow impersonation thread
  211. NULL, // No Callback ace function
  212. NULL, // We compute our own dynamic groups
  213. NULL, // " "
  214. Application->GenericObject.ObjectName->ObjectName.String,
  215. &Application->AuthzResourceManager ) ) {
  216. WinStatus = GetLastError();
  217. goto Cleanup;
  218. }
  219. } else {
  220. goto Cleanup;
  221. }
  222. }
  223. }
  224. //
  225. // Initialize the lists of child objects
  226. // Let the generic object manager know all of the types of children we support
  227. //
  228. ChildGenericObject->ChildGenericObjectHead = &Application->Operations;
  229. // List of child operations
  230. ObInitGenericHead( &Application->Operations,
  231. OBJECT_TYPE_OPERATION,
  232. ChildGenericObject,
  233. &Application->Tasks );
  234. // List of child tasks
  235. ObInitGenericHead( &Application->Tasks,
  236. OBJECT_TYPE_TASK,
  237. ChildGenericObject,
  238. &Application->Scopes );
  239. // List of child scopes
  240. ObInitGenericHead( &Application->Scopes,
  241. OBJECT_TYPE_SCOPE,
  242. ChildGenericObject,
  243. &Application->Groups );
  244. // List of child groups
  245. ObInitGenericHead( &Application->Groups,
  246. OBJECT_TYPE_GROUP,
  247. ChildGenericObject,
  248. &Application->Roles );
  249. // List of child roles
  250. ObInitGenericHead( &Application->Roles,
  251. OBJECT_TYPE_ROLE,
  252. ChildGenericObject,
  253. &Application->ClientContexts );
  254. // List of child ClientContexts
  255. ObInitGenericHead( &Application->ClientContexts,
  256. OBJECT_TYPE_CLIENT_CONTEXT,
  257. ChildGenericObject,
  258. &ChildGenericObject->AzpSids );
  259. // List of child AzpSids
  260. ObInitGenericHead( &ChildGenericObject->AzpSids,
  261. OBJECT_TYPE_SID,
  262. ChildGenericObject,
  263. NULL );
  264. //
  265. // Allocate a luid for this instance of the application
  266. //
  267. Status = NtAllocateLocallyUniqueId(&Application->InstanceId);
  268. if ( !NT_SUCCESS(Status) ) {
  269. WinStatus = RtlNtStatusToDosError( Status );
  270. goto Cleanup;
  271. }
  272. //
  273. // By default generate audits
  274. //
  275. Application->GenericObject.IsGeneratingAudits = TRUE;
  276. //
  277. // Generate app initialization audit if the authorization store level boolean
  278. // is true and we are not in manage store mode
  279. //
  280. if ( AzAuthorizationStore->GenericObject.IsGeneratingAudits &&
  281. !AzpOpenToManageStore(AzAuthorizationStore) ) {
  282. WinStatus = AzpApplicationGenerateInitializationAudit( Application,
  283. AzAuthorizationStore );
  284. if ( WinStatus != NO_ERROR ) {
  285. goto Cleanup;
  286. }
  287. }
  288. //
  289. // If the parent AzAuthorizationStore object support delegation, then the application object
  290. // supports the following options:
  291. // . AZPE_OPTIONS_SUPPORTS_DACL
  292. // . AZPE_OPTIONS_SUPPORTS_DELEGATION
  293. // . AZPE_OPTIONS_SUPPORTS_SACL
  294. //
  295. if ( CHECK_DELEGATION_SUPPORT( ParentGenericObject ) == NO_ERROR ) {
  296. ChildGenericObject->IsAclSupported = TRUE;
  297. ChildGenericObject->IsDelegationSupported = TRUE;
  298. ChildGenericObject->IsSACLSupported = TRUE;
  299. }
  300. //
  301. // If the provider does not support Lazy load, set the AreChildrenLoaded to
  302. // TRUE. Else leave it as FALSE. This will be set to true during the call
  303. // to AzPersistUpdateChildrenCache.
  304. //
  305. if ( !(AzAuthorizationStore->ChildLazyLoadSupported) ) {
  306. ChildGenericObject->AreChildrenLoaded = TRUE;
  307. } else {
  308. ChildGenericObject->AreChildrenLoaded = FALSE;
  309. }
  310. //
  311. // Set the boolean to indicate that the application needs to be unloaded to FALSE
  312. // For providers where lazy load is not supported, this will always remain FALSE.
  313. //
  314. ((PAZP_APPLICATION)ChildGenericObject)->UnloadApplicationObject = FALSE;
  315. //
  316. // Set the boolean to indicate that the application is closed. This will
  317. // be set to false whenever the application is opened by the user (lazy
  318. // loading the application is similar to open)
  319. //
  320. ChildGenericObject->ObjectClosed = TRUE;
  321. //
  322. // Set the AppSequenceNumber to 1. Whenever the application is closed,
  323. // increment the AppSequenceNumber. This is used to track invalid COM
  324. // handles to the application object after the application object has
  325. // been closed
  326. //
  327. ((PAZP_APPLICATION)ChildGenericObject)->AppSequenceNumber = 1;
  328. Cleanup:
  329. //
  330. // If we had adjusted the audit privilege, revert to the original state.
  331. //
  332. if ( PrivilegeAdjusted ) {
  333. DWORD TempWinStatus;
  334. TempWinStatus = AzpChangeSinglePrivilege(
  335. 0, // This is ignored since OldState is NULL.
  336. hToken,
  337. &OldState,
  338. NULL ); // This should be set to NULL to specify REVERT.
  339. ASSERT( TempWinStatus == NO_ERROR );
  340. }
  341. if ( hToken != NULL ) {
  342. CloseHandle( hToken );
  343. hToken = NULL;
  344. }
  345. if ( WinStatus != NO_ERROR ) {
  346. //
  347. // Free the authz resource manager handle.
  348. //
  349. if ( Application->AuthzResourceManager != NULL ) {
  350. AuthzFreeResourceManager( Application->AuthzResourceManager );
  351. Application->AuthzResourceManager = NULL;
  352. }
  353. }
  354. return WinStatus;
  355. }
  356. VOID
  357. AzpApplicationFree(
  358. IN PGENERIC_OBJECT GenericObject
  359. )
  360. /*++
  361. Routine Description:
  362. This routine is a worker routine for Application object free. It does any object specific
  363. cleanup that needs to be done.
  364. On entry, AzGlResource must be locked exclusively.
  365. Arguments:
  366. GenericObject - Specifies a pointer to the object to be deleted.
  367. Return Value:
  368. None
  369. --*/
  370. {
  371. PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
  372. //
  373. // Initialization
  374. //
  375. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  376. //
  377. // Free any local strings
  378. //
  379. AzpFreeString( &Application->AppVersion );
  380. AzpFreeString( &Application->AuthzInterfaceClsid );
  381. if ( Application->AuthzResourceManager != NULL ) {
  382. if ( !AuthzFreeResourceManager( Application->AuthzResourceManager ) ) {
  383. ASSERT( FALSE );
  384. }
  385. }
  386. }
  387. DWORD
  388. AzpApplicationGetProperty(
  389. IN PGENERIC_OBJECT GenericObject,
  390. IN ULONG Flags,
  391. IN ULONG PropertyId,
  392. OUT PVOID *PropertyValue
  393. )
  394. /*++
  395. Routine Description:
  396. This routine is the Application specific worker routine for AzGetProperty.
  397. It does any object specific property gets.
  398. On entry, AzGlResource must be locked shared.
  399. Arguments:
  400. GenericObject - Specifies a pointer to the object to be queried
  401. Flags - Specifies internal flags
  402. AZP_FLAGS_BY_GUID - name lists should be returned as GUID lists
  403. AZP_FLAGS_PERSIST_* - Call is from the persistence provider
  404. PropertyId - Specifies which property to return.
  405. PropertyValue - Specifies a pointer to return the property in.
  406. The returned pointer must be freed using AzFreeMemory.
  407. The returned value and type depends in PropertyId. The valid values are:
  408. AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID LPWSTR - CLSID of the IAppAuthzInterface interface supplied by the application
  409. AZ_PROP_APPLICATION_VERSION LPWSTR - Version string for the application
  410. Return Value:
  411. Status of the operation
  412. --*/
  413. {
  414. DWORD WinStatus = NO_ERROR;
  415. PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
  416. UNREFERENCED_PARAMETER( Flags );
  417. //
  418. // Initialization
  419. //
  420. ASSERT( AzpIsLockedShared( &AzGlResource ) );
  421. *PropertyValue = NULL;
  422. //
  423. // Return any object specific attribute
  424. //
  425. switch ( PropertyId ) {
  426. //
  427. // Return IAppAuthzInterface CLSID
  428. //
  429. case AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID:
  430. *PropertyValue = AzpGetStringProperty( &Application->AuthzInterfaceClsid );
  431. if ( *PropertyValue == NULL ) {
  432. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  433. }
  434. break;
  435. //
  436. // Return application version to the caller
  437. //
  438. case AZ_PROP_APPLICATION_VERSION:
  439. *PropertyValue = AzpGetStringProperty( &Application->AppVersion );
  440. if ( *PropertyValue == NULL ) {
  441. WinStatus = ERROR_NOT_ENOUGH_MEMORY;
  442. }
  443. break;
  444. default:
  445. AzPrint(( AZD_INVPARM, "AzApplicationGetProperty: invalid prop id %ld\n", PropertyId ));
  446. WinStatus = ERROR_INVALID_PARAMETER;
  447. break;
  448. }
  449. return WinStatus;
  450. }
  451. DWORD
  452. AzpApplicationSetProperty(
  453. IN PGENERIC_OBJECT GenericObject,
  454. IN ULONG Flags,
  455. IN ULONG PropertyId,
  456. IN PVOID PropertyValue
  457. )
  458. /*++
  459. Routine Description:
  460. This routine is the Application object specific worker routine for AzSetProperty.
  461. It does any object specific property sets.
  462. On entry, AzGlResource must be locked exclusive.
  463. Arguments:
  464. GenericObject - Specifies a pointer to the object to be modified
  465. Flags - Specifies flags controlling to operation of the routine
  466. AZP_FLAGS_SETTING_TO_DEFAULT - Property is being set to default value
  467. AZP_FLAGS_PERSIST_* - Call is from the persistence provider
  468. PropertyId - Specifies which property to set.
  469. PropertyValue - Specifies a pointer to the property.
  470. The specified value and type depends in PropertyId. The valid values are:
  471. AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID LPWSTR - CLSID of the IAppAuthzInterface interface supplied by the application
  472. AZ_PROP_APPLICATION_VERSION LPWSTR - Version string for the application
  473. Return Value:
  474. Status of the operation
  475. --*/
  476. {
  477. DWORD WinStatus = NO_ERROR;
  478. PAZP_APPLICATION Application = (PAZP_APPLICATION) GenericObject;
  479. AZP_STRING CapturedString;
  480. BOOL bHasChanged = TRUE;
  481. //
  482. // Initialization
  483. //
  484. UNREFERENCED_PARAMETER( Flags );
  485. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  486. AzpInitString( &CapturedString, NULL );
  487. //
  488. // Set any object specific attribute
  489. //
  490. switch ( PropertyId ) {
  491. //
  492. // Set IAppAuthzInterface CLSID attribute
  493. //
  494. case AZ_PROP_APPLICATION_AUTHZ_INTERFACE_CLSID:
  495. BEGIN_SETPROP( &WinStatus, Application, Flags, AZ_DIRTY_APPLICATION_AUTHZ_INTERFACE_CLSID ) {
  496. //
  497. // Capture the input string
  498. //
  499. WinStatus = AzpCaptureString( &CapturedString,
  500. (LPWSTR) PropertyValue,
  501. CHECK_STRING_LENGTH( Flags, 512), // Guess larger than needed
  502. TRUE ); // NULL is OK
  503. if ( WinStatus != NO_ERROR ) {
  504. goto Cleanup;
  505. }
  506. //
  507. // Do parameter validity checking
  508. //
  509. BEGIN_VALIDITY_CHECKING( Flags ) {
  510. GUID TempGuid;
  511. //
  512. // It must syntactically be a UUID
  513. //
  514. WinStatus = UuidFromString( CapturedString.String,
  515. &TempGuid );
  516. if ( WinStatus != NO_ERROR ) {
  517. AzPrint(( AZD_INVPARM, "AzpApplicationSetProperty: cannot convert CLSID %ws %ld\n", CapturedString.String, WinStatus ));
  518. goto Cleanup;
  519. }
  520. } END_VALIDITY_CHECKING;
  521. //
  522. // Swap the old/new names
  523. //
  524. AzpSwapStrings( &CapturedString, &Application->AuthzInterfaceClsid );
  525. } END_SETPROP(bHasChanged);
  526. break;
  527. //
  528. // Set application version on the object
  529. //
  530. case AZ_PROP_APPLICATION_VERSION:
  531. BEGIN_SETPROP( &WinStatus, Application, Flags, AZ_DIRTY_APPLICATION_VERSION ) {
  532. //
  533. // Capture the input string
  534. //
  535. WinStatus = AzpCaptureString( &CapturedString,
  536. (LPWSTR) PropertyValue,
  537. CHECK_STRING_LENGTH( Flags, AZ_MAX_APPLICATION_VERSION_LENGTH),
  538. TRUE ); // NULL is OK
  539. if ( WinStatus != NO_ERROR ) {
  540. goto Cleanup;
  541. }
  542. //
  543. // Swap the old/new names
  544. //
  545. AzpSwapStrings( &CapturedString, &Application->AppVersion );
  546. } END_SETPROP(bHasChanged);
  547. break;
  548. default:
  549. AzPrint(( AZD_INVPARM, "AzpApplicationSetProperty: invalid prop id %ld\n", PropertyId ));
  550. WinStatus = ERROR_INVALID_PARAMETER;
  551. goto Cleanup;
  552. }
  553. //
  554. // Free any local resources
  555. //
  556. Cleanup:
  557. AzpFreeString( &CapturedString );
  558. return WinStatus;
  559. }
  560. DWORD
  561. WINAPI
  562. AzApplicationCreate(
  563. IN AZ_HANDLE AzAuthorizationStoreHandle,
  564. IN LPCWSTR ApplicationName,
  565. IN DWORD Reserved,
  566. OUT PAZ_HANDLE ApplicationHandle
  567. )
  568. /*++
  569. Routine Description:
  570. This routine adds an application into the scope of the specified AzAuthorizationStore. It also sets
  571. Application object specific optional characteristics using the parent AzAuthorizationStore object.
  572. Arguments:
  573. AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
  574. ApplicationName - Specifies the name of the application to add.
  575. Reserved - Reserved. Must by zero.
  576. ApplicationHandle - Return a handle to the application.
  577. The caller must close this handle by calling AzCloseHandle.
  578. Return Value:
  579. NO_ERROR - The operation was successful
  580. ERROR_ALREADY_EXISTS - An object by that name already exists
  581. --*/
  582. {
  583. //
  584. // Call the common routine to do most of the work
  585. //
  586. return ObCommonCreateObject(
  587. (PGENERIC_OBJECT) AzAuthorizationStoreHandle,
  588. OBJECT_TYPE_AZAUTHSTORE,
  589. &(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
  590. OBJECT_TYPE_APPLICATION,
  591. ApplicationName,
  592. Reserved,
  593. (PGENERIC_OBJECT *) ApplicationHandle );
  594. }
  595. DWORD
  596. WINAPI
  597. AzApplicationOpen(
  598. IN AZ_HANDLE AzAuthorizationStoreHandle,
  599. IN LPCWSTR ApplicationName,
  600. IN DWORD Reserved,
  601. OUT PAZ_HANDLE ApplicationHandle
  602. )
  603. /*++
  604. Routine Description:
  605. This routine opens an application into the scope of the specified AzAuthorizationStore.
  606. Arguments:
  607. AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
  608. ApplicationName - Specifies the name of the application to open
  609. Reserved - Reserved. Must by zero.
  610. ApplicationHandle - Return a handle to the application.
  611. The caller must close this handle by calling AzCloseHandle.
  612. Return Value:
  613. NO_ERROR - The operation was successful
  614. ERROR_NOT_FOUND - There is no application by that name
  615. --*/
  616. {
  617. DWORD WinStatus = 0;
  618. //
  619. // Call the common routine to do most of the work
  620. //
  621. WinStatus = ObCommonOpenObject(
  622. (PGENERIC_OBJECT) AzAuthorizationStoreHandle,
  623. OBJECT_TYPE_AZAUTHSTORE,
  624. &(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
  625. OBJECT_TYPE_APPLICATION,
  626. ApplicationName,
  627. Reserved,
  628. (PGENERIC_OBJECT *) ApplicationHandle );
  629. if ( WinStatus == NO_ERROR ) {
  630. //
  631. // Load the children if the Application object has already been submitted to
  632. // the store
  633. //
  634. if ( !((PGENERIC_OBJECT) *ApplicationHandle)->AreChildrenLoaded ) {
  635. //
  636. // Grab the resource lock exclusive
  637. //
  638. AzpLockResourceExclusive( &AzGlResource );
  639. WinStatus = AzPersistUpdateChildrenCache(
  640. (PGENERIC_OBJECT) *ApplicationHandle
  641. );
  642. AzpUnlockResource( &AzGlResource );
  643. if ( WinStatus != NO_ERROR ) {
  644. //
  645. // Dereference the application handle and return nothing to the caller
  646. //
  647. AzCloseHandle( (PGENERIC_OBJECT)*ApplicationHandle, 0 );
  648. *ApplicationHandle = NULL;
  649. }
  650. }
  651. }
  652. //
  653. // The application object is no longer closed. Mark that in the object.
  654. //
  655. if ( WinStatus == NO_ERROR ) {
  656. ((PGENERIC_OBJECT)*ApplicationHandle)->ObjectClosed = FALSE;
  657. }
  658. return WinStatus;
  659. }
  660. DWORD
  661. WINAPI
  662. AzApplicationClose(
  663. IN AZ_HANDLE AzAuthorizationStoreHandle,
  664. IN LPCWSTR pApplicationName,
  665. IN LONG lFlags
  666. )
  667. /*++
  668. Routine Description:
  669. This routine unloads the children of the application object specified
  670. by pApplicationName from the cache. It will leave the application object
  671. in cache however.
  672. If the provider does not support lazy loading of objects, then it is not
  673. possible to call the close API. Return ERROR_NOT_SUPPORTED.
  674. Arguments:
  675. AzAuthorizationStoreHandle - Handle to the authorization store object
  676. pApplicationName - Name of the application to be unloaded from the cache
  677. lFlags - Flag specifying the behavior of the close
  678. AZ_AZSTORE_FORCE_APPLICATION_CLOSE - Forcefully remove all children
  679. of the specified of application from cache
  680. If no flags are specified, then the application will be unloaded only
  681. when the reference handle count reaches zero.
  682. Return Value:
  683. NO_ERROR - The application was successfully unloaded from the cache
  684. ERROR_NOT_SUPPORTED - Provider does not support this API
  685. ERROR_NOT_ENOUGH_MEMORY - Lack of resources
  686. Other status codes
  687. --*/
  688. {
  689. DWORD WinStatus = NO_ERROR;
  690. PGENERIC_OBJECT pApplication = NULL;
  691. AZP_STRING AppName;
  692. BOOLEAN bResourceLocked = FALSE;
  693. //
  694. // Validation
  695. //
  696. ASSERT( AzAuthorizationStoreHandle != INVALID_HANDLE_VALUE );
  697. AzpInitString( &AppName, NULL );
  698. //
  699. // If the store is a provider that does not support lazy load,
  700. // then we do not support unloading an application for that
  701. // provider
  702. //
  703. if ( !((PAZP_AZSTORE)AzAuthorizationStoreHandle)->ChildLazyLoadSupported ) {
  704. WinStatus = ERROR_NOT_SUPPORTED;
  705. goto Cleanup;
  706. }
  707. //
  708. // Reference the application object by name
  709. //
  710. WinStatus = AzpCaptureString(
  711. &AppName,
  712. pApplicationName,
  713. AZ_MAX_APPLICATION_NAME_LENGTH,
  714. FALSE // NULL not OK
  715. );
  716. if ( WinStatus != NO_ERROR ) {
  717. AzPrint(( AZD_INVPARM,
  718. "AzApplicationClose: Failed to capture application name: %ld\n",
  719. WinStatus
  720. ));
  721. goto Cleanup;
  722. }
  723. //
  724. // Grab the cache lock exclusively to unload the application
  725. //
  726. AzpLockResourceExclusive( &AzGlResource );
  727. bResourceLocked = TRUE;
  728. WinStatus = ObReferenceObjectByName(
  729. &((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications,
  730. &AppName,
  731. 0, // No flags
  732. &pApplication
  733. );
  734. if ( WinStatus != NULL ) {
  735. AzPrint(( AZD_REF,
  736. "AzApplicationClose: Cannot reference application %ws: %ld\n",
  737. pApplicationName,
  738. WinStatus
  739. ));
  740. goto Cleanup;
  741. }
  742. //
  743. // Check the flags that were sent by the user. If the user
  744. // does not wish to perform a forcefull unloading of the application,
  745. // then simply set the boolean on the application object indicating
  746. // that the application object needs to be unloaded when the handle
  747. // reference count reaches 0.
  748. //
  749. if ( (lFlags & AZ_AZSTORE_FORCE_APPLICATION_CLOSE) != 0 ) {
  750. //
  751. // Forcefull close required
  752. //
  753. //
  754. // Call the routine to clean up all the child generic heads
  755. //
  756. WinStatus = ObUnloadChildGenericHeads( pApplication );
  757. if ( WinStatus != ERROR_NOT_SUPPORTED && WinStatus != NO_ERROR ) {
  758. //
  759. // Update the children cache of this application object
  760. //
  761. DWORD TempWinStatus = NO_ERROR;
  762. TempWinStatus = AzPersistUpdateChildrenCache( pApplication );
  763. if ( TempWinStatus != NO_ERROR ) {
  764. AzPrint(( AZD_REF,
  765. "AzApplicationClose: Cannot reload children on unload failure: %ld\n",
  766. TempWinStatus
  767. ));
  768. }
  769. goto Cleanup;
  770. }
  771. //
  772. // Set the boolean on the object specifying that its children are no
  773. // longer loaded
  774. //
  775. ((PGENERIC_OBJECT)pApplication)->AreChildrenLoaded = FALSE;
  776. } else {
  777. ((PAZP_APPLICATION)pApplication)->UnloadApplicationObject = TRUE;
  778. }
  779. WinStatus = NO_ERROR;
  780. Cleanup:
  781. if ( pApplication != NULL ) {
  782. ObDereferenceObject( pApplication );
  783. }
  784. AzpFreeString( &AppName );
  785. //
  786. // drop the global lock
  787. //
  788. if ( bResourceLocked ) {
  789. AzpUnlockResource( &AzGlResource );
  790. }
  791. return WinStatus;
  792. }
  793. DWORD
  794. WINAPI
  795. AzApplicationEnum(
  796. IN AZ_HANDLE AzAuthorizationStoreHandle,
  797. IN DWORD Reserved,
  798. IN OUT PULONG EnumerationContext,
  799. OUT PAZ_HANDLE ApplicationHandle
  800. )
  801. /*++
  802. Routine Description:
  803. Enumerates all of the applications for the specified AzAuthorizationStore.
  804. Arguments:
  805. AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
  806. Reserved - Reserved. Must by zero.
  807. EnumerationContext - Specifies a context indicating the next application to return
  808. On input for the first call, should point to zero.
  809. On input for subsequent calls, should point to the value returned on the previous call.
  810. On output, returns a value to be passed on the next call.
  811. ApplicationHandle - Returns a handle to the next application object.
  812. The caller must close this handle by calling AzCloseHandle.
  813. Return Value:
  814. NO_ERROR - The operation was successful (a handle was returned)
  815. ERROR_NO_MORE_ITEMS - No more items were available for enumeration
  816. --*/
  817. {
  818. //
  819. // Call the common routine to do most of the work
  820. //
  821. return ObCommonEnumObjects(
  822. (PGENERIC_OBJECT) AzAuthorizationStoreHandle,
  823. OBJECT_TYPE_AZAUTHSTORE,
  824. &(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
  825. EnumerationContext,
  826. Reserved,
  827. (PGENERIC_OBJECT *) ApplicationHandle );
  828. }
  829. DWORD
  830. WINAPI
  831. AzApplicationDelete(
  832. IN AZ_HANDLE AzAuthorizationStoreHandle,
  833. IN LPCWSTR ApplicationName,
  834. IN DWORD Reserved
  835. )
  836. /*++
  837. Routine Description:
  838. This routine deletes an application from the scope of the specified AzAuthorizationStore.
  839. Also deletes any child objects of ApplicationName.
  840. Arguments:
  841. AzAuthorizationStoreHandle - Specifies a handle to the AzAuthorizationStore.
  842. ApplicationName - Specifies the name of the application to delete.
  843. Reserved - Reserved. Must by zero.
  844. Return Value:
  845. NO_ERROR - The operation was successful
  846. ERROR_NOT_FOUND - An object by that name cannot be found
  847. --*/
  848. {
  849. //
  850. // Call the common routine to do most of the work
  851. //
  852. return ObCommonDeleteObject(
  853. (PGENERIC_OBJECT) AzAuthorizationStoreHandle,
  854. OBJECT_TYPE_AZAUTHSTORE,
  855. &(((PAZP_AZSTORE)AzAuthorizationStoreHandle)->Applications),
  856. OBJECT_TYPE_APPLICATION,
  857. ApplicationName,
  858. Reserved );
  859. }