home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / winbase / security / winnt / audit / audit.c next >
C/C++ Source or Header  |  1997-10-05  |  12KB  |  514 lines

  1. /*++
  2.  
  3. Copyright 1996 - 1997 Microsoft Corporation
  4.  
  5. Module Name:
  6.  
  7.     audit.c
  8.  
  9. Abstract:
  10.  
  11.     This module illustrates how to use the Windows NT LSA security API
  12.     to manage the audit status on the local machine or a remote machine.
  13.  
  14.     Querying the current audit status is illustrated, in addition to
  15.     changing the audit state of an audit event type.  Enabling and
  16.     disabling all auditing is also illustrated.
  17.  
  18.     When targetting a domain controller for an audit update operation,
  19.     be sure to target the primary domain controller for the domain.
  20.     The audit settings are replicated by the primary domain controller
  21.     to each backup domain controller as appropriate.  The NetGetDCName()
  22.     Lan Manager API call can be used to get the primary domain controller
  23.     computer name from a domain name.
  24.  
  25.     This sample will target the local machine if no command line argument is
  26.     specified, or the machine specified on argv[1], eg. audit.exe \\winbase
  27.  
  28.     The sample relies on the ntsecapi.h header file found in the Win32SDK
  29.     \mstools\security directory.
  30.  
  31. Author:
  32.  
  33.     Scott Field (sfield)    13-Apr-96
  34.  
  35. --*/
  36.  
  37. #include <windows.h>
  38. #include <stdio.h>
  39.  
  40. #include "ntsecapi.h" // \mstools\samples\win32\winnt\security\include\ntsecapi.h
  41.  
  42. #define RTN_OK 0
  43. #define RTN_USAGE 1
  44. #define RTN_ERROR 13
  45.  
  46. //
  47. // if you have the ddk, include ntstatus.h
  48. //
  49. #ifndef STATUS_SUCCESS
  50. #define STATUS_SUCCESS              ((NTSTATUS)0x00000000L)
  51. #define STATUS_INVALID_PARAMETER    ((NTSTATUS)0xC000000DL)
  52. #endif
  53.  
  54.  
  55. NTSTATUS
  56. DisplayAudit(
  57.     LSA_HANDLE PolicyHandle
  58.     );
  59.  
  60. void
  61. DisplayAuditEventOption(
  62.     DWORD EventTypeIndex,
  63.     POLICY_AUDIT_EVENT_OPTIONS EventOption
  64.     );
  65.  
  66. NTSTATUS
  67. SetAuditEvent(
  68.     LSA_HANDLE PolicyHandle,
  69.     POLICY_AUDIT_EVENT_TYPE EventType,
  70.     POLICY_AUDIT_EVENT_OPTIONS EventOption
  71.     );
  72.  
  73. NTSTATUS
  74. SetAuditMode(
  75.     LSA_HANDLE PolicyHandle,
  76.     BOOL bEnable
  77.     );
  78.  
  79. //
  80. // helper functions
  81. //
  82.  
  83. NTSTATUS
  84. OpenPolicy(
  85.     LPWSTR ServerName,
  86.     DWORD DesiredAccess,
  87.     PLSA_HANDLE PolicyHandle
  88.     );
  89.  
  90. void
  91. InitLsaString(
  92.     PLSA_UNICODE_STRING LsaString,
  93.     LPWSTR String
  94.     );
  95.  
  96. void
  97. DisplayNtStatus(
  98.     LPSTR szAPI,        // pointer to Ansi function name
  99.     NTSTATUS Status     // NTSTATUS error value
  100.     );
  101.  
  102. void
  103. DisplayWinError(
  104.     LPSTR szAPI,    // pointer to Ansi function name
  105.     DWORD dwError   // DWORD WinError
  106.     );
  107.  
  108. //
  109. // unicode entry point and argv
  110. //
  111. int
  112. __cdecl
  113. wmain(
  114.     int argc,
  115.     wchar_t *argv[]
  116.     )
  117. {
  118.     LPWSTR wComputerName;
  119.     LSA_HANDLE PolicyHandle;
  120.     NTSTATUS Status;
  121.  
  122.     //
  123.     // pickup machine name if appropriate
  124.     //
  125.     if(argc == 2)
  126.         wComputerName = argv[1];
  127.     else
  128.         wComputerName = NULL; // local machine
  129.  
  130.     //
  131.     // display current audit state
  132.     //
  133.  
  134.     Status = OpenPolicy(
  135.                 wComputerName,
  136.                 POLICY_VIEW_AUDIT_INFORMATION,
  137.                 &PolicyHandle
  138.                 );
  139.  
  140.     if(Status == STATUS_SUCCESS) {
  141.         //
  142.         // display current auditing status
  143.         //
  144.         Status = DisplayAudit(PolicyHandle);
  145.  
  146.         LsaClose(PolicyHandle);
  147.  
  148.         if(Status != STATUS_SUCCESS) {
  149.             DisplayNtStatus("DisplayAudit", Status);
  150.             return RTN_ERROR;
  151.         }
  152.     } else {
  153.         DisplayNtStatus("OpenPolicy", Status);
  154.         return RTN_ERROR;
  155.     }
  156.  
  157.     //
  158.     // enable success and failure audits of logon/logoff events
  159.     //
  160.  
  161.     Status = OpenPolicy(
  162.                 wComputerName,
  163.                 POLICY_VIEW_AUDIT_INFORMATION |
  164.                 POLICY_SET_AUDIT_REQUIREMENTS,
  165.                 &PolicyHandle
  166.                 );
  167.  
  168.     if(Status == STATUS_SUCCESS) {
  169.  
  170.         //
  171.         // enable success and failure auditing of logon/logoff
  172.         //
  173.         Status = SetAuditEvent(
  174.             PolicyHandle,
  175.             AuditCategoryLogon,
  176.             POLICY_AUDIT_EVENT_SUCCESS | POLICY_AUDIT_EVENT_FAILURE
  177.             );
  178.  
  179.         //
  180.         // enable audits
  181.         //
  182.         if( Status == STATUS_SUCCESS )
  183.             Status = SetAuditMode(PolicyHandle, TRUE);
  184.  
  185.         LsaClose(PolicyHandle);
  186.  
  187.         if(Status != STATUS_SUCCESS) {
  188.             DisplayNtStatus("SetAuditMode", Status);
  189.             return RTN_ERROR;
  190.         }
  191.     } else {
  192.         DisplayNtStatus("OpenPolicy", Status);
  193.         return RTN_ERROR;
  194.     }
  195.  
  196.     return RTN_OK;
  197. }
  198.  
  199.  
  200. NTSTATUS
  201. DisplayAudit(
  202.     LSA_HANDLE PolicyHandle
  203.     )
  204. {
  205.     PPOLICY_AUDIT_EVENTS_INFO AuditEvents;
  206.     NTSTATUS Status;
  207.     DWORD i; // index into EventAuditingOptions
  208.  
  209.     //
  210.     // obtain AuditEvents
  211.     //
  212.     Status = LsaQueryInformationPolicy(
  213.                 PolicyHandle,
  214.                 PolicyAuditEventsInformation,
  215.                 &AuditEvents
  216.                 );
  217.  
  218.     if(Status != STATUS_SUCCESS) return Status;
  219.  
  220.     //
  221.     // successfully obtained AuditEventsInformation.  Now display.
  222.     //
  223.     if(AuditEvents->AuditingMode) {
  224.         printf("Auditing Enabled\n");
  225.     } else {
  226.         printf("Auditing Disabled\n");
  227.     }
  228.  
  229.     for(i = 0 ; i < AuditEvents->MaximumAuditEventCount ; i++) {
  230.         DisplayAuditEventOption(i, AuditEvents->EventAuditingOptions[i]);
  231.     }
  232.  
  233.     //
  234.     // free allocated memory
  235.     //
  236.     LsaFreeMemory(AuditEvents);
  237.  
  238.     return Status;
  239. }
  240.  
  241. void
  242. DisplayAuditEventOption(
  243.     DWORD EventTypeIndex,
  244.     POLICY_AUDIT_EVENT_OPTIONS EventOption
  245.     )
  246. {
  247.     printf("AuditCategory");
  248.  
  249.     switch (EventTypeIndex) {
  250.         case AuditCategorySystem:
  251.         printf("System");
  252.         break;
  253.  
  254.         case AuditCategoryLogon:
  255.         printf("Logon");
  256.         break;
  257.  
  258.         case AuditCategoryObjectAccess:
  259.         printf("ObjectAccess");
  260.         break;
  261.  
  262.         case AuditCategoryPrivilegeUse:
  263.         printf("PrivilegeUse");
  264.         break;
  265.  
  266.         case AuditCategoryDetailedTracking:
  267.         printf("DetailedTracking");
  268.         break;
  269.  
  270.         case AuditCategoryPolicyChange:
  271.         printf("PolicyChange");
  272.         break;
  273.  
  274.         case AuditCategoryAccountManagement:
  275.         printf("AccountManagement");
  276.         break;
  277.  
  278.         default:
  279.         printf("Unknown");
  280.     }
  281.  
  282.     if(EventOption & POLICY_AUDIT_EVENT_SUCCESS)
  283.         printf(" AUDIT_EVENT_SUCCESS");
  284.  
  285.     if(EventOption & POLICY_AUDIT_EVENT_FAILURE)
  286.         printf(" AUDIT_EVENT_FAILURE");
  287.  
  288.     printf("\n");
  289. }
  290.  
  291. NTSTATUS
  292. SetAuditEvent(
  293.     LSA_HANDLE PolicyHandle,
  294.     POLICY_AUDIT_EVENT_TYPE EventType,
  295.     POLICY_AUDIT_EVENT_OPTIONS EventOption
  296.     )
  297. {
  298.     PPOLICY_AUDIT_EVENTS_INFO pae;
  299.     NTSTATUS Status;
  300.     DWORD i; // index into EventAuditingOptions
  301.  
  302.     //
  303.     // obtain AuditEvents
  304.     //
  305.     Status = LsaQueryInformationPolicy(
  306.                 PolicyHandle,
  307.                 PolicyAuditEventsInformation,
  308.                 &pae
  309.                 );
  310.  
  311.     if(Status != STATUS_SUCCESS) return Status;
  312.  
  313.     //
  314.     // insure we were passed a valid EventType and EventOption
  315.     //
  316.     if((ULONG)EventType > pae->MaximumAuditEventCount ||
  317.       (!EventOption & POLICY_AUDIT_EVENT_MASK) ) {
  318.         LsaFreeMemory(pae);
  319.         return STATUS_INVALID_PARAMETER;
  320.     }
  321.  
  322.     //
  323.     // set all auditevents to the unchanged status...
  324.     //
  325.     for(i = 0 ; i < pae->MaximumAuditEventCount ; i++) {
  326.         pae->EventAuditingOptions[i] = POLICY_AUDIT_EVENT_UNCHANGED;
  327.     }
  328.  
  329.     //
  330.     // ...and update only the specified EventType
  331.     //
  332.     pae->EventAuditingOptions[EventType] = EventOption;
  333.  
  334.     //
  335.     // set the new AuditEvents
  336.     //
  337.     Status = LsaSetInformationPolicy(
  338.                 PolicyHandle,
  339.                 PolicyAuditEventsInformation,
  340.                 pae
  341.                 );
  342.  
  343.     //
  344.     // free allocated memory
  345.     //
  346.     LsaFreeMemory(pae);
  347.  
  348.     return Status;
  349. }
  350.  
  351. NTSTATUS
  352. SetAuditMode(
  353.     LSA_HANDLE PolicyHandle,
  354.     BOOL bEnable
  355.     )
  356. {
  357.     PPOLICY_AUDIT_EVENTS_INFO AuditEvents;
  358.     NTSTATUS Status;
  359.     DWORD i;
  360.  
  361.     //
  362.     // obtain current AuditEvents
  363.     //
  364.     Status = LsaQueryInformationPolicy(
  365.                 PolicyHandle,
  366.                 PolicyAuditEventsInformation,
  367.                 &AuditEvents
  368.                 );
  369.  
  370.     if(Status != STATUS_SUCCESS) return Status;
  371.  
  372.     //
  373.     // update the relevant member
  374.     //
  375.     AuditEvents->AuditingMode = bEnable;
  376.  
  377.     //
  378.     // set all auditevents to the unchanged status...
  379.     //
  380.     for(i = 0 ; i < AuditEvents->MaximumAuditEventCount ; i++) {
  381.         AuditEvents->EventAuditingOptions[i] = POLICY_AUDIT_EVENT_UNCHANGED;
  382.     }
  383.  
  384.     //
  385.     // set the new auditing mode (enabled or disabled)
  386.     //
  387.     Status = LsaSetInformationPolicy(
  388.                 PolicyHandle,
  389.                 PolicyAuditEventsInformation,
  390.                 AuditEvents
  391.                 );
  392.  
  393.     LsaFreeMemory(AuditEvents);
  394.  
  395.     return Status;
  396. }
  397.  
  398. void
  399. InitLsaString(
  400.     PLSA_UNICODE_STRING LsaString,
  401.     LPWSTR String
  402.     )
  403. {
  404.     DWORD StringLength;
  405.  
  406.     if(String == NULL) {
  407.         LsaString->Buffer = NULL;
  408.         LsaString->Length = 0;
  409.         LsaString->MaximumLength = 0;
  410.  
  411.         return;
  412.     }
  413.  
  414.     StringLength = lstrlenW(String);
  415.     LsaString->Buffer = String;
  416.     LsaString->Length = (USHORT) StringLength * sizeof(WCHAR);
  417.     LsaString->MaximumLength = (USHORT) (StringLength + 1) *
  418.         sizeof(WCHAR);
  419. }
  420.  
  421. NTSTATUS
  422. OpenPolicy(
  423.     LPWSTR ServerName,
  424.     DWORD DesiredAccess,
  425.     PLSA_HANDLE PolicyHandle
  426.     )
  427. {
  428.     PLSA_UNICODE_STRING Server;
  429.     LSA_OBJECT_ATTRIBUTES ObjectAttributes;
  430.     LSA_UNICODE_STRING ServerString;
  431.  
  432.     //
  433.     // Always initialize the object attributes to all zeroes
  434.     //
  435.     ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
  436.  
  437.     if(ServerName != NULL) {
  438.         //
  439.         // Make a LSA_UNICODE_STRING out of the LPWSTR passed in
  440.         //
  441.         InitLsaString(&ServerString, ServerName);
  442.         Server = &ServerString;
  443.     } else {
  444.         Server = NULL; // default to local machine
  445.     }
  446.  
  447.     //
  448.     // Attempt to open the policy and return NTSTATUS
  449.     //
  450.     return LsaOpenPolicy(
  451.                 Server,
  452.                 &ObjectAttributes,
  453.                 DesiredAccess,
  454.                 PolicyHandle
  455.                 );
  456. }
  457.  
  458. void
  459. DisplayNtStatus(
  460.     LPSTR szAPI,
  461.     NTSTATUS Status
  462.     )
  463. {
  464.     //
  465.     // convert the NTSTATUS to Winerror and DisplayWinError()
  466.     //
  467.     DisplayWinError(szAPI, LsaNtStatusToWinError(Status) );
  468. }
  469.  
  470. void
  471. DisplayWinError(
  472.     LPSTR szAPI,    // pointer to Ansi function name
  473.     DWORD dwError   // DWORD WinError
  474.     )
  475. {
  476.     LPSTR MessageBuffer;
  477.     DWORD dwBufferLength;
  478.  
  479.     //
  480.     // TODO get this fprintf out of here!
  481.     //
  482.     fprintf(stderr,"%s error!\n", szAPI);
  483.  
  484.     if(dwBufferLength=FormatMessageA(
  485.             FORMAT_MESSAGE_ALLOCATE_BUFFER |
  486.             FORMAT_MESSAGE_FROM_SYSTEM,
  487.             NULL,
  488.             dwError,
  489.             MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
  490.             (LPSTR) &MessageBuffer,
  491.             0,
  492.             NULL
  493.             ))
  494.     {
  495.         DWORD dwBytesWritten; // unused
  496.  
  497.         //
  498.         // Output message string on stderr
  499.         //
  500.         WriteFile(
  501.                 GetStdHandle(STD_ERROR_HANDLE),
  502.                 MessageBuffer,
  503.                 dwBufferLength,
  504.                 &dwBytesWritten,
  505.                 NULL
  506.                 );
  507.  
  508.         //
  509.         // free the buffer allocated by the system
  510.         //
  511.         LocalFree(MessageBuffer);
  512.     }
  513. }
  514.