in managementnode/lib/VCL/Module/OS/Windows/Version_6.pm [2408:2565]
sub get_logon_events {
my $self = shift;
if (ref($self) !~ /VCL::Module/i) {
notify($ERRORS{'CRITICAL'}, 0, "subroutine was called as a function, it must be called as a class method");
return;
}
my ($past_minutes) = @_;
my $offset_minutes = $self->get_timezone_offset_minutes() || 0;
my $logon_type_names = {
0 => 'System',
2 => 'Interactive',
3 => 'Network',
4 => 'Batch',
5 => 'Service',
6 => 'Proxy',
7 => 'Unlock',
8 => 'NetworkCleartext',
9 => 'NewCredentials',
10 => 'RemoteInteractive',
11 => 'CachedInteractive',
12 => 'CachedRemoteInteractive',
13 => 'CachedUnlock',
};
my $security_event_log = 'Security';
my $lsm_event_log = 'Microsoft-Windows-TerminalServices-LocalSessionManager/Operational';
my $event_ids = {
'Microsoft-Windows-Security-Auditing' => {
4624 => 'An account was successfully logged on',
},
'Microsoft-Windows-TerminalServices-LocalSessionManager' => {
21 => 'Remote Desktop Services: Session logon succeeded',
25 => 'Remote Desktop Services: Session reconnection succeeded',
1101 => 'Remote Desktop Services: Session logon succeeded',
1105 => 'Remote Desktop Services: Session reconnection succeeded',
},
};
my $security_event_id_string = "EventID=" . join(' or EventID=', keys(%{$event_ids->{'Microsoft-Windows-Security-Auditing'}}));
my $lsm_event_id_string = "EventID=" . join(' or EventID=', keys(%{$event_ids->{'Microsoft-Windows-TerminalServices-LocalSessionManager'}}));
my $time_created_string = '';
if ($past_minutes) {
my $milliseconds = ($past_minutes * 60 * 1000);
$time_created_string = "and TimeCreated[timediff(\@SystemTime) <= $milliseconds]";
}
my $security_query = <<EOF;
*[
System[
Provider[\@Name="Microsoft-Windows-Security-Auditing"]
and Task=12544
and ($security_event_id_string)
$time_created_string
]
and
EventData[
Data[\@Name="TargetUserName"]!="ANONYMOUS LOGON"
and Data[\@Name="TargetUserName"]!="SYSTEM"
and Data[\@Name="IpAddress"]!="127.0.0.1"
and Data[\@Name="LogonType"]!="5"
]
]
EOF
my $lsm_query = <<EOF;
*[
System[
Provider[\@Name="Microsoft-Windows-TerminalServices-LocalSessionManager"]
and ($lsm_event_id_string)
$time_created_string
]
]
EOF
my (@security_events, @lsm_events);
@security_events = $self->query_event_log($security_event_log, $security_query);
@lsm_events = $self->query_event_log($lsm_event_log, $lsm_query);
my $logon_event_hash = {};
for my $event (@security_events, @lsm_events) {
my $system = $event->{System} || next;
my $provider_name = $system->{Provider}{Name};
my $system_time = $system->{TimeCreated}{SystemTime};
my $event_record_id = $system->{EventRecordID};
my $event_id = $system->{EventID};
my $process_pid = $system->{Execution}{ProcessID};
my $logon_event = {
event_record_id => $event_record_id,
event_id => $event_id,
provider => $provider_name,
pid => $event_id,
};
$logon_event->{description} = $event_ids->{$provider_name}{$event_id} if $event_ids->{$provider_name}{$event_id};
# Convert system time format to datetime: 2014-03-18T19:18:41.421250000Z
my ($date, $time) = $system_time =~ /^([\d-]+)T([\d:]+)\./;
next if (!$date || !$time);
my $datetime = "$date $time";
# The time returned is UTC and not adjusted for the computer's time zone
my $epoch_seconds = convert_to_epoch_seconds($datetime);
$epoch_seconds += ($offset_minutes * 60);
$datetime = convert_to_datetime($epoch_seconds);
$logon_event->{datetime} = $datetime;
$logon_event->{epoch} = $epoch_seconds;
if ($provider_name eq 'Microsoft-Windows-Security-Auditing') {
my $event_data = $event->{EventData}{Data} || next;
$logon_event->{user} = $event_data->{TargetUserName};
$logon_event->{remote_ip} = $event_data->{IpAddress} if $event_data->{IpAddress};
$logon_event->{remote_port} = $event_data->{IpPort} if $event_data->{IpPort};
$logon_event->{logon_type_id} = $event_data->{LogonType} if $event_data->{LogonType};
my $logon_type_id = $event_data->{LogonType};
if (defined($logon_type_id)) {
$logon_event->{logon_type_id} = $logon_type_id;
$logon_event->{logon_type} = $logon_type_names->{$logon_type_id} if $logon_type_names->{$logon_type_id};
}
}
elsif ($provider_name eq 'Microsoft-Windows-TerminalServices-LocalSessionManager') {
my $user_data = $event->{UserData}{EventXML} || next;;
$logon_event->{user} = $user_data->{User};
$logon_event->{remote_ip} = $user_data->{Address} if $user_data->{Address};
$logon_event->{session_id} = $user_data->{SessionID} if $user_data->{SessionID};
}
if (!$logon_event->{user} || ref($logon_event->{user})) {
next;
}
$logon_event->{user} =~ s/.*\\+//g;
if ($logon_event->{remote_ip} && ($logon_event->{remote_ip} eq '0.0.0.0' || $logon_event->{remote_ip} =~ /-/)) {
delete $logon_event->{remote_ip};
}
if ($logon_event->{remote_port} && $logon_event->{remote_port} =~ /-/) {
delete $logon_event->{remote_port};
}
# Add to the hash - use key containing the provider name and record ID in case events have the same epoch time
$logon_event_hash->{"$epoch_seconds-$provider_name-$event_record_id"} = $logon_event;
}
# Convert the hash to an array sorted by the epoch time keys
my @logon_events = map { $logon_event_hash->{$_} } sort keys %$logon_event_hash;
my $logon_event_count = scalar(@logon_events);
notify($ERRORS{'DEBUG'}, 0, "retrieved $logon_event_count logon event" . ($logon_event_count == 1 ? '' : 's') . ":\n" . format_data(\@logon_events));
return @logon_events;
}