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.

1196 lines
37 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dbpolex.c
  5. Abstract:
  6. LSA Database - Policy Object Private API Workers
  7. Author:
  8. Mac McLain (MacM) January 17, 1997
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include <lsapch2.h>
  13. #include <dbp.h>
  14. #include "lsawmi.h"
  15. #ifndef LSAP_DB_POLICY_MAX_BUFFERS
  16. #define LSAP_DB_POLICY_MAX_BUFFERS ((ULONG) 0x00000005L)
  17. #endif
  18. NTSTATUS
  19. LsapDbVerifyInfoAllQueryPolicy(
  20. IN LSAPR_HANDLE PolicyHandle,
  21. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  22. OUT PACCESS_MASK RequiredAccess
  23. )
  24. /*++
  25. Routine Description:
  26. This function validates a Local Policy Information Class. If valid, a mask
  27. of the accesses required to set the Policy Information of the class is
  28. returned.
  29. Arguments:
  30. PolicyHandle - Handle from an LsapDbOpenPolicy call. The handle
  31. may be trusted.
  32. InformationClass - Specifies a Policy Information Class.
  33. RequiredAccess - Points to variable that will receive a mask of the
  34. accesses required to query the given class of Policy Information.
  35. If an error is returned, this value is cleared to 0.
  36. Return Values:
  37. NTSTATUS - Standard Nt Result Code
  38. STATUS_SUCCESS - The Policy Information Class provided is
  39. valid and the information provided is consistent with this
  40. class.
  41. STATUS_INVALID_PARAMETER - Invalid parameter:
  42. Information Class is invalid
  43. Policy Information not valid for the class
  44. STATUS_SHARED_POLICY - The policy is replicated from the DCs and cannot be modified
  45. locally
  46. --*/
  47. {
  48. //
  49. // Ensure the info level is valid.
  50. //
  51. if ( InformationClass < PolicyDomainEfsInformation ||
  52. InformationClass > PolicyDomainKerberosTicketInformation ) {
  53. return STATUS_INVALID_PARAMETER;
  54. }
  55. *RequiredAccess = LsapDbRequiredAccessQueryDomainPolicy[InformationClass];
  56. return STATUS_SUCCESS;
  57. }
  58. NTSTATUS
  59. LsapDbVerifyInfoAllSetPolicy(
  60. IN LSAPR_HANDLE PolicyHandle,
  61. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  62. IN PVOID PolicyInformation,
  63. OUT PACCESS_MASK RequiredAccess
  64. )
  65. /*++
  66. Routine Description:
  67. This function validates a Policy Information Class. If valid, a mask
  68. of the accesses required to set the Policy Information of the class is
  69. returned.
  70. Arguments:
  71. PolicyHandle - Handle from an LsapDbOpenPolicy call. The handle
  72. may be trusted.
  73. InformationClass - Specifies a Policy Information Class.
  74. RequiredAccess - Points to variable that will receive a mask of the
  75. accesses required to query the given class of Policy Information.
  76. If an error is returned, this value is cleared to 0.
  77. Return Values:
  78. NTSTATUS - Standard Nt Result Code
  79. STATUS_SUCCESS - The Policy Information Class provided is
  80. valid and the information provided is consistent with this
  81. class.
  82. STATUS_INVALID_PARAMETER - Invalid parameter:
  83. Information Class is invalid
  84. Policy Information not valid for the class
  85. --*/
  86. {
  87. //
  88. // Ensure the info level is valid.
  89. //
  90. if ( InformationClass < PolicyDomainEfsInformation ||
  91. InformationClass > PolicyDomainKerberosTicketInformation ) {
  92. return STATUS_INVALID_PARAMETER;
  93. } else if ( InformationClass == PolicyDomainKerberosTicketInformation &&
  94. PolicyInformation == NULL ) {
  95. return STATUS_INVALID_PARAMETER;
  96. }
  97. *RequiredAccess = LsapDbRequiredAccessSetDomainPolicy[InformationClass];
  98. return STATUS_SUCCESS;
  99. }
  100. NTSTATUS
  101. NTAPI
  102. LsarQueryDomainInformationPolicy(
  103. IN LSA_HANDLE PolicyHandle,
  104. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  105. OUT PLSAPR_POLICY_DOMAIN_INFORMATION *PolicyDomainInformation
  106. )
  107. /*++
  108. Routine Description:
  109. This function is the LSA server RPC worker routine for the
  110. LsarQueryDomainInformationPolicy API.
  111. The LsaQueryDomainInformationPolicy API obtains information from the Local Policy
  112. object. The caller must have access appropriate to the information
  113. being requested (see InformationClass parameter).
  114. Arguments:
  115. PolicyHandle - Handle from an LsaOpenPolicy call.
  116. InformationClass - Specifies the information to be returned. The
  117. Information Classes and accesses required are as follows:
  118. Information Class Required Access Type
  119. PolicyDomainEfsInformation POLICY_VIEW_LOCAL_INFORMATION
  120. PolicyDomainKerberosTicketInformation POLICY_VIEW_LOCAL_INFORMATION
  121. PolicyLocalInformation - receives a pointer to the buffer returned comtaining the
  122. requested information. This buffer is allocated by this service
  123. and must be freed when no longer needed by passing the returned
  124. value to LsaFreeMemory().
  125. Return Value:
  126. NTSTATUS - Standard Nt Result Code
  127. STATUS_ACCESS_DENIED - Caller does not have the appropriate
  128. access to complete the operation.
  129. STATUS_INTERNAL_DB_CORRUPTION - The Policy Database is possibly
  130. corrupt. The returned Policy Information is invalid for
  131. the given class.
  132. --*/
  133. {
  134. NTSTATUS Status = STATUS_SUCCESS;
  135. BOOLEAN ObjectReferenced = FALSE;
  136. ACCESS_MASK DesiredAccess;
  137. ULONG ReferenceOptions, DereferenceOptions = 0;
  138. LsarpReturnCheckSetup();
  139. LsapDsDebugOut(( DEB_FTRACE, "LsarQueryDomainInformationPolicy\n" ));
  140. LsapTraceEvent(EVENT_TRACE_TYPE_START, LsaTraceEvent_QueryDomainInformationPolicy);
  141. Status = LsapDbVerifyInfoAllQueryPolicy(
  142. PolicyHandle,
  143. InformationClass,
  144. &DesiredAccess
  145. );
  146. if (!NT_SUCCESS(Status)) {
  147. goto QueryInfoDomainPolicyFinish;
  148. }
  149. //
  150. // If querying the Audit Log Full information, we may need to perform a
  151. // test write to the Audit Log to verify that the Log Full status is
  152. // up to date. The Audit Log Queue Lock must always be taken
  153. // prior to acquiring the LSA Database lock, so take the former lock
  154. // here in case we need it.
  155. //
  156. ReferenceOptions = LSAP_DB_LOCK |
  157. LSAP_DB_START_TRANSACTION | LSAP_DB_READ_ONLY_TRANSACTION |
  158. LSAP_DB_NO_DS_OP_TRANSACTION;
  159. DereferenceOptions = LSAP_DB_LOCK |
  160. LSAP_DB_FINISH_TRANSACTION | LSAP_DB_READ_ONLY_TRANSACTION |
  161. LSAP_DB_NO_DS_OP_TRANSACTION;
  162. //
  163. // Acquire the Lsa Database lock. Verify that the handle is valid, is
  164. // a handle to the Policy object and has the necessary access granted.
  165. // Reference the handle.
  166. //
  167. Status = LsapDbReferenceObject(
  168. PolicyHandle,
  169. DesiredAccess,
  170. PolicyObject,
  171. PolicyObject,
  172. ReferenceOptions
  173. );
  174. if (!NT_SUCCESS(Status)) {
  175. goto QueryInfoDomainPolicyFinish;
  176. }
  177. ObjectReferenced = TRUE;
  178. //
  179. // If caching is enabled for this Information Class, grab the info from the
  180. // cache.
  181. //
  182. *PolicyDomainInformation = NULL;
  183. Status = LsapDbQueryInformationPolicyEx(
  184. LsapPolicyHandle,
  185. InformationClass,
  186. PolicyDomainInformation
  187. );
  188. QueryInfoDomainPolicyFinish:
  189. //
  190. // If necessary, dereference the Policy Object, release the LSA Database lock and
  191. // return.
  192. //
  193. if (ObjectReferenced) {
  194. Status = LsapDbDereferenceObject(
  195. &PolicyHandle,
  196. PolicyObject,
  197. PolicyObject,
  198. DereferenceOptions,
  199. (SECURITY_DB_DELTA_TYPE) 0,
  200. Status
  201. );
  202. }
  203. LsapDsDebugOut(( DEB_FTRACE, "LsarQueryDomainInformationPolicy: 0x%lx\n", Status ));
  204. LsapTraceEvent(EVENT_TRACE_TYPE_END, LsaTraceEvent_QueryDomainInformationPolicy);
  205. LsarpReturnPrologue();
  206. return(Status);
  207. }
  208. NTSTATUS
  209. NTAPI
  210. LsarSetDomainInformationPolicy(
  211. IN LSA_HANDLE PolicyHandle,
  212. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  213. IN PLSAPR_POLICY_DOMAIN_INFORMATION PolicyDomainInformation
  214. )
  215. /*++
  216. Routine Description:
  217. This function is the LSA server RPC worker routine for the
  218. LsarSetDomainInformationPolicy API.
  219. The LsarSetDomainInformationPolicy API obtains information from the Domain Policy
  220. object. The caller must have access appropriate to the information
  221. being requested (see InformationClass parameter).
  222. Arguments:
  223. PolicyHandle - Handle from an LsaOpenPolicy call.
  224. InformationClass - Specifies the information to be set. The
  225. Information Classes and accesses required are as follows:
  226. Information Class Required Access Type
  227. PolicyAuditEventsInformation POLICY_VIEW_AUDIT_INFORMATION
  228. PolicyAccountDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  229. PolicyPdAccountInformation POLICY_GET_PRIVATE_INFORMATION
  230. PolicyLsaServerRoleInformation POLICY_VIEW_LOCAL_INFORMATION
  231. PolicyReplicaSourceInformation POLICY_VIEW_LOCAL_INFORMATION
  232. PolicyDefaultQuotaInformation POLICY_VIEW_LOCAL_INFORMATION
  233. PolicyAuditFullQueryInformation POLICY_VIEW_AUDIT_INFORMATION
  234. PolicyDnsDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  235. PolicyDnsDomainInformationInt POLICY_VIEW_LOCAL_INFORMATION
  236. PolicyLocalInformation - receives a pointer to the buffer information to be set
  237. Return Value:
  238. NTSTATUS - Standard Nt Result Code
  239. --*/
  240. {
  241. NTSTATUS Status = STATUS_SUCCESS;
  242. BOOLEAN ObjectReferenced = FALSE;
  243. ACCESS_MASK DesiredAccess;
  244. ULONG ReferenceOptions, DereferenceOptions = 0;
  245. LsarpReturnCheckSetup();
  246. LsapTraceEvent(EVENT_TRACE_TYPE_START, LsaTraceEvent_SetDomainInformationPolicy);
  247. Status = LsapDbVerifyInfoAllSetPolicy(
  248. PolicyHandle,
  249. InformationClass,
  250. PolicyDomainInformation,
  251. &DesiredAccess
  252. );
  253. if (!NT_SUCCESS(Status)) {
  254. goto QueryInfoDomainPolicyFinish;
  255. }
  256. //
  257. // If querying the Audit Log Full information, we may need to perform a
  258. // test write to the Audit Log to verify that the Log Full status is
  259. // up to date. The Audit Log Queue Lock must always be taken
  260. // prior to acquiring the LSA Database lock, so take the former lock
  261. // here in case we need it.
  262. //
  263. ReferenceOptions = LSAP_DB_LOCK | LSAP_DB_NO_DS_OP_TRANSACTION | LSAP_DB_START_TRANSACTION;
  264. DereferenceOptions = LSAP_DB_LOCK | LSAP_DB_NO_DS_OP_TRANSACTION | LSAP_DB_FINISH_TRANSACTION;
  265. //
  266. // Acquire the Lsa Database lock. Verify that the handle is valid, is
  267. // a handle to the Policy object and has the necessary access granted.
  268. // Reference the handle.
  269. //
  270. Status = LsapDbReferenceObject(
  271. PolicyHandle,
  272. DesiredAccess,
  273. PolicyObject,
  274. PolicyObject,
  275. ReferenceOptions
  276. );
  277. if (!NT_SUCCESS(Status)) {
  278. goto QueryInfoDomainPolicyFinish;
  279. }
  280. ObjectReferenced = TRUE;
  281. Status = LsapDbSetInformationPolicyEx(
  282. LsapPolicyHandle,
  283. InformationClass,
  284. PolicyDomainInformation
  285. );
  286. QueryInfoDomainPolicyFinish:
  287. //
  288. // If necessary, dereference the Policy Object, release the LSA Database lock and
  289. // return.
  290. //
  291. if (ObjectReferenced) {
  292. //
  293. // Don't notify the NT 4 replicator. NT 4 doesn't understand any of the attributes
  294. // changed by this API.
  295. //
  296. Status = LsapDbDereferenceObject(
  297. &PolicyHandle,
  298. PolicyObject,
  299. PolicyObject,
  300. DereferenceOptions | LSAP_DB_OMIT_REPLICATOR_NOTIFICATION,
  301. SecurityDbChange,
  302. Status
  303. );
  304. }
  305. #if DBG
  306. LsapDsDebugOut(( DEB_POLICY,
  307. "LsarSetDomainInformationPolicy for info %lu returned 0x%lx\n",
  308. InformationClass,
  309. Status ));
  310. #endif
  311. LsapTraceEvent(EVENT_TRACE_TYPE_END, LsaTraceEvent_SetDomainInformationPolicy);
  312. LsarpReturnPrologue();
  313. return(Status);
  314. }
  315. NTSTATUS
  316. LsapDbQueryInformationPolicyEx(
  317. IN LSAPR_HANDLE PolicyHandle,
  318. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  319. IN OUT PVOID *Buffer
  320. )
  321. /*++
  322. Routine Description:
  323. This function is a thin wrapper around LsapDbSlowQueryInformationPolicyEx
  324. The LsaQueryInformationPolicy API obtains information from the Policy
  325. object. The caller must have access appropriate to the information
  326. being requested (see InformationClass parameter).
  327. Arguments:
  328. PolicyHandle - Handle from an LsaOpenPolicy call.
  329. NOTE: Currently, this function only allows the
  330. PolicyDefaultQuotaInformation information class to be read from
  331. the Policy Cache. Other information classes can be added
  332. in the future.
  333. InformationClass - Specifies the information to be returned. The
  334. Information Classes and accesses required are as follows:
  335. Information Class Required Access Type
  336. PolicyAuditEventsInformation POLICY_VIEW_AUDIT_INFORMATION
  337. PolicyPrimaryDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  338. PolicyAccountDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  339. PolicyPdAccountInformation POLICY_GET_PRIVATE_INFORMATION
  340. PolicyLsaServerRoleInformation POLICY_VIEW_LOCAL_INFORMATION
  341. PolicyReplicaSourceInformation POLICY_VIEW_LOCAL_INFORMATION
  342. PolicyDefaultQuotaInformation POLICY_VIEW_LOCAL_INFORMATION
  343. PolicyAuditFullQueryInformation POLICY_VIEW_AUDIT_INFORMATION
  344. Buffer - Pointer to location that contains either a pointer to the
  345. buffer that will be used to return the information. If NULL
  346. is contained in this location, a buffer will be allocated via
  347. MIDL_user_allocate and a pointer to it returned.
  348. Return Value:
  349. NTSTATUS - Standard Nt Result Code
  350. STATUS_ACCESS_DENIED - Caller does not have the appropriate
  351. access to complete the operation.
  352. STATUS_INTERNAL_DB_CORRUPTION - The Policy Database is possibly
  353. corrupt. The returned Policy Information is invalid for
  354. the given class.
  355. --*/
  356. {
  357. NTSTATUS Status = STATUS_SUCCESS;
  358. Status = LsapDbSlowQueryInformationPolicyEx(
  359. LsapPolicyHandle,
  360. InformationClass,
  361. Buffer
  362. );
  363. return(Status);
  364. }
  365. NTSTATUS
  366. LsapDbSlowQueryInformationPolicyEx(
  367. IN LSAPR_HANDLE PolicyHandle,
  368. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  369. IN OUT PVOID *Buffer
  370. )
  371. /*++
  372. Routine Description:
  373. This function is the slow LSA server RPC worker routine for the
  374. LsarQueryInformationPolicy API. It actually reads the information
  375. from backing storage.
  376. The LsaQueryInformationPolicy API obtains information from the Policy
  377. object. The caller must have access appropriate to the information
  378. being requested (see InformationClass parameter).
  379. Arguments:
  380. PolicyHandle - Handle from an LsaOpenPolicy call.
  381. InformationClass - Specifies the information to be returned. The
  382. Information Classes and accesses required are as follows:
  383. Information Class Required Access Type
  384. PolicyAuditEventsInformation POLICY_VIEW_AUDIT_INFORMATION
  385. PolicyPrimaryDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  386. PolicyAccountDomainInformation POLICY_VIEW_LOCAL_INFORMATION
  387. PolicyPdAccountInformation POLICY_GET_PRIVATE_INFORMATION
  388. PolicyLsaServerRoleInformation POLICY_VIEW_LOCAL_INFORMATION
  389. PolicyReplicaSourceInformation POLICY_VIEW_LOCAL_INFORMATION
  390. PolicyDefaultQuotaInformation POLICY_VIEW_LOCAL_INFORMATION
  391. PolicyAuditFullQueryInformation POLICY_VIEW_AUDIT_INFORMATION
  392. Buffer - Pointer to location that contains either a pointer to the
  393. buffer that will be used to return the information. If NULL
  394. is contained in this location, a buffer will be allocated via
  395. MIDL_user_allocate and a pointer to it returned.
  396. Return Value:
  397. NTSTATUS - Standard Nt Result Code
  398. STATUS_ACCESS_DENIED - Caller does not have the appropriate
  399. access to complete the operation.
  400. STATUS_INTERNAL_DB_CORRUPTION - The Policy Database is possibly
  401. corrupt. The returned Policy Information is invalid for
  402. the given class.
  403. --*/
  404. {
  405. NTSTATUS Status = STATUS_SUCCESS;
  406. PPOLICY_DOMAIN_EFS_INFO PolicyEfsInfo;
  407. PPOLICY_DOMAIN_KERBEROS_TICKET_INFO PolicyKerbTicketInfo;
  408. LSAP_DB_ATTRIBUTE Attributes[LSAP_DB_ATTRS_INFO_CLASS_POLICY];
  409. PLSAP_DB_ATTRIBUTE NextAttribute;
  410. ULONG AttributeCount = 0;
  411. ULONG AttributeNumber = 0;
  412. LSAP_DB_HANDLE InternalHandle = (LSAP_DB_HANDLE) PolicyHandle;
  413. PVOID InformationBuffer = NULL;
  414. BOOLEAN ObjectReferenced = FALSE;
  415. ULONG EventAuditingOptionsSize, InfoSize;
  416. BOOLEAN InfoBufferInAttributeArray = TRUE;
  417. BOOLEAN BufferProvided = FALSE;
  418. if (*Buffer != NULL) {
  419. BufferProvided = TRUE;
  420. }
  421. //
  422. // Compile a list of the attributes that hold the Policy Information of
  423. // the specified class.
  424. //
  425. NextAttribute = Attributes;
  426. switch (InformationClass) {
  427. case PolicyDomainEfsInformation:
  428. //
  429. // Request read of the Efs policy attribute
  430. //
  431. LsapDbInitializeAttributeDs( NextAttribute,
  432. PolEfDat,
  433. NULL,
  434. 0,
  435. FALSE );
  436. NextAttribute++;
  437. AttributeCount++;
  438. break;
  439. case PolicyDomainKerberosTicketInformation:
  440. {
  441. int i;
  442. LSAP_DB_NAMES Names[] = { KerOpts, KerMinT, KerMaxT, KerMaxR, KerProxy, KerLogoff };
  443. for(i = 0; i < sizeof(Names) / sizeof(Names[0]) ; ++i){
  444. LsapDbInitializeAttributeDs( NextAttribute,
  445. Names[i],
  446. NULL,
  447. 0,
  448. TRUE );
  449. NextAttribute++;
  450. }
  451. AttributeCount += sizeof(Names) / sizeof(Names[0]);
  452. }
  453. break;
  454. default:
  455. Status = STATUS_INVALID_PARAMETER;
  456. break;
  457. }
  458. if (!NT_SUCCESS(Status)) {
  459. goto SlowQueryInformationPolicyError;
  460. }
  461. //
  462. //
  463. // Read the attributes corresponding to the given Policy Information
  464. // Class. Memory will be allocated where required for output
  465. // Attribute Value buffers, via MIDL_user_allocate().
  466. //
  467. Status = LsapDbReadAttributesObject( PolicyHandle,
  468. 0,
  469. Attributes,
  470. AttributeCount );
  471. if (!NT_SUCCESS(Status)) {
  472. //
  473. // Some attributes may not exist because they were never set
  474. // or were deleted because they were set to NULL values.
  475. //
  476. goto SlowQueryInformationPolicyError;
  477. }
  478. //
  479. // Now copy the information read to the output. The following flags
  480. // are used to control freeing of memory buffers:
  481. //
  482. // InfoBufferInAttributeArray
  483. //
  484. // If set to TRUE (the default), the information to be returned to
  485. // the caller consists of a single buffer which was read directly
  486. // from a single attribute of the Policy object and can be returned
  487. // as is to the caller. The information buffer being returned is
  488. // therefore referenced by the single Attribute Information block's
  489. // AttributeValue field.
  490. //
  491. // If set to FALSE, the information to be returned to the caller
  492. // does not satisfy the above. The information to be returned is
  493. // either obtained from a single attribute, but is in a different form
  494. // from that read from the Database, or it is complex, consisting
  495. // of information read from multiple attributes, hung off a top-level
  496. // node. In these cases, the top level information buffer is not
  497. // referenced by any member of the Attribute Info Array.
  498. //
  499. // Attribute->MemoryAllocated
  500. //
  501. // When an attribute is read via LsapDbReadAttributesObject, this
  502. // field is set to TRUE to indicate that memory was allocated via
  503. // MIDL_user_allocate() for the AttributeValue. If this memory
  504. // buffer is to be returned to the caller (i.e. referenced from
  505. // the output structure graph returned), it is set to FALSE so that
  506. // the normal success finish part of this routine will not free it.
  507. // In this case, the calling server RPC stub will free the memory after
  508. // marshalling its contents into the return buffer. If this memory
  509. // buffer is not to be returned to the calling RPC server stub (because
  510. // the memory is an intermediate buffer), the field is left set to TRUE
  511. // so that normal cleanup will free it.
  512. //
  513. NextAttribute = Attributes;
  514. switch (InformationClass) {
  515. case PolicyDomainEfsInformation:
  516. //
  517. // Get the size of the item
  518. //
  519. InfoSize = NextAttribute->AttributeValueLength;
  520. //
  521. // Allocate memory for output buffer top-level structure.
  522. //
  523. InfoBufferInAttributeArray = FALSE;
  524. PolicyEfsInfo = MIDL_user_allocate( sizeof( POLICY_DOMAIN_EFS_INFO ) );
  525. if (PolicyEfsInfo == NULL) {
  526. Status = STATUS_INSUFFICIENT_RESOURCES;
  527. break;
  528. }
  529. PolicyEfsInfo->InfoLength = InfoSize;
  530. //
  531. // Next, the blob
  532. //
  533. PolicyEfsInfo->EfsBlob = NextAttribute->AttributeValue;
  534. NextAttribute->MemoryAllocated = FALSE;
  535. InformationBuffer = PolicyEfsInfo;
  536. break;
  537. case PolicyDomainKerberosTicketInformation:
  538. //
  539. // Allocate memory for output buffer top-level structure.
  540. //
  541. InfoBufferInAttributeArray = FALSE;
  542. PolicyKerbTicketInfo = MIDL_user_allocate( sizeof( POLICY_DOMAIN_KERBEROS_TICKET_INFO ) );
  543. if (PolicyKerbTicketInfo == NULL) {
  544. Status = STATUS_INSUFFICIENT_RESOURCES;
  545. break;
  546. }
  547. PolicyKerbTicketInfo->AuthenticationOptions = *(PULONG)NextAttribute->AttributeValue;
  548. NextAttribute++;
  549. RtlCopyMemory( &PolicyKerbTicketInfo->MaxServiceTicketAge,
  550. NextAttribute->AttributeValue,
  551. sizeof( LARGE_INTEGER ) );
  552. NextAttribute++;
  553. RtlCopyMemory( &PolicyKerbTicketInfo->MaxTicketAge,
  554. NextAttribute->AttributeValue,
  555. sizeof( LARGE_INTEGER ) );
  556. NextAttribute++;
  557. RtlCopyMemory( &PolicyKerbTicketInfo->MaxRenewAge,
  558. NextAttribute->AttributeValue,
  559. sizeof( LARGE_INTEGER ) );
  560. NextAttribute++;
  561. RtlCopyMemory( &PolicyKerbTicketInfo->MaxClockSkew,
  562. NextAttribute->AttributeValue,
  563. sizeof( LARGE_INTEGER ) );
  564. NextAttribute++;
  565. RtlCopyMemory( &PolicyKerbTicketInfo->Reserved,
  566. NextAttribute->AttributeValue,
  567. sizeof( LARGE_INTEGER ) );
  568. NextAttribute++;
  569. InformationBuffer = PolicyKerbTicketInfo;
  570. break;
  571. default:
  572. Status = STATUS_INVALID_PARAMETER;
  573. break;
  574. }
  575. if (!NT_SUCCESS(Status)) {
  576. goto SlowQueryInformationPolicyError;
  577. }
  578. Status = STATUS_SUCCESS;
  579. //
  580. // If the caller provided a buffer, return information there.
  581. //
  582. if (BufferProvided) {
  583. RtlCopyMemory(
  584. *Buffer,
  585. InformationBuffer,
  586. LsapDbPolicy.Info[ InformationClass ].AttributeLength
  587. );
  588. MIDL_user_free( InformationBuffer );
  589. InformationBuffer = NULL;
  590. } else {
  591. *Buffer = InformationBuffer;
  592. }
  593. SlowQueryInformationPolicyFinish:
  594. //
  595. // Free any unwanted buffers that were allocated by
  596. // LsapDbReadAttributesObject() and that are not being returned to the
  597. // caller server stub. The server stub will free the buffers that we
  598. // do return after copying them to the return RPC transmit buffer.
  599. //
  600. //$ REVIEW kumarp 22-March-1999
  601. // replace this for loop with LsapDbFreeAttributes
  602. //
  603. for (NextAttribute = Attributes, AttributeNumber = 0;
  604. AttributeNumber < AttributeCount;
  605. NextAttribute++, AttributeNumber++) {
  606. //
  607. // If buffer holding attribute is marked as allocated, it is
  608. // to be freed here.
  609. //
  610. if (NextAttribute->MemoryAllocated) {
  611. if (NextAttribute->AttributeValue != NULL) {
  612. MIDL_user_free(NextAttribute->AttributeValue);
  613. }
  614. }
  615. }
  616. return(Status);
  617. SlowQueryInformationPolicyError:
  618. //
  619. // If necessary, free the memory allocated for the output buffer.
  620. // We only do this free if the buffer is not referenced by the
  621. // attribute array, since all buffers so referenced will be freed
  622. // here or in the Finish section.
  623. //
  624. if ((InformationBuffer != NULL) && !InfoBufferInAttributeArray) {
  625. MIDL_user_free(InformationBuffer);
  626. InformationBuffer = NULL;
  627. }
  628. //
  629. // Free the buffers referenced by the attributes array that will not be
  630. // freed by the Finish section of this routine.
  631. //
  632. //$ REVIEW kumarp 22-March-1999
  633. // replace this for loop with LsapDbFreeAttributes
  634. //
  635. for (NextAttribute = Attributes, AttributeNumber = 0;
  636. AttributeNumber < AttributeCount;
  637. NextAttribute++, AttributeNumber++) {
  638. //
  639. // If buffer holding attribute is marked as normally not to be freed,
  640. // will not get freed by the Finish section so it must be freed here.
  641. //
  642. if (!NextAttribute->MemoryAllocated) {
  643. if (NextAttribute->AttributeValue != NULL) {
  644. MIDL_user_free(NextAttribute->AttributeValue);
  645. NextAttribute->AttributeValue = NULL;
  646. NextAttribute->MemoryAllocated = FALSE;
  647. }
  648. NextAttribute->MemoryAllocated = FALSE;
  649. }
  650. }
  651. goto SlowQueryInformationPolicyFinish;
  652. }
  653. NTSTATUS
  654. LsapDbSetInformationPolicyEx(
  655. IN LSAPR_HANDLE PolicyHandle,
  656. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  657. IN PVOID PolicyInformation
  658. )
  659. /*++
  660. Routine Description:
  661. This function is the LSA server RPC worker routine for the
  662. LsaSetInformationPolicy API.
  663. The LsaSetInformationPolicy API modifies information in the Policy Object.
  664. The caller must have access appropriate to the information to be changed
  665. in the Policy Object, see the InformationClass parameter.
  666. Arguments:
  667. PolicyHandle - Handle from an LsaOpenPolicy call.
  668. InformationClass - Specifies the type of information being changed.
  669. The information types and accesses required to change them are as
  670. follows:
  671. PolicyDomainEfsInformation POLICY_TRUST_ADMIN
  672. PolicyDomainKerberosTicketInformation POLICY_TRUST_ADMIN
  673. Buffer - Points to a structure containing the information appropriate
  674. to the information type specified by the InformationClass parameter.
  675. Return Value:
  676. NTSTATUS - Standard Nt Result Code
  677. STATUS_ACCESS_DENIED - Caller does not have the appropriate access
  678. to complete the operation.
  679. Others TBS
  680. --*/
  681. {
  682. NTSTATUS Status = STATUS_SUCCESS, SavedStatus;
  683. ACCESS_MASK DesiredAccess;
  684. PPOLICY_DOMAIN_EFS_INFO PolicyEfsInfo;
  685. PPOLICY_DOMAIN_KERBEROS_TICKET_INFO PolicyKerbTicketInfo;
  686. LSAP_DB_ATTRIBUTE Attributes[LSAP_DB_ATTRS_INFO_CLASS_POLICY];
  687. LSAP_DB_ATTRIBUTE OldAttributes[LSAP_DB_ATTRS_INFO_CLASS_POLICY];
  688. PLSAP_DB_ATTRIBUTE NextAttribute;
  689. PLSAP_DB_ATTRIBUTE NextOldAttribute;
  690. ULONG AttributeCount = 0;
  691. ULONG OldAttributeCount = 0;
  692. ULONG AttributeNumber;
  693. ULONG AccountUlong;
  694. BOOLEAN RemoveAttributes = FALSE;
  695. BOOLEAN OldHandleDs;
  696. BOOLEAN BooleanStatus;
  697. BOOLEAN PreviousAuditEventsInfoExists;
  698. BOOLEAN ResetClientSyncData;
  699. PUNICODE_STRING DomainName = NULL;
  700. LARGE_INTEGER ModifiedIdAtLastPromotion;
  701. PUNICODE_STRING ReplicaSource = NULL;
  702. PUNICODE_STRING AccountName = NULL;
  703. ULONG SpecialProcessing = 0;
  704. BOOLEAN Notify = FALSE;
  705. BOOLEAN AuditingEnabled=FALSE;
  706. BOOLEAN AuditingSuccessEnabled=FALSE;
  707. BOOLEAN AuditingFailureEnabled=FALSE;
  708. USHORT AuditEventType;
  709. POLICY_NOTIFICATION_INFORMATION_CLASS NotifyClass = 0;
  710. if ( PolicyInformation == NULL ) {
  711. RemoveAttributes = TRUE;
  712. }
  713. AuditingFailureEnabled = LsapAdtAuditingEnabledHint( AuditCategoryPolicyChange,
  714. EVENTLOG_AUDIT_FAILURE );
  715. AuditingSuccessEnabled = LsapAdtAuditingEnabledHint( AuditCategoryPolicyChange,
  716. EVENTLOG_AUDIT_SUCCESS );
  717. AuditingEnabled = AuditingSuccessEnabled || AuditingFailureEnabled;
  718. //
  719. // Build the list of attributes
  720. //
  721. NextAttribute = Attributes;
  722. NextOldAttribute = OldAttributes;
  723. switch (InformationClass) {
  724. case PolicyDomainEfsInformation:
  725. PolicyEfsInfo = ( PPOLICY_DOMAIN_EFS_INFO )PolicyInformation;
  726. //
  727. // Do the blob attribute
  728. //
  729. LsapDbInitializeAttributeDs( NextAttribute,
  730. PolEfDat,
  731. PolicyEfsInfo ? PolicyEfsInfo->EfsBlob : NULL,
  732. PolicyEfsInfo ? PolicyEfsInfo->InfoLength : 0,
  733. FALSE );
  734. AttributeCount++;
  735. Notify = TRUE;
  736. NotifyClass = PolicyNotifyDomainEfsInformation;
  737. if (AuditingEnabled) {
  738. LsapDbInitializeAttributeDs( NextOldAttribute,
  739. PolEfDat,
  740. NULL,
  741. 0,
  742. FALSE );
  743. OldAttributeCount++;
  744. }
  745. break;
  746. case PolicyDomainKerberosTicketInformation:
  747. PolicyKerbTicketInfo = ( PPOLICY_DOMAIN_KERBEROS_TICKET_INFO )PolicyInformation;
  748. LsapDbInitializeAttributeDs( NextAttribute,
  749. KerOpts,
  750. PolicyKerbTicketInfo ?
  751. &PolicyKerbTicketInfo->AuthenticationOptions : 0,
  752. sizeof( ULONG ),
  753. FALSE );
  754. AttributeCount++;
  755. NextAttribute++;
  756. LsapDbInitializeAttributeDs( NextAttribute,
  757. KerMinT,
  758. PolicyKerbTicketInfo ?
  759. &PolicyKerbTicketInfo->MaxServiceTicketAge: 0,
  760. sizeof( LARGE_INTEGER ),
  761. FALSE );
  762. AttributeCount++;
  763. NextAttribute++;
  764. LsapDbInitializeAttributeDs( NextAttribute,
  765. KerMaxT,
  766. PolicyKerbTicketInfo ?
  767. &PolicyKerbTicketInfo->MaxTicketAge : 0,
  768. sizeof( LARGE_INTEGER ),
  769. FALSE );
  770. AttributeCount++;
  771. NextAttribute++;
  772. LsapDbInitializeAttributeDs( NextAttribute,
  773. KerMaxR,
  774. PolicyKerbTicketInfo ?
  775. &PolicyKerbTicketInfo->MaxRenewAge : 0,
  776. sizeof( LARGE_INTEGER ),
  777. FALSE );
  778. AttributeCount++;
  779. NextAttribute++;
  780. LsapDbInitializeAttributeDs( NextAttribute,
  781. KerProxy,
  782. PolicyKerbTicketInfo ?
  783. &PolicyKerbTicketInfo->MaxClockSkew: 0,
  784. sizeof( LARGE_INTEGER ),
  785. FALSE );
  786. AttributeCount++;
  787. NextAttribute++;
  788. LsapDbInitializeAttributeDs( NextAttribute,
  789. KerLogoff,
  790. PolicyKerbTicketInfo ?
  791. &PolicyKerbTicketInfo->Reserved: 0,
  792. sizeof( LARGE_INTEGER ),
  793. FALSE );
  794. AttributeCount++;
  795. NextAttribute++;
  796. Notify = TRUE;
  797. NotifyClass = PolicyNotifyDomainKerberosTicketInformation;
  798. if (AuditingEnabled) {
  799. LsapDbInitializeAttributeDs( NextOldAttribute,
  800. KerOpts,
  801. 0, sizeof( ULONG ), FALSE );
  802. OldAttributeCount++;
  803. NextOldAttribute++;
  804. LsapDbInitializeAttributeDs( NextOldAttribute,
  805. KerMinT,
  806. 0, sizeof( LARGE_INTEGER ), FALSE );
  807. OldAttributeCount++;
  808. NextOldAttribute++;
  809. LsapDbInitializeAttributeDs( NextOldAttribute,
  810. KerMaxT,
  811. 0, sizeof( LARGE_INTEGER ), FALSE );
  812. OldAttributeCount++;
  813. NextOldAttribute++;
  814. LsapDbInitializeAttributeDs( NextOldAttribute,
  815. KerMaxR,
  816. 0, sizeof( LARGE_INTEGER ), FALSE );
  817. OldAttributeCount++;
  818. NextOldAttribute++;
  819. LsapDbInitializeAttributeDs( NextOldAttribute,
  820. KerProxy,
  821. 0, sizeof( LARGE_INTEGER ), FALSE );
  822. OldAttributeCount++;
  823. NextOldAttribute++;
  824. LsapDbInitializeAttributeDs( NextOldAttribute,
  825. KerLogoff,
  826. 0, sizeof( LARGE_INTEGER ), FALSE );
  827. OldAttributeCount++;
  828. NextOldAttribute++;
  829. }
  830. break;
  831. default:
  832. Status = STATUS_INVALID_PARAMETER;
  833. break;
  834. }
  835. if (!NT_SUCCESS(Status)) {
  836. goto SetInformationPolicyError;
  837. }
  838. //
  839. // Query the existing values before we modify them
  840. //
  841. if (AuditingEnabled) {
  842. (void) LsapDbReadAttributesObject( PolicyHandle,
  843. 0, // no options
  844. OldAttributes,
  845. OldAttributeCount );
  846. }
  847. //
  848. // Update the Policy Object attributes
  849. //
  850. if ( RemoveAttributes ) {
  851. Status = LsapDbDeleteAttributesObject( PolicyHandle,
  852. Attributes,
  853. AttributeCount );
  854. } else {
  855. Status = LsapDbWriteAttributesObject( PolicyHandle,
  856. Attributes,
  857. AttributeCount );
  858. }
  859. if ( ( AuditingSuccessEnabled && NT_SUCCESS(Status) ) ||
  860. ( AuditingFailureEnabled && !NT_SUCCESS(Status) ) ) {
  861. AuditEventType = NT_SUCCESS(Status) ?
  862. EVENTLOG_AUDIT_SUCCESS : EVENTLOG_AUDIT_FAILURE;
  863. (void) LsapAdtGenerateDomainPolicyChangeAuditEvent(
  864. InformationClass,
  865. AuditEventType,
  866. OldAttributes,
  867. Attributes,
  868. AttributeCount);
  869. }
  870. if (!NT_SUCCESS(Status)) {
  871. goto SetInformationPolicyError;
  872. }
  873. //
  874. // Finally, call the notification routines. We don't care about errors coming back
  875. // from this.
  876. //
  877. if ( Notify ) {
  878. LsaINotifyChangeNotification( NotifyClass );
  879. }
  880. SetInformationPolicyFinish:
  881. //
  882. // Free memory allocated by this routine for attribute buffers.
  883. // These have MemoryAllocated = TRUE in their attribute information.
  884. // Leave alone buffers allocated by calling RPC stub.
  885. //
  886. (void) LsapDbFreeAttributes(AttributeCount, Attributes);
  887. (void) LsapDbFreeAttributes(OldAttributeCount, OldAttributes);
  888. return(Status);
  889. SetInformationPolicyError:
  890. goto SetInformationPolicyFinish;
  891. }