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.

3319 lines
81 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. adtifn.c
  5. Abstract:
  6. This file has functions exported to other trusted modules in LSA.
  7. (LsaIAudit* functions)
  8. Author:
  9. 16-August-2000 kumarp
  10. --*/
  11. #include <lsapch2.h>
  12. #include "adtp.h"
  13. #include "adtutil.h"
  14. #include <md5.h>
  15. #include <msobjs.h>
  16. //
  17. // local helper routines for filling in audit params
  18. // from SAM's extended attributes.
  19. //
  20. VOID
  21. LsapAdtAppendDomainAttrValues(
  22. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  23. IN PLSAP_AUDIT_DOMAIN_ATTR_VALUES pAttributes OPTIONAL
  24. );
  25. VOID
  26. LsapAdtAppendUserAttrValues(
  27. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  28. IN PLSAP_AUDIT_USER_ATTR_VALUES pAttributes OPTIONAL,
  29. IN BOOL MachineAudit
  30. );
  31. VOID
  32. LsapAdtAppendGroupAttrValues(
  33. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  34. IN PLSAP_AUDIT_GROUP_ATTR_VALUES pAttributes OPTIONAL
  35. );
  36. //
  37. // LSA interface functions.
  38. //
  39. NTSTATUS
  40. LsaIGetLogonGuid(
  41. IN PUNICODE_STRING pUserName,
  42. IN PUNICODE_STRING pUserDomain,
  43. IN PBYTE pBuffer,
  44. IN UINT BufferSize,
  45. OUT LPGUID pLogonGuid
  46. )
  47. /*++
  48. Routine Description:
  49. Concatenate pUserName->Buffer, pUserDomain->Buffer and pBuffer
  50. into a single binary buffer. Get a MD5 hash of this concatenated
  51. buffer and return it in the form of a GUID.
  52. Arguments:
  53. pUserName - name of user
  54. pUserDomain - name of user domain
  55. pBuffer - pointer to KERB_TIME structure. The caller casts this to
  56. PBYTE and passes this to us. This allows us to keep KERB_TIME
  57. structure private to kerberos and offer future extensibility,
  58. should we decide to use another field from the ticket.
  59. BufferSize - size of buffer (currently sizeof(KERB_TIME))
  60. pLogonGuid - pointer to returned logon GUID
  61. Return Value:
  62. NTSTATUS - Standard Nt Result Code
  63. Notes:
  64. The generated GUID is recorded in the audit log in the form of
  65. 'Logon GUID' field in the following events:
  66. * On client machine
  67. -- SE_AUDITID_LOGON_USING_EXPLICIT_CREDENTIALS
  68. * On KDC
  69. -- SE_AUDITID_TGS_TICKET_REQUEST
  70. * On target server
  71. -- SE_AUDITID_NETWORK_LOGON
  72. -- SE_AUDITID_SUCCESSFUL_LOGON
  73. This allows us to correlate these events to aid in intrusion detection.
  74. --*/
  75. {
  76. NTSTATUS Status = STATUS_SUCCESS;
  77. UINT TempBufferLength=0;
  78. //
  79. // LSAI_TEMP_MD5_BUFFER_SIZE == UNLEN + DNS_MAX_NAME_LENGTH + sizeof(KERB_TIME) + padding
  80. //
  81. #define LSAI_TEMP_MD5_BUFFER_SIZE (256+256+16)
  82. BYTE TempBuffer[LSAI_TEMP_MD5_BUFFER_SIZE];
  83. MD5_CTX MD5Context = { 0 };
  84. ASSERT( LsapIsValidUnicodeString( pUserName ) );
  85. ASSERT( LsapIsValidUnicodeString( pUserDomain ) );
  86. ASSERT( pBuffer && BufferSize );
  87. #if DBG
  88. // DbgPrint("LsaIGetLogonGuid: user: %wZ\\%wZ, buf: %I64x\n",
  89. // pUserDomain, pUserName, *((ULONGLONG *) pBuffer));
  90. #endif
  91. TempBufferLength = pUserName->Length + pUserDomain->Length + BufferSize;
  92. if ( TempBufferLength < LSAI_TEMP_MD5_BUFFER_SIZE )
  93. {
  94. //
  95. // first concatenate user+domain+buffer and treat that as
  96. // a contiguous buffer.
  97. //
  98. RtlCopyMemory( TempBuffer, pUserName->Buffer, pUserName->Length );
  99. TempBufferLength = pUserName->Length;
  100. RtlCopyMemory( TempBuffer + TempBufferLength,
  101. pUserDomain->Buffer, pUserDomain->Length );
  102. TempBufferLength += pUserDomain->Length;
  103. RtlCopyMemory( TempBuffer + TempBufferLength,
  104. pBuffer, BufferSize );
  105. TempBufferLength += BufferSize;
  106. //
  107. // get MD5 hash of the concatenated buffer
  108. //
  109. MD5Init( &MD5Context );
  110. MD5Update( &MD5Context, TempBuffer, TempBufferLength );
  111. MD5Final( &MD5Context );
  112. //
  113. // return the hash as a GUID
  114. //
  115. RtlCopyMemory( pLogonGuid, MD5Context.digest, 16 );
  116. Status = STATUS_SUCCESS;
  117. }
  118. else
  119. {
  120. ASSERT( FALSE && "LsaIGetLogonGuid: TempBuffer overflow");
  121. Status = STATUS_BUFFER_OVERFLOW;
  122. }
  123. return Status;
  124. }
  125. VOID
  126. LsaIAuditKerberosLogon(
  127. IN NTSTATUS LogonStatus,
  128. IN NTSTATUS LogonSubStatus,
  129. IN PUNICODE_STRING AccountName,
  130. IN PUNICODE_STRING AuthenticatingAuthority,
  131. IN PUNICODE_STRING WorkstationName,
  132. IN PSID UserSid, OPTIONAL
  133. IN SECURITY_LOGON_TYPE LogonType,
  134. IN PTOKEN_SOURCE TokenSource,
  135. IN PLUID LogonId,
  136. IN LPGUID LogonGuid,
  137. IN PLSA_ADT_STRING_LIST TransittedServices
  138. )
  139. /*++
  140. Routine Description/Arguments/Return value
  141. See header comment for LsapAuditLogonHelper
  142. Notes:
  143. A new field (logon GUID) was added to this audit event.
  144. In order to send this new field to LSA, we had two options:
  145. 1) add new function (AuditLogonEx) to LSA dispatch table
  146. 2) define a private (LsaI) function to do the job
  147. option#2 was chosen because the logon GUID is a Kerberos only feature.
  148. --*/
  149. {
  150. LsapAuditLogonHelper(
  151. LogonStatus,
  152. LogonSubStatus,
  153. AccountName,
  154. AuthenticatingAuthority,
  155. WorkstationName,
  156. UserSid,
  157. LogonType,
  158. TokenSource,
  159. LogonId,
  160. LogonGuid,
  161. NULL, // caller logon-ID
  162. NULL, // caller process-ID
  163. TransittedServices
  164. );
  165. }
  166. NTSTATUS
  167. LsaIAuditLogonUsingExplicitCreds(
  168. IN USHORT AuditEventType,
  169. IN PLUID pUser1LogonId,
  170. IN LPGUID pUser1LogonGuid, OPTIONAL
  171. IN HANDLE User1ProcessId,
  172. IN PUNICODE_STRING pUser2Name,
  173. IN PUNICODE_STRING pUser2Domain,
  174. IN LPGUID pUser2LogonGuid,
  175. IN PUNICODE_STRING pTargetName, OPTIONAL
  176. IN PUNICODE_STRING pTargetInfo OPTIONAL
  177. )
  178. /*++
  179. Routine Description:
  180. This event is generated by Kerberos package when a logged on user
  181. (pUser1*) supplies explicit credentials of another user (pUser2*) and
  182. creates a new logon session either locally or on a remote machine.
  183. Parmeters:
  184. AuditEventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  185. pUser1LogonId - logon-id of user1
  186. pUser1LogonGuid - logon GUID of user1
  187. This is NULL if user1 logged on using NTLM.
  188. (NTLM does not support logon GUID)
  189. pUser2Name - name of user2
  190. NULL ==> ANONYMOUS
  191. pUser2Domain - domain of user2
  192. pUser2LogonGuid - logon-id of user2
  193. pTargetName - name of the logon target machine
  194. pTargetInfo - additional info (such as SPN) of the target
  195. Return Value:
  196. NTSTATUS - Standard Nt Result Code
  197. --*/
  198. {
  199. NTSTATUS Status = STATUS_SUCCESS;
  200. SE_ADT_PARAMETER_ARRAY AuditParameters;
  201. BOOLEAN bAudit;
  202. PSID pUser1Sid = NULL;
  203. PUNICODE_STRING pUser1Name = NULL;
  204. PUNICODE_STRING pUser1Domain = NULL;
  205. UNICODE_STRING usUser2Name = {0};
  206. UNICODE_STRING usUser2Domain = {0};
  207. PLSAP_LOGON_SESSION pUser1LogonSession = NULL;
  208. GUID NullGuid = { 0 };
  209. LUID LocalSystemLuid = SYSTEM_LUID;
  210. LUID AnonymousLuid = ANONYMOUS_LOGON_LUID;
  211. PLSA_CALL_INFO pCallInfo;
  212. SOCKADDR* pSockAddr = NULL;
  213. //
  214. // get the IP address/port of the caller
  215. //
  216. pCallInfo = LsapGetCurrentCall();
  217. DsysAssertMsg( pCallInfo != NULL, "LsapAuditLogon" );
  218. pSockAddr = (SOCKADDR*) pCallInfo->IpAddress;
  219. ASSERT( pUser1LogonId );
  220. if ( pTargetName )
  221. {
  222. ASSERT( pTargetName->Buffer && pTargetName->Length );
  223. }
  224. if ( pTargetInfo )
  225. {
  226. ASSERT( pTargetInfo->Buffer && pTargetInfo->Length );
  227. }
  228. //
  229. // if policy is not enabled then return quickly.
  230. //
  231. Status = LsapAdtAuditingEnabledByLogonId(
  232. AuditCategoryLogon,
  233. pUser1LogonId,
  234. AuditEventType,
  235. &bAudit);
  236. if (!NT_SUCCESS(Status) || !bAudit)
  237. {
  238. goto Cleanup;
  239. }
  240. //
  241. // Sanity check the strings we got passed since they might come from
  242. // NTLM and not be validated yet.
  243. //
  244. if (pUser2Name)
  245. {
  246. usUser2Name = *pUser2Name;
  247. usUser2Name.Length =
  248. (USHORT)LsapSafeWcslen(usUser2Name.Buffer,
  249. usUser2Name.MaximumLength);
  250. }
  251. pUser2Name = &usUser2Name;
  252. if (pUser2Domain)
  253. {
  254. usUser2Domain = *pUser2Domain;
  255. usUser2Domain.Length =
  256. (USHORT)LsapSafeWcslen(usUser2Domain.Buffer,
  257. usUser2Domain.MaximumLength);
  258. }
  259. pUser2Domain = &usUser2Domain;
  260. //
  261. // Locate the logon-session of user1 so that we can obtain
  262. // name/domain/sid info from it.
  263. //
  264. pUser1LogonSession = LsapLocateLogonSession( pUser1LogonId );
  265. if ( pUser1LogonSession )
  266. {
  267. pUser1Sid = pUser1LogonSession->UserSid;
  268. pUser1Name = &pUser1LogonSession->AccountName;
  269. pUser1Domain = &pUser1LogonSession->AuthorityName;
  270. //
  271. // We have implicit credentials if:
  272. // 1) UserName and DomainName are NULL
  273. // 2) and logon type is not NewCredentials
  274. //
  275. if (!pUser2Name->Buffer && !pUser2Domain->Buffer)
  276. {
  277. if (pUser1LogonSession->LogonType == NewCredentials)
  278. {
  279. pUser2Name = &pUser1LogonSession->NewAccountName;
  280. pUser2Domain = &pUser1LogonSession->NewAuthorityName;
  281. }
  282. else
  283. {
  284. // not an explict cred
  285. Status = STATUS_SUCCESS;
  286. goto Cleanup;
  287. }
  288. }
  289. //
  290. // Handle ambiguous credentials where NTLM supplies NULL username or
  291. // domain name.
  292. //
  293. if (!pUser2Name->Buffer)
  294. {
  295. pUser2Name = &pUser1LogonSession->AccountName;
  296. }
  297. if (!pUser2Domain->Buffer)
  298. {
  299. pUser2Domain = &pUser1LogonSession->AuthorityName;
  300. }
  301. //
  302. // This is an additional check to see whether we are dealing with implicit creds.
  303. // It works well for NTLM but might not catch all instances with Kerberos where
  304. // DNS names are preferred.
  305. //
  306. if (RtlEqualUnicodeString(pUser2Name, &pUser1LogonSession->AccountName, TRUE)
  307. && RtlEqualUnicodeString(pUser2Domain, &pUser1LogonSession->AuthorityName, TRUE))
  308. {
  309. // not an explict cred
  310. Status = STATUS_SUCCESS;
  311. goto Cleanup;
  312. }
  313. if ( pUser1LogonGuid &&
  314. memcmp( pUser1LogonGuid, &NullGuid, sizeof(GUID)) )
  315. {
  316. //
  317. // if the logon GUID in the logon session is null and
  318. // if the passed logon GUID is not null
  319. // update its value using what is passed to this function
  320. //
  321. if ( !memcmp( &pUser1LogonSession->LogonGuid, &NullGuid, sizeof(GUID)))
  322. {
  323. Status = LsaISetLogonGuidInLogonSession(
  324. pUser1LogonId,
  325. pUser1LogonGuid
  326. );
  327. }
  328. }
  329. else
  330. {
  331. pUser1LogonGuid = &pUser1LogonSession->LogonGuid;
  332. }
  333. }
  334. //
  335. // skip the audits for local-system changing to local/network service
  336. //
  337. if ( RtlEqualLuid( pUser1LogonId, &LocalSystemLuid ) &&
  338. LsapIsLocalOrNetworkService( pUser2Name, pUser2Domain ) )
  339. {
  340. Status = STATUS_SUCCESS;
  341. goto Cleanup;
  342. }
  343. //
  344. // skip the audits for anonymous changing to anonymous
  345. //
  346. // for anonymous user, the passed name/domain is null/empty
  347. //
  348. if ( RtlEqualLuid( pUser1LogonId, &AnonymousLuid ) )
  349. {
  350. if (((!pUser2Name || !pUser2Name->Length) && (!pUser2Domain || !pUser2Domain->Length)) ||
  351. LsapIsAnonymous(pUser2Name, pUser2Domain))
  352. {
  353. Status = STATUS_SUCCESS;
  354. goto Cleanup;
  355. }
  356. }
  357. Status =
  358. LsapAdtInitParametersArray(
  359. &AuditParameters,
  360. SE_CATEGID_LOGON,
  361. SE_AUDITID_LOGON_USING_EXPLICIT_CREDENTIALS,
  362. AuditEventType,
  363. 11, // there are 11 params to init
  364. //
  365. // User Sid
  366. //
  367. SeAdtParmTypeSid, pUser1Sid ? pUser1Sid : LsapLocalSystemSid,
  368. //
  369. // Subsystem name
  370. //
  371. SeAdtParmTypeString, &LsapSubsystemName,
  372. //
  373. // current user logon id
  374. //
  375. SeAdtParmTypeLogonId, *pUser1LogonId,
  376. //
  377. // user1 logon GUID
  378. //
  379. SeAdtParmTypeGuid, pUser1LogonGuid,
  380. //
  381. // user2 name
  382. //
  383. SeAdtParmTypeString, pUser2Name,
  384. //
  385. // user2 domain name
  386. //
  387. SeAdtParmTypeString, pUser2Domain,
  388. //
  389. // user2 logon GUID
  390. //
  391. SeAdtParmTypeGuid, pUser2LogonGuid,
  392. //
  393. // target server name
  394. //
  395. SeAdtParmTypeString, pTargetName,
  396. //
  397. // target server info (such as SPN)
  398. //
  399. SeAdtParmTypeString, pTargetInfo,
  400. //
  401. // Caller Process ID
  402. //
  403. SeAdtParmTypePtr, User1ProcessId,
  404. //
  405. // IP address/port info
  406. //
  407. SeAdtParmTypeSockAddr, pSockAddr
  408. );
  409. if (!NT_SUCCESS(Status))
  410. {
  411. goto Cleanup;
  412. }
  413. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  414. Cleanup:
  415. if ( pUser1LogonSession )
  416. {
  417. LsapReleaseLogonSession( pUser1LogonSession );
  418. }
  419. if (!NT_SUCCESS(Status)) {
  420. LsapAuditFailed( Status );
  421. }
  422. return Status;
  423. }
  424. NTSTATUS
  425. LsaIAdtAuditingEnabledByCategory(
  426. IN POLICY_AUDIT_EVENT_TYPE Category,
  427. IN USHORT AuditEventType,
  428. IN PSID pUserSid OPTIONAL,
  429. IN PLUID pLogonId OPTIONAL,
  430. OUT PBOOLEAN pbAudit
  431. )
  432. /*++
  433. Routine Description:
  434. Returns whether auditing is enabled for the given category - event
  435. type - user combination. The user can be supplied as sid or logon id.
  436. If none is supplied, the general settings (not user specific) are returned.
  437. If both are supplied, the sid takes precedence and the logon id is ignored.
  438. Parmeters:
  439. Category - Category to be queried
  440. AuditEventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  441. pUserSid - sid of user
  442. pLogonId - logon-id of user
  443. pbAudit - returns whether auditing is enabled for the requested parameters
  444. Return Value:
  445. NTSTATUS - Standard Nt Result Code
  446. --*/
  447. {
  448. NTSTATUS Status = STATUS_SUCCESS;
  449. if (pUserSid)
  450. {
  451. Status = LsapAdtAuditingEnabledBySid(
  452. Category,
  453. pUserSid,
  454. AuditEventType,
  455. pbAudit
  456. );
  457. }
  458. else if (pLogonId)
  459. {
  460. Status = LsapAdtAuditingEnabledByLogonId(
  461. Category,
  462. pLogonId,
  463. AuditEventType,
  464. pbAudit
  465. );
  466. }
  467. else
  468. {
  469. *pbAudit = LsapAdtAuditingEnabledByCategory(
  470. Category,
  471. AuditEventType
  472. );
  473. }
  474. return Status;
  475. }
  476. NTSTATUS
  477. LsaIAuditKdcEvent(
  478. IN ULONG AuditId,
  479. IN PUNICODE_STRING ClientName,
  480. IN PUNICODE_STRING ClientDomain,
  481. IN PSID ClientSid,
  482. IN PUNICODE_STRING ServiceName,
  483. IN PSID ServiceSid,
  484. IN PULONG KdcOptions,
  485. IN PULONG KerbStatus,
  486. IN PULONG EncryptionType,
  487. IN PULONG PreauthType,
  488. IN PBYTE ClientAddress,
  489. IN LPGUID LogonGuid OPTIONAL,
  490. IN PLSA_ADT_STRING_LIST TransittedServices OPTIONAL,
  491. IN PUNICODE_STRING CertIssuerName OPTIONAL,
  492. IN PUNICODE_STRING CertSerialNumber OPTIONAL,
  493. IN PUNICODE_STRING CertThumbprint OPTIONAL
  494. )
  495. /*++
  496. Abstract:
  497. This routine produces an audit record representing a KDC
  498. operation.
  499. This routine goes through the list of parameters and adds a string
  500. representation of each (in order) to an audit message. Note that
  501. the full complement of account audit message formats is achieved by
  502. selecting which optional parameters to include in this call.
  503. In addition to any parameters passed below, this routine will ALWAYS
  504. add the impersonation client's user name, domain, and logon ID as
  505. the LAST parameters in the audit message.
  506. Parmeters:
  507. AuditId - Specifies the message ID of the audit being generated.
  508. ClientName -
  509. ClientDomain -
  510. ClientSid -
  511. ServiceName -
  512. ServiceSid -
  513. KdcOptions -
  514. KerbStatus -
  515. EncryptionType -
  516. PreauthType -
  517. ClientAddress -
  518. LogonGuid -
  519. TransittedServices -
  520. CertIssuerName -
  521. CertSerialNumber -
  522. CertThumbprint -
  523. --*/
  524. {
  525. SE_ADT_PARAMETER_ARRAY AuditParameters;
  526. UNICODE_STRING AddressString;
  527. WCHAR AddressBuffer[3*4+4]; // space for a dotted-quad IP address
  528. NTSTATUS Status;
  529. BOOLEAN bAudit;
  530. RtlZeroMemory (
  531. (PVOID) &AuditParameters,
  532. sizeof( AuditParameters )
  533. );
  534. AuditParameters.CategoryId = SE_CATEGID_ACCOUNT_LOGON;
  535. AuditParameters.AuditId = AuditId;
  536. AuditParameters.Type = ((ARGUMENT_PRESENT(KerbStatus) &&
  537. (*KerbStatus != 0)) ?
  538. EVENTLOG_AUDIT_FAILURE :
  539. EVENTLOG_AUDIT_SUCCESS );
  540. Status = LsapAdtAuditingEnabledBySid(
  541. AuditCategoryAccountLogon,
  542. ClientSid ? ClientSid : LsapLocalSystemSid,
  543. AuditParameters.Type,
  544. &bAudit
  545. );
  546. if (!NT_SUCCESS(Status) || !bAudit)
  547. {
  548. goto Cleanup;
  549. }
  550. AuditParameters.ParameterCount = 0;
  551. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
  552. AuditParameters.ParameterCount++;
  553. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  554. AuditParameters.ParameterCount++;
  555. if (ARGUMENT_PRESENT(ClientName)) {
  556. //
  557. // Add a UNICODE_STRING to the audit message
  558. //
  559. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, ClientName );
  560. AuditParameters.ParameterCount++;
  561. }
  562. if (ARGUMENT_PRESENT(ClientDomain)) {
  563. //
  564. // Add a UNICODE_STRING to the audit message
  565. //
  566. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, ClientDomain );
  567. AuditParameters.ParameterCount++;
  568. }
  569. if (ARGUMENT_PRESENT(ClientSid)) {
  570. //
  571. // Add a SID to the audit message
  572. //
  573. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
  574. AuditParameters.ParameterCount++;
  575. } else if (AuditId == SE_AUDITID_AS_TICKET) {
  576. AuditParameters.ParameterCount++;
  577. }
  578. if (ARGUMENT_PRESENT(ServiceName)) {
  579. //
  580. // Add a UNICODE_STRING to the audit message
  581. //
  582. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, ServiceName );
  583. AuditParameters.ParameterCount++;
  584. }
  585. if (ARGUMENT_PRESENT(ServiceSid)) {
  586. //
  587. // Add a SID to the audit message
  588. //
  589. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ServiceSid );
  590. AuditParameters.ParameterCount++;
  591. } else if (AuditId == SE_AUDITID_AS_TICKET || AuditId == SE_AUDITID_TGS_TICKET_REQUEST) {
  592. AuditParameters.ParameterCount++;
  593. }
  594. if (ARGUMENT_PRESENT(KdcOptions)) {
  595. //
  596. // Add a ULONG to the audit message
  597. //
  598. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *KdcOptions );
  599. AuditParameters.ParameterCount++;
  600. }
  601. //
  602. // Failure code is the last parameter for SE_AUDITID_TGS_TICKET_REQUEST
  603. //
  604. if (AuditId != SE_AUDITID_TGS_TICKET_REQUEST)
  605. {
  606. if (ARGUMENT_PRESENT(KerbStatus)) {
  607. //
  608. // Add a ULONG to the audit message
  609. //
  610. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *KerbStatus );
  611. AuditParameters.ParameterCount++;
  612. } else if (AuditId == SE_AUDITID_AS_TICKET) {
  613. AuditParameters.ParameterCount++;
  614. }
  615. }
  616. if (ARGUMENT_PRESENT(EncryptionType)) {
  617. //
  618. // Add a ULONG to the audit message
  619. //
  620. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *EncryptionType );
  621. AuditParameters.ParameterCount++;
  622. } else if (AuditId == SE_AUDITID_AS_TICKET || AuditId == SE_AUDITID_TGS_TICKET_REQUEST) {
  623. AuditParameters.ParameterCount++;
  624. }
  625. if (ARGUMENT_PRESENT(PreauthType)) {
  626. //
  627. // Add a ULONG to the audit message
  628. //
  629. LsapSetParmTypeUlong( AuditParameters, AuditParameters.ParameterCount, *PreauthType );
  630. AuditParameters.ParameterCount++;
  631. } else if (AuditId == SE_AUDITID_AS_TICKET) {
  632. AuditParameters.ParameterCount++;
  633. }
  634. if (ARGUMENT_PRESENT(ClientAddress)) {
  635. AddressBuffer[0] = L'\0';
  636. swprintf(AddressBuffer,L"%d.%d.%d.%d",
  637. ClientAddress[0],
  638. (ULONG) ClientAddress[1],
  639. (ULONG) ClientAddress[2],
  640. (ULONG) ClientAddress[3]
  641. );
  642. RtlInitUnicodeString(
  643. &AddressString,
  644. AddressBuffer
  645. );
  646. //
  647. // IP address
  648. //
  649. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &AddressString );
  650. AuditParameters.ParameterCount++;
  651. }
  652. //
  653. // Transitted Services is the last parameter for SE_AUDITID_TGS_TICKET_REQUEST
  654. //
  655. if (AuditId == SE_AUDITID_TGS_TICKET_REQUEST)
  656. {
  657. if (ARGUMENT_PRESENT(KerbStatus)) {
  658. //
  659. // Add a ULONG to the audit message
  660. //
  661. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *KerbStatus );
  662. AuditParameters.ParameterCount++;
  663. } else {
  664. AuditParameters.ParameterCount++;
  665. }
  666. if (ARGUMENT_PRESENT(LogonGuid)) {
  667. //
  668. // Add the globally unique logon-id to the audit message
  669. //
  670. LsapSetParmTypeGuid( AuditParameters, AuditParameters.ParameterCount, LogonGuid );
  671. AuditParameters.ParameterCount++;
  672. }
  673. else {
  674. if (( AuditParameters.Type == EVENTLOG_AUDIT_SUCCESS ) &&
  675. ( AuditId == SE_AUDITID_TGS_TICKET_REQUEST )) {
  676. ASSERT( FALSE && L"LsaIAuditKdcEvent: UniqueID not supplied to successful SE_AUDITID_TGS_TICKET_REQUEST audit event" );
  677. }
  678. AuditParameters.ParameterCount++;
  679. }
  680. if (ARGUMENT_PRESENT(TransittedServices)) {
  681. //
  682. // Transitted Services
  683. //
  684. LsapSetParmTypeStringList( AuditParameters, AuditParameters.ParameterCount, TransittedServices );
  685. }
  686. AuditParameters.ParameterCount++;
  687. } else if (AuditId == SE_AUDITID_AS_TICKET) {
  688. if (ARGUMENT_PRESENT(CertIssuerName)) {
  689. //
  690. // Certificate Issuer Name
  691. //
  692. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CertIssuerName );
  693. }
  694. AuditParameters.ParameterCount++;
  695. if (ARGUMENT_PRESENT(CertSerialNumber)) {
  696. //
  697. // Certificate Serial Number
  698. //
  699. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CertSerialNumber );
  700. }
  701. AuditParameters.ParameterCount++;
  702. if (ARGUMENT_PRESENT(CertThumbprint)) {
  703. //
  704. // Certificate Thumbprint
  705. //
  706. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, CertThumbprint );
  707. }
  708. AuditParameters.ParameterCount++;
  709. }
  710. //
  711. // Now write out the audit record to the audit log
  712. //
  713. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  714. Cleanup:
  715. if (!NT_SUCCESS(Status)) {
  716. LsapAuditFailed(Status);
  717. }
  718. return Status;
  719. }
  720. NTSTATUS
  721. LsaIAuditAccountLogon(
  722. IN ULONG AuditId,
  723. IN BOOLEAN Successful,
  724. IN PUNICODE_STRING Source,
  725. IN PUNICODE_STRING ClientName,
  726. IN PUNICODE_STRING MappedName,
  727. IN NTSTATUS LogonStatus
  728. )
  729. {
  730. return LsaIAuditAccountLogonEx(
  731. AuditId,
  732. Successful,
  733. Source,
  734. ClientName,
  735. MappedName,
  736. LogonStatus,
  737. NULL // client SID
  738. );
  739. }
  740. NTSTATUS
  741. LsaIAuditAccountLogonEx(
  742. IN ULONG AuditId,
  743. IN BOOLEAN Successful,
  744. IN PUNICODE_STRING Source,
  745. IN PUNICODE_STRING ClientName,
  746. IN PUNICODE_STRING MappedName,
  747. IN NTSTATUS LogonStatus,
  748. IN PSID ClientSid
  749. )
  750. /*++
  751. Abstract:
  752. This routine produces an audit record representing the mapping of a
  753. foreign principal name onto an NT account.
  754. This routine goes through the list of parameters and adds a string
  755. representation of each (in order) to an audit message. Note that
  756. the full complement of account audit message formats is achieved by
  757. selecting which optional parameters to include in this call.
  758. Parmeters:
  759. AuditId - Specifies the message ID of the audit being generated.
  760. Successful - Indicates the code should generate a success audit
  761. Source - Source module generating audit, such as SCHANNEL or KDC
  762. ClientName - Name being mapped.
  763. MappedName - Name of NT account to which the client name was mapped.
  764. LogonStatus- NT Status code for any failures.
  765. ClientSid - SID of the client
  766. --*/
  767. {
  768. NTSTATUS Status = STATUS_SUCCESS;
  769. BOOLEAN bAudit = FALSE;
  770. SE_ADT_PARAMETER_ARRAY AuditParameters;
  771. UNICODE_STRING LocalClientName;
  772. UNICODE_STRING LocalMappedName;
  773. RtlZeroMemory (
  774. (PVOID) &AuditParameters,
  775. sizeof( AuditParameters )
  776. );
  777. AuditParameters.CategoryId = SE_CATEGID_ACCOUNT_LOGON;
  778. AuditParameters.AuditId = AuditId;
  779. AuditParameters.Type = Successful ?
  780. EVENTLOG_AUDIT_SUCCESS :
  781. EVENTLOG_AUDIT_FAILURE ;
  782. if ( ClientSid )
  783. {
  784. //
  785. // if the client SID is specified use it for checking pua policy
  786. //
  787. Status = LsapAdtAuditingEnabledBySid(
  788. AuditCategoryAccountLogon,
  789. ClientSid,
  790. AuditParameters.Type,
  791. &bAudit
  792. );
  793. if (!NT_SUCCESS(Status) || !bAudit)
  794. {
  795. goto Cleanup;
  796. }
  797. }
  798. else
  799. {
  800. //
  801. // if the client SID is not supplied, check the global policy
  802. //
  803. if (AuditParameters.Type == EVENTLOG_AUDIT_SUCCESS) {
  804. if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategoryAccountLogon] & POLICY_AUDIT_EVENT_SUCCESS)) {
  805. return( STATUS_SUCCESS );
  806. }
  807. } else {
  808. if (!(LsapAdtEventsInformation.EventAuditingOptions[AuditCategoryAccountLogon] & POLICY_AUDIT_EVENT_FAILURE)) {
  809. return( STATUS_SUCCESS );
  810. }
  811. }
  812. }
  813. AuditParameters.ParameterCount = 0;
  814. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid ? ClientSid : LsapLocalSystemSid );
  815. AuditParameters.ParameterCount++;
  816. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  817. AuditParameters.ParameterCount++;
  818. if (ARGUMENT_PRESENT(Source)) {
  819. //
  820. // Add a UNICODE_STRING to the audit message
  821. //
  822. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, Source );
  823. AuditParameters.ParameterCount++;
  824. }
  825. if (ARGUMENT_PRESENT(ClientName)) {
  826. //
  827. // Add a UNICODE_STRING to the audit message
  828. //
  829. LocalClientName = *ClientName;
  830. if ( !Successful ) {
  831. //
  832. // For failed logons the client name can be invalid (for example,
  833. // with embedded NULLs). This causes the
  834. // eventlog to reject the string and we drop the audit.
  835. //
  836. // To avoid this, adjust the length parameter if necessary.
  837. //
  838. LocalClientName.Length =
  839. (USHORT) LsapSafeWcslen( LocalClientName.Buffer,
  840. LocalClientName.MaximumLength );
  841. }
  842. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LocalClientName );
  843. AuditParameters.ParameterCount++;
  844. }
  845. if (ARGUMENT_PRESENT(MappedName)) {
  846. //
  847. // Add MappedName to the audit message
  848. //
  849. // This is somewhat overloaded. For SE_AUDITID_ACCOUNT_LOGON, the
  850. // caller passes the workstation name in this param.
  851. //
  852. // The workstation name can be invalid (for example,
  853. // with embedded NULLs). This causes the
  854. // eventlog to reject the string and we drop the audit.
  855. //
  856. // To avoid this, adjust the length parameter if necessary.
  857. //
  858. LocalMappedName = *MappedName;
  859. LocalMappedName.Length =
  860. (USHORT) LsapSafeWcslen( LocalMappedName.Buffer,
  861. LocalMappedName.MaximumLength );
  862. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LocalMappedName );
  863. AuditParameters.ParameterCount++;
  864. }
  865. //
  866. // Add a ULONG to the audit message
  867. //
  868. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, LogonStatus );
  869. AuditParameters.ParameterCount++;
  870. //
  871. // Now write out the audit record to the audit log
  872. //
  873. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  874. Cleanup:
  875. if (!NT_SUCCESS(Status))
  876. {
  877. LsapAuditFailed(Status);
  878. }
  879. return Status;
  880. }
  881. NTSTATUS NTAPI
  882. LsaIAuditDPAPIEvent(
  883. IN ULONG AuditId,
  884. IN PSID UserSid,
  885. IN PUNICODE_STRING MasterKeyID,
  886. IN PUNICODE_STRING RecoveryServer,
  887. IN PULONG Reason,
  888. IN PUNICODE_STRING RecoverykeyID,
  889. IN PULONG FailureReason
  890. )
  891. /*++
  892. Abstract:
  893. This routine produces an audit record representing a DPAPI
  894. operation.
  895. This routine goes through the list of parameters and adds a string
  896. representation of each (in order) to an audit message. Note that
  897. the full complement of account audit message formats is achieved by
  898. selecting which optional parameters to include in this call.
  899. In addition to any parameters passed below, this routine will ALWAYS
  900. add the impersonation client's user name, domain, and logon ID as
  901. the LAST parameters in the audit message.
  902. Parmeters:
  903. AuditId - Specifies the message ID of the audit being generated.
  904. MasterKeyID -
  905. RecoveryServer -
  906. Reason -
  907. RecoverykeyID -
  908. FailureReason -
  909. --*/
  910. {
  911. SE_ADT_PARAMETER_ARRAY AuditParameters;
  912. NTSTATUS Status;
  913. BOOLEAN bAudit;
  914. RtlZeroMemory (
  915. (PVOID) &AuditParameters,
  916. sizeof( AuditParameters )
  917. );
  918. AuditParameters.CategoryId = SE_CATEGID_DETAILED_TRACKING;
  919. AuditParameters.AuditId = AuditId;
  920. AuditParameters.Type = ((ARGUMENT_PRESENT(FailureReason) &&
  921. (*FailureReason != 0)) ?
  922. EVENTLOG_AUDIT_FAILURE :
  923. EVENTLOG_AUDIT_SUCCESS );
  924. Status = LsapAdtAuditingEnabledBySid(
  925. AuditCategoryDetailedTracking,
  926. UserSid,
  927. AuditParameters.Type,
  928. &bAudit
  929. );
  930. if (!NT_SUCCESS(Status) || !bAudit)
  931. {
  932. goto Cleanup;
  933. }
  934. AuditParameters.ParameterCount = 0;
  935. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, UserSid ? UserSid : LsapLocalSystemSid );
  936. AuditParameters.ParameterCount++;
  937. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  938. AuditParameters.ParameterCount++;
  939. if (ARGUMENT_PRESENT(MasterKeyID)) {
  940. //
  941. // Add a UNICODE_STRING to the audit message
  942. //
  943. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, MasterKeyID );
  944. AuditParameters.ParameterCount++;
  945. }
  946. if (ARGUMENT_PRESENT(RecoveryServer)) {
  947. //
  948. // Add a UNICODE_STRING to the audit message
  949. //
  950. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, RecoveryServer );
  951. AuditParameters.ParameterCount++;
  952. }
  953. if (ARGUMENT_PRESENT(Reason)) {
  954. //
  955. // Add a ULONG to the audit message
  956. //
  957. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *Reason );
  958. AuditParameters.ParameterCount++;
  959. }
  960. if (ARGUMENT_PRESENT(RecoverykeyID)) {
  961. //
  962. // Add a UNICODE_STRING to the audit message
  963. //
  964. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, RecoverykeyID );
  965. AuditParameters.ParameterCount++;
  966. }
  967. if (ARGUMENT_PRESENT(FailureReason)) {
  968. //
  969. // Add a ULONG to the audit message
  970. //
  971. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, *FailureReason );
  972. AuditParameters.ParameterCount++;
  973. }
  974. //
  975. // Now write out the audit record to the audit log
  976. //
  977. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  978. Cleanup:
  979. if (!NT_SUCCESS(Status))
  980. {
  981. LsapAuditFailed(Status);
  982. }
  983. return Status;
  984. }
  985. NTSTATUS
  986. LsaIWriteAuditEvent(
  987. IN PSE_ADT_PARAMETER_ARRAY AuditParameters,
  988. IN ULONG Options
  989. )
  990. /*++
  991. Abstract:
  992. This routine writes an audit record to the log.
  993. Parmeters:
  994. AuditParameters - The audit record
  995. Options - must be zero
  996. --*/
  997. {
  998. NTSTATUS Status = STATUS_SUCCESS;
  999. BOOLEAN bAudit = FALSE;
  1000. POLICY_AUDIT_EVENT_TYPE CategoryId;
  1001. if ( !ARGUMENT_PRESENT(AuditParameters) ||
  1002. (Options != 0) ||
  1003. !IsValidCategoryId( AuditParameters->CategoryId ) ||
  1004. !IsValidAuditId( AuditParameters->AuditId ) ||
  1005. !IsValidParameterCount( AuditParameters->ParameterCount ) ||
  1006. (AuditParameters->Parameters[0].Type != SeAdtParmTypeSid) ||
  1007. (AuditParameters->Parameters[1].Type != SeAdtParmTypeString))
  1008. {
  1009. return STATUS_INVALID_PARAMETER;
  1010. }
  1011. //
  1012. // LsapAdtEventsInformation.EventAuditingOptions needs to be indexed
  1013. // by one of enum POLICY_AUDIT_EVENT_TYPE values whereas the value
  1014. // of SE_ADT_PARAMETER_ARRAY.CategoryId must be one of SE_CATEGID_*
  1015. // values. The value of corresponding elements in the two types differ by 1.
  1016. // Subtract 1 from AuditParameters->CategoryId to get the right
  1017. // AuditCategory* value.
  1018. //
  1019. CategoryId = AuditParameters->CategoryId - 1;
  1020. Status = LsapAdtAuditingEnabledBySid(
  1021. CategoryId,
  1022. (PSID) AuditParameters->Parameters[0].Address,
  1023. AuditParameters->Type,
  1024. &bAudit
  1025. );
  1026. if (!NT_SUCCESS(Status) || !bAudit) {
  1027. goto Cleanup;
  1028. }
  1029. //
  1030. // Audit the event
  1031. //
  1032. Status = LsapAdtWriteLog( AuditParameters );
  1033. Cleanup:
  1034. return Status;
  1035. }
  1036. NTSTATUS
  1037. LsaIAuditNotifyPackageLoad(
  1038. PUNICODE_STRING PackageFileName
  1039. )
  1040. /*++
  1041. Routine Description:
  1042. Audits the loading of an notification package.
  1043. Arguments:
  1044. PackageFileName - The name of the package being loaded.
  1045. Return Value:
  1046. NTSTATUS.
  1047. --*/
  1048. {
  1049. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1050. NTSTATUS Status;
  1051. BOOLEAN bAudit;
  1052. Status = LsapAdtAuditingEnabledBySid(
  1053. AuditCategorySystem,
  1054. LsapLocalSystemSid,
  1055. EVENTLOG_AUDIT_SUCCESS,
  1056. &bAudit
  1057. );
  1058. if (!NT_SUCCESS(Status) || !bAudit) {
  1059. goto Cleanup;
  1060. }
  1061. RtlZeroMemory (
  1062. (PVOID) &AuditParameters,
  1063. sizeof( AuditParameters )
  1064. );
  1065. AuditParameters.CategoryId = SE_CATEGID_SYSTEM;
  1066. AuditParameters.AuditId = SE_AUDITID_NOTIFY_PACKAGE_LOAD;
  1067. AuditParameters.Type = EVENTLOG_AUDIT_SUCCESS;
  1068. AuditParameters.ParameterCount = 0;
  1069. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, LsapLocalSystemSid );
  1070. AuditParameters.ParameterCount++;
  1071. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1072. AuditParameters.ParameterCount++;
  1073. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, PackageFileName );
  1074. AuditParameters.ParameterCount++;
  1075. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1076. Cleanup:
  1077. if (!NT_SUCCESS(Status)) {
  1078. LsapAuditFailed(Status);
  1079. }
  1080. return Status;
  1081. }
  1082. NTSTATUS
  1083. LsaIAuditSamEvent(
  1084. IN NTSTATUS PassedStatus,
  1085. IN ULONG AuditId,
  1086. IN PSID DomainSid,
  1087. IN PUNICODE_STRING AdditionalInfo OPTIONAL,
  1088. IN PULONG MemberRid OPTIONAL,
  1089. IN PSID MemberSid OPTIONAL,
  1090. IN PUNICODE_STRING AccountName OPTIONAL,
  1091. IN PUNICODE_STRING DomainName,
  1092. IN PULONG AccountRid OPTIONAL,
  1093. IN PPRIVILEGE_SET Privileges OPTIONAL,
  1094. IN PVOID ExtendedInfo OPTIONAL
  1095. )
  1096. /*++
  1097. Abstract:
  1098. This routine produces an audit record representing an account
  1099. operation.
  1100. This routine goes through the list of parameters and adds a string
  1101. representation of each (in order) to an audit message. Note that
  1102. the full complement of account audit message formats is achieved by
  1103. selecting which optional parameters to include in this call.
  1104. In addition to any parameters passed below, this routine will ALWAYS
  1105. add the impersonation client's user name, domain, and logon ID as
  1106. the LAST parameters in the audit message.
  1107. Parmeters:
  1108. AuditId - Specifies the message ID of the audit being generated.
  1109. DomainSid - This parameter results in a SID string being generated
  1110. ONLY if neither the MemberRid nor AccountRid parameters are
  1111. passed. If either of those parameters are passed, this parameter
  1112. is used as a prefix of a SID.
  1113. AdditionalInfo - This optional parameter, if present, is used to
  1114. produce any additional inforamtion the caller wants to add.
  1115. Used by SE_AUDITID_USER_CHANGE and SE_AUDITID_GROUP_TYPE_CHANGE.
  1116. for user change, the additional info states the nature of the
  1117. change, such as Account Disable, unlocked or account Name Changed.
  1118. For Group type change, this parameter should state the group type
  1119. has been change from AAA to BBB.
  1120. MemberRid - This optional parameter, if present, is added to the end of
  1121. the DomainSid parameter to produce a "Member" sid. The resultant
  1122. member SID is then used to build a sid-string which is added to the
  1123. audit message following all preceeding parameters.
  1124. This parameter supports global group membership change audits, where
  1125. member IDs are always relative to a local domain.
  1126. MemberSid - This optional parameter, if present, is converted to a
  1127. SID string and added following preceeding parameters. This parameter
  1128. is generally used for describing local group (alias) members, where
  1129. the member IDs are not relative to a local domain.
  1130. AccountName - This optional parameter, if present, is added to the audit
  1131. message without change following any preceeding parameters.
  1132. This parameter is needed for almost all account audits and does not
  1133. need localization.
  1134. DomainName - This optional parameter, if present, is added to the audit
  1135. message without change following any preceeding parameters.
  1136. This parameter is needed for almost all account audits and does not
  1137. need localization.
  1138. AccountRid - This optional parameter, if present, is added to the end of
  1139. the DomainSid parameter to produce an "Account" sid. The resultant
  1140. Account SID is then used to build a sid-string which is added to the
  1141. audit message following all preceeding parameters.
  1142. This parameter supports audits that include "New account ID" or
  1143. "Target Account ID" fields.
  1144. Privileges - The privileges passed via this optional parameter,
  1145. if present, will be converted to string format and added to the
  1146. audit message following any preceeding parameters. NOTE: the
  1147. caller is responsible for freeing the privilege_set (in fact,
  1148. it may be on the stack). ALSO NOTE: The privilege set will be
  1149. destroyed by this call (due to use of the routine used to
  1150. convert the privilege values to privilege names).
  1151. ExtendedInfo - Pointer to an optional parameter containing extended
  1152. information about attributes of sam objects. This parameter gets typecast
  1153. to a structure describing the attributes, depending on the audit id.
  1154. --*/
  1155. {
  1156. NTSTATUS Status;
  1157. LUID LogonId = SYSTEM_LUID;
  1158. PSID NewAccountSid = NULL;
  1159. PSID NewMemberSid = NULL;
  1160. PSID SidPointer;
  1161. PSID ClientSid = NULL;
  1162. PTOKEN_USER TokenUserInformation = NULL;
  1163. SE_ADT_PARAMETER_ARRAY AuditParameters;
  1164. UCHAR AccountSidBuffer[256];
  1165. UCHAR MemberSidBuffer[256];
  1166. UCHAR SubAuthorityCount;
  1167. ULONG LengthRequired;
  1168. BOOLEAN bAudit;
  1169. if ( AuditId == SE_AUDITID_ACCOUNT_AUTO_LOCKED )
  1170. {
  1171. //
  1172. // In this case use LogonID as SYSTEM, SID is SYSTEM.
  1173. //
  1174. ClientSid = LsapLocalSystemSid;
  1175. } else {
  1176. Status = LsapQueryClientInfo(
  1177. &TokenUserInformation,
  1178. &LogonId
  1179. );
  1180. if ( !NT_SUCCESS( Status )) {
  1181. goto Cleanup;
  1182. }
  1183. ClientSid = TokenUserInformation->User.Sid;
  1184. }
  1185. RtlZeroMemory (
  1186. (PVOID) &AuditParameters,
  1187. sizeof( AuditParameters )
  1188. );
  1189. AuditParameters.CategoryId = SE_CATEGID_ACCOUNT_MANAGEMENT;
  1190. AuditParameters.AuditId = AuditId;
  1191. AuditParameters.Type = (NT_SUCCESS(PassedStatus) ? EVENTLOG_AUDIT_SUCCESS : EVENTLOG_AUDIT_FAILURE );
  1192. AuditParameters.ParameterCount = 0;
  1193. Status = LsapAdtAuditingEnabledByLogonId(
  1194. AuditCategoryAccountManagement,
  1195. &LogonId,
  1196. AuditParameters.Type,
  1197. &bAudit
  1198. );
  1199. if (!NT_SUCCESS(Status) || !bAudit)
  1200. {
  1201. goto Cleanup;
  1202. }
  1203. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, ClientSid );
  1204. AuditParameters.ParameterCount++;
  1205. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, &LsapSubsystemName );
  1206. AuditParameters.ParameterCount++;
  1207. if (ARGUMENT_PRESENT(AdditionalInfo))
  1208. {
  1209. //
  1210. // Add a UNICODE_STRING to the audit message
  1211. //
  1212. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, AdditionalInfo );
  1213. AuditParameters.ParameterCount++;
  1214. }
  1215. if (ARGUMENT_PRESENT(MemberRid)) {
  1216. //
  1217. // Add a member SID string to the audit message
  1218. //
  1219. // Domain Sid + Member Rid = Final SID.
  1220. SubAuthorityCount = *RtlSubAuthorityCountSid( DomainSid );
  1221. if ( (LengthRequired = RtlLengthRequiredSid( SubAuthorityCount + 1 )) > 256 ) {
  1222. NewMemberSid = LsapAllocateLsaHeap( LengthRequired );
  1223. if ( NewMemberSid == NULL ) {
  1224. Status = STATUS_NO_MEMORY;
  1225. goto Cleanup;
  1226. }
  1227. SidPointer = NewMemberSid;
  1228. } else {
  1229. SidPointer = (PSID)MemberSidBuffer;
  1230. }
  1231. Status = RtlCopySid (
  1232. LengthRequired,
  1233. SidPointer,
  1234. DomainSid
  1235. );
  1236. ASSERT( NT_SUCCESS( Status ));
  1237. *(RtlSubAuthoritySid( SidPointer, SubAuthorityCount )) = *MemberRid;
  1238. *RtlSubAuthorityCountSid( SidPointer ) = SubAuthorityCount + 1;
  1239. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, SidPointer );
  1240. AuditParameters.ParameterCount++;
  1241. }
  1242. if (ARGUMENT_PRESENT(MemberSid)) {
  1243. //
  1244. // Add a member SID string to the audit message
  1245. //
  1246. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, MemberSid );
  1247. AuditParameters.ParameterCount++;
  1248. } else {
  1249. if (SE_AUDITID_ADD_SID_HISTORY == AuditId) {
  1250. //
  1251. // Add dash ( - ) string to the audit message (SeAdtParmTypeNone)
  1252. // by calling LsapSetParmTypeSid with NULL as third parameter
  1253. //
  1254. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, NULL );
  1255. AuditParameters.ParameterCount++;
  1256. }
  1257. }
  1258. if (ARGUMENT_PRESENT(AccountName)) {
  1259. //
  1260. // Add a UNICODE_STRING to the audit message
  1261. //
  1262. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, AccountName );
  1263. AuditParameters.ParameterCount++;
  1264. }
  1265. if (ARGUMENT_PRESENT(DomainName)) {
  1266. //
  1267. // Add a UNICODE_STRING to the audit message
  1268. //
  1269. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, DomainName );
  1270. AuditParameters.ParameterCount++;
  1271. }
  1272. if (ARGUMENT_PRESENT(DomainSid) &&
  1273. !(ARGUMENT_PRESENT(MemberRid) || ARGUMENT_PRESENT(AccountRid))
  1274. ) {
  1275. //
  1276. // Add the domain SID as a SID string to the audit message
  1277. //
  1278. // Just the domain SID.
  1279. //
  1280. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, DomainSid );
  1281. AuditParameters.ParameterCount++;
  1282. }
  1283. if (ARGUMENT_PRESENT(AccountRid)) {
  1284. //
  1285. // Add a member SID string to the audit message
  1286. // Domain Sid + account Rid = final sid
  1287. //
  1288. SubAuthorityCount = *RtlSubAuthorityCountSid( DomainSid );
  1289. if ( (LengthRequired = RtlLengthRequiredSid( SubAuthorityCount + 1 )) > 256 ) {
  1290. NewAccountSid = LsapAllocateLsaHeap( LengthRequired );
  1291. if ( NewAccountSid == NULL ) {
  1292. Status = STATUS_NO_MEMORY;
  1293. goto Cleanup;
  1294. }
  1295. SidPointer = NewAccountSid;
  1296. } else {
  1297. SidPointer = (PSID)AccountSidBuffer;
  1298. }
  1299. Status = RtlCopySid (
  1300. LengthRequired,
  1301. SidPointer,
  1302. DomainSid
  1303. );
  1304. ASSERT( NT_SUCCESS( Status ));
  1305. *(RtlSubAuthoritySid( SidPointer, SubAuthorityCount )) = *AccountRid;
  1306. *RtlSubAuthorityCountSid( SidPointer ) = SubAuthorityCount + 1;
  1307. LsapSetParmTypeSid( AuditParameters, AuditParameters.ParameterCount, SidPointer );
  1308. AuditParameters.ParameterCount++;
  1309. }
  1310. //
  1311. // Now add the caller information
  1312. //
  1313. // Caller name
  1314. // Caller domain
  1315. // Caller logon ID
  1316. //
  1317. LsapSetParmTypeLogonId( AuditParameters, AuditParameters.ParameterCount, LogonId );
  1318. AuditParameters.ParameterCount++;
  1319. //
  1320. // Add any privileges
  1321. //
  1322. if (ARGUMENT_PRESENT(Privileges)) {
  1323. LsapSetParmTypePrivileges( AuditParameters, AuditParameters.ParameterCount, Privileges );
  1324. }
  1325. AuditParameters.ParameterCount++;
  1326. //
  1327. // Take care of the extended info.
  1328. //
  1329. switch (AuditId)
  1330. {
  1331. case SE_AUDITID_ADD_SID_HISTORY:
  1332. if (ExtendedInfo)
  1333. {
  1334. LsapSetParmTypeStringList(
  1335. AuditParameters,
  1336. AuditParameters.ParameterCount,
  1337. (PLSA_ADT_STRING_LIST)ExtendedInfo);
  1338. }
  1339. AuditParameters.ParameterCount++;
  1340. break;
  1341. case SE_AUDITID_DOMAIN_POLICY_CHANGE:
  1342. LsapAdtAppendDomainAttrValues(
  1343. &AuditParameters,
  1344. (PLSAP_AUDIT_DOMAIN_ATTR_VALUES)ExtendedInfo);
  1345. break;
  1346. case SE_AUDITID_COMPUTER_CREATED:
  1347. case SE_AUDITID_COMPUTER_CHANGE:
  1348. LsapAdtAppendUserAttrValues(
  1349. &AuditParameters,
  1350. (PLSAP_AUDIT_USER_ATTR_VALUES)ExtendedInfo,
  1351. TRUE);
  1352. break;
  1353. case SE_AUDITID_USER_CREATED:
  1354. case SE_AUDITID_USER_CHANGE:
  1355. LsapAdtAppendUserAttrValues(
  1356. &AuditParameters,
  1357. (PLSAP_AUDIT_USER_ATTR_VALUES)ExtendedInfo,
  1358. FALSE);
  1359. break;
  1360. case SE_AUDITID_LOCAL_GROUP_CREATED:
  1361. case SE_AUDITID_LOCAL_GROUP_CHANGE:
  1362. case SE_AUDITID_GLOBAL_GROUP_CREATED:
  1363. case SE_AUDITID_GLOBAL_GROUP_CHANGE:
  1364. case SE_AUDITID_SECURITY_ENABLED_UNIVERSAL_GROUP_CREATED:
  1365. case SE_AUDITID_SECURITY_ENABLED_UNIVERSAL_GROUP_CHANGE:
  1366. case SE_AUDITID_SECURITY_DISABLED_LOCAL_GROUP_CREATED:
  1367. case SE_AUDITID_SECURITY_DISABLED_LOCAL_GROUP_CHANGE:
  1368. case SE_AUDITID_SECURITY_DISABLED_GLOBAL_GROUP_CREATED:
  1369. case SE_AUDITID_SECURITY_DISABLED_GLOBAL_GROUP_CHANGE:
  1370. case SE_AUDITID_SECURITY_DISABLED_UNIVERSAL_GROUP_CREATED:
  1371. case SE_AUDITID_SECURITY_DISABLED_UNIVERSAL_GROUP_CHANGE:
  1372. case SE_AUDITID_APP_BASIC_GROUP_CREATED:
  1373. case SE_AUDITID_APP_BASIC_GROUP_CHANGE:
  1374. case SE_AUDITID_APP_QUERY_GROUP_CREATED:
  1375. case SE_AUDITID_APP_QUERY_GROUP_CHANGE:
  1376. LsapAdtAppendGroupAttrValues(
  1377. &AuditParameters,
  1378. (PLSAP_AUDIT_GROUP_ATTR_VALUES)ExtendedInfo);
  1379. break;
  1380. case SE_AUDITID_PASSWORD_POLICY_API_CALLED:
  1381. {
  1382. PUNICODE_STRING *Information = ( PUNICODE_STRING *) ExtendedInfo;
  1383. ULONG i;
  1384. //
  1385. // Parameter count was moved in advance, move
  1386. // it to its original place.
  1387. //
  1388. AuditParameters.ParameterCount--;
  1389. //
  1390. // Add workstation ip and provided account name if present
  1391. //
  1392. for( i = 0; i < 2; ++i ) {
  1393. if( Information[i]->Length != 0 ) {
  1394. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, Information[i] );
  1395. } else {
  1396. AuditParameters.Parameters[AuditParameters.ParameterCount].Type = SeAdtParmTypeNone;
  1397. AuditParameters.Parameters[AuditParameters.ParameterCount].Length = 0;
  1398. AuditParameters.Parameters[AuditParameters.ParameterCount].Address = NULL;
  1399. }
  1400. AuditParameters.ParameterCount++;
  1401. }
  1402. //
  1403. // Add the status code
  1404. //
  1405. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, PassedStatus );
  1406. AuditParameters.ParameterCount++;
  1407. ASSERTMSG( "There must be 6 parameters! Not more, not less", AuditParameters.ParameterCount == 6 );
  1408. }
  1409. break;
  1410. case SE_AUDITID_DSRM_PASSWORD_SET:
  1411. {
  1412. PUNICODE_STRING String = ( PUNICODE_STRING ) ExtendedInfo;
  1413. //
  1414. // Parameter count was moved in advance, move
  1415. // it to its original place.
  1416. //
  1417. AuditParameters.ParameterCount--;
  1418. if( String->Length != 0 ) {
  1419. LsapSetParmTypeString( AuditParameters, AuditParameters.ParameterCount, String );
  1420. } else {
  1421. AuditParameters.Parameters[AuditParameters.ParameterCount].Type = SeAdtParmTypeNone;
  1422. AuditParameters.Parameters[AuditParameters.ParameterCount].Length = 0;
  1423. AuditParameters.Parameters[AuditParameters.ParameterCount].Address = NULL;
  1424. }
  1425. AuditParameters.ParameterCount++;
  1426. //
  1427. // Add the status code
  1428. //
  1429. LsapSetParmTypeHexUlong( AuditParameters, AuditParameters.ParameterCount, PassedStatus );
  1430. AuditParameters.ParameterCount++;
  1431. }
  1432. break;
  1433. }
  1434. //
  1435. // Now write out the audit record to the audit log
  1436. //
  1437. ( VOID ) LsapAdtWriteLog( &AuditParameters );
  1438. //
  1439. // And clean up any allocated memory
  1440. //
  1441. Status = STATUS_SUCCESS;
  1442. Cleanup:
  1443. if ( !NT_SUCCESS(Status) ) {
  1444. LsapAuditFailed(Status);
  1445. }
  1446. if ( NewMemberSid != NULL ) {
  1447. LsapFreeLsaHeap( NewMemberSid );
  1448. }
  1449. if ( NewAccountSid != NULL ) {
  1450. LsapFreeLsaHeap( NewAccountSid );
  1451. }
  1452. if ( TokenUserInformation != NULL ) {
  1453. LsapFreeLsaHeap( TokenUserInformation );
  1454. }
  1455. return Status;
  1456. UNREFERENCED_PARAMETER(ExtendedInfo);
  1457. }
  1458. NTSTATUS
  1459. LsaIAuditPasswordAccessEvent(
  1460. IN USHORT EventType,
  1461. IN PCWSTR pszTargetUserName,
  1462. IN PCWSTR pszTargetUserDomain
  1463. )
  1464. /*++
  1465. Routine Description:
  1466. Generate SE_AUDITID_PASSWORD_HASH_ACCESS event. This is generated when
  1467. user password hash is retrieved by the ADMT password filter DLL.
  1468. This typically happens during ADMT password migration.
  1469. Arguments:
  1470. EventType - EVENTLOG_AUDIT_SUCCESS or EVENTLOG_AUDIT_FAILURE
  1471. pszTargetUserName - name of user whose password is being retrieved
  1472. pszTargetUserDomain - domain of user whose password is being retrieved
  1473. Return Value:
  1474. NTSTATUS - Standard NT Result Code
  1475. Notes:
  1476. --*/
  1477. {
  1478. NTSTATUS Status = STATUS_SUCCESS;
  1479. LUID ClientAuthenticationId;
  1480. PTOKEN_USER TokenUserInformation=NULL;
  1481. SE_ADT_PARAMETER_ARRAY AuditParameters = { 0 };
  1482. UNICODE_STRING TargetUser;
  1483. UNICODE_STRING TargetDomain;
  1484. BOOLEAN bAudit;
  1485. if ( !((EventType == EVENTLOG_AUDIT_SUCCESS) ||
  1486. (EventType == EVENTLOG_AUDIT_FAILURE)) ||
  1487. !pszTargetUserName || !pszTargetUserDomain ||
  1488. !*pszTargetUserName || !*pszTargetUserDomain )
  1489. {
  1490. Status = STATUS_INVALID_PARAMETER;
  1491. goto Cleanup;
  1492. }
  1493. //
  1494. // get caller info from the thread token
  1495. //
  1496. Status = LsapQueryClientInfo( &TokenUserInformation, &ClientAuthenticationId );
  1497. if ( !NT_SUCCESS( Status ))
  1498. {
  1499. goto Cleanup;
  1500. }
  1501. //
  1502. // if auditing is not enabled, return asap
  1503. //
  1504. Status = LsapAdtAuditingEnabledByLogonId(
  1505. AuditCategoryAccountManagement,
  1506. &ClientAuthenticationId,
  1507. EventType,
  1508. &bAudit
  1509. );
  1510. if (!NT_SUCCESS(Status) || !bAudit)
  1511. {
  1512. goto Cleanup;
  1513. }
  1514. RtlInitUnicodeString( &TargetUser, pszTargetUserName );
  1515. RtlInitUnicodeString( &TargetDomain, pszTargetUserDomain );
  1516. Status =
  1517. LsapAdtInitParametersArray(
  1518. &AuditParameters,
  1519. SE_CATEGID_ACCOUNT_MANAGEMENT,
  1520. SE_AUDITID_PASSWORD_HASH_ACCESS,
  1521. EventType,
  1522. 5, // there are 5 params to init
  1523. //
  1524. // User Sid
  1525. //
  1526. SeAdtParmTypeSid, TokenUserInformation->User.Sid,
  1527. //
  1528. // Subsystem name
  1529. //
  1530. SeAdtParmTypeString, &LsapSubsystemName,
  1531. //
  1532. // target user name
  1533. //
  1534. SeAdtParmTypeString, &TargetUser,
  1535. //
  1536. // target user domain name
  1537. //
  1538. SeAdtParmTypeString, &TargetDomain,
  1539. //
  1540. // client auth-id
  1541. //
  1542. SeAdtParmTypeLogonId, ClientAuthenticationId
  1543. );
  1544. if (!NT_SUCCESS(Status))
  1545. {
  1546. goto Cleanup;
  1547. }
  1548. Status = LsapAdtWriteLog( &AuditParameters );
  1549. Cleanup:
  1550. if (TokenUserInformation != NULL)
  1551. {
  1552. LsapFreeLsaHeap( TokenUserInformation );
  1553. }
  1554. if (!NT_SUCCESS(Status))
  1555. {
  1556. LsapAuditFailed( Status );
  1557. }
  1558. return Status;
  1559. }
  1560. VOID
  1561. LsaIAuditFailed(
  1562. NTSTATUS AuditStatus
  1563. )
  1564. /*++
  1565. Routine Description:
  1566. Components must call this function if they encounter any problem
  1567. that prevent them from generating any audit.
  1568. Arguments:
  1569. AuditStatus : failure code
  1570. Return Value:
  1571. none.
  1572. --*/
  1573. {
  1574. //
  1575. // make sure that we are not called for success case
  1576. //
  1577. ASSERT(!NT_SUCCESS(AuditStatus));
  1578. LsapAuditFailed( AuditStatus );
  1579. }
  1580. VOID
  1581. LsapAdtAppendDomainAttrValues(
  1582. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  1583. IN PLSAP_AUDIT_DOMAIN_ATTR_VALUES pAttributes OPTIONAL
  1584. )
  1585. /*++
  1586. Routine Description:
  1587. Helper function to insert the domain attributes
  1588. into the audit parameter array.
  1589. Arguments:
  1590. pParameters : audit parameter array
  1591. pAttributes : pointer to structure containing the
  1592. attributes to insert
  1593. Return Value:
  1594. none.
  1595. --*/
  1596. {
  1597. ULONG Index;
  1598. PLSAP_SAM_AUDIT_ATTR_DELTA_TYPE pDelta;
  1599. DsysAssertMsg(
  1600. pParameters->ParameterCount + LSAP_DOMAIN_ATTR_COUNT <= SE_MAX_AUDIT_PARAMETERS,
  1601. "LsapAdtAppendDomainAttrValues: Insuffient audit param slots");
  1602. if (pAttributes == 0)
  1603. {
  1604. pParameters->ParameterCount += LSAP_DOMAIN_ATTR_COUNT;
  1605. return;
  1606. }
  1607. //
  1608. // Initialize our 'loop' vars.
  1609. //
  1610. Index = pParameters->ParameterCount;
  1611. pDelta = pAttributes->AttrDeltaType;
  1612. //
  1613. // Min Password Age
  1614. //
  1615. if (pAttributes->MinPasswordAge &&
  1616. *pDelta == LsapAuditSamAttrNewValue &&
  1617. !(pAttributes->MinPasswordAge->LowPart == 0 &&
  1618. pAttributes->MinPasswordAge->HighPart == MINLONG))
  1619. {
  1620. LsapSetParmTypeDuration(
  1621. *pParameters,
  1622. Index,
  1623. *pAttributes->MinPasswordAge);
  1624. }
  1625. else if (*pDelta == LsapAuditSamAttrNoValue)
  1626. {
  1627. LsapSetParmTypeMessage(
  1628. *pParameters,
  1629. Index,
  1630. SE_ADT_VALUE_NOT_SET);
  1631. }
  1632. pDelta++;
  1633. Index++;
  1634. //
  1635. // Max Password Age
  1636. //
  1637. if (pAttributes->MaxPasswordAge &&
  1638. *pDelta == LsapAuditSamAttrNewValue &&
  1639. !(pAttributes->MaxPasswordAge->LowPart == 0 &&
  1640. pAttributes->MaxPasswordAge->HighPart == MINLONG))
  1641. {
  1642. LsapSetParmTypeDuration(
  1643. *pParameters,
  1644. Index,
  1645. *pAttributes->MaxPasswordAge);
  1646. }
  1647. else if (*pDelta == LsapAuditSamAttrNoValue)
  1648. {
  1649. LsapSetParmTypeMessage(
  1650. *pParameters,
  1651. Index,
  1652. SE_ADT_VALUE_NOT_SET);
  1653. }
  1654. pDelta++;
  1655. Index++;
  1656. //
  1657. // Force Logoff
  1658. //
  1659. if (pAttributes->ForceLogoff &&
  1660. *pDelta == LsapAuditSamAttrNewValue &&
  1661. !(pAttributes->ForceLogoff->LowPart == 0 &&
  1662. pAttributes->ForceLogoff->HighPart == MINLONG))
  1663. {
  1664. LsapSetParmTypeDuration(
  1665. *pParameters,
  1666. Index,
  1667. *pAttributes->ForceLogoff);
  1668. }
  1669. else if (*pDelta == LsapAuditSamAttrNoValue)
  1670. {
  1671. LsapSetParmTypeMessage(
  1672. *pParameters,
  1673. Index,
  1674. SE_ADT_VALUE_NOT_SET);
  1675. }
  1676. pDelta++;
  1677. Index++;
  1678. //
  1679. // Lockout Threshold
  1680. //
  1681. if (pAttributes->LockoutThreshold &&
  1682. *pDelta == LsapAuditSamAttrNewValue)
  1683. {
  1684. LsapSetParmTypeUlong(
  1685. *pParameters,
  1686. Index,
  1687. (ULONG)(*pAttributes->LockoutThreshold));
  1688. }
  1689. else if (*pDelta == LsapAuditSamAttrNoValue)
  1690. {
  1691. LsapSetParmTypeMessage(
  1692. *pParameters,
  1693. Index,
  1694. SE_ADT_VALUE_NOT_SET);
  1695. }
  1696. pDelta++;
  1697. Index++;
  1698. //
  1699. // Lockout Observation Window
  1700. //
  1701. if (pAttributes->LockoutObservationWindow &&
  1702. *pDelta == LsapAuditSamAttrNewValue &&
  1703. !(pAttributes->LockoutObservationWindow->LowPart == 0 &&
  1704. pAttributes->LockoutObservationWindow->HighPart == MINLONG))
  1705. {
  1706. LsapSetParmTypeDuration(
  1707. *pParameters,
  1708. Index,
  1709. *pAttributes->LockoutObservationWindow);
  1710. }
  1711. else if (*pDelta == LsapAuditSamAttrNoValue)
  1712. {
  1713. LsapSetParmTypeMessage(
  1714. *pParameters,
  1715. Index,
  1716. SE_ADT_VALUE_NOT_SET);
  1717. }
  1718. pDelta++;
  1719. Index++;
  1720. //
  1721. // Lockout Duration
  1722. //
  1723. if (pAttributes->LockoutDuration &&
  1724. *pDelta == LsapAuditSamAttrNewValue &&
  1725. !(pAttributes->LockoutDuration->LowPart == 0 &&
  1726. pAttributes->LockoutDuration->HighPart == MINLONG))
  1727. {
  1728. LsapSetParmTypeDuration(
  1729. *pParameters,
  1730. Index,
  1731. *pAttributes->LockoutDuration);
  1732. }
  1733. else if (*pDelta == LsapAuditSamAttrNoValue)
  1734. {
  1735. LsapSetParmTypeMessage(
  1736. *pParameters,
  1737. Index,
  1738. SE_ADT_VALUE_NOT_SET);
  1739. }
  1740. pDelta++;
  1741. Index++;
  1742. //
  1743. // Password Properties
  1744. //
  1745. if (pAttributes->PasswordProperties &&
  1746. *pDelta == LsapAuditSamAttrNewValue)
  1747. {
  1748. LsapSetParmTypeUlong(
  1749. *pParameters,
  1750. Index,
  1751. *pAttributes->PasswordProperties);
  1752. }
  1753. else if (*pDelta == LsapAuditSamAttrNoValue)
  1754. {
  1755. LsapSetParmTypeMessage(
  1756. *pParameters,
  1757. Index,
  1758. SE_ADT_VALUE_NOT_SET);
  1759. }
  1760. pDelta++;
  1761. Index++;
  1762. //
  1763. // Min Password Length
  1764. //
  1765. if (pAttributes->MinPasswordLength &&
  1766. *pDelta == LsapAuditSamAttrNewValue)
  1767. {
  1768. LsapSetParmTypeUlong(
  1769. *pParameters,
  1770. Index,
  1771. (ULONG)(*pAttributes->MinPasswordLength));
  1772. }
  1773. else if (*pDelta == LsapAuditSamAttrNoValue)
  1774. {
  1775. LsapSetParmTypeMessage(
  1776. *pParameters,
  1777. Index,
  1778. SE_ADT_VALUE_NOT_SET);
  1779. }
  1780. pDelta++;
  1781. Index++;
  1782. //
  1783. // Password History Length
  1784. //
  1785. if (pAttributes->PasswordHistoryLength &&
  1786. *pDelta == LsapAuditSamAttrNewValue)
  1787. {
  1788. LsapSetParmTypeUlong(
  1789. *pParameters,
  1790. Index,
  1791. (ULONG)(*pAttributes->PasswordHistoryLength));
  1792. }
  1793. else if (*pDelta == LsapAuditSamAttrNoValue)
  1794. {
  1795. LsapSetParmTypeMessage(
  1796. *pParameters,
  1797. Index,
  1798. SE_ADT_VALUE_NOT_SET);
  1799. }
  1800. pDelta++;
  1801. Index++;
  1802. //
  1803. // Machine Account Quota
  1804. //
  1805. if (pAttributes->MachineAccountQuota &&
  1806. *pDelta == LsapAuditSamAttrNewValue)
  1807. {
  1808. LsapSetParmTypeUlong(
  1809. *pParameters,
  1810. Index,
  1811. *pAttributes->MachineAccountQuota);
  1812. }
  1813. else if (*pDelta == LsapAuditSamAttrNoValue)
  1814. {
  1815. LsapSetParmTypeMessage(
  1816. *pParameters,
  1817. Index,
  1818. SE_ADT_VALUE_NOT_SET);
  1819. }
  1820. pDelta++;
  1821. Index++;
  1822. //
  1823. // Mixed Domain Mode
  1824. //
  1825. if (pAttributes->MixedDomainMode &&
  1826. *pDelta == LsapAuditSamAttrNewValue)
  1827. {
  1828. LsapSetParmTypeUlong(
  1829. *pParameters,
  1830. Index,
  1831. *pAttributes->MixedDomainMode);
  1832. }
  1833. else if (*pDelta == LsapAuditSamAttrNoValue)
  1834. {
  1835. LsapSetParmTypeMessage(
  1836. *pParameters,
  1837. Index,
  1838. SE_ADT_VALUE_NOT_SET);
  1839. }
  1840. pDelta++;
  1841. Index++;
  1842. //
  1843. // Domain Behavior Version
  1844. //
  1845. if (pAttributes->DomainBehaviorVersion &&
  1846. *pDelta == LsapAuditSamAttrNewValue)
  1847. {
  1848. LsapSetParmTypeUlong(
  1849. *pParameters,
  1850. Index,
  1851. *pAttributes->DomainBehaviorVersion);
  1852. }
  1853. else if (*pDelta == LsapAuditSamAttrNoValue)
  1854. {
  1855. LsapSetParmTypeMessage(
  1856. *pParameters,
  1857. Index,
  1858. SE_ADT_VALUE_NOT_SET);
  1859. }
  1860. pDelta++;
  1861. Index++;
  1862. //
  1863. // Oem Information
  1864. //
  1865. if (pAttributes->OemInformation &&
  1866. *pDelta == LsapAuditSamAttrNewValue)
  1867. {
  1868. LsapSetParmTypeString(
  1869. *pParameters,
  1870. Index,
  1871. pAttributes->OemInformation);
  1872. }
  1873. else if (*pDelta == LsapAuditSamAttrNoValue)
  1874. {
  1875. LsapSetParmTypeMessage(
  1876. *pParameters,
  1877. Index,
  1878. SE_ADT_VALUE_NOT_SET);
  1879. }
  1880. pDelta++;
  1881. Index++;
  1882. //
  1883. // Verify we added the right number of params and fixup the param count.
  1884. //
  1885. DsysAssertMsg(
  1886. Index - pParameters->ParameterCount == LSAP_DOMAIN_ATTR_COUNT,
  1887. "LsapAdtAppendDomainAttrValues: Wrong param count");
  1888. pParameters->ParameterCount = Index;
  1889. }
  1890. VOID
  1891. LsapAdtAppendUserAttrValues(
  1892. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  1893. IN PLSAP_AUDIT_USER_ATTR_VALUES pAttributes OPTIONAL,
  1894. IN BOOL MachineAudit
  1895. )
  1896. /*++
  1897. Routine Description:
  1898. Helper function to insert the user attributes
  1899. into the audit parameter array. We are only going
  1900. to insert values that have changed.
  1901. Arguments:
  1902. pParameters : audit parameter array
  1903. pAttributes : pointer to structure containing the
  1904. attributes to insert
  1905. Return Value:
  1906. none.
  1907. --*/
  1908. {
  1909. ULONG Index;
  1910. ULONG AttrCount = LSAP_USER_ATTR_COUNT;
  1911. PLSAP_SAM_AUDIT_ATTR_DELTA_TYPE pDelta;
  1912. LARGE_INTEGER FileTime;
  1913. if (!MachineAudit)
  1914. {
  1915. //
  1916. // User audits don't have the last two attributes.
  1917. //
  1918. AttrCount -= 2;
  1919. }
  1920. DsysAssertMsg(
  1921. pParameters->ParameterCount + AttrCount <= SE_MAX_AUDIT_PARAMETERS,
  1922. "LsapAdtAppendUserAttrValues: Insuffient audit param slots");
  1923. if (pAttributes == 0)
  1924. {
  1925. //
  1926. // The user account control param actually produces 3 strings,
  1927. // so we have to increase the parameter count by 2 to make up for it.
  1928. // We also have to check/assert whether we hit the max param limit.
  1929. //
  1930. AttrCount += 2;
  1931. pParameters->ParameterCount += AttrCount;
  1932. if (pParameters->ParameterCount > SE_MAX_AUDIT_PARAMETERS)
  1933. {
  1934. DsysAssertMsg(
  1935. pParameters->ParameterCount <= SE_MAX_AUDIT_PARAMETERS,
  1936. "LsapAdtAppendUserAttrValues: Insuffient audit param slots");
  1937. //
  1938. // It is better to have one or two %xx entries in the log
  1939. // than av'ing or dropping the audit...
  1940. //
  1941. pParameters->ParameterCount = SE_MAX_AUDIT_PARAMETERS;
  1942. }
  1943. return;
  1944. }
  1945. //
  1946. // Initialize our 'loop' vars.
  1947. //
  1948. Index = pParameters->ParameterCount;
  1949. pDelta = pAttributes->AttrDeltaType;
  1950. //
  1951. // Sam Account Name
  1952. //
  1953. if (pAttributes->SamAccountName &&
  1954. *pDelta == LsapAuditSamAttrNewValue)
  1955. {
  1956. LsapSetParmTypeString(
  1957. *pParameters,
  1958. Index,
  1959. pAttributes->SamAccountName);
  1960. }
  1961. else if (*pDelta == LsapAuditSamAttrNoValue)
  1962. {
  1963. LsapSetParmTypeMessage(
  1964. *pParameters,
  1965. Index,
  1966. SE_ADT_VALUE_NOT_SET);
  1967. }
  1968. pDelta++;
  1969. Index++;
  1970. //
  1971. // Display Name
  1972. //
  1973. if (pAttributes->DisplayName &&
  1974. *pDelta == LsapAuditSamAttrNewValue)
  1975. {
  1976. LsapSetParmTypeString(
  1977. *pParameters,
  1978. Index,
  1979. pAttributes->DisplayName);
  1980. }
  1981. else if (*pDelta == LsapAuditSamAttrNoValue)
  1982. {
  1983. LsapSetParmTypeMessage(
  1984. *pParameters,
  1985. Index,
  1986. SE_ADT_VALUE_NOT_SET);
  1987. }
  1988. pDelta++;
  1989. Index++;
  1990. //
  1991. // User Principal Name
  1992. //
  1993. if (pAttributes->UserPrincipalName &&
  1994. *pDelta == LsapAuditSamAttrNewValue)
  1995. {
  1996. LsapSetParmTypeString(
  1997. *pParameters,
  1998. Index,
  1999. pAttributes->UserPrincipalName);
  2000. }
  2001. else if (*pDelta == LsapAuditSamAttrNoValue)
  2002. {
  2003. LsapSetParmTypeMessage(
  2004. *pParameters,
  2005. Index,
  2006. SE_ADT_VALUE_NOT_SET);
  2007. }
  2008. pDelta++;
  2009. Index++;
  2010. //
  2011. // Home Directory
  2012. //
  2013. if (pAttributes->HomeDirectory &&
  2014. *pDelta == LsapAuditSamAttrNewValue)
  2015. {
  2016. LsapSetParmTypeString(
  2017. *pParameters,
  2018. Index,
  2019. pAttributes->HomeDirectory);
  2020. }
  2021. else if (*pDelta == LsapAuditSamAttrNoValue)
  2022. {
  2023. LsapSetParmTypeMessage(
  2024. *pParameters,
  2025. Index,
  2026. SE_ADT_VALUE_NOT_SET);
  2027. }
  2028. pDelta++;
  2029. Index++;
  2030. //
  2031. // Home Drive
  2032. //
  2033. if (pAttributes->HomeDrive &&
  2034. *pDelta == LsapAuditSamAttrNewValue)
  2035. {
  2036. LsapSetParmTypeString(
  2037. *pParameters,
  2038. Index,
  2039. pAttributes->HomeDrive);
  2040. }
  2041. else if (*pDelta == LsapAuditSamAttrNoValue)
  2042. {
  2043. LsapSetParmTypeMessage(
  2044. *pParameters,
  2045. Index,
  2046. SE_ADT_VALUE_NOT_SET);
  2047. }
  2048. pDelta++;
  2049. Index++;
  2050. //
  2051. // Script Path
  2052. //
  2053. if (pAttributes->ScriptPath &&
  2054. *pDelta == LsapAuditSamAttrNewValue)
  2055. {
  2056. LsapSetParmTypeString(
  2057. *pParameters,
  2058. Index,
  2059. pAttributes->ScriptPath);
  2060. }
  2061. else if (*pDelta == LsapAuditSamAttrNoValue)
  2062. {
  2063. LsapSetParmTypeMessage(
  2064. *pParameters,
  2065. Index,
  2066. SE_ADT_VALUE_NOT_SET);
  2067. }
  2068. pDelta++;
  2069. Index++;
  2070. //
  2071. // Profile Path
  2072. //
  2073. if (pAttributes->ProfilePath &&
  2074. *pDelta == LsapAuditSamAttrNewValue)
  2075. {
  2076. LsapSetParmTypeString(
  2077. *pParameters,
  2078. Index,
  2079. pAttributes->ProfilePath);
  2080. }
  2081. else if (*pDelta == LsapAuditSamAttrNoValue)
  2082. {
  2083. LsapSetParmTypeMessage(
  2084. *pParameters,
  2085. Index,
  2086. SE_ADT_VALUE_NOT_SET);
  2087. }
  2088. pDelta++;
  2089. Index++;
  2090. //
  2091. // User WorkStations
  2092. //
  2093. if (pAttributes->UserWorkStations &&
  2094. *pDelta == LsapAuditSamAttrNewValue)
  2095. {
  2096. LsapSetParmTypeString(
  2097. *pParameters,
  2098. Index,
  2099. pAttributes->UserWorkStations);
  2100. }
  2101. else if (*pDelta == LsapAuditSamAttrNoValue)
  2102. {
  2103. LsapSetParmTypeMessage(
  2104. *pParameters,
  2105. Index,
  2106. SE_ADT_VALUE_NOT_SET);
  2107. }
  2108. pDelta++;
  2109. Index++;
  2110. //
  2111. // Password Last Set
  2112. //
  2113. if (pAttributes->PasswordLastSet &&
  2114. *pDelta == LsapAuditSamAttrNewValue)
  2115. {
  2116. FileTime.LowPart = pAttributes->PasswordLastSet->dwLowDateTime;
  2117. FileTime.HighPart = pAttributes->PasswordLastSet->dwHighDateTime;
  2118. if ((FileTime.LowPart == MAXULONG && FileTime.HighPart == MAXLONG) || // SampWillNeverTime
  2119. (FileTime.LowPart == 0 && FileTime.HighPart == 0)) // SampHasNeverTime
  2120. {
  2121. LsapSetParmTypeMessage(
  2122. *pParameters,
  2123. Index,
  2124. SE_ADT_TIME_NEVER);
  2125. }
  2126. else
  2127. {
  2128. LsapSetParmTypeDateTime(
  2129. *pParameters,
  2130. Index,
  2131. FileTime);
  2132. }
  2133. }
  2134. else if (*pDelta == LsapAuditSamAttrNoValue)
  2135. {
  2136. LsapSetParmTypeMessage(
  2137. *pParameters,
  2138. Index,
  2139. SE_ADT_VALUE_NOT_SET);
  2140. }
  2141. else
  2142. {
  2143. FileTime.LowPart = 0;
  2144. FileTime.HighPart = 0;
  2145. LsapSetParmTypeDateTime(
  2146. *pParameters,
  2147. Index,
  2148. FileTime);
  2149. }
  2150. pDelta++;
  2151. Index++;
  2152. //
  2153. // Account Expires
  2154. //
  2155. if (pAttributes->AccountExpires &&
  2156. *pDelta == LsapAuditSamAttrNewValue)
  2157. {
  2158. FileTime.LowPart = pAttributes->AccountExpires->dwLowDateTime;
  2159. FileTime.HighPart = pAttributes->AccountExpires->dwHighDateTime;
  2160. if ((FileTime.LowPart == MAXULONG && FileTime.HighPart == MAXLONG) || // SampWillNeverTime
  2161. (FileTime.LowPart == 0 && FileTime.HighPart == 0)) // SampHasNeverTime
  2162. {
  2163. LsapSetParmTypeMessage(
  2164. *pParameters,
  2165. Index,
  2166. SE_ADT_TIME_NEVER);
  2167. }
  2168. else
  2169. {
  2170. LsapSetParmTypeDateTime(
  2171. *pParameters,
  2172. Index,
  2173. FileTime);
  2174. }
  2175. }
  2176. else if (*pDelta == LsapAuditSamAttrNoValue)
  2177. {
  2178. LsapSetParmTypeMessage(
  2179. *pParameters,
  2180. Index,
  2181. SE_ADT_VALUE_NOT_SET);
  2182. }
  2183. else
  2184. {
  2185. FileTime.LowPart = 0;
  2186. FileTime.HighPart = 0;
  2187. LsapSetParmTypeDateTime(
  2188. *pParameters,
  2189. Index,
  2190. FileTime);
  2191. }
  2192. pDelta++;
  2193. Index++;
  2194. //
  2195. // Primary Group Id
  2196. //
  2197. if (pAttributes->PrimaryGroupId &&
  2198. *pDelta == LsapAuditSamAttrNewValue)
  2199. {
  2200. LsapSetParmTypeUlong(
  2201. *pParameters,
  2202. Index,
  2203. *pAttributes->PrimaryGroupId);
  2204. }
  2205. else if (*pDelta == LsapAuditSamAttrNoValue)
  2206. {
  2207. LsapSetParmTypeMessage(
  2208. *pParameters,
  2209. Index,
  2210. SE_ADT_VALUE_NOT_SET);
  2211. }
  2212. pDelta++;
  2213. Index++;
  2214. //
  2215. // Allowed To Delegate To
  2216. //
  2217. if (pAttributes->AllowedToDelegateTo &&
  2218. *pDelta == LsapAuditSamAttrNewValue)
  2219. {
  2220. LsapSetParmTypeStringList(
  2221. *pParameters,
  2222. Index,
  2223. pAttributes->AllowedToDelegateTo);
  2224. }
  2225. else if (*pDelta == LsapAuditSamAttrNoValue)
  2226. {
  2227. LsapSetParmTypeMessage(
  2228. *pParameters,
  2229. Index,
  2230. SE_ADT_VALUE_NOT_SET);
  2231. }
  2232. pDelta++;
  2233. Index++;
  2234. //
  2235. // User Account Control
  2236. //
  2237. if (pAttributes->UserAccountControl &&
  2238. *pDelta == LsapAuditSamAttrNewValue)
  2239. {
  2240. LsapSetParmTypeUac(
  2241. *pParameters,
  2242. Index,
  2243. *pAttributes->PrevUserAccountControl,
  2244. *pAttributes->UserAccountControl);
  2245. }
  2246. else if (*pDelta == LsapAuditSamAttrNoValue)
  2247. {
  2248. LsapSetParmTypeMessage(
  2249. *pParameters,
  2250. Index,
  2251. SE_ADT_VALUE_NOT_SET);
  2252. }
  2253. else
  2254. {
  2255. LsapSetParmTypeNoUac(
  2256. *pParameters,
  2257. Index);
  2258. }
  2259. pDelta++;
  2260. Index++;
  2261. //
  2262. // User Parameters
  2263. // This value is special since it never gets displayed. Instead, we
  2264. // display only a string indicating that the value has changed.
  2265. //
  2266. if (*pDelta == LsapAuditSamAttrNewValue ||
  2267. *pDelta == LsapAuditSamAttrSecret)
  2268. {
  2269. LsapSetParmTypeMessage(
  2270. *pParameters,
  2271. Index,
  2272. SE_ADT_VALUE_NOT_DISPLAYED);
  2273. }
  2274. else if (*pDelta == LsapAuditSamAttrNoValue)
  2275. {
  2276. LsapSetParmTypeMessage(
  2277. *pParameters,
  2278. Index,
  2279. SE_ADT_VALUE_NOT_SET);
  2280. }
  2281. pDelta++;
  2282. Index++;
  2283. //
  2284. // Sid History
  2285. //
  2286. if (pAttributes->SidHistory &&
  2287. *pDelta == LsapAuditSamAttrNewValue)
  2288. {
  2289. LsapSetParmTypeSidList(
  2290. *pParameters,
  2291. Index,
  2292. pAttributes->SidHistory);
  2293. }
  2294. else if (*pDelta == LsapAuditSamAttrNoValue)
  2295. {
  2296. LsapSetParmTypeMessage(
  2297. *pParameters,
  2298. Index,
  2299. SE_ADT_VALUE_NOT_SET);
  2300. }
  2301. pDelta++;
  2302. Index++;
  2303. //
  2304. // Logon Hours (display not yet supported)
  2305. //
  2306. if (pAttributes->LogonHours &&
  2307. *pDelta == LsapAuditSamAttrNewValue)
  2308. {
  2309. LsapSetParmTypeMessage(
  2310. *pParameters,
  2311. Index,
  2312. SE_ADT_VALUE_NOT_DISPLAYED);
  2313. }
  2314. else if (*pDelta == LsapAuditSamAttrNoValue)
  2315. {
  2316. LsapSetParmTypeMessage(
  2317. *pParameters,
  2318. Index,
  2319. SE_ADT_VALUE_NOT_SET);
  2320. }
  2321. pDelta++;
  2322. Index++;
  2323. //
  2324. // DnsHostName and SCPs are available for computer audits only.
  2325. //
  2326. if (MachineAudit)
  2327. {
  2328. //
  2329. // Dns Host Name
  2330. //
  2331. if (pAttributes->DnsHostName &&
  2332. *pDelta == LsapAuditSamAttrNewValue)
  2333. {
  2334. LsapSetParmTypeString(
  2335. *pParameters,
  2336. Index,
  2337. pAttributes->DnsHostName);
  2338. }
  2339. else if (*pDelta == LsapAuditSamAttrNoValue)
  2340. {
  2341. LsapSetParmTypeMessage(
  2342. *pParameters,
  2343. Index,
  2344. SE_ADT_VALUE_NOT_SET);
  2345. }
  2346. pDelta++;
  2347. Index++;
  2348. //
  2349. // Service Principal Names
  2350. //
  2351. if (pAttributes->ServicePrincipalNames &&
  2352. *pDelta == LsapAuditSamAttrNewValue)
  2353. {
  2354. LsapSetParmTypeStringList(
  2355. *pParameters,
  2356. Index,
  2357. pAttributes->ServicePrincipalNames);
  2358. }
  2359. else if (*pDelta == LsapAuditSamAttrNoValue)
  2360. {
  2361. LsapSetParmTypeMessage(
  2362. *pParameters,
  2363. Index,
  2364. SE_ADT_VALUE_NOT_SET);
  2365. }
  2366. pDelta++;
  2367. Index++;
  2368. }
  2369. //
  2370. // Verify we added the right number of params and fixup the param count.
  2371. //
  2372. DsysAssertMsg(
  2373. Index - pParameters->ParameterCount == AttrCount,
  2374. "LsapAdtAppendGroupAttrValues: Wrong param count");
  2375. pParameters->ParameterCount = Index;
  2376. }
  2377. VOID
  2378. LsapAdtAppendGroupAttrValues(
  2379. IN OUT PSE_ADT_PARAMETER_ARRAY pParameters,
  2380. IN PLSAP_AUDIT_GROUP_ATTR_VALUES pAttributes OPTIONAL
  2381. )
  2382. /*++
  2383. Routine Description:
  2384. Helper function to insert the group attributes
  2385. into the audit parameter array.
  2386. Arguments:
  2387. pParameters : audit parameter array
  2388. pAttributes : pointer to structure containing the
  2389. attributes to insert
  2390. Return Value:
  2391. none.
  2392. --*/
  2393. {
  2394. ULONG Index;
  2395. PLSAP_SAM_AUDIT_ATTR_DELTA_TYPE pDelta;
  2396. DsysAssertMsg(
  2397. pParameters->ParameterCount + LSAP_GROUP_ATTR_COUNT <= SE_MAX_AUDIT_PARAMETERS,
  2398. "LsapAdtAppendGroupAttrValues: Insuffient audit param slots");
  2399. if (pAttributes == 0)
  2400. {
  2401. pParameters->ParameterCount += LSAP_GROUP_ATTR_COUNT;
  2402. return;
  2403. }
  2404. //
  2405. // Initialize our 'loop' vars.
  2406. //
  2407. Index = pParameters->ParameterCount;
  2408. pDelta = pAttributes->AttrDeltaType;
  2409. //
  2410. // Sam Account Name
  2411. //
  2412. if (pAttributes->SamAccountName &&
  2413. *pDelta == LsapAuditSamAttrNewValue)
  2414. {
  2415. LsapSetParmTypeString(
  2416. *pParameters,
  2417. Index,
  2418. pAttributes->SamAccountName);
  2419. }
  2420. else if (*pDelta == LsapAuditSamAttrNoValue)
  2421. {
  2422. LsapSetParmTypeMessage(
  2423. *pParameters,
  2424. Index,
  2425. SE_ADT_VALUE_NOT_SET);
  2426. }
  2427. pDelta++;
  2428. Index++;
  2429. //
  2430. // Sid History
  2431. //
  2432. if (pAttributes->SidHistory &&
  2433. *pDelta == LsapAuditSamAttrNewValue)
  2434. {
  2435. LsapSetParmTypeSidList(
  2436. *pParameters,
  2437. Index,
  2438. pAttributes->SidHistory);
  2439. }
  2440. else if (*pDelta == LsapAuditSamAttrNoValue)
  2441. {
  2442. LsapSetParmTypeMessage(
  2443. *pParameters,
  2444. Index,
  2445. SE_ADT_VALUE_NOT_SET);
  2446. }
  2447. pDelta++;
  2448. Index++;
  2449. //
  2450. // Verify we added the right number of params and fixup the param count.
  2451. //
  2452. DsysAssertMsg(
  2453. Index - pParameters->ParameterCount == LSAP_GROUP_ATTR_COUNT,
  2454. "LsapAdtAppendGroupAttrValues: Wrong param count");
  2455. pParameters->ParameterCount = Index;
  2456. }