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.

699 lines
14 KiB

  1. /*++
  2. Copyright (c) 2001 Microsoft Corporation
  3. Module Name:
  4. adminmgr.cxx
  5. Abstract:
  6. Routines implementing the Admin Manager object
  7. Author:
  8. Cliff Van Dyke (cliffv) 11-Apr-2001
  9. --*/
  10. #include "pch.hxx"
  11. //
  12. // Global Data
  13. //
  14. //
  15. // Global list of all admin manager for this process
  16. // Access serialized by AzGlResource
  17. //
  18. GENERIC_OBJECT_HEAD AzGlAdminManagers;
  19. RTL_RESOURCE AzGlResource;
  20. BOOL ResourceInitialized = FALSE;
  21. GUID AzGlZeroGuid;
  22. #if DBG
  23. BOOL CritSectInitialized = FALSE;
  24. #endif // DBG
  25. BOOL
  26. AzDllInitialize(VOID)
  27. /*++
  28. Routine Description
  29. This initializes global events and variables for the DLL.
  30. Arguments
  31. none
  32. Return Value
  33. Boolean: TRUE on success, FALSE on fail.
  34. --*/
  35. {
  36. BOOL RetVal = TRUE;
  37. //
  38. // Don't call back on thread start/stop
  39. // ???
  40. RtlZeroMemory( &AzGlZeroGuid, sizeof(AzGlZeroGuid) );
  41. // Initialize the resource
  42. //
  43. __try {
  44. RtlInitializeResource( &AzGlResource );
  45. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  46. RetVal = FALSE;
  47. KdPrint(("AzRoles.dll: RtlInitializeResource failed: 0x%lx\n",
  48. GetExceptionCode() ));
  49. }
  50. ResourceInitialized = TRUE;
  51. //
  52. // Initialize the root of the tree of objects
  53. //
  54. AzpLockResourceExclusive( &AzGlResource );
  55. ObInitGenericHead( &AzGlAdminManagers, OBJECT_TYPE_ADMIN_MANAGER, NULL, NULL, NULL );
  56. AzpUnlockResource( &AzGlResource );
  57. //
  58. // Initialize the stack allocator
  59. //
  60. SafeAllocaInitialize(
  61. SAFEALLOCA_USE_DEFAULT,
  62. SAFEALLOCA_USE_DEFAULT,
  63. AzpAllocateHeap,
  64. AzpFreeHeap
  65. );
  66. #if DBG
  67. //
  68. // Initialize the allocator
  69. //
  70. InitializeListHead ( &AzGlAllocatedBlocks );
  71. __try {
  72. InitializeCriticalSection ( &AzGlAllocatorCritSect );
  73. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  74. RetVal = FALSE;
  75. KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlAllocatorCritSect) failed: 0x%lx\n",
  76. GetExceptionCode() ));
  77. }
  78. CritSectInitialized = TRUE;
  79. #endif // DBG
  80. #ifdef AZROLESDBG
  81. //
  82. // Initialize debugging
  83. //
  84. __try {
  85. InitializeCriticalSection ( &AzGlLogFileCritSect );
  86. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  87. RetVal = FALSE;
  88. KdPrint(("AzRoles.dll: InitializCriticalSection (AzGlLogFileCritSect) failed: 0x%lx\n",
  89. GetExceptionCode() ));
  90. }
  91. // AzGlDbFlag = AZD_ALL;
  92. AzGlDbFlag = AZD_INVPARM; // | AZD_PERSIST | AZD_PERSIST_MORE;
  93. // AzGlLogFile = INVALID_HANDLE_VALUE;
  94. #endif // AZROLESDBG
  95. return RetVal;
  96. }
  97. BOOL
  98. AzDllUnInitialize(VOID)
  99. /*++
  100. Routine Description
  101. This uninitializes global events and variables for the DLL.
  102. Arguments
  103. none
  104. Return Value
  105. Boolean: TRUE on success, FALSE on fail.
  106. --*/
  107. {
  108. BOOL RetVal = TRUE;
  109. //
  110. // Don't call back on thread start/stop
  111. //
  112. // Handle detaching from a process.
  113. //
  114. //
  115. // Delete the resource
  116. //
  117. if ( ResourceInitialized ) {
  118. RtlDeleteResource( &AzGlResource );
  119. ResourceInitialized = FALSE;
  120. }
  121. #if DBG
  122. //
  123. // Done with the allocator
  124. //
  125. if ( CritSectInitialized ) {
  126. ASSERT( IsListEmpty( &AzGlAllocatedBlocks ));
  127. DeleteCriticalSection ( &AzGlAllocatorCritSect );
  128. CritSectInitialized = FALSE;
  129. }
  130. #endif // DBG
  131. return RetVal;
  132. }
  133. VOID
  134. AzpUnload(
  135. VOID
  136. )
  137. /*++
  138. Routine Description
  139. Force the DLL unload routine to execute
  140. Arguments
  141. NONE
  142. Return Value
  143. NONE
  144. --*/
  145. {
  146. #if DBG // Don't check this in ???
  147. AzDllUnInitialize();
  148. ASSERT( IsListEmpty( &AzGlAllocatedBlocks ));
  149. #endif // DBG
  150. }
  151. DWORD
  152. AzpAdminManagerInit(
  153. IN PGENERIC_OBJECT ParentGenericObject,
  154. IN PGENERIC_OBJECT ChildGenericObject
  155. )
  156. /*++
  157. Routine Description:
  158. This routine is a worker routine for AzInitialize. It does any object specific
  159. initialization that needs to be done.
  160. On entry, AzGlResource must be locked exclusively.
  161. Arguments:
  162. ParentGenericObject - Specifies the parent object to add the child object onto.
  163. The reference count has been incremented on this object.
  164. ChildGenericObject - Specifies the newly allocated child object.
  165. The reference count has been incremented on this object.
  166. Return Value:
  167. NO_ERROR - The operation was successful
  168. ERROR_NOT_ENOUGH_MEMORY - not enough memory
  169. Other exception status codes
  170. --*/
  171. {
  172. PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) ChildGenericObject;
  173. //
  174. // Initialization
  175. //
  176. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  177. //
  178. // Initialize the lists of child objects
  179. // Let the generic object manager know all of the types of children we support
  180. //
  181. ASSERT( ParentGenericObject == NULL );
  182. UNREFERENCED_PARAMETER( ParentGenericObject );
  183. ChildGenericObject->ChildGenericObjectHead = &AdminManager->Applications;
  184. // List of child applications
  185. ObInitGenericHead( &AdminManager->Applications,
  186. OBJECT_TYPE_APPLICATION,
  187. ChildGenericObject,
  188. &AdminManager->Groups,
  189. NULL ); // Doesn't share namespace
  190. // List of child groups
  191. ObInitGenericHead( &AdminManager->Groups,
  192. OBJECT_TYPE_GROUP,
  193. ChildGenericObject,
  194. &AdminManager->AzpSids,
  195. NULL ); // Doesn't share namespace (YET)
  196. // List of child AzpSids
  197. ObInitGenericHead( &AdminManager->AzpSids,
  198. OBJECT_TYPE_SID,
  199. ChildGenericObject,
  200. NULL,
  201. NULL ); // Doesn't share namespace
  202. return NO_ERROR;
  203. }
  204. VOID
  205. AzpAdminManagerFree(
  206. IN PGENERIC_OBJECT GenericObject
  207. )
  208. /*++
  209. Routine Description:
  210. This routine is a worker routine for AdminManager object free. It does any object specific
  211. cleanup that needs to be done.
  212. On entry, AzGlResource must be locked exclusively.
  213. Arguments:
  214. GenericObject - Specifies a pointer to the object to be deleted.
  215. Return Value:
  216. None
  217. --*/
  218. {
  219. PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) GenericObject;
  220. //
  221. // Initialization
  222. //
  223. ASSERT( AzpIsLockedExclusive( &AzGlResource ) );
  224. //
  225. // Free any local strings
  226. //
  227. AzpFreeString( &AdminManager->PolicyUrl );
  228. }
  229. DWORD
  230. WINAPI
  231. AzInitialize(
  232. IN DWORD StoreType,
  233. IN LPCWSTR PolicyUrl,
  234. IN DWORD Flags,
  235. IN DWORD Reserved,
  236. OUT PAZ_HANDLE AdminManagerHandle
  237. )
  238. /*++
  239. Routine Description:
  240. This routine initializes admin manager. This routine must be called before any other
  241. routine.
  242. Arguments:
  243. StoreType - Takes one of the AZ_ADMIN_STORE_* defines
  244. PolicyUrl - Specifies the location of the policy store
  245. Flags - Specifies flags that control the behavior of AzInitialize
  246. AZ_ADMIN_FLAG_CREATE: Create the policy database
  247. Reserved - Reserved. Must by zero.
  248. AdminManagerHandle - Return a handle to the AdminManager.
  249. The caller must close this handle by calling AzCloseHandle.
  250. Return Value:
  251. NO_ERROR - The operation was successful
  252. ERROR_ALREADY_EXISTS - AZ_ADMIN_FLAG_CREATE flag was specified and the policy already exists
  253. ERROR_FILE_NOT_FOUND - AZ_ADMIN_FLAG_CREATE flag was not specified and the policy does not already exist
  254. --*/
  255. {
  256. DWORD WinStatus;
  257. PGENERIC_OBJECT AdminManager = NULL;
  258. AZP_STRING AdminManagerName;
  259. AZP_STRING CapturedString;
  260. //
  261. // Grab the global lock
  262. //
  263. AzpLockResourceExclusive( &AzGlResource );
  264. AzpInitString( &AdminManagerName, NULL );
  265. AzpInitString( &CapturedString, NULL );
  266. //
  267. // Initialization
  268. //
  269. __try {
  270. *AdminManagerHandle = NULL;
  271. } __except( EXCEPTION_EXECUTE_HANDLER ) {
  272. WinStatus = RtlNtStatusToDosError( GetExceptionCode());
  273. goto Cleanup;
  274. }
  275. //
  276. // Validate the input parameters
  277. //
  278. if ( Reserved != 0 ) {
  279. AzPrint(( AZD_INVPARM, "AzInitialize: Reserved != 0\n" ));
  280. WinStatus = ERROR_INVALID_PARAMETER;
  281. goto Cleanup;
  282. }
  283. switch ( StoreType ) {
  284. case AZ_ADMIN_STORE_SAMPLE:
  285. break;
  286. case AZ_ADMIN_STORE_UNKNOWN:
  287. case AZ_ADMIN_STORE_AD:
  288. case AZ_ADMIN_STORE_XML:
  289. default:
  290. AzPrint(( AZD_INVPARM, "AzInitialize: StoreType invalid %ld\n", StoreType ));
  291. WinStatus = ERROR_INVALID_PARAMETER;
  292. goto Cleanup;
  293. }
  294. if ( Flags & ~AZ_ADMIN_FLAG_VALID ) {
  295. AzPrint(( AZD_INVPARM, "AzInitialize: Invalid flags 0x%lx\n", Flags ));
  296. WinStatus = ERROR_INVALID_FLAGS;
  297. goto Cleanup;
  298. }
  299. //
  300. // Capture the Policy URL
  301. //
  302. WinStatus = AzpCaptureString( &CapturedString,
  303. (LPWSTR) PolicyUrl,
  304. AZ_MAX_POLICY_URL_LENGTH,
  305. TRUE ); // NULL is OK
  306. if ( WinStatus != NO_ERROR ) {
  307. goto Cleanup;
  308. }
  309. //
  310. // Create the object
  311. //
  312. WinStatus = ObCreateObject(
  313. NULL, // There is no parent object
  314. &AzGlAdminManagers,
  315. OBJECT_TYPE_ADMIN_MANAGER,
  316. &AdminManagerName,
  317. &AdminManager );
  318. if ( WinStatus != NO_ERROR ) {
  319. goto Cleanup;
  320. }
  321. //
  322. // Set admin manager specific fields
  323. //
  324. AzpSwapStrings( &CapturedString, &((PAZP_ADMIN_MANAGER)AdminManager)->PolicyUrl );
  325. ((PAZP_ADMIN_MANAGER)AdminManager)->StoreType = StoreType;
  326. //
  327. // Load the objects for the database store
  328. //
  329. WinStatus = AzpPersistOpen(
  330. (PAZP_ADMIN_MANAGER)AdminManager,
  331. (Flags & AZ_ADMIN_FLAG_CREATE) != 0 );
  332. if ( WinStatus != NO_ERROR ) {
  333. goto Cleanup;
  334. }
  335. //
  336. // Return the handle to the caller
  337. //
  338. ObIncrHandleRefCount( AdminManager );
  339. *AdminManagerHandle = AdminManager;
  340. WinStatus = NO_ERROR;
  341. //
  342. // Free locally used resources
  343. //
  344. Cleanup:
  345. if ( AdminManager != NULL ) {
  346. ObDereferenceObject( AdminManager );
  347. }
  348. AzpFreeString( &CapturedString );
  349. //
  350. // Drop the global lock
  351. //
  352. AzpUnlockResource( &AzGlResource );
  353. return WinStatus;
  354. }
  355. DWORD
  356. WINAPI
  357. AzCloseHandle(
  358. IN AZ_HANDLE AzHandle,
  359. IN DWORD Reserved
  360. )
  361. /*++
  362. Routine Description:
  363. Close a handle returned from any of the Az* routines
  364. Arguments:
  365. AzHandle - Passes in the handle to be closed.
  366. Reserved - Reserved. Must by zero.
  367. Return Value:
  368. NO_ERROR - The operation was successful.
  369. ERROR_INVALID_HANDLE - The passed in handle was invalid
  370. ERROR_SERVER_HAS_OPEN_HANDLES - That passed in handle is an AdminManager handle
  371. and the caller open handles to child objects.
  372. --*/
  373. {
  374. DWORD WinStatus;
  375. PGENERIC_OBJECT ReferencedGenericObject = NULL;
  376. PGENERIC_OBJECT GenericObject = (PGENERIC_OBJECT) AzHandle;
  377. DWORD ObjectType;
  378. //
  379. // Grab the global lock
  380. // Only for the admin manager case do we modify anything.
  381. //
  382. AzpLockResourceShared( &AzGlResource );
  383. //
  384. // Validate the input parameters
  385. //
  386. if ( Reserved != 0 ) {
  387. AzPrint(( AZD_INVPARM, "AzCloseHandle: Reserved != 0\n" ));
  388. WinStatus = ERROR_INVALID_PARAMETER;
  389. goto Cleanup;
  390. }
  391. //
  392. // Determine the type of the object
  393. //
  394. WinStatus = ObGetHandleType( GenericObject,
  395. TRUE, // Ok to close handle for deleted object
  396. &ObjectType );
  397. if ( WinStatus != NO_ERROR ) {
  398. goto Cleanup;
  399. }
  400. //
  401. // Grab the lock exclusively if we're going to change the database
  402. //
  403. if ( ObjectType == OBJECT_TYPE_ADMIN_MANAGER ) {
  404. AzpLockResourceSharedToExclusive( &AzGlResource );
  405. }
  406. //
  407. // Validate the passed in handle
  408. //
  409. WinStatus = ObReferenceObjectByHandle( GenericObject,
  410. TRUE, // Allow deleted objects
  411. FALSE, // No need to refresh cache on a close
  412. ObjectType );
  413. if ( WinStatus != NO_ERROR ) {
  414. goto Cleanup;
  415. }
  416. ReferencedGenericObject = GenericObject;
  417. //
  418. // Handle close of AdminManager handles
  419. //
  420. if ( ObjectType == OBJECT_TYPE_ADMIN_MANAGER ) {
  421. PAZP_ADMIN_MANAGER AdminManager = (PAZP_ADMIN_MANAGER) GenericObject;
  422. //
  423. // Fail if there are any child handles open
  424. // Otherwise we'll have dangling references
  425. //
  426. if ( AdminManager->TotalHandleReferenceCount != 1 ) {
  427. WinStatus = ERROR_SERVER_HAS_OPEN_HANDLES;
  428. goto Cleanup;
  429. }
  430. //
  431. // Close the database store
  432. //
  433. AzpPersistClose( AdminManager );
  434. //
  435. // Remove the entry from the global list of AdminManagers
  436. //
  437. RemoveEntryList( &GenericObject->Next );
  438. // One from ObReferenceObjectByHandle,
  439. // one for being in the global list,
  440. // one because the handle itself isn't closed yet.
  441. ASSERT( GenericObject->ReferenceCount == 3 );
  442. // No longer in the global list
  443. ObDereferenceObject( GenericObject );
  444. }
  445. //
  446. // Actually close the handle
  447. //
  448. ObDecrHandleRefCount( GenericObject );
  449. //
  450. // ??? This is really an overactive assert. Yank it once someone complains.
  451. ASSERT( (GenericObject->Flags & GENOBJ_FLAGS_DIRTY) == 0 );
  452. WinStatus = NO_ERROR;
  453. //
  454. // Free locally used resources
  455. //
  456. Cleanup:
  457. if ( ReferencedGenericObject != NULL ) {
  458. ObDereferenceObject( ReferencedGenericObject );
  459. }
  460. //
  461. // Drop the global lock
  462. //
  463. AzpUnlockResource( &AzGlResource );
  464. return WinStatus;
  465. }
  466. VOID
  467. WINAPI
  468. AzFreeMemory(
  469. IN PVOID Buffer
  470. )
  471. /*++
  472. Routine Description
  473. Free memory returned from AzXXXGetProperty
  474. Arguments
  475. Buffer - address of buffer to free
  476. Return Value
  477. None
  478. --*/
  479. {
  480. if ( Buffer != NULL ) {
  481. AzpFreeHeap( Buffer );
  482. }
  483. }