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.

3955 lines
97 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. adtevent.c
  5. Abstract:
  6. Functions that implement audits generated by LSA itself.
  7. Author:
  8. Scott Birrell (ScottBi) January 19, 1993
  9. Environment:
  10. Revision History:
  11. --*/
  12. #include <lsapch2.h>
  13. #include "adtp.h"
  14. #include "adtutil.h"
  15. #include "adtdebug.h"
  16. #include "msobjs.h"
  17. //
  18. // Forwards
  19. //
  20. NTSTATUS
  21. LsapAdtGetDbAttributesChangeString(
  22. IN LSAP_DB_ATTRIBUTE* OldAttributes,
  23. IN LSAP_DB_ATTRIBUTE* NewAttributes,
  24. IN ULONG AttributeCount,
  25. OUT LPWSTR* AttributeChangeString
  26. );
  27. NTSTATUS
  28. LsapAdtGenerateObjectOperationAuditEvent(
  29. IN LSAPR_HANDLE ObjectHandle,
  30. IN USHORT AuditEventType,
  31. IN OBJECT_OPERATION_TYPE OperationType
  32. )
  33. /*++
  34. Routine Description:
  35. Generates an audit entry when an operation on the object
  36. represented by ObjectHandle succeeds/fails and if this type of
  37. auditing is enabled.
  38. Arguments:
  39. ObjectHandle - Handle of the object being accessed
  40. AuditEventType - The type of audit event to be generated.
  41. EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  42. OperationType - Type of operation performed on the object
  43. represented by ObjectHandle.
  44. Return Value:
  45. NTSTATUS - Standard Nt Result Code
  46. --*/
  47. {
  48. NTSTATUS Status = STATUS_SUCCESS;
  49. SE_ADT_PARAMETER_ARRAY AuditParameters;
  50. LUID ClientAuthenticationId;
  51. PTOKEN_USER TokenUserInformation=NULL;
  52. UNICODE_STRING OperationTypeName;
  53. LSAP_DB_HANDLE InternalHandle;
  54. UNICODE_STRING ObjectName;
  55. LUID SystemAuthId = SYSTEM_LUID;
  56. BOOLEAN bAudit;
  57. static LPCWSTR ObjectOperationNames[ObjectOperationDummyLast] = {
  58. L"None",
  59. L"Query"
  60. };
  61. LsapEnterFunc("LsapAdtGenerateObjectAcessAuditEvent");
  62. InternalHandle = (LSAP_DB_HANDLE) ObjectHandle;
  63. Status = LsapQueryClientInfo(
  64. &TokenUserInformation,
  65. &ClientAuthenticationId
  66. );
  67. if ( !NT_SUCCESS( Status )) {
  68. goto Cleanup;
  69. }
  70. if ( RtlEqualLuid( &ClientAuthenticationId, &SystemAuthId )) {
  71. //
  72. // do not audit secret queries by the system
  73. //
  74. goto Cleanup;
  75. }
  76. Status = LsapAdtAuditingEnabledByLogonId(
  77. AuditCategoryObjectAccess,
  78. &ClientAuthenticationId,
  79. AuditEventType,
  80. &bAudit
  81. );
  82. if (!NT_SUCCESS(Status) || !bAudit)
  83. {
  84. goto Cleanup;
  85. }
  86. //
  87. // LsarQuerySecret sometimes passes us a secret whose name will
  88. // be rejected by ElfReportEventW because the length parameter
  89. // includes the terminating NULL.
  90. //
  91. // For example,
  92. // name.Buffer = "foo\0"
  93. // name.Length = 8
  94. // name.MaximumLength = 8
  95. //
  96. // We cannot change the input param or change the LSA code to
  97. // not do this, therfore we make a local copy, fix it
  98. // and use that instead
  99. //
  100. ObjectName = InternalHandle->PhysicalNameU;
  101. ObjectName.Length = (USHORT) LsapSafeWcslen( ObjectName.Buffer,
  102. ObjectName.MaximumLength );
  103. //
  104. // Build an audit parameters structure.
  105. //
  106. RtlInitUnicodeString( &OperationTypeName, ObjectOperationNames[OperationType] );
  107. Status =
  108. LsapAdtInitParametersArray(
  109. &AuditParameters,
  110. SE_CATEGID_OBJECT_ACCESS,
  111. SE_AUDITID_OBJECT_OPERATION,
  112. AuditEventType,
  113. 13, // there are 13 params to init
  114. //
  115. // User Sid
  116. //
  117. SeAdtParmTypeSid, TokenUserInformation->User.Sid,
  118. //
  119. // Subsystem name
  120. //
  121. SeAdtParmTypeString, &LsapSubsystemName,
  122. //
  123. // Object server
  124. //
  125. SeAdtParmTypeString, &LsapLsaName,
  126. //
  127. // Operation Type
  128. //
  129. SeAdtParmTypeString, &OperationTypeName,
  130. //
  131. // Object Type : index of this is 4, used later
  132. //
  133. SeAdtParmTypeString, &LsapDbObjectTypeNames[InternalHandle->
  134. ObjectTypeId],
  135. //
  136. // Object Name
  137. //
  138. SeAdtParmTypeString, &ObjectName,
  139. //
  140. // Object Handle ID
  141. //
  142. SeAdtParmTypePtr, ObjectHandle,
  143. //
  144. // Primary Authentication information
  145. //
  146. SeAdtParmTypeLogonId, LsapSystemLogonId,
  147. //
  148. // Clients's Authentication information
  149. //
  150. SeAdtParmTypeLogonId, ClientAuthenticationId,
  151. //
  152. // Requested access : 4 is the index of ObjectType parameter
  153. //
  154. SeAdtParmTypeAccessMask, InternalHandle->RequestedAccess, 4,
  155. //
  156. // there are no object properties (object-type list)
  157. //
  158. SeAdtParmTypeNone,
  159. //
  160. // no additional information
  161. //
  162. SeAdtParmTypeNone,
  163. //
  164. // Access Mask (hex)
  165. //
  166. SeAdtParmTypeHexUlong, InternalHandle->RequestedAccess
  167. );
  168. if (!NT_SUCCESS(Status))
  169. {
  170. goto Cleanup;
  171. }
  172. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  173. Cleanup:
  174. if (TokenUserInformation != NULL)
  175. {
  176. LsapFreeLsaHeap( TokenUserInformation );
  177. }
  178. if (!NT_SUCCESS(Status)) {
  179. LsapAuditFailed( Status );
  180. }
  181. LsapExitFunc("LsapAdtGenerateObjectAcessAuditEvent", Status);
  182. return Status;
  183. }
  184. NTSTATUS
  185. LsapAdtGenerateLsaAuditEvent(
  186. IN LSAPR_HANDLE ObjectHandle,
  187. IN ULONG AuditEventCategory,
  188. IN ULONG AuditEventId,
  189. IN PPRIVILEGE_SET Privileges,
  190. IN ULONG SidCount,
  191. IN PSID *Sids OPTIONAL,
  192. IN ULONG UnicodeStringCount,
  193. IN PUNICODE_STRING UnicodeStrings OPTIONAL,
  194. IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo OPTIONAL
  195. )
  196. /*++
  197. Routine Description:
  198. This function generates an Lsa-originated Audit Event. Audit Events
  199. of this kind are generated as a result of Local Security Policy changes
  200. such as assigning/removing user rights to an account.
  201. Arguments:
  202. ObjectHandle - Specifies the handle of an object in the Lsa Policy
  203. Database. For global changes to policy, a handle to the
  204. Lsa Policy object is passed.
  205. AuditEventCategory - Specifies the Id of the Audit Event Category
  206. to which this Audit Event belongs.
  207. AuditEventId - Specifies the Id of the Audit Event being generated.
  208. Privileges - set of privileges to be recorded
  209. SidCount - Count of Sids being passed via the Sids parameter. If no
  210. Sids are passed, this parameter must be set to 0.
  211. Sids - Pointer to array of SidCount Sids. If 0 is passed for the
  212. SidCount parameter, this parameter is ignored and NULL may be
  213. specified.
  214. UnicodeStringCount - Count of Unicode Strings being passed via the
  215. UnicodeStrings parameter. If no Unicode Strings are passed, this
  216. parameter must be set to 0.
  217. UnicodeStrings - Pointer to array of UnicodeStringCount strings. If 0 is
  218. passed for the SidCount parameter, this parameter is ignored and NULL
  219. may be specified.
  220. PolicyAuditEventsInfo - Pointer to Auditing Events information structure
  221. containing the AuditingMode and the array of Policy Audit Event
  222. Information entries. This parameter must be non-NULL if and only if
  223. the AuditEventCategory parameter is SE_AUDIT_POLICY_CHANGE.
  224. --*/
  225. {
  226. NTSTATUS Status = STATUS_SUCCESS;
  227. LUID ClientAuthenticationId;
  228. PTOKEN_USER TokenUserInformation = NULL;
  229. PSID ClientSid;
  230. BOOLEAN bAudit;
  231. UNREFERENCED_PARAMETER( ObjectHandle );
  232. if (Privileges && !IsValidPrivilegeCount(Privileges->PrivilegeCount)) {
  233. Status = STATUS_INVALID_PARAMETER;
  234. goto Cleanup;
  235. }
  236. Status = LsapQueryClientInfo(
  237. &TokenUserInformation,
  238. &ClientAuthenticationId
  239. );
  240. if ( !NT_SUCCESS( Status )) {
  241. goto Cleanup;
  242. }
  243. ClientSid = TokenUserInformation->User.Sid;
  244. if (AuditEventId != SE_AUDITID_POLICY_CHANGE) {
  245. Status = LsapAdtAuditingEnabledByLogonId(
  246. LsapAdtEventTypeFromCategoryId(AuditEventCategory),
  247. &ClientAuthenticationId,
  248. EVENTLOG_AUDIT_SUCCESS,
  249. &bAudit
  250. );
  251. if (!NT_SUCCESS(Status) || !bAudit) {
  252. goto Cleanup;
  253. }
  254. }
  255. Status = LsapAdtGenerateLsaAuditEventWithClientSid( AuditEventCategory,
  256. AuditEventId,
  257. ClientSid,
  258. ClientAuthenticationId,
  259. Privileges,
  260. SidCount,
  261. Sids,
  262. UnicodeStringCount,
  263. UnicodeStrings,
  264. PolicyAuditEventsInfo );
  265. Cleanup:
  266. if (TokenUserInformation != NULL)
  267. {
  268. LsapFreeLsaHeap( TokenUserInformation );
  269. }
  270. if ( !NT_SUCCESS( Status )) {
  271. LsapAuditFailed( Status );
  272. }
  273. return(Status);
  274. }
  275. NTSTATUS
  276. LsapAdtGenerateLsaAuditEventWithClientSid(
  277. IN ULONG AuditEventCategory,
  278. IN ULONG AuditEventId,
  279. IN PSID ClientSid,
  280. IN LUID ClientAuthenticationId,
  281. IN PPRIVILEGE_SET Privileges,
  282. IN ULONG SidCount,
  283. IN PSID *Sids OPTIONAL,
  284. IN ULONG UnicodeStringCount,
  285. IN PUNICODE_STRING UnicodeStrings OPTIONAL,
  286. IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo OPTIONAL
  287. )
  288. /*++
  289. Routine Description:
  290. This function generates an Lsa-originated Audit Event. Audit Events
  291. of this kind are generated as a result of Local Security Policy changes
  292. such as assigning/removing user rights to an account.
  293. The decision to generate these audits is made in LsapAdtGenerateLsaAuditEvent.
  294. Arguments:
  295. ObjectHandle - Specifies the handle of an object in the Lsa Policy
  296. Database. For global changes to policy, a handle to the
  297. Lsa Policy object is passed.
  298. AuditEventCategory - Specifies the Id of the Audit Event Category
  299. to which this Audit Event belongs.
  300. AuditEventId - Specifies the Id of the Audit Event being generated.
  301. Privileges - set of privileges to be recorded
  302. SidCount - Count of Sids being passed via the Sids parameter. If no
  303. Sids are passed, this parameter must be set to 0.
  304. Sids - Pointer to array of SidCount Sids. If 0 is passed for the
  305. SidCount parameter, this parameter is ignored and NULL may be
  306. specified.
  307. UnicodeStringCount - Count of Unicode Strings being passed via the
  308. UnicodeStrings parameter. If no Unicode Strings are passed, this
  309. parameter must be set to 0.
  310. UnicodeStrings - Pointer to array of UnicodeStringCount strings. If 0 is
  311. passed for the SidCount parameter, this parameter is ignored and NULL
  312. may be specified.
  313. PolicyAuditEventsInfo - Pointer to Auditing Events information structure
  314. containing the AuditingMode and the array of Policy Audit Event
  315. Information entries. This parameter must be non-NULL if and only if
  316. the AuditEventCategory parameter is SE_AUDIT_POLICY_CHANGE.
  317. --*/
  318. {
  319. NTSTATUS Status = STATUS_SUCCESS;
  320. UNICODE_STRING NullString = {0};
  321. if (NULL == UnicodeStrings)
  322. {
  323. UnicodeStrings = &NullString;
  324. }
  325. UNREFERENCED_PARAMETER( UnicodeStringCount );
  326. UNREFERENCED_PARAMETER( SidCount );
  327. switch ( AuditEventCategory ) {
  328. case SE_CATEGID_POLICY_CHANGE:
  329. {
  330. switch ( AuditEventId ) {
  331. default:
  332. DsysAssertMsg(FALSE, "LsapAdtGenerateLsaAuditEventWithClientSid: invalid AuditEventId");
  333. break;
  334. case SE_AUDITID_POLICY_CHANGE:
  335. {
  336. LsapAdtPolicyChange(
  337. (USHORT)AuditEventCategory,
  338. AuditEventId,
  339. EVENTLOG_AUDIT_SUCCESS,
  340. ClientSid,
  341. ClientAuthenticationId,
  342. PolicyAuditEventsInfo
  343. );
  344. break;
  345. }
  346. case SE_AUDITID_USER_RIGHT_ASSIGNED:
  347. case SE_AUDITID_USER_RIGHT_REMOVED:
  348. {
  349. DsysAssertMsg( SidCount == 1,
  350. "LsapAdtGenerateLsaAuditEventWithClientSid" );
  351. LsapAdtUserRightAssigned(
  352. (USHORT)AuditEventCategory,
  353. AuditEventId,
  354. EVENTLOG_AUDIT_SUCCESS,
  355. ClientSid,
  356. ClientAuthenticationId,
  357. Sids[0],
  358. Privileges
  359. );
  360. break;
  361. }
  362. }
  363. break;
  364. }
  365. default:
  366. {
  367. DsysAssertMsg( FALSE, "LsapAdtGenerateLsaAuditEventWithClientSid: unsupported audit category" );
  368. return( STATUS_SUCCESS );
  369. }
  370. }
  371. return(Status);
  372. }
  373. VOID
  374. LsapAdtUserRightAssigned(
  375. IN USHORT EventCategory,
  376. IN ULONG EventID,
  377. IN USHORT EventType,
  378. IN PSID ClientSid,
  379. IN LUID CallerAuthenticationId,
  380. IN PSID TargetSid,
  381. IN PPRIVILEGE_SET Privileges
  382. )
  383. /*++
  384. Routine Description:
  385. Generates an audit for a user right being either assigned or removed.
  386. The decision to generate this audit is made in LsapAdtGenerateLsaAuditEvent.
  387. Arguments:
  388. ISSUE-2002/03/11-kumarp : add desc
  389. Return Value:
  390. None.
  391. --*/
  392. {
  393. SE_ADT_PARAMETER_ARRAY AuditParameters;
  394. //
  395. // if no privileges are being assigned/removed, dont generate the audit
  396. //
  397. if (!(Privileges && Privileges->PrivilegeCount))
  398. {
  399. return;
  400. }
  401. //
  402. // Build an audit parameters structure.
  403. //
  404. RtlZeroMemory (
  405. (PVOID) &AuditParameters,
  406. sizeof( AuditParameters )
  407. );
  408. AuditParameters.CategoryId = EventCategory;
  409. AuditParameters.AuditId = EventID;
  410. AuditParameters.Type = EventType;
  411. AuditParameters.ParameterCount = 0;
  412. //
  413. // User Sid
  414. //
  415. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
  416. AuditParameters.ParameterCount++;
  417. //
  418. // Subsystem name (if available)
  419. //
  420. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  421. AuditParameters.ParameterCount++;
  422. //
  423. // Rights
  424. //
  425. LsapSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, Privileges );
  426. AuditParameters.ParameterCount++;
  427. //
  428. // Target Sid
  429. //
  430. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, TargetSid );
  431. AuditParameters.ParameterCount++;
  432. //
  433. // Caller's Authentication information
  434. //
  435. LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, CallerAuthenticationId );
  436. AuditParameters.ParameterCount++;
  437. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  438. return;
  439. }
  440. VOID
  441. LsapAdtGenerateLsaAuditSystemAccessChange(
  442. IN USHORT EventCategory,
  443. IN ULONG EventID,
  444. IN USHORT EventType,
  445. IN PSID ClientSid,
  446. IN LUID CallerAuthenticationId,
  447. IN PSID TargetSid,
  448. IN PCWSTR szSystemAccess
  449. )
  450. /*++
  451. Routine Description:
  452. Generates an audit for System Security Access changes.
  453. The decision to generate this audit is made in LsapSetSystemAccessAccount.
  454. Arguments:
  455. EventCategory - The category of this event
  456. EventID - specific ID of event
  457. EventType - success or failure
  458. ClientSid - sid of client
  459. CallerAuthenticationID - Logon ID of caller
  460. TargetSid - receives access change
  461. szSystemAccess - string describing which access changed
  462. Return Value:
  463. None.
  464. --*/
  465. {
  466. NTSTATUS Status = STATUS_SUCCESS;
  467. SE_ADT_PARAMETER_ARRAY AuditParameters;
  468. UNICODE_STRING SystemAccessString;
  469. //
  470. // Build an audit parameters structure.
  471. //
  472. RtlZeroMemory (
  473. (PVOID) &AuditParameters,
  474. sizeof( AuditParameters )
  475. );
  476. RtlInitUnicodeString( &SystemAccessString, szSystemAccess );
  477. Status =
  478. LsapAdtInitParametersArray( &AuditParameters,
  479. EventCategory,
  480. EventID,
  481. EventType,
  482. 5,
  483. SeAdtParmTypeSid, ClientSid,
  484. SeAdtParmTypeString, &LsapSubsystemName,
  485. SeAdtParmTypeLogonId, CallerAuthenticationId,
  486. SeAdtParmTypeString, &SystemAccessString,
  487. SeAdtParmTypeSid, TargetSid
  488. );
  489. if (!NT_SUCCESS(Status))
  490. {
  491. goto Cleanup;
  492. }
  493. (VOID) LsapAdtWriteLog( &AuditParameters );
  494. Cleanup:
  495. if (!NT_SUCCESS(Status))
  496. {
  497. LsapAuditFailed( Status );
  498. }
  499. }
  500. NTSTATUS
  501. LsapAdtTrustedDomainAdd(
  502. IN USHORT EventType,
  503. IN PUNICODE_STRING pName,
  504. IN PSID pSid,
  505. IN ULONG Type,
  506. IN ULONG Direction,
  507. IN ULONG Attributes
  508. )
  509. /*++
  510. Routine Description:
  511. Generate an audit event when a trusted domain object (TDO) is created.
  512. Arguments:
  513. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  514. pName - name of the domain
  515. pSid - domain SID
  516. Type - TDO type
  517. Direction - TDO direction
  518. Attributes - TDO attributes
  519. Return Value:
  520. NTSTATUS - Standard Nt Result Code
  521. Notes:
  522. --*/
  523. {
  524. NTSTATUS Status = STATUS_SUCCESS;
  525. LUID ClientAuthenticationId;
  526. PTOKEN_USER TokenUserInformation=NULL;
  527. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  528. BOOLEAN bAudit = FALSE;
  529. Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
  530. if ( !NT_SUCCESS( Status ))
  531. {
  532. goto Cleanup;
  533. }
  534. Status = LsapAdtAuditingEnabledByLogonId(
  535. AuditCategoryPolicyChange,
  536. &ClientAuthenticationId,
  537. EventType,
  538. &bAudit
  539. );
  540. if (!NT_SUCCESS(Status) || !bAudit)
  541. {
  542. goto Cleanup;
  543. }
  544. //
  545. // Build an audit parameters structure.
  546. //
  547. Status =
  548. LsapAdtInitParametersArray(
  549. &AuditParameters,
  550. SE_CATEGID_POLICY_CHANGE,
  551. SE_AUDITID_TRUSTED_DOMAIN_ADD,
  552. EventType,
  553. 9, // there are 9 params to init
  554. //
  555. // User Sid
  556. //
  557. SeAdtParmTypeSid, TokenUserInformation->User.Sid,
  558. //
  559. // Subsystem name (if available)
  560. //
  561. SeAdtParmTypeString, &LsapSubsystemName,
  562. //
  563. // domain name
  564. //
  565. SeAdtParmTypeString, pName,
  566. //
  567. // domain id
  568. //
  569. SeAdtParmTypeSid, pSid,
  570. //
  571. // client auth-id
  572. //
  573. SeAdtParmTypeLogonId, ClientAuthenticationId,
  574. //
  575. // TDO type
  576. //
  577. SeAdtParmTypeUlong, Type,
  578. //
  579. // TDO direction
  580. //
  581. SeAdtParmTypeUlong, Direction,
  582. //
  583. // TDO attributes
  584. //
  585. SeAdtParmTypeUlong, Attributes,
  586. //
  587. // TDO: attribute quarantined spelled out
  588. //
  589. SeAdtParmTypeMessage, (Attributes & TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ? SE_ADT_MSG_ENABLED : SE_ADT_MSG_DISABLED
  590. );
  591. if (!NT_SUCCESS(Status))
  592. {
  593. goto Cleanup;
  594. }
  595. Status = LsapAdtWriteLog( &AuditParameters );
  596. Cleanup:
  597. if (TokenUserInformation != NULL)
  598. {
  599. LsapFreeLsaHeap( TokenUserInformation );
  600. }
  601. if (!NT_SUCCESS(Status))
  602. {
  603. LsapAuditFailed( Status );
  604. }
  605. return Status;
  606. }
  607. NTSTATUS
  608. LsapAdtTrustedDomainRem(
  609. IN USHORT EventType,
  610. IN PUNICODE_STRING pName,
  611. IN PSID pSid,
  612. IN PSID pClientSid,
  613. IN PLUID pClientAuthId
  614. )
  615. /*++
  616. Routine Description:
  617. Generate an audit event when a trusted domain object (TDO) is deleted.
  618. Arguments:
  619. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  620. pName - name of the domain
  621. pSid - domain SID
  622. pClientSid - SID of the client who deleted the TDO
  623. if NULL, it is determined from the thread token
  624. pClientAuthId- auth-id of the client who deleted the TDO
  625. if NULL, it is determined from the thread token
  626. Return Value:
  627. NTSTATUS - Standard Nt Result Code
  628. Notes:
  629. --*/
  630. {
  631. NTSTATUS Status = STATUS_SUCCESS;
  632. LUID ClientAuthenticationId;
  633. PTOKEN_USER TokenUserInformation=NULL;
  634. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  635. BOOLEAN bAudit = FALSE;
  636. if ( pClientSid == NULL )
  637. {
  638. DsysAssertMsg( pClientAuthId == NULL, "LsapAdtTrustedDomainRem" );
  639. Status = LsapQueryClientInfo( &TokenUserInformation,
  640. &ClientAuthenticationId );
  641. if ( !NT_SUCCESS( Status ))
  642. {
  643. goto Cleanup;
  644. }
  645. pClientSid = TokenUserInformation->User.Sid;
  646. pClientAuthId = &ClientAuthenticationId;
  647. }
  648. #if DBG
  649. else
  650. {
  651. DsysAssertMsg( pClientAuthId != NULL, "LsapAdtTrustedDomainRem" );
  652. }
  653. #endif
  654. Status = LsapAdtAuditingEnabledByLogonId(
  655. AuditCategoryPolicyChange,
  656. pClientAuthId,
  657. EventType,
  658. &bAudit
  659. );
  660. if (!NT_SUCCESS(Status) || !bAudit)
  661. {
  662. goto Cleanup;
  663. }
  664. //
  665. // Build an audit parameters structure.
  666. //
  667. Status =
  668. LsapAdtInitParametersArray(
  669. &AuditParameters,
  670. SE_CATEGID_POLICY_CHANGE,
  671. SE_AUDITID_TRUSTED_DOMAIN_REM,
  672. EventType,
  673. 5, // there are 5 params to init
  674. //
  675. // User Sid
  676. //
  677. SeAdtParmTypeSid, pClientSid,
  678. //
  679. // Subsystem name (if available)
  680. //
  681. SeAdtParmTypeString, &LsapSubsystemName,
  682. //
  683. // domain name
  684. //
  685. SeAdtParmTypeString, pName,
  686. //
  687. // domain id (SID of the root domain)
  688. //
  689. SeAdtParmTypeSid, pSid,
  690. //
  691. // client auth-id
  692. //
  693. SeAdtParmTypeLogonId, *pClientAuthId
  694. );
  695. if (!NT_SUCCESS(Status))
  696. {
  697. goto Cleanup;
  698. }
  699. Status = LsapAdtWriteLog( &AuditParameters );
  700. Cleanup:
  701. if (TokenUserInformation != NULL)
  702. {
  703. LsapFreeLsaHeap( TokenUserInformation );
  704. }
  705. if (!NT_SUCCESS(Status))
  706. {
  707. LsapAuditFailed( Status );
  708. }
  709. return Status;
  710. }
  711. NTSTATUS
  712. LsapAdtTrustedDomainMod(
  713. IN USHORT EventType,
  714. IN PSID pDomainSid,
  715. IN PUNICODE_STRING pOldName,
  716. IN ULONG OldType,
  717. IN ULONG OldDirection,
  718. IN ULONG OldAttributes,
  719. IN PUNICODE_STRING pNewName,
  720. IN ULONG NewType,
  721. IN ULONG NewDirection,
  722. IN ULONG NewAttributes
  723. )
  724. /*++
  725. Routine Description:
  726. Generate an audit event when a trusted domain object (TDO) is modified.
  727. the unmodified fields are represented by a '-' in the audit log.
  728. Arguments:
  729. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  730. pOldName - old name of the domain
  731. pOldSid - old domain SID
  732. OldType - old TDO type
  733. OldDirection - old TDO direction
  734. OldAttributes - old TDO attributes
  735. pNewName - new name of the domain
  736. pNewSid - new domain SID
  737. NewType - new TDO type
  738. NewDirection - new TDO direction
  739. NewAttributes - new TDO attributes
  740. Return Value:
  741. NTSTATUS - Standard Nt Result Code
  742. Notes:
  743. --*/
  744. {
  745. NTSTATUS Status = STATUS_SUCCESS;
  746. LUID ClientAuthenticationId;
  747. PTOKEN_USER TokenUserInformation=NULL;
  748. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  749. BOOLEAN bAudit = FALSE;
  750. Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
  751. if ( !NT_SUCCESS( Status ))
  752. {
  753. goto Cleanup;
  754. }
  755. //
  756. // if auditing is not enabled, return asap
  757. //
  758. Status = LsapAdtAuditingEnabledByLogonId(
  759. AuditCategoryPolicyChange,
  760. &ClientAuthenticationId,
  761. EventType,
  762. &bAudit
  763. );
  764. if (!NT_SUCCESS(Status) || !bAudit)
  765. {
  766. goto Cleanup;
  767. }
  768. AuditParameters.CategoryId = SE_CATEGID_POLICY_CHANGE;
  769. AuditParameters.AuditId = SE_AUDITID_TRUSTED_DOMAIN_MOD;
  770. AuditParameters.Type = EventType;
  771. AuditParameters.ParameterCount = 9;
  772. //
  773. // User Sid
  774. //
  775. LsapSetParmTypeSid( AuditParameters, 0, TokenUserInformation->User.Sid );
  776. //
  777. // Subsystem name (if available)
  778. //
  779. LsapSetParmTypeString( AuditParameters, 1, &LsapSubsystemName );
  780. //
  781. // for all subsequent fields (except the domain SID),
  782. // output a value only if it changed.
  783. //
  784. //
  785. // domain name
  786. //
  787. if ( pOldName && pNewName &&
  788. !RtlEqualUnicodeString( pOldName, pNewName, TRUE ) )
  789. {
  790. LsapSetParmTypeString( AuditParameters, 2, pNewName );
  791. }
  792. //
  793. // domain id
  794. //
  795. LsapSetParmTypeSid( AuditParameters, 3, pDomainSid );
  796. //
  797. // client auth-id
  798. //
  799. LsapSetParmTypeLogonId( AuditParameters, 4, ClientAuthenticationId );
  800. //
  801. // TDO type
  802. //
  803. if ( OldType != NewType )
  804. {
  805. LsapSetParmTypeUlong( AuditParameters, 5, NewType );
  806. }
  807. //
  808. // TDO direction
  809. //
  810. if ( OldDirection != NewDirection )
  811. {
  812. LsapSetParmTypeUlong( AuditParameters, 6, NewDirection );
  813. }
  814. //
  815. // TDO attributes
  816. //
  817. if ( OldAttributes != NewAttributes )
  818. {
  819. LsapSetParmTypeUlong( AuditParameters, 7, NewAttributes );
  820. }
  821. //
  822. // TDO attributes
  823. //
  824. if ( OldAttributes != NewAttributes )
  825. {
  826. LsapSetParmTypeMessage( AuditParameters, 8, (NewAttributes & TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) ? SE_ADT_MSG_ENABLED : SE_ADT_MSG_DISABLED );
  827. }
  828. Status = LsapAdtWriteLog( &AuditParameters );
  829. Cleanup:
  830. if (TokenUserInformation != NULL)
  831. {
  832. LsapFreeLsaHeap( TokenUserInformation );
  833. }
  834. if (!NT_SUCCESS(Status))
  835. {
  836. LsapAuditFailed( Status );
  837. }
  838. return Status;
  839. }
  840. NTSTATUS
  841. LsapAdtTrustedForestNamespaceCollision(
  842. IN LSA_FOREST_TRUST_COLLISION_RECORD_TYPE CollisionTargetType,
  843. IN PUNICODE_STRING pCollisionTargetName,
  844. IN PUNICODE_STRING pForestRootDomainName,
  845. IN PUNICODE_STRING pTopLevelName,
  846. IN PUNICODE_STRING pDnsName,
  847. IN PUNICODE_STRING pNetbiosName,
  848. IN PSID pSid,
  849. IN ULONG NewFlags
  850. )
  851. /*++
  852. Routine Description:
  853. This function generates the audit event that represents
  854. a namespace element collision.
  855. Arguments:
  856. CollisionTargetType - type of the collision target
  857. CollisionTdo : indicates a collision with a namespace element of
  858. another forest
  859. CollisionXref : indicates a collision with a domain in our forest
  860. pCollisionTargetName -
  861. name of the collision target (TDO name or Xref name)
  862. pForestRootDomainName - name of other forest
  863. pTopLevelName - top level name (NULL == not in conflict)
  864. pDnsName - DNS domain name (this is NULL if TLN is non-NULL)
  865. pNetbiosName - NetBIOS name (NULL == not in conflict)
  866. pSid - SID of domain (NULL == not in conflict)
  867. NewFlags - the new value of flags
  868. Return Value:
  869. NTSTATUS - Standard Nt Result Code
  870. Notes:
  871. This event is generated only in the success case.
  872. --*/
  873. {
  874. NTSTATUS Status = STATUS_SUCCESS;
  875. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  876. BOOLEAN bAudit;
  877. #if DBG
  878. HANDLE hToken;
  879. #endif
  880. DsysAssert(( CollisionTargetType == CollisionTdo ) ||
  881. ( CollisionTargetType == CollisionXref));
  882. DsysAssert( pCollisionTargetName != NULL );
  883. DsysAssert( pForestRootDomainName != NULL );
  884. #if DBG
  885. if ( pTopLevelName )
  886. {
  887. DsysAssert( pDnsName == NULL );
  888. DsysAssert( pNetbiosName == NULL );
  889. DsysAssert( pSid == NULL );
  890. }
  891. else
  892. {
  893. DsysAssert( pDnsName != NULL );
  894. if ( pNetbiosName != NULL )
  895. {
  896. DsysAssert( pSid == NULL );
  897. }
  898. if ( pSid != NULL )
  899. {
  900. DsysAssert( pNetbiosName == NULL );
  901. }
  902. }
  903. #endif
  904. //
  905. // if auditing is not enabled, return asap
  906. //
  907. Status = LsapAdtAuditingEnabledBySid(
  908. AuditCategoryPolicyChange,
  909. LsapLocalSystemSid,
  910. EVENTLOG_AUDIT_SUCCESS,
  911. &bAudit
  912. );
  913. if (!NT_SUCCESS(Status) || !bAudit)
  914. {
  915. goto Cleanup;
  916. }
  917. #if DBG
  918. //
  919. // make sure that this is called in the system context
  920. //
  921. Status = NtOpenThreadToken( NtCurrentThread(), TOKEN_QUERY, TRUE, &hToken );
  922. DsysAssertMsg( Status == STATUS_NO_TOKEN, "LsapAdtTrustedForestNamespaceCollision" );
  923. if ( NT_SUCCESS(Status) )
  924. {
  925. NtClose( hToken );
  926. }
  927. else
  928. {
  929. Status = STATUS_SUCCESS;
  930. }
  931. #endif
  932. //
  933. // Build an audit parameters structure.
  934. //
  935. Status =
  936. LsapAdtInitParametersArray(
  937. &AuditParameters,
  938. SE_CATEGID_POLICY_CHANGE,
  939. SE_AUDITID_NAMESPACE_COLLISION,
  940. EVENTLOG_AUDIT_SUCCESS,
  941. //
  942. // number of params to follow
  943. //
  944. 10,
  945. //
  946. // User Sid
  947. //
  948. SeAdtParmTypeSid, LsapLocalSystemSid,
  949. //
  950. // Subsystem name (if available)
  951. //
  952. SeAdtParmTypeString, &LsapSubsystemName,
  953. //
  954. // collision target type
  955. //
  956. // 0 == CollisionTdo
  957. // 1 == CollisionXref
  958. //
  959. SeAdtParmTypeUlong, CollisionTargetType,
  960. //
  961. // collision target name
  962. //
  963. // name of a TDO or cross-ref
  964. //
  965. SeAdtParmTypeString, pCollisionTargetName,
  966. //
  967. // Name of forest involved in the collision
  968. //
  969. SeAdtParmTypeString, pForestRootDomainName,
  970. //
  971. // top level name
  972. //
  973. SeAdtParmTypeString, pTopLevelName,
  974. //
  975. // DNS name
  976. //
  977. SeAdtParmTypeString, pDnsName,
  978. //
  979. // NetBIOS name
  980. //
  981. SeAdtParmTypeString, pNetbiosName,
  982. //
  983. // SID
  984. //
  985. SeAdtParmTypeSid, pSid,
  986. //
  987. // new flags value
  988. //
  989. SeAdtParmTypeUlong, NewFlags
  990. );
  991. if (!NT_SUCCESS(Status))
  992. {
  993. goto Cleanup;
  994. }
  995. Status = LsapAdtWriteLog( &AuditParameters );
  996. Cleanup:
  997. if (!NT_SUCCESS(Status))
  998. {
  999. LsapAuditFailed( Status );
  1000. }
  1001. return Status;
  1002. }
  1003. NTSTATUS
  1004. LsapAdtTrustedForestInfoEntryAddRemHelper(
  1005. IN ULONG EventId,
  1006. IN USHORT EventType,
  1007. IN PUNICODE_STRING ForestName,
  1008. IN PSID pForestRootDomainSid,
  1009. IN PLUID pOperationId,
  1010. IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
  1011. IN ULONG Flags,
  1012. IN PUNICODE_STRING TopLevelName,
  1013. IN PUNICODE_STRING DnsName,
  1014. IN PUNICODE_STRING NetbiosName,
  1015. IN PSID pSid
  1016. )
  1017. /*++
  1018. Routine Description:
  1019. Helper function for generating audit event when a namespace
  1020. element has been added to / removed from forest trust info.
  1021. If multiple entries get added, deleted or modified
  1022. in a single update of the forest trust information, all the generated
  1023. audit events will have a single unique identifier called OperationID.
  1024. This allows one to determine that the multiple generated audits are
  1025. the result of a single operation.
  1026. Arguments:
  1027. EventId - SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_ADD/REM
  1028. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  1029. ForestName - name of the forest
  1030. pForestRootDomainSid - SID of the forest
  1031. pOperationId - operation id (see description above)
  1032. EntryType - type of entry ( TLN | TLN excl. | domain info )
  1033. Flags - flags associated with the entry ( see ntlsa.h )
  1034. TopLevelName - TopLevel name
  1035. DnsName - Dns name
  1036. NetbiosName - Netbios name
  1037. pSid - domain sid
  1038. Return Value:
  1039. NTSTATUS - Standard Nt Result Code
  1040. Notes:
  1041. --*/
  1042. {
  1043. NTSTATUS Status = STATUS_SUCCESS;
  1044. LUID ClientAuthenticationId;
  1045. PTOKEN_USER TokenUserInformation=NULL;
  1046. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  1047. BOOLEAN bAudit;
  1048. Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
  1049. if ( !NT_SUCCESS( Status ))
  1050. {
  1051. goto Cleanup;
  1052. }
  1053. //
  1054. // if auditing is not enabled, return asap
  1055. //
  1056. Status = LsapAdtAuditingEnabledByLogonId(
  1057. AuditCategoryPolicyChange,
  1058. &ClientAuthenticationId,
  1059. EventType,
  1060. &bAudit);
  1061. if (!NT_SUCCESS(Status) || !bAudit)
  1062. {
  1063. goto Cleanup;
  1064. }
  1065. //
  1066. // Build an audit parameters structure.
  1067. //
  1068. Status =
  1069. LsapAdtInitParametersArray(
  1070. &AuditParameters,
  1071. SE_CATEGID_POLICY_CHANGE,
  1072. EventId,
  1073. EventType,
  1074. //
  1075. // number of params to follow
  1076. //
  1077. 13,
  1078. //
  1079. // User Sid
  1080. //
  1081. SeAdtParmTypeSid, TokenUserInformation->User.Sid,
  1082. //
  1083. // Subsystem name (if available)
  1084. //
  1085. SeAdtParmTypeString, &LsapSubsystemName,
  1086. //
  1087. // Forest name
  1088. //
  1089. SeAdtParmTypeString, ForestName,
  1090. //
  1091. // Forest SID
  1092. //
  1093. SeAdtParmTypeSid, pForestRootDomainSid,
  1094. //
  1095. // Operation ID
  1096. //
  1097. SeAdtParmTypeUlong, pOperationId->HighPart,
  1098. SeAdtParmTypeUlong, pOperationId->LowPart,
  1099. //
  1100. // Entry Type
  1101. //
  1102. SeAdtParmTypeUlong, EntryType,
  1103. //
  1104. // Flags
  1105. //
  1106. SeAdtParmTypeUlong, Flags,
  1107. //
  1108. // top level name
  1109. //
  1110. SeAdtParmTypeString, TopLevelName,
  1111. //
  1112. // DNS domain name
  1113. //
  1114. SeAdtParmTypeString, DnsName,
  1115. //
  1116. // NetBIOS domain name
  1117. //
  1118. SeAdtParmTypeString, NetbiosName,
  1119. //
  1120. // domain SID
  1121. //
  1122. SeAdtParmTypeSid, pSid,
  1123. //
  1124. // user info
  1125. //
  1126. SeAdtParmTypeLogonId, ClientAuthenticationId
  1127. );
  1128. if (!NT_SUCCESS(Status))
  1129. {
  1130. goto Cleanup;
  1131. }
  1132. Status = LsapAdtWriteLog( &AuditParameters );
  1133. Cleanup:
  1134. if (TokenUserInformation != NULL)
  1135. {
  1136. LsapFreeLsaHeap( TokenUserInformation );
  1137. }
  1138. if (!NT_SUCCESS(Status))
  1139. {
  1140. LsapAuditFailed( Status );
  1141. }
  1142. return Status;
  1143. }
  1144. NTSTATUS
  1145. LsapAdtTrustedForestInfoEntryAdd(
  1146. IN PUNICODE_STRING pForestRootDomainName,
  1147. IN PSID pForestRootDomainSid,
  1148. IN PLUID pOperationId,
  1149. IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
  1150. IN ULONG Flags,
  1151. IN PUNICODE_STRING TopLevelName,
  1152. IN PUNICODE_STRING DnsName,
  1153. IN PUNICODE_STRING NetbiosName,
  1154. IN PSID pSid
  1155. )
  1156. {
  1157. return LsapAdtTrustedForestInfoEntryAddRemHelper(
  1158. SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_ADD,
  1159. EVENTLOG_AUDIT_SUCCESS,
  1160. pForestRootDomainName,
  1161. pForestRootDomainSid,
  1162. pOperationId,
  1163. EntryType,
  1164. Flags,
  1165. TopLevelName,
  1166. DnsName,
  1167. NetbiosName,
  1168. pSid
  1169. );
  1170. }
  1171. NTSTATUS
  1172. LsapAdtTrustedForestInfoEntryRem(
  1173. IN PUNICODE_STRING pForestRootDomainName,
  1174. IN PSID pForestRootDomainSid,
  1175. IN PLUID pOperationId,
  1176. IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
  1177. IN ULONG Flags,
  1178. IN PUNICODE_STRING TopLevelName,
  1179. IN PUNICODE_STRING DnsName,
  1180. IN PUNICODE_STRING NetbiosName,
  1181. IN PSID pSid
  1182. )
  1183. {
  1184. return LsapAdtTrustedForestInfoEntryAddRemHelper(
  1185. SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_REM,
  1186. EVENTLOG_AUDIT_SUCCESS,
  1187. pForestRootDomainName,
  1188. pForestRootDomainSid,
  1189. pOperationId,
  1190. EntryType,
  1191. Flags,
  1192. TopLevelName,
  1193. DnsName,
  1194. NetbiosName,
  1195. pSid
  1196. );
  1197. }
  1198. NTSTATUS
  1199. LsapAdtTrustedForestInfoEntryMod(
  1200. IN PUNICODE_STRING pForestRootDomainName,
  1201. IN PSID pForestRootDomainSid,
  1202. IN PLUID pOperationId,
  1203. IN LSA_FOREST_TRUST_RECORD_TYPE EntryType,
  1204. IN ULONG OldFlags,
  1205. IN PUNICODE_STRING pOldTopLevelName,
  1206. IN PUNICODE_STRING pOldDnsName,
  1207. IN PUNICODE_STRING pOldNetbiosName,
  1208. IN PSID pOldSid,
  1209. IN ULONG NewFlags,
  1210. IN PUNICODE_STRING pNewTopLevelName,
  1211. IN PUNICODE_STRING pNewDnsName,
  1212. IN PUNICODE_STRING pNewNetbiosName,
  1213. IN PSID pNewSid
  1214. )
  1215. /*++
  1216. Routine Description:
  1217. Helper function for generating audit event when a namespace
  1218. element in forest trust info has been modified.
  1219. If multiple entries get added, deleted or modified
  1220. in a single update of the forest trust information, all the generated
  1221. audit events will have a single unique identifier called OperationID.
  1222. This allows one to determine that the multiple generated audits are
  1223. the result of a single operation.
  1224. Arguments:
  1225. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  1226. ForestName - name of the forest
  1227. pForestRootDomainSid - SID of the forest
  1228. pOperationId - operation id (see description above)
  1229. EntryType - type of entry ( TLN | TLN excl. | domain info )
  1230. OldFlags - old flags associated with the entry ( see ntlsa.h )
  1231. pOldTopLevelName - old TopLevel name
  1232. pOldDnsName - old Dns name
  1233. pOldNetbiosName - old Netbios name
  1234. pOldSid - old domain sid
  1235. NewFlags - new flags associated with the entry ( see ntlsa.h )
  1236. pNewTopLevelName - new TopLevel name
  1237. pNewDnsName - new Dns name
  1238. pNewNetbiosName - new Netbios name
  1239. pNewSid - new domain sid
  1240. Return Value:
  1241. NTSTATUS - Standard Nt Result Code
  1242. Notes:
  1243. The unmodified fields are represented by a '-' in the audit log.
  1244. --*/
  1245. {
  1246. NTSTATUS Status = STATUS_SUCCESS;
  1247. LUID ClientAuthenticationId;
  1248. PTOKEN_USER TokenUserInformation=NULL;
  1249. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  1250. BOOLEAN bAudit;
  1251. Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
  1252. if ( !NT_SUCCESS( Status ))
  1253. {
  1254. goto Cleanup;
  1255. }
  1256. //
  1257. // if auditing is not enabled, return asap
  1258. //
  1259. Status = LsapAdtAuditingEnabledByLogonId(
  1260. AuditCategoryPolicyChange,
  1261. &ClientAuthenticationId,
  1262. EVENTLOG_AUDIT_SUCCESS,
  1263. &bAudit
  1264. );
  1265. if (!NT_SUCCESS(Status) || !bAudit)
  1266. {
  1267. goto Cleanup;
  1268. }
  1269. AuditParameters.CategoryId = SE_CATEGID_POLICY_CHANGE;
  1270. AuditParameters.AuditId = SE_AUDITID_TRUSTED_FOREST_INFO_ENTRY_MOD;
  1271. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  1272. AuditParameters.ParameterCount = 13;
  1273. //
  1274. // User Sid
  1275. //
  1276. LsapSetParmTypeSid( AuditParameters, 0, TokenUserInformation->User.Sid );
  1277. //
  1278. // Subsystem name (if available)
  1279. //
  1280. LsapSetParmTypeString( AuditParameters, 1, &LsapSubsystemName );
  1281. //
  1282. // forest name
  1283. //
  1284. LsapSetParmTypeString( AuditParameters, 2, pForestRootDomainName );
  1285. //
  1286. // forest id (SID of the root domain)
  1287. //
  1288. LsapSetParmTypeSid( AuditParameters, 3, pForestRootDomainSid );
  1289. //
  1290. // Operation ID
  1291. //
  1292. LsapSetParmTypeUlong( AuditParameters, 4, pOperationId->HighPart );
  1293. LsapSetParmTypeUlong( AuditParameters, 5, pOperationId->LowPart );
  1294. //
  1295. // entry type
  1296. //
  1297. LsapSetParmTypeUlong( AuditParameters, 6, EntryType );
  1298. //
  1299. // for all subsequent types, output a value only if it changed.
  1300. //
  1301. //
  1302. // Flags
  1303. //
  1304. if ( OldFlags != NewFlags )
  1305. {
  1306. LsapSetParmTypeUlong( AuditParameters, 7, NewFlags );
  1307. }
  1308. //
  1309. // top level name
  1310. //
  1311. if ( pOldTopLevelName && pNewTopLevelName &&
  1312. !RtlEqualUnicodeString( pOldTopLevelName, pNewTopLevelName, TRUE ) )
  1313. {
  1314. LsapSetParmTypeString( AuditParameters, 8, pNewTopLevelName );
  1315. }
  1316. //
  1317. // DNS domain name
  1318. //
  1319. if ( pOldDnsName && pNewDnsName &&
  1320. !RtlEqualUnicodeString( pOldDnsName, pNewDnsName, TRUE ) )
  1321. {
  1322. LsapSetParmTypeString( AuditParameters, 9, pNewDnsName );
  1323. }
  1324. //
  1325. // NetBIOS domain name
  1326. //
  1327. if ( pOldNetbiosName && pNewNetbiosName &&
  1328. !RtlEqualUnicodeString( pOldNetbiosName, pNewNetbiosName, TRUE ) )
  1329. {
  1330. LsapSetParmTypeString( AuditParameters, 10, pNewNetbiosName );
  1331. }
  1332. //
  1333. // domain SID
  1334. //
  1335. if ( pOldSid && pNewSid && !RtlEqualSid( pOldSid, pNewSid ) )
  1336. {
  1337. LsapSetParmTypeSid( AuditParameters, 11, pNewSid );
  1338. }
  1339. //
  1340. // client auth-id
  1341. //
  1342. LsapSetParmTypeLogonId( AuditParameters, 12, ClientAuthenticationId );
  1343. Status = LsapAdtWriteLog( &AuditParameters );
  1344. Cleanup:
  1345. if (TokenUserInformation != NULL)
  1346. {
  1347. LsapFreeLsaHeap( TokenUserInformation );
  1348. }
  1349. if (!NT_SUCCESS(Status))
  1350. {
  1351. LsapAuditFailed( Status );
  1352. }
  1353. return Status;
  1354. }
  1355. VOID
  1356. LsapAdtPolicyChange(
  1357. IN USHORT EventCategory,
  1358. IN ULONG EventID,
  1359. IN USHORT EventType,
  1360. IN PSID ClientSid,
  1361. IN LUID CallerAuthenticationId,
  1362. IN PLSARM_POLICY_AUDIT_EVENTS_INFO PolicyAuditEventsInfo
  1363. )
  1364. /*++
  1365. Routine Description:
  1366. Generates an audit for a policy change event.
  1367. The decision to generate this audit is made in LsapAdtGenerateLsaAuditEvent.
  1368. Arguments:
  1369. EventCategory - The category of this audit.
  1370. EventID - The event we are auditing.
  1371. EventType - Whether the audit is success or failure.
  1372. ClientSid - The SID of the user performing the policy change.
  1373. CallerAuthenticationId - The Authentication id of the user.
  1374. PolicyAuditEventsInfo - The information to audit.
  1375. Return Value:
  1376. None.
  1377. Note:
  1378. --*/
  1379. {
  1380. PPOLICY_AUDIT_EVENT_OPTIONS EventAuditingOptions;
  1381. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1382. UNICODE_STRING Enabled;
  1383. UNICODE_STRING Disabled;
  1384. ULONG i;
  1385. RtlInitUnicodeString( &Enabled, L"+" );
  1386. RtlInitUnicodeString( &Disabled, L"-" );
  1387. EventAuditingOptions = PolicyAuditEventsInfo->EventAuditingOptions;
  1388. //
  1389. // Build an audit parameters structure.
  1390. //
  1391. RtlZeroMemory (
  1392. (PVOID) &AuditParameters,
  1393. sizeof( AuditParameters )
  1394. );
  1395. AuditParameters.CategoryId = EventCategory;
  1396. AuditParameters.AuditId = EventID;
  1397. AuditParameters.Type = EventType;
  1398. AuditParameters.ParameterCount = 0;
  1399. //
  1400. // User Sid
  1401. //
  1402. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
  1403. AuditParameters.ParameterCount++;
  1404. //
  1405. // Subsystem name (if available)
  1406. //
  1407. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1408. AuditParameters.ParameterCount++;
  1409. //
  1410. // If auditing is disabled, mark all options as disabled. Otherwise
  1411. // mark them as the appropriate
  1412. //
  1413. for ( i=0; i<POLICY_AUDIT_EVENT_TYPE_COUNT; i++ ) {
  1414. LsapSetParmTypeString(
  1415. AuditParameters,
  1416. AuditParameters.ParameterCount,
  1417. (EventAuditingOptions[i] & POLICY_AUDIT_EVENT_SUCCESS ? &Enabled : &Disabled)
  1418. );
  1419. AuditParameters.ParameterCount++;
  1420. LsapSetParmTypeString(
  1421. AuditParameters,
  1422. AuditParameters.ParameterCount,
  1423. (EventAuditingOptions[i] & POLICY_AUDIT_EVENT_FAILURE ? &Enabled : &Disabled)
  1424. );
  1425. AuditParameters.ParameterCount++;
  1426. }
  1427. //
  1428. // Caller's Authentication information
  1429. //
  1430. LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, CallerAuthenticationId );
  1431. AuditParameters.ParameterCount++;
  1432. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1433. return;
  1434. }
  1435. NTSTATUS
  1436. LsapAdtGenerateDomainPolicyChangeAuditEvent(
  1437. IN POLICY_DOMAIN_INFORMATION_CLASS InformationClass,
  1438. IN USHORT AuditEventType,
  1439. IN LSAP_DB_ATTRIBUTE* OldAttributes,
  1440. IN LSAP_DB_ATTRIBUTE* NewAttributes,
  1441. IN ULONG AttributeCount
  1442. )
  1443. /*++
  1444. Routine Description:
  1445. Generate an audit event when any of the following policies changes:
  1446. - PolicyDomainEfsInformation
  1447. - PolicyDomainKerberosTicketInformation
  1448. Arguments:
  1449. InformationClass - type of policy that changed
  1450. AuditEventType - The type of audit event to be generated.
  1451. EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  1452. OldAttributes - pointer to array of old attributes
  1453. NewAttributes - pointer to array of new attributes
  1454. AttributeCount - number of attributes
  1455. Return Value:
  1456. NTSTATUS - Standard Nt Result Code
  1457. Notes:
  1458. --*/
  1459. {
  1460. NTSTATUS Status=STATUS_SUCCESS;
  1461. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1462. ULONG AuditId;
  1463. LPWSTR AttributeChanges=NULL;
  1464. UNICODE_STRING ChangesToAttributes;
  1465. LUID ClientAuthenticationId;
  1466. PTOKEN_USER TokenUserInformation=NULL;
  1467. BOOLEAN bAudit;
  1468. Status = LsapQueryClientInfo(
  1469. &TokenUserInformation,
  1470. &ClientAuthenticationId
  1471. );
  1472. if ( !NT_SUCCESS( Status )) {
  1473. goto Cleanup;
  1474. }
  1475. Status = LsapAdtAuditingEnabledByLogonId(
  1476. AuditCategoryPolicyChange,
  1477. &ClientAuthenticationId,
  1478. AuditEventType,
  1479. &bAudit
  1480. );
  1481. if (!NT_SUCCESS(Status) || !bAudit)
  1482. {
  1483. goto Cleanup;
  1484. }
  1485. switch (InformationClass) {
  1486. default:
  1487. ASSERT(FALSE);
  1488. goto Cleanup;
  1489. break;
  1490. case PolicyDomainEfsInformation:
  1491. AuditId = SE_AUDITID_EFS_POLICY_CHANGE;
  1492. break;
  1493. case PolicyDomainKerberosTicketInformation:
  1494. AuditId = SE_AUDITID_KERBEROS_POLICY_CHANGE;
  1495. break;
  1496. }
  1497. Status = LsapAdtGetDbAttributesChangeString( OldAttributes,
  1498. NewAttributes,
  1499. AttributeCount,
  1500. &AttributeChanges );
  1501. if (!NT_SUCCESS(Status)) {
  1502. goto Cleanup;
  1503. }
  1504. RtlInitUnicodeString(&ChangesToAttributes, AttributeChanges);
  1505. Status =
  1506. LsapAdtInitParametersArray(
  1507. &AuditParameters,
  1508. SE_CATEGID_POLICY_CHANGE,
  1509. AuditId,
  1510. AuditEventType,
  1511. 4,
  1512. //
  1513. // User Sid
  1514. //
  1515. SeAdtParmTypeSid, TokenUserInformation->User.Sid,
  1516. //
  1517. // Subsystem name (if available)
  1518. //
  1519. SeAdtParmTypeString, &LsapSubsystemName,
  1520. //
  1521. // Caller's Authentication information
  1522. //
  1523. SeAdtParmTypeLogonId, ClientAuthenticationId,
  1524. //
  1525. // Changes to attributes
  1526. //
  1527. SeAdtParmTypeString, &ChangesToAttributes);
  1528. if (!NT_SUCCESS(Status))
  1529. {
  1530. goto Cleanup;
  1531. }
  1532. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1533. Cleanup:
  1534. if (!NT_SUCCESS(Status))
  1535. {
  1536. LsapAuditFailed(Status);
  1537. }
  1538. if (TokenUserInformation != NULL)
  1539. {
  1540. LsapFreeLsaHeap( TokenUserInformation );
  1541. }
  1542. LsapFreeLsaHeap( AttributeChanges );
  1543. return Status;
  1544. }
  1545. VOID
  1546. LsapAdtGetAttributeValueString(
  1547. IN LSAP_DB_ATTRIBUTE* Attribute,
  1548. OUT LPWSTR ValueString OPTIONAL,
  1549. IN OUT PULONG RequiredLength
  1550. )
  1551. /*++
  1552. Routine Description:
  1553. Generate a string representation of the value of an attribute
  1554. Arguments:
  1555. Attribute - pointer to attribute
  1556. ValueString - receives a string representation of the value of Attribute
  1557. RequiredLength - pointer to length of ValueString
  1558. Return Value:
  1559. None
  1560. Notes:
  1561. --*/
  1562. {
  1563. WCHAR Buffer[32];
  1564. ULONG Length;
  1565. if (Attribute->AttributeValue) {
  1566. switch (Attribute->DbNameIndex) {
  1567. default:
  1568. lstrcpy(Buffer, L"unknown");
  1569. break;
  1570. // binary blob
  1571. case PolEfDat:
  1572. lstrcpy(Buffer, L"<binary data>");
  1573. break;
  1574. // ULONG
  1575. case KerOpts:
  1576. swprintf(Buffer, L"0x%x", *((ULONG*) Attribute->AttributeValue));
  1577. break;
  1578. // LARGE_INTEGER
  1579. case KerMinT:
  1580. case KerMaxT:
  1581. case KerMaxR:
  1582. case KerProxy:
  1583. case KerLogoff:
  1584. swprintf(Buffer, L"0x%I64x",
  1585. *((ULONGLONG*) Attribute->AttributeValue));
  1586. break;
  1587. }
  1588. } else {
  1589. lstrcpy(Buffer, L"none");
  1590. }
  1591. Length = lstrlen(Buffer);
  1592. if (ValueString && Length <= *RequiredLength)
  1593. {
  1594. CopyMemory(
  1595. ValueString,
  1596. Buffer,
  1597. Length * sizeof(WCHAR));
  1598. }
  1599. *RequiredLength = Length;
  1600. }
  1601. VOID
  1602. LsapAdtGetDbAttributeChangeString(
  1603. IN LSAP_DB_ATTRIBUTE* OldAttribute,
  1604. IN LSAP_DB_ATTRIBUTE* NewAttribute,
  1605. OUT LPWSTR AttributeChangeString, OPTIONAL
  1606. IN OUT PULONG RequiredLength
  1607. )
  1608. /*++
  1609. Routine Description:
  1610. Given an old attribute and a new attribute, return
  1611. a string representation of the difference between the two.
  1612. If there are no changes, RequiredLength is returned as 0
  1613. and AttributeChangeString is left unchanged;
  1614. otherwise if AttributeChangeString is non-NULL, the change is
  1615. written to it as:
  1616. <ParameterName>: <new value> (<old value>)
  1617. Arguments:
  1618. OldAttribute - pointer to old attribute
  1619. NewAttribute - pointer to new attribute
  1620. AttributeChangeString - if non-NULL, receives the string representation
  1621. of the difference between OldAttribute and NewAttribute
  1622. RequiredLength - pointer to length of AttributeChangeString
  1623. Return Value:
  1624. None
  1625. Notes:
  1626. --*/
  1627. {
  1628. PWSTR TmpString;
  1629. ULONG ChangeStringLength = 0;
  1630. ULONG ValueLength;
  1631. //
  1632. // do the processing only if there is a change in value
  1633. //
  1634. if ((OldAttribute->AttributeValue && NewAttribute->AttributeValue &&
  1635. (0 != memcmp(OldAttribute->AttributeValue,
  1636. NewAttribute->AttributeValue,
  1637. OldAttribute->AttributeValueLength))) ||
  1638. (OldAttribute->AttributeValue && !NewAttribute->AttributeValue) ||
  1639. (!OldAttribute->AttributeValue && NewAttribute->AttributeValue))
  1640. {
  1641. ChangeStringLength += OldAttribute->AttributeName->Length / sizeof(WCHAR);
  1642. ChangeStringLength += 2; // ": "
  1643. LsapAdtGetAttributeValueString(NewAttribute, 0, &ValueLength);
  1644. ChangeStringLength += ValueLength;
  1645. ChangeStringLength += 2; // " ("
  1646. LsapAdtGetAttributeValueString(OldAttribute, 0, &ValueLength);
  1647. ChangeStringLength += ValueLength;
  1648. ChangeStringLength += 4; // "); "
  1649. if (AttributeChangeString && ChangeStringLength <= *RequiredLength)
  1650. {
  1651. //
  1652. // Parameter Name
  1653. //
  1654. lstrcpy(AttributeChangeString, OldAttribute->AttributeName->Buffer);
  1655. ChangeStringLength = OldAttribute->AttributeName->Length / sizeof(WCHAR);
  1656. TmpString = AttributeChangeString + ChangeStringLength;
  1657. lstrcpy(TmpString, L": ");
  1658. ChangeStringLength += 2;
  1659. TmpString = AttributeChangeString + ChangeStringLength;
  1660. //
  1661. // Old value
  1662. //
  1663. ValueLength = *RequiredLength - ChangeStringLength;
  1664. LsapAdtGetAttributeValueString( NewAttribute, TmpString, &ValueLength );
  1665. ChangeStringLength += ValueLength;
  1666. TmpString = AttributeChangeString + ChangeStringLength;
  1667. //
  1668. // New value
  1669. //
  1670. lstrcpy(TmpString, L" (");
  1671. ChangeStringLength += 2;
  1672. TmpString = AttributeChangeString + ChangeStringLength;
  1673. ValueLength = *RequiredLength - ChangeStringLength;
  1674. LsapAdtGetAttributeValueString( OldAttribute, TmpString, &ValueLength );
  1675. ChangeStringLength += ValueLength;
  1676. TmpString = AttributeChangeString + ChangeStringLength;
  1677. //
  1678. // Don't copy the terminating '\0' in order to avoid a BO !
  1679. //
  1680. CopyMemory(TmpString, L"); ", 4 * sizeof(WCHAR));
  1681. ChangeStringLength += 4;
  1682. }
  1683. }
  1684. *RequiredLength = ChangeStringLength;
  1685. }
  1686. NTSTATUS
  1687. LsapAdtGetDbAttributesChangeString(
  1688. IN LSAP_DB_ATTRIBUTE* OldAttributes,
  1689. IN LSAP_DB_ATTRIBUTE* NewAttributes,
  1690. IN ULONG AttributeCount,
  1691. OUT LPWSTR* AttributeChangeString
  1692. )
  1693. /*++
  1694. Routine Description:
  1695. Given old attributes and new attributes, return a string representation
  1696. of the difference between old and new attributes.
  1697. If there are no changes, "--" is returned,
  1698. otherwise each change is written to the string as:
  1699. <ParameterName>: <new value> (<old value>)
  1700. This function is used for writing information about
  1701. changes to certain policies to the audit log.
  1702. Arguments:
  1703. OldAttributes - pointer to array of old attributes
  1704. NewAttributes - pointer to array of new attributes
  1705. AttributeCount - Number of attributes.
  1706. AttributeChangeString - pointer to string that receives the diff.
  1707. Return Value:
  1708. NTSTATUS - Standard Nt Result Code
  1709. Notes:
  1710. Memory allocated for AttributeChangeString must be freed by the
  1711. caller using LsapFreeLsaHeap.
  1712. --*/
  1713. {
  1714. NTSTATUS Status=STATUS_SUCCESS;
  1715. LSAP_DB_ATTRIBUTE* OldAttribute;
  1716. LSAP_DB_ATTRIBUTE* NewAttribute;
  1717. ULONG TmpStringLength;
  1718. ULONG TotalRequiredLength;
  1719. LPWSTR TmpString;
  1720. UINT AttributeNumber;
  1721. USHORT n=1;
  1722. OldAttribute = OldAttributes;
  1723. NewAttribute = NewAttributes;
  1724. TotalRequiredLength = 0;
  1725. //
  1726. // first find out the size of the buffer required
  1727. //
  1728. for (AttributeNumber = 0; AttributeNumber < AttributeCount; AttributeNumber++) {
  1729. LsapAdtGetDbAttributeChangeString( OldAttribute, NewAttribute,
  1730. NULL, &TmpStringLength );
  1731. OldAttribute++;
  1732. NewAttribute++;
  1733. TotalRequiredLength += TmpStringLength;
  1734. }
  1735. //
  1736. // reserve space for '--'
  1737. //
  1738. if (!TotalRequiredLength) {
  1739. n += 2;
  1740. }
  1741. *AttributeChangeString = TmpString =
  1742. LsapAllocateLsaHeap((TotalRequiredLength+n)*sizeof(WCHAR));
  1743. if ( TmpString ) {
  1744. if (TotalRequiredLength) {
  1745. //
  1746. // Now get the actual string
  1747. //
  1748. OldAttribute = OldAttributes;
  1749. NewAttribute = NewAttributes;
  1750. for (AttributeNumber = 0;
  1751. AttributeNumber < AttributeCount;
  1752. AttributeNumber++) {
  1753. TmpStringLength = TotalRequiredLength;
  1754. LsapAdtGetDbAttributeChangeString( OldAttribute, NewAttribute,
  1755. TmpString, &TmpStringLength );
  1756. TmpString += TmpStringLength;
  1757. OldAttribute++;
  1758. NewAttribute++;
  1759. }
  1760. *TmpString = L'\0';
  1761. } else {
  1762. lstrcpy(TmpString, L"--");
  1763. }
  1764. } else {
  1765. Status = STATUS_NO_MEMORY;
  1766. }
  1767. return Status;
  1768. }
  1769. PLUID LsaFilterPrivileges[] =
  1770. {
  1771. &ChangeNotifyPrivilege,
  1772. &AuditPrivilege,
  1773. &CreateTokenPrivilege,
  1774. &AssignPrimaryTokenPrivilege,
  1775. &BackupPrivilege,
  1776. &RestorePrivilege,
  1777. &DebugPrivilege,
  1778. NULL
  1779. };
  1780. VOID
  1781. LsapAdtAuditSpecialPrivileges(
  1782. PPRIVILEGE_SET Privileges,
  1783. LUID LogonId,
  1784. PSID UserSid
  1785. )
  1786. /*++
  1787. Routine Description:
  1788. Audits the assignment of special privileges at logon time.
  1789. Arguments:
  1790. Privileges - List of privileges being assigned.
  1791. Return Value:
  1792. None.
  1793. --*/
  1794. {
  1795. PPRIVILEGE_SET Buffer = NULL;
  1796. PLUID *FilterPrivilege = NULL;
  1797. ULONG i;
  1798. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1799. BOOLEAN bAuditPrivUse = FALSE;
  1800. BOOLEAN bAuditLogon = FALSE;
  1801. NTSTATUS Status = STATUS_SUCCESS;
  1802. if ( (Privileges == NULL) || (Privileges->PrivilegeCount == 0) ) {
  1803. goto Cleanup;
  1804. }
  1805. //
  1806. // allow this audit to be generated when either the logon/logoff
  1807. // or the priv-use category is enabled
  1808. //
  1809. Status = LsapAdtAuditingEnabledByLogonId(
  1810. AuditCategoryPrivilegeUse,
  1811. &LogonId,
  1812. EVENTLOG_AUDIT_SUCCESS,
  1813. &bAuditPrivUse
  1814. );
  1815. if (!NT_SUCCESS(Status)) {
  1816. goto Cleanup;
  1817. }
  1818. Status = LsapAdtAuditingEnabledByLogonId(
  1819. AuditCategoryLogon,
  1820. &LogonId,
  1821. EVENTLOG_AUDIT_SUCCESS,
  1822. &bAuditLogon
  1823. );
  1824. if (!NT_SUCCESS(Status)) {
  1825. goto Cleanup;
  1826. }
  1827. //
  1828. // if neither category is set, return quickly
  1829. //
  1830. if ( !bAuditPrivUse && !bAuditLogon ) {
  1831. goto Cleanup;
  1832. }
  1833. DsysAssertMsg( IsValidPrivilegeCount(Privileges->PrivilegeCount),
  1834. "LsapAdtAuditSpecialPrivileges" );
  1835. //
  1836. // We can't need any more space than what's being passed in.
  1837. //
  1838. Buffer = (PPRIVILEGE_SET)LsapAllocateLsaHeap( LsapPrivilegeSetSize( Privileges ) );
  1839. if ( Buffer == NULL ) {
  1840. Status = STATUS_NO_MEMORY;
  1841. goto Cleanup;
  1842. }
  1843. Buffer->PrivilegeCount = 0;
  1844. //
  1845. // For each privilege in the privilege set, see if it's in the filter
  1846. // list.
  1847. //
  1848. for ( i=0; i<Privileges->PrivilegeCount; i++) {
  1849. FilterPrivilege = LsaFilterPrivileges;
  1850. do {
  1851. if ( RtlEqualLuid( &Privileges->Privilege[i].Luid, *FilterPrivilege )) {
  1852. Buffer->Privilege[Buffer->PrivilegeCount].Luid = **FilterPrivilege;
  1853. Buffer->PrivilegeCount++;
  1854. }
  1855. } while ( *++FilterPrivilege != NULL );
  1856. }
  1857. if ( Buffer->PrivilegeCount == 0 ) {
  1858. goto Cleanup;
  1859. }
  1860. //
  1861. // We matched on at least one, generate an audit.
  1862. //
  1863. RtlZeroMemory ((PVOID) &AuditParameters, sizeof( AuditParameters ));
  1864. AuditParameters.CategoryId = SE_CATEGID_PRIVILEGE_USE;
  1865. AuditParameters.AuditId = SE_AUDITID_ASSIGN_SPECIAL_PRIV;
  1866. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  1867. AuditParameters.ParameterCount = 0;
  1868. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid );
  1869. AuditParameters.ParameterCount++;
  1870. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1871. AuditParameters.ParameterCount++;
  1872. LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, LogonId );
  1873. AuditParameters.ParameterCount++;
  1874. LsapSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, Buffer );
  1875. AuditParameters.ParameterCount++;
  1876. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1877. Cleanup:
  1878. if (!NT_SUCCESS(Status)) {
  1879. LsapAuditFailed(Status);
  1880. }
  1881. if (Buffer != NULL) {
  1882. LsapFreeLsaHeap( Buffer );
  1883. }
  1884. return;
  1885. }
  1886. VOID
  1887. LsapAdtAuditPackageLoad(
  1888. PUNICODE_STRING PackageFileName
  1889. )
  1890. /*++
  1891. Routine Description:
  1892. Audits the loading of an authentication package.
  1893. Arguments:
  1894. PackageFileName - The name of the package being loaded.
  1895. Return Value:
  1896. None.
  1897. --*/
  1898. {
  1899. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1900. NTSTATUS Status;
  1901. BOOLEAN bAudit;
  1902. Status = LsapAdtAuditingEnabledBySid(
  1903. AuditCategorySystem,
  1904. LsapLocalSystemSid,
  1905. EVENTLOG_AUDIT_SUCCESS,
  1906. &bAudit
  1907. );
  1908. if (!NT_SUCCESS(Status) || !bAudit) {
  1909. goto Cleanup;
  1910. }
  1911. RtlZeroMemory (
  1912. (PVOID) &AuditParameters,
  1913. sizeof( AuditParameters )
  1914. );
  1915. AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
  1916. AuditParameters.AuditId = SE_AUDITID_AUTH_PACKAGE_LOAD;
  1917. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  1918. AuditParameters.ParameterCount = 0;
  1919. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
  1920. AuditParameters.ParameterCount++;
  1921. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1922. AuditParameters.ParameterCount++;
  1923. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, PackageFileName );
  1924. AuditParameters.ParameterCount++;
  1925. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1926. Cleanup:
  1927. if (!NT_SUCCESS(Status)) {
  1928. LsapAuditFailed(Status);
  1929. }
  1930. return;
  1931. }
  1932. VOID
  1933. LsapAdtAuditLogonProcessRegistration(
  1934. IN PLSAP_AU_REGISTER_CONNECT_INFO_EX ConnectInfo
  1935. )
  1936. /*++
  1937. Routine Description:
  1938. Audits the registration of a logon process
  1939. Arguments:
  1940. ConnectInfo - Supplies the connection information for the new
  1941. logon process.
  1942. Return Value:
  1943. None.
  1944. --*/
  1945. {
  1946. NTSTATUS Status;
  1947. ANSI_STRING AnsiString;
  1948. UNICODE_STRING Unicode = {0};
  1949. PSZ LogonProcessNameBuffer = NULL;
  1950. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1951. BOOLEAN bAudit;
  1952. Status = LsapAdtAuditingEnabledBySid(
  1953. AuditCategorySystem,
  1954. LsapLocalSystemSid,
  1955. EVENTLOG_AUDIT_SUCCESS,
  1956. &bAudit
  1957. );
  1958. if (!NT_SUCCESS(Status) || !bAudit) {
  1959. goto Cleanup;
  1960. }
  1961. //
  1962. // Turn the name text in the ConnectInfo structure into
  1963. // something we can work with.
  1964. //
  1965. LogonProcessNameBuffer = (PSZ)LsapAllocateLsaHeap( ConnectInfo->LogonProcessNameLength+1 );
  1966. if ( LogonProcessNameBuffer == NULL ) {
  1967. Status = STATUS_NO_MEMORY;
  1968. goto Cleanup;
  1969. }
  1970. RtlCopyMemory(
  1971. LogonProcessNameBuffer,
  1972. ConnectInfo->LogonProcessName,
  1973. ConnectInfo->LogonProcessNameLength
  1974. );
  1975. LogonProcessNameBuffer[ConnectInfo->LogonProcessNameLength] = 0;
  1976. RtlInitAnsiString( &AnsiString, LogonProcessNameBuffer );
  1977. Status = RtlAnsiStringToUnicodeString( &Unicode, &AnsiString, TRUE );
  1978. if ( !NT_SUCCESS( Status )) {
  1979. goto Cleanup;
  1980. }
  1981. RtlZeroMemory (
  1982. (PVOID) &AuditParameters,
  1983. sizeof( AuditParameters )
  1984. );
  1985. AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
  1986. AuditParameters.AuditId = SE_AUDITID_SYSTEM_LOGON_PROC_REGISTER;
  1987. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  1988. AuditParameters.ParameterCount = 0;
  1989. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
  1990. AuditParameters.ParameterCount++;
  1991. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1992. AuditParameters.ParameterCount++;
  1993. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &Unicode );
  1994. AuditParameters.ParameterCount++;
  1995. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1996. Cleanup:
  1997. if (!NT_SUCCESS(Status)) {
  1998. LsapAuditFailed(Status);
  1999. }
  2000. LsapFreeLsaHeap( LogonProcessNameBuffer );
  2001. RtlFreeUnicodeString( &Unicode );
  2002. return;
  2003. }
  2004. VOID
  2005. LsapAdtSystemRestart(
  2006. PLSARM_POLICY_AUDIT_EVENTS_INFO AuditEventsInfo
  2007. )
  2008. /*++
  2009. Routine Description:
  2010. This function is called during LSA initialization to generate
  2011. a system restart event.
  2012. Arguments:
  2013. AuditEventsInfo - Auditing data.
  2014. Return Value:
  2015. NTSTATUS - Standard Nt Result Code.
  2016. --*/
  2017. {
  2018. NTSTATUS Status = STATUS_SUCCESS;
  2019. SE_ADT_PARAMETER_ARRAY AuditParameters;
  2020. BOOLEAN bAudit;
  2021. Status = LsapAdtAuditingEnabledBySid(
  2022. AuditCategorySystem,
  2023. LsapLocalSystemSid,
  2024. EVENTLOG_AUDIT_SUCCESS,
  2025. &bAudit
  2026. );
  2027. if (!NT_SUCCESS(Status) || !bAudit) {
  2028. goto Cleanup;
  2029. }
  2030. //
  2031. // Construct an audit parameters array
  2032. // for the restart event.
  2033. //
  2034. RtlZeroMemory (
  2035. (PVOID) &AuditParameters,
  2036. sizeof( AuditParameters )
  2037. );
  2038. AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
  2039. AuditParameters.AuditId = SE_AUDITID_SYSTEM_RESTART;
  2040. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  2041. AuditParameters.ParameterCount = 0;
  2042. //
  2043. // User Sid
  2044. //
  2045. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
  2046. AuditParameters.ParameterCount++;
  2047. //
  2048. // Subsystem name
  2049. //
  2050. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  2051. AuditParameters.ParameterCount++;
  2052. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  2053. Cleanup:
  2054. if (!NT_SUCCESS(Status)) {
  2055. LsapAuditFailed(Status);
  2056. }
  2057. return;
  2058. }
  2059. VOID
  2060. LsapAdtAuditLogon(
  2061. IN USHORT EventCategory,
  2062. IN ULONG EventID,
  2063. IN USHORT EventType,
  2064. IN PUNICODE_STRING AccountName,
  2065. IN PUNICODE_STRING AuthenticatingAuthority,
  2066. IN PUNICODE_STRING Source,
  2067. IN PUNICODE_STRING PackageName,
  2068. IN SECURITY_LOGON_TYPE LogonType,
  2069. IN PSID UserSid,
  2070. IN LUID AuthenticationId,
  2071. IN PUNICODE_STRING WorkstationName,
  2072. IN NTSTATUS LogonStatus,
  2073. IN NTSTATUS SubStatus,
  2074. IN LPGUID LogonGuid, OPTIONAL
  2075. IN PLUID CallerLogonId, OPTIONAL
  2076. IN PHANDLE CallerProcessID, OPTIONAL
  2077. IN PLSA_ADT_STRING_LIST TransittedServices, OPTIONAL
  2078. IN SOCKADDR* pSockAddr OPTIONAL
  2079. )
  2080. /*++
  2081. Routine Description:
  2082. Generates an audit of a logon event as appropriate.
  2083. Arguments:
  2084. Return Value:
  2085. None.
  2086. --*/
  2087. {
  2088. NTSTATUS Status = STATUS_SUCCESS;
  2089. UNICODE_STRING AuthenticationIdString = { 0 };
  2090. BOOLEAN FreeWhenDone = FALSE;
  2091. SE_ADT_PARAMETER_ARRAY AuditParameters;
  2092. BOOL AuditingSuccess;
  2093. BOOL AuditingFailure;
  2094. PSID pSid;
  2095. PLSAP_LOGON_SESSION pLogonSession = NULL;
  2096. BOOLEAN bAudit = FALSE;
  2097. UNICODE_STRING LocalAccountName;
  2098. UNICODE_STRING LocalAuthenticatingAuthority;
  2099. UNICODE_STRING LocalWorkstationName;
  2100. //
  2101. // Get the system Audit settings
  2102. //
  2103. AuditingFailure = (EventType == EVENTLOG_AUDIT_FAILURE) && LsapAdtAuditingEnabledByCategory(AuditCategoryLogon, EVENTLOG_AUDIT_FAILURE);
  2104. AuditingSuccess = (EventType == EVENTLOG_AUDIT_SUCCESS) && LsapAdtAuditingEnabledByCategory(AuditCategoryLogon, EVENTLOG_AUDIT_SUCCESS);
  2105. //
  2106. // If this is a success audit then we have a real user sid. Check if there
  2107. // exist per user audit settings for the user which may override system
  2108. // settings.
  2109. //
  2110. // In case of failed logons, the auth packages do not pass us the
  2111. // user SID therefore we cannot check pua policy here
  2112. //
  2113. if (AuditingSuccess)
  2114. {
  2115. Status = LsapAdtAuditingEnabledByLogonId(
  2116. AuditCategoryLogon,
  2117. &AuthenticationId,
  2118. EVENTLOG_AUDIT_SUCCESS,
  2119. &bAudit
  2120. );
  2121. if (!NT_SUCCESS(Status) || !bAudit)
  2122. {
  2123. goto Finish;
  2124. }
  2125. }
  2126. //
  2127. // return quickly if auditing is not enabled
  2128. //
  2129. if ( !(AuditingFailure || AuditingSuccess || bAudit) )
  2130. {
  2131. return;
  2132. }
  2133. //
  2134. // Build an audit parameters structure.
  2135. //
  2136. RtlZeroMemory ( (PVOID) &AuditParameters, sizeof( AuditParameters ) );
  2137. AuditParameters.CategoryId = EventCategory;
  2138. AuditParameters.AuditId = EventID;
  2139. AuditParameters.Type = EventType;
  2140. AuditParameters.ParameterCount = 0;
  2141. //
  2142. // If this is a successful logon audit event and the caller did not
  2143. // supply a logon GUID, extract it from the logon session.
  2144. //
  2145. if ( AuditingSuccess && !LogonGuid &&
  2146. ( EventType == EVENTLOG_AUDIT_SUCCESS ) )
  2147. {
  2148. pLogonSession = LsapLocateLogonSession( &AuthenticationId );
  2149. ASSERT( pLogonSession && L"LsapAdtAuditLogon: logon session not found" );
  2150. if ( pLogonSession )
  2151. {
  2152. LogonGuid = &pLogonSession->LogonGuid;
  2153. }
  2154. }
  2155. #if DBG
  2156. if ( AuditingSuccess )
  2157. {
  2158. DsysAssert( EventID != SE_AUDITID_DOMAIN_TRUST_INCONSISTENT );
  2159. }
  2160. #endif
  2161. //
  2162. // User Sid
  2163. //
  2164. pSid = AuditingSuccess ? UserSid : LsapLocalSystemSid;
  2165. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, pSid );
  2166. AuditParameters.ParameterCount++;
  2167. //
  2168. // Subsystem name
  2169. //
  2170. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  2171. AuditParameters.ParameterCount++;
  2172. //
  2173. // Account name
  2174. //
  2175. if ( ARGUMENT_PRESENT( AccountName ) ) {
  2176. LocalAccountName = *AccountName;
  2177. if ( EventID == SE_AUDITID_UNKNOWN_USER_OR_PWD ) {
  2178. //
  2179. // For failed logons of type SE_AUDITID_UNKNOWN_USER_OR_PWD
  2180. // the user name can be invalid (for example,
  2181. // with embedded NULLs). This causes the
  2182. // eventlog to reject the string and we drop the audit.
  2183. //
  2184. // To avoid this, adjust the length parameter if necessary.
  2185. //
  2186. LocalAccountName.Length =
  2187. (USHORT) LsapSafeWcslen( LocalAccountName.Buffer,
  2188. LocalAccountName.MaximumLength );
  2189. }
  2190. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LocalAccountName );
  2191. }
  2192. AuditParameters.ParameterCount++;
  2193. //
  2194. // Authenticating Authority (domain name)
  2195. //
  2196. if ( ARGUMENT_PRESENT( AuthenticatingAuthority ) ) {
  2197. LocalAuthenticatingAuthority = *AuthenticatingAuthority;
  2198. //
  2199. // The domain name is used by NTLM as unauthenticated hint
  2200. // thus it can be invalid (for example,
  2201. // with embedded NULLs). This causes the
  2202. // eventlog to reject the string and we drop the audit.
  2203. //
  2204. // To avoid this, adjust the length parameter if necessary.
  2205. //
  2206. LocalAuthenticatingAuthority.Length =
  2207. (USHORT) LsapSafeWcslen( LocalAuthenticatingAuthority.Buffer,
  2208. LocalAuthenticatingAuthority.MaximumLength );
  2209. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LocalAuthenticatingAuthority );
  2210. }
  2211. AuditParameters.ParameterCount++;
  2212. if ( AuditingSuccess ) {
  2213. //
  2214. // Logon Id (as a string)
  2215. //
  2216. Status = LsapAdtBuildLuidString(
  2217. &AuthenticationId,
  2218. &AuthenticationIdString,
  2219. &FreeWhenDone
  2220. );
  2221. if ( NT_SUCCESS( Status )) {
  2222. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &AuthenticationIdString );
  2223. } else {
  2224. goto Finish;
  2225. }
  2226. AuditParameters.ParameterCount++;
  2227. }
  2228. //
  2229. // Logon Type
  2230. //
  2231. LsapSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, LogonType );
  2232. AuditParameters.ParameterCount++;
  2233. //
  2234. // Source
  2235. //
  2236. if ( ARGUMENT_PRESENT( Source )) {
  2237. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, Source );
  2238. } else {
  2239. //
  2240. // No need to do anything here, since an empty entry will turn
  2241. // into a '-' in the output
  2242. //
  2243. }
  2244. AuditParameters.ParameterCount++;
  2245. //
  2246. // Authentication Package
  2247. //
  2248. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, PackageName );
  2249. AuditParameters.ParameterCount++;
  2250. //
  2251. // Workstation Name
  2252. //
  2253. if ( ARGUMENT_PRESENT( WorkstationName )) {
  2254. LocalWorkstationName = *WorkstationName;
  2255. //
  2256. // NTLM accepts wks name from clients. A client can supply
  2257. // invalid name (for example, with embedded NULLs). This causes
  2258. // eventlog to reject the string and we drop the audit.
  2259. //
  2260. // To avoid this, adjust the length parameter if necessary.
  2261. //
  2262. LocalWorkstationName.Length =
  2263. (USHORT) LsapSafeWcslen( LocalWorkstationName.Buffer,
  2264. LocalWorkstationName.MaximumLength );
  2265. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LocalWorkstationName );
  2266. }
  2267. AuditParameters.ParameterCount++;
  2268. if ( EventID == SE_AUDITID_UNSUCCESSFUL_LOGON ) {
  2269. //
  2270. // we need to supply the logon status for this event,
  2271. // so that some information can be gleened from the log.
  2272. //
  2273. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, LogonStatus );
  2274. AuditParameters.ParameterCount++;
  2275. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, SubStatus );
  2276. AuditParameters.ParameterCount++;
  2277. }
  2278. //
  2279. // Logon GUID
  2280. //
  2281. if ( ARGUMENT_PRESENT( LogonGuid )) {
  2282. LsapSetParmTypeGuid( AuditParameters, AuditParameters.ParameterCount, LogonGuid );
  2283. AuditParameters.ParameterCount++;
  2284. }
  2285. //
  2286. // Caller Logon-ID
  2287. //
  2288. if ( ARGUMENT_PRESENT( CallerLogonId )) {
  2289. LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, *CallerLogonId );
  2290. } else {
  2291. LsapSetParmTypeNoLogon( AuditParameters, AuditParameters.ParameterCount );
  2292. }
  2293. AuditParameters.ParameterCount++;
  2294. //
  2295. // Caller Process-ID
  2296. //
  2297. if ( ARGUMENT_PRESENT( CallerProcessID )) {
  2298. LsapSetParmTypePtr( AuditParameters, AuditParameters.ParameterCount, *CallerProcessID );
  2299. }
  2300. AuditParameters.ParameterCount++;
  2301. //
  2302. // Transitted Services (Kerberos only)
  2303. //
  2304. if ( ARGUMENT_PRESENT( TransittedServices )) {
  2305. LsapSetParmTypeStringList( AuditParameters, AuditParameters.ParameterCount, TransittedServices );
  2306. }
  2307. AuditParameters.ParameterCount++;
  2308. //
  2309. // IP address/port of caller
  2310. //
  2311. if ( ARGUMENT_PRESENT( pSockAddr )) {
  2312. LsapSetParmTypeSockAddr( AuditParameters, AuditParameters.ParameterCount, pSockAddr );
  2313. }
  2314. AuditParameters.ParameterCount++;
  2315. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  2316. Finish:
  2317. if (!NT_SUCCESS(Status))
  2318. {
  2319. LsapAuditFailed( Status );
  2320. }
  2321. if ( FreeWhenDone ) {
  2322. LsapFreeLsaHeap( AuthenticationIdString.Buffer );
  2323. }
  2324. if ( pLogonSession != NULL )
  2325. {
  2326. LsapReleaseLogonSession( pLogonSession );
  2327. }
  2328. }
  2329. VOID
  2330. LsapAuditLogon(
  2331. IN NTSTATUS LogonStatus,
  2332. IN NTSTATUS LogonSubStatus,
  2333. IN PUNICODE_STRING AccountName,
  2334. IN PUNICODE_STRING AuthenticatingAuthority,
  2335. IN PUNICODE_STRING WorkstationName,
  2336. IN PSID UserSid, OPTIONAL
  2337. IN SECURITY_LOGON_TYPE LogonType,
  2338. IN PTOKEN_SOURCE TokenSource,
  2339. IN PLUID LogonId
  2340. )
  2341. /*++
  2342. Routine Description/Arguments/Return value
  2343. See header comment for LsapAuditLogonHelper
  2344. --*/
  2345. {
  2346. LsapAuditLogonHelper(
  2347. LogonStatus,
  2348. LogonSubStatus,
  2349. AccountName,
  2350. AuthenticatingAuthority,
  2351. WorkstationName,
  2352. UserSid,
  2353. LogonType,
  2354. TokenSource,
  2355. LogonId,
  2356. NULL, // no logon guid
  2357. NULL, // caller logon-id
  2358. NULL, // caller process-id
  2359. NULL // no transitted services
  2360. );
  2361. }
  2362. VOID
  2363. LsapAuditLogonHelper(
  2364. IN NTSTATUS LogonStatus,
  2365. IN NTSTATUS LogonSubStatus,
  2366. IN PUNICODE_STRING AccountName,
  2367. IN PUNICODE_STRING AuthenticatingAuthority,
  2368. IN PUNICODE_STRING WorkstationName,
  2369. IN PSID UserSid, OPTIONAL
  2370. IN SECURITY_LOGON_TYPE LogonType,
  2371. IN PTOKEN_SOURCE TokenSource,
  2372. IN PLUID LogonId,
  2373. IN LPGUID LogonGuid, OPTIONAL
  2374. IN PLUID CallerLogonId, OPTIONAL
  2375. IN PHANDLE CallerProcessID, OPTIONAL
  2376. IN PLSA_ADT_STRING_LIST TransittedServices OPTIONAL
  2377. )
  2378. /*++
  2379. Routine Description:
  2380. Helper routine for security packages to generate a logon audit
  2381. Arguments:
  2382. LogonStatus - Status code for the logon.
  2383. LogonSubStatus - more detailed Status code for the logon.
  2384. AccountName - Name of principal attempting logon.
  2385. AuthenticatingAuthority - Authority validating the logon.
  2386. Workstation - Machine from which the logon was attempted.
  2387. For a network logon, this is the client machine.
  2388. UserSid - Sid for the logged on account.
  2389. LogonType - Type of logon, such as Network, Interactive, etc.
  2390. TokenSource - Source for the token.
  2391. LogonId - If the logon was successful,
  2392. the logon ID for the logon session.
  2393. LogonGuid - globally unique ID for a logon.
  2394. This is supported only by the kerberos package.
  2395. CallerLogonId - Logon-ID of the caller.
  2396. For example, if foo calls LsaLogonUser to create
  2397. a logon session for bar. This will be the logon-ID
  2398. of foo.
  2399. CallerProcessID - Process ID of the calling process.
  2400. Return Value:
  2401. None.
  2402. --*/
  2403. {
  2404. ANSI_STRING AnsiSourceContext;
  2405. CHAR AnsiBuffer[TOKEN_SOURCE_LENGTH + 2];
  2406. UNICODE_STRING UnicodeSourceContext;
  2407. WCHAR UnicodeBuffer[TOKEN_SOURCE_LENGTH + 2];
  2408. NTSTATUS Status;
  2409. USHORT EventType;
  2410. USHORT EventCategory;
  2411. ULONG EventID;
  2412. PLSAP_SECURITY_PACKAGE SecurityPackage;
  2413. ULONG_PTR PackageId;
  2414. PLSA_CALL_INFO pCallInfo;
  2415. SOCKADDR* pSockAddr = NULL;
  2416. SOCKADDR EmptySockAddr = {0};
  2417. //
  2418. // get the IP address/port of the caller
  2419. //
  2420. pCallInfo = LsapGetCurrentCall();
  2421. if ( pCallInfo == NULL ) {
  2422. //
  2423. // If we cannot get the call info then use the 0.0.0.0:0 address.
  2424. //
  2425. pSockAddr = &EmptySockAddr;
  2426. pSockAddr->sa_family = AF_INET;
  2427. } else {
  2428. pSockAddr = (SOCKADDR*) pCallInfo->IpAddress;
  2429. }
  2430. PackageId = GetCurrentPackageId();
  2431. DsysAssertMsg( PackageId != SPMGR_ID, "LsapAuditLogon" );
  2432. SecurityPackage = SpmpLocatePackage( PackageId );
  2433. DsysAssertMsg( SecurityPackage != NULL, "LsapAuditLogon" );
  2434. //
  2435. // Audit the logon attempt. The event type and logged information
  2436. // will depend to some extent on the whether we failed and why.
  2437. //
  2438. //
  2439. // Turn the SourceContext into something we can
  2440. // work with.
  2441. //
  2442. AnsiSourceContext.Buffer = AnsiBuffer;
  2443. AnsiSourceContext.Length = TOKEN_SOURCE_LENGTH * sizeof( CHAR );
  2444. AnsiSourceContext.MaximumLength = (TOKEN_SOURCE_LENGTH + 2) * sizeof( CHAR );
  2445. UnicodeSourceContext.Buffer = UnicodeBuffer;
  2446. UnicodeSourceContext.MaximumLength = (TOKEN_SOURCE_LENGTH + 2) * sizeof( WCHAR );
  2447. RtlCopyMemory(
  2448. AnsiBuffer,
  2449. TokenSource->SourceName,
  2450. TOKEN_SOURCE_LENGTH * sizeof( CHAR )
  2451. );
  2452. Status = RtlAnsiStringToUnicodeString(
  2453. &UnicodeSourceContext,
  2454. &AnsiSourceContext,
  2455. FALSE
  2456. );
  2457. if ( NT_SUCCESS( Status )) {
  2458. UnicodeSourceContext.Length =
  2459. (USHORT) LsapSafeWcslen( UnicodeSourceContext.Buffer,
  2460. UnicodeSourceContext.MaximumLength );
  2461. } else {
  2462. UnicodeSourceContext.Buffer = NULL;
  2463. //
  2464. // we cannot fail the audit because of this but catch the
  2465. // internal clients who supply bad source contexts
  2466. //
  2467. DsysAssertMsg( FALSE, "LsapAuditLogon: could not convert AnsiSourceContext to unicode" );
  2468. }
  2469. //
  2470. // Assume the logon failed, reset if necessary.
  2471. //
  2472. EventCategory = SE_CATEGID_LOGON;
  2473. EventType = EVENTLOG_AUDIT_FAILURE;
  2474. switch ( LogonStatus )
  2475. {
  2476. case STATUS_SUCCESS:
  2477. {
  2478. //
  2479. // Use a separate event for network logons
  2480. //
  2481. if (( LogonType == Network ) ||
  2482. ( LogonType == NetworkCleartext ))
  2483. {
  2484. EventID = SE_AUDITID_NETWORK_LOGON;
  2485. }
  2486. else
  2487. {
  2488. EventID = SE_AUDITID_SUCCESSFUL_LOGON;
  2489. }
  2490. EventType = EVENTLOG_AUDIT_SUCCESS;
  2491. break;
  2492. }
  2493. case STATUS_BAD_VALIDATION_CLASS:
  2494. EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
  2495. break;
  2496. case STATUS_ACCOUNT_EXPIRED:
  2497. EventID = SE_AUDITID_ACCOUNT_EXPIRED;
  2498. break;
  2499. case STATUS_NETLOGON_NOT_STARTED:
  2500. EventID = SE_AUDITID_NETLOGON_NOT_STARTED;
  2501. break;
  2502. case STATUS_ACCOUNT_LOCKED_OUT:
  2503. EventID = SE_AUDITID_ACCOUNT_LOCKED;
  2504. break;
  2505. case STATUS_LOGON_TYPE_NOT_GRANTED:
  2506. EventID = SE_AUDITID_LOGON_TYPE_RESTR;
  2507. break;
  2508. case STATUS_PASSWORD_MUST_CHANGE:
  2509. EventID = SE_AUDITID_PASSWORD_EXPIRED;
  2510. break;
  2511. case STATUS_ACCOUNT_RESTRICTION:
  2512. {
  2513. switch ( LogonSubStatus )
  2514. {
  2515. case STATUS_PASSWORD_EXPIRED:
  2516. EventID = SE_AUDITID_PASSWORD_EXPIRED;
  2517. break;
  2518. case STATUS_ACCOUNT_DISABLED:
  2519. EventID = SE_AUDITID_ACCOUNT_DISABLED;
  2520. break;
  2521. case STATUS_INVALID_LOGON_HOURS:
  2522. EventID = SE_AUDITID_ACCOUNT_TIME_RESTR;
  2523. break;
  2524. case STATUS_INVALID_WORKSTATION:
  2525. EventID = SE_AUDITID_WORKSTATION_RESTR;
  2526. break;
  2527. default:
  2528. EventID = SE_AUDITID_UNKNOWN_USER_OR_PWD;
  2529. break;
  2530. }
  2531. break;
  2532. }
  2533. case STATUS_LOGON_FAILURE:
  2534. {
  2535. if ( ( LogonSubStatus == STATUS_WRONG_PASSWORD ) ||
  2536. ( LogonSubStatus == STATUS_NO_SUCH_USER ) )
  2537. {
  2538. EventID = SE_AUDITID_UNKNOWN_USER_OR_PWD;
  2539. }
  2540. else if ( LogonSubStatus == STATUS_DOMAIN_TRUST_INCONSISTENT )
  2541. {
  2542. EventID = SE_AUDITID_DOMAIN_TRUST_INCONSISTENT;
  2543. }
  2544. else
  2545. {
  2546. EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
  2547. }
  2548. break;
  2549. }
  2550. default:
  2551. EventID = SE_AUDITID_UNSUCCESSFUL_LOGON;
  2552. break;
  2553. }
  2554. LsapAdtAuditLogon( EventCategory,
  2555. EventID,
  2556. EventType,
  2557. AccountName,
  2558. AuthenticatingAuthority,
  2559. &UnicodeSourceContext,
  2560. &SecurityPackage->Name,
  2561. LogonType,
  2562. UserSid,
  2563. *LogonId,
  2564. WorkstationName,
  2565. LogonStatus,
  2566. LogonSubStatus,
  2567. LogonGuid,
  2568. CallerLogonId,
  2569. CallerProcessID,
  2570. TransittedServices,
  2571. pSockAddr
  2572. );
  2573. }
  2574. VOID
  2575. LsapAdtAuditLogoff(
  2576. PLSAP_LOGON_SESSION Session
  2577. )
  2578. /*++
  2579. Routine Description:
  2580. Generates a logoff audit. The caller is responsible for determining
  2581. if logoff auditing is enabled.
  2582. Arguments:
  2583. Session - Points to the logon session being removed.
  2584. Return Value:
  2585. None.
  2586. --*/
  2587. {
  2588. SE_ADT_PARAMETER_ARRAY AuditParameters;
  2589. NTSTATUS Status;
  2590. UNICODE_STRING usLogonId;
  2591. BOOLEAN fFreeLogonId=FALSE;
  2592. RtlZeroMemory ( &usLogonId, sizeof(UNICODE_STRING) );
  2593. //
  2594. // normally we would simply store the logon-id to be audited
  2595. // as SeAdtParmTypeLogonId. But in this case, the logon session
  2596. // will have gone away by the time we try to convert it
  2597. // to a string representation in LsapAdtDemarshallAuditInfo.
  2598. // using LsapGetLogonSessionAccountInfo.
  2599. //
  2600. // To avoid this, we pre-convert the logon-id here
  2601. //
  2602. Status = LsapAdtBuildLuidString( &Session->LogonId,
  2603. &usLogonId, &fFreeLogonId );
  2604. if ( !NT_SUCCESS(Status) )
  2605. {
  2606. goto Cleanup;
  2607. }
  2608. Status =
  2609. LsapAdtInitParametersArray(
  2610. &AuditParameters,
  2611. SE_CATEGID_LOGON,
  2612. SE_AUDITID_LOGOFF,
  2613. EVENTLOG_AUDIT_SUCCESS,
  2614. 6, // there are 6 params to init
  2615. //
  2616. // User Sid
  2617. //
  2618. SeAdtParmTypeSid, Session->UserSid,
  2619. //
  2620. // Subsystem name (if available)
  2621. //
  2622. SeAdtParmTypeString, &LsapSubsystemName,
  2623. //
  2624. // User
  2625. //
  2626. SeAdtParmTypeString, &Session->AccountName,
  2627. //
  2628. // Domain
  2629. //
  2630. SeAdtParmTypeString, &Session->AuthorityName,
  2631. //
  2632. // LogonId
  2633. //
  2634. SeAdtParmTypeString, &usLogonId,
  2635. //
  2636. // Logon Type
  2637. //
  2638. SeAdtParmTypeUlong, Session->LogonType
  2639. );
  2640. if (!NT_SUCCESS(Status))
  2641. {
  2642. goto Cleanup;
  2643. }
  2644. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  2645. Cleanup:
  2646. if (fFreeLogonId)
  2647. {
  2648. LsapFreeLsaHeap(usLogonId.Buffer);
  2649. }
  2650. }
  2651. VOID
  2652. LsapAdtAuditPerUserTableCreation(
  2653. BOOLEAN bSuccess
  2654. )
  2655. /*++
  2656. Routine Description:
  2657. Generates an audit to report that the per user table was regenerated. The
  2658. table should be locked for read access during this call.
  2659. This routine will generate a single audit to indicate that the table
  2660. has been created. It will then generate individual audits for each
  2661. user that has an element in the per user audit table.
  2662. Arguments:
  2663. None.
  2664. Return Value:
  2665. None.
  2666. --*/
  2667. {
  2668. SE_ADT_PARAMETER_ARRAY AuditParameters;
  2669. NTSTATUS Status;
  2670. BOOLEAN bAudit;
  2671. ULONG i;
  2672. ULONG j;
  2673. PPER_USER_AUDITING_ELEMENT pElement = NULL;
  2674. LUID TableId;
  2675. ULONG AuditSettings[POLICY_AUDIT_EVENT_TYPE_COUNT];
  2676. if (!AllocateLocallyUniqueId(&TableId))
  2677. {
  2678. Status = LsapWinerrorToNtStatus(GetLastError());
  2679. goto Cleanup;
  2680. }
  2681. //
  2682. // First log an audit to indicate that the table is being
  2683. // created.
  2684. //
  2685. Status = LsapAdtAuditingEnabledBySid(
  2686. AuditCategoryPolicyChange,
  2687. LsapLocalSystemSid,
  2688. EVENTLOG_AUDIT_SUCCESS,
  2689. &bAudit
  2690. );
  2691. if (!NT_SUCCESS( Status ))
  2692. {
  2693. goto Cleanup;
  2694. }
  2695. if (bAudit)
  2696. {
  2697. Status =
  2698. LsapAdtInitParametersArray(
  2699. &AuditParameters,
  2700. SE_CATEGID_POLICY_CHANGE,
  2701. SE_AUDITID_PER_USER_AUDIT_TABLE_CREATION,
  2702. bSuccess ? EVENTLOG_AUDIT_SUCCESS : EVENTLOG_AUDIT_FAILURE,
  2703. 4,
  2704. //
  2705. // User Sid
  2706. //
  2707. SeAdtParmTypeSid, LsapLocalSystemSid,
  2708. //
  2709. // Subsystem name (if available)
  2710. //
  2711. SeAdtParmTypeString, &LsapSubsystemName,
  2712. //
  2713. // Number of users in the per user table
  2714. //
  2715. SeAdtParmTypeUlong, bSuccess ? LsapAdtPerUserAuditUserCount : 0,
  2716. //
  2717. // Table ID
  2718. //
  2719. SeAdtParmTypeLuid, TableId
  2720. );
  2721. if (!NT_SUCCESS(Status))
  2722. {
  2723. goto Cleanup;
  2724. }
  2725. (VOID)LsapAdtWriteLog(&AuditParameters);
  2726. //
  2727. // If this is a failure audit, then exit now.
  2728. //
  2729. if (!bSuccess)
  2730. {
  2731. return;
  2732. }
  2733. }
  2734. //
  2735. // Now log audits for the individual records in the table.
  2736. //
  2737. for (i = 0; i < PER_USER_AUDITING_POLICY_TABLE_SIZE; i++)
  2738. {
  2739. pElement = LsapAdtPerUserAuditingTable[i];
  2740. while (pElement)
  2741. {
  2742. RtlZeroMemory(
  2743. AuditSettings,
  2744. sizeof(AuditSettings)
  2745. );
  2746. for (j = 0; j < pElement->TokenAuditPolicy.PolicyCount; j++)
  2747. {
  2748. AuditSettings[pElement->TokenAuditPolicy.Policy[j].Category] = pElement->TokenAuditPolicy.Policy[j].PolicyMask;
  2749. }
  2750. Status =
  2751. LsapAdtInitParametersArray(
  2752. &AuditParameters,
  2753. SE_CATEGID_POLICY_CHANGE,
  2754. SE_AUDITID_PER_USER_AUDIT_TABLE_ELEMENT_CREATION,
  2755. EVENTLOG_AUDIT_SUCCESS,
  2756. 13,
  2757. //
  2758. // User Sid
  2759. //
  2760. SeAdtParmTypeSid, LsapLocalSystemSid,
  2761. //
  2762. // Subsystem name (if available)
  2763. //
  2764. SeAdtParmTypeString, &LsapSubsystemName,
  2765. //
  2766. // User Sid
  2767. //
  2768. SeAdtParmTypeSid, pElement->pSid,
  2769. //
  2770. // Table Id
  2771. //
  2772. SeAdtParmTypeLuid, TableId,
  2773. //
  2774. // System
  2775. //
  2776. SeAdtParmTypeHexUlong, AuditSettings[AuditCategorySystem],
  2777. //
  2778. // Logon
  2779. //
  2780. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryLogon],
  2781. //
  2782. // Object Access
  2783. //
  2784. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryObjectAccess],
  2785. //
  2786. // Privilege Use
  2787. //
  2788. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryPrivilegeUse],
  2789. //
  2790. // Detailed Tracking
  2791. //
  2792. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryDetailedTracking],
  2793. //
  2794. // Policy Change
  2795. //
  2796. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryPolicyChange],
  2797. //
  2798. // Account Management
  2799. //
  2800. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryAccountManagement],
  2801. //
  2802. // DS Access
  2803. //
  2804. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryDirectoryServiceAccess],
  2805. //
  2806. // Account Logon
  2807. //
  2808. SeAdtParmTypeHexUlong, AuditSettings[AuditCategoryAccountLogon]
  2809. );
  2810. if (!NT_SUCCESS(Status))
  2811. {
  2812. goto Cleanup;
  2813. }
  2814. (VOID)LsapAdtWriteLog(&AuditParameters);
  2815. pElement = pElement->Next;
  2816. }
  2817. }
  2818. Cleanup:
  2819. if (!NT_SUCCESS( Status ))
  2820. {
  2821. LsapAuditFailed( Status );
  2822. }
  2823. }
  2824. VOID
  2825. LsapAdtLogAuditFailureEvent(
  2826. NTSTATUS AuditStatus
  2827. )
  2828. /*++
  2829. Routine Description:
  2830. Generates SE_AUDITID_UNABLE_TO_LOG_EVENTS event
  2831. Arguments:
  2832. AuditStatus : failure code
  2833. Return Value:
  2834. None.
  2835. --*/
  2836. {
  2837. SE_ADT_PARAMETER_ARRAY AuditParameters;
  2838. NTSTATUS Status = STATUS_SUCCESS;
  2839. ULONG CrashOnAuditFailState;
  2840. //
  2841. // determine the CrashOnAuditFailState value
  2842. //
  2843. if ( LsapCrashOnAuditFail )
  2844. {
  2845. CrashOnAuditFailState = 1;
  2846. }
  2847. else if ( LsapAllowAdminLogonsOnly )
  2848. {
  2849. CrashOnAuditFailState = 2;
  2850. }
  2851. else
  2852. {
  2853. CrashOnAuditFailState = 0;
  2854. }
  2855. Status =
  2856. LsapAdtInitParametersArray(
  2857. &AuditParameters,
  2858. SE_CATEGID_SYSTEM,
  2859. SE_AUDITID_UNABLE_TO_LOG_EVENTS,
  2860. EVENTLOG_AUDIT_SUCCESS,
  2861. 4, // there are 4 params to init
  2862. //
  2863. // User Sid
  2864. //
  2865. SeAdtParmTypeSid, LsapLocalSystemSid,
  2866. //
  2867. // Subsystem name (if available)
  2868. //
  2869. SeAdtParmTypeString, &LsapSubsystemName,
  2870. //
  2871. // Audit failure code
  2872. //
  2873. SeAdtParmTypeHexUlong, AuditStatus,
  2874. //
  2875. // value of CrashOnAuditFail
  2876. //
  2877. SeAdtParmTypeUlong, CrashOnAuditFailState
  2878. );
  2879. AdtAssert(NT_SUCCESS(Status), ("LsapAdtLogAuditFailureEvent: LsapAdtInitParametersArray failed: %x", Status));
  2880. //
  2881. // note: we do not call LsapAuditFailed here because this function
  2882. // itself gets called by LsapAuditFailed. We just hope
  2883. // for the best.
  2884. //
  2885. //
  2886. // call LsapAdtDemarshallAuditInfo directly so that the audit event
  2887. // will bypass the queue and go directly to the eventlog.
  2888. //
  2889. Status = LsapAdtDemarshallAuditInfo( &AuditParameters );
  2890. AdtAssert(NT_SUCCESS(Status), ("LsapAdtLogAuditFailureEvent: LsapAdtDemarshallAuditInfo failed: %x", Status));
  2891. //
  2892. // now flush the eventlog
  2893. //
  2894. Status = LsapFlushSecurityLog();
  2895. AdtAssert(NT_SUCCESS(Status), ("LsapAdtLogAuditFailureEvent: ElfFlushEventLog failed: %x", Status));
  2896. }