Fixes lookup time for Icinga managed user

This commit is contained in:
Lord Hepipud 2022-01-04 01:22:40 +01:00
parent 08cda55428
commit 7dc1ffc3c5
6 changed files with 99 additions and 35 deletions

View file

@ -14,6 +14,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
### Bugfixes ### Bugfixes
* [#379](https://github.com/Icinga/icinga-powershell-framework/issues/379) Fixes memory leak for Icinga for Windows by using a custom function being more aggressive on memory cleanup * [#379](https://github.com/Icinga/icinga-powershell-framework/issues/379) Fixes memory leak for Icinga for Windows by using a custom function being more aggressive on memory cleanup
* [#394](https://github.com/Icinga/icinga-powershell-framework/issues/394) Fixes lookup time for Icinga managed user for large Active Directory environments by limiting lookup to local system only
* [#402](https://github.com/Icinga/icinga-powershell-framework/pull/402) Fixes missing address attribute for REST-Api daemon, making it unable to change the listening address * [#402](https://github.com/Icinga/icinga-powershell-framework/pull/402) Fixes missing address attribute for REST-Api daemon, making it unable to change the listening address
* [#403](https://github.com/Icinga/icinga-powershell-framework/pull/403) Fixes memory leak on newly EventLog reader for CLI event stream * [#403](https://github.com/Icinga/icinga-powershell-framework/pull/403) Fixes memory leak on newly EventLog reader for CLI event stream
* [#407](https://github.com/Icinga/icinga-powershell-framework/pull/407) Removes unnecessary module import inside `Invoke-IcingaNamespaceCmdlets` * [#407](https://github.com/Icinga/icinga-powershell-framework/pull/407) Removes unnecessary module import inside `Invoke-IcingaNamespaceCmdlets`

View file

@ -0,0 +1,79 @@
<#
.SYNOPSIS
Will return certain configuration values for specified users by
using the username or SID by doing a local lookup with Get-LocalUser,
in case the Cmdlet is installed
.DESCRIPTION
Will return certain configuration values for specified users by
using the username or SID by doing a local lookup with Get-LocalUser,
in case the Cmdlet is installed.
Allows to test if a user does exist and if the user is managed by
Icinga for Windows.
In case both, -UserName and -SID are used, the -SID argument will always be
prioritized and therefor only one argument should be used at the same time.
.PARAMETER UserName
The local username you want to fetch config from
.PARAMETER SID
The SID of a local user you want to fetch config from. This argument
will always be prioritized, even when -UserName is set
.EXAMPLE
PS> Get-IcingaWindowsUserConfig -UserName 'icinga';
.EXAMPLE
PS> Get-IcingaWindowsUserConfig -SID 'S-1-5-21-1004336348-1177238915-682003330-512';
#>
function Get-IcingaWindowsUserConfig()
{
param (
[string]$UserName = '',
[string]$SID = ''
);
if ([string]::IsNullOrEmpty($SID) -And [string]::IsNullOrEmpty($UserName) -eq $FALSE) {
$SID = Get-IcingaUserSID -User $UserName;
}
$UserConfig = @{
'SID' = '';
'Name' = '';
'FullName' = '';
'Caption' = '';
'Domain' = (Get-IcingaNetbiosName);
'Description' = '';
'IcingaManagedUser' = $FALSE;
'UserExist' = $FALSE;
};
if ([string]::IsNullOrEmpty($SID) -And [string]::IsNullOrEmpty($UserName)) {
return $UserConfig;
}
# If we are not running PowerShell 5.0 or later, 'Get-LocalUser' will not be available
# which should always result in "false" for the managed user
if ((Test-IcingaFunction 'Get-LocalUser') -eq $FALSE) {
return $UserConfig;
}
$UserMetadata = Get-IcingaWindowsUserMetadata;
try {
$UserData = Get-LocalUser -SID $SID -ErrorAction Stop;
} catch {
return $UserConfig;
}
$UserConfig.SID = $UserData.SID.Value;
$UserConfig.Name = $UserData.Name;
$UserConfig.FullName = $UserData.FullName;
$UserConfig.Caption = [string]::Format('{0}\{1}', $UserConfig.Domain, $UserData.Name);
$UserConfig.Description = $UserData.Description;
if ($UserConfig.FullName -eq $UserMetadata.FullName -And $UserConfig.Description -eq $UserMetadata.Description) {
$UserConfig.IcingaManagedUser = $TRUE;
}
$UserConfig.UserExist = $TRUE;
return $UserConfig;
}

View file

@ -14,17 +14,13 @@ function New-IcingaWindowsUser()
} }
$UserMetadata = Get-IcingaWindowsUserMetadata; $UserMetadata = Get-IcingaWindowsUserMetadata;
$UserConfig = $null; $UserConfig = Get-IcingaWindowsUserConfig -UserName $IcingaUser;
$SID = Get-IcingaUserSID -User $IcingaUser; # In case the user exist, we can check if it is a managed user for modifying the login password
if ([string]::IsNullOrEmpty($SID) -eq $FALSE) { if ($UserConfig.UserExist) {
$UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID));
}
if ($null -ne $UserConfig) {
# User already exist -> override password - but only if the user is entirely managed by Icinga # User already exist -> override password - but only if the user is entirely managed by Icinga
if ($UserConfig.FullName -eq $UserMetadata.FullName -And $UserConfig.Description -eq $UserMetadata.Description) { if ($UserConfig.IcingaManagedUser) {
$Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" "{1}"', $IcingaUser, (ConvertFrom-IcingaSecureString -SecureString (New-IcingaWindowsUserPassword)))); $Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" "{1}"', $IcingaUser, (ConvertFrom-IcingaSecureString -SecureString (New-IcingaWindowsUserPassword))));
if ($Result.ExitCode -ne 0) { if ($Result.ExitCode -ne 0) {
@ -68,8 +64,7 @@ function New-IcingaWindowsUser()
$LocalUserGroup.Add("WinNT://$Env:COMPUTERNAME/$IcingaUser,user") $LocalUserGroup.Add("WinNT://$Env:COMPUTERNAME/$IcingaUser,user")
#> #>
$SID = Get-IcingaUserSID -User $IcingaUser; $UserConfig = Get-IcingaWindowsUserConfig -UserName $IcingaUser;
$UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID));
Write-IcingaConsoleNotice 'User was successfully created.'; Write-IcingaConsoleNotice 'User was successfully created.';

View file

@ -4,10 +4,14 @@ function Remove-IcingaWindowsUser()
$IcingaUser = 'icinga' $IcingaUser = 'icinga'
); );
$SID = Get-IcingaUserSID -User $IcingaUser; $UserConfig = Get-IcingaWindowsUserConfig -UserName $IcingaUser;
if ((Test-IcingaManagedUser -IcingaUser $IcingaUser) -eq $FALSE) { if ($UserConfig.UserExist -eq $FALSE -Or $UserConfig.IcingaManagedUser -eq $FALSE) {
Write-IcingaConsoleNotice 'The user "{0}" is not present or not created by Icinga for Windows. Unable to remove user' -Objects $IcingaUser; if ($UserConfig.UserExist -eq $FALSE) {
Write-IcingaConsoleNotice 'The user "{0}" is not present on this system' -Objects $IcingaUser;
} elseif ($UserConfig.IcingaManagedUser -eq $FALSE) {
Write-IcingaConsoleNotice 'The user "{0}" was not created by Icinga for Windows. Unable to remove user' -Objects $IcingaUser;
}
return @{ return @{
'User' = $IcingaUser; 'User' = $IcingaUser;
@ -15,8 +19,7 @@ function Remove-IcingaWindowsUser()
}; };
} }
$UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); $Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" /DELETE', $UserConfig.Name));
$Result = Start-IcingaProcess -Executable 'net' -Arguments ([string]::Format('user "{0}" /DELETE', $UserConfig.Name));
if ($Result.ExitCode -ne 0) { if ($Result.ExitCode -ne 0) {
Write-IcingaConsoleError 'Failed to delete user "{0}": {1}' -Objects $IcingaUser, $Result.Error; Write-IcingaConsoleError 'Failed to delete user "{0}": {1}' -Objects $IcingaUser, $Result.Error;

View file

@ -1,24 +1,11 @@
function Test-IcingaManagedUser() function Test-IcingaManagedUser()
{ {
param ( param (
[string]$IcingaUser, [string]$IcingaUser = '',
[string]$SID [string]$SID = ''
); );
if ([string]::IsNullOrEmpty($SID)) { $UserConfig = Get-IcingaWindowsUserConfig -UserName $IcingaUser -SID $SID;
$SID = Get-IcingaUserSID -User $IcingaUser;
}
if ([string]::IsNullOrEmpty($SID)) { return $UserConfig.IcingaManagedUser;
return $FALSE;
}
$UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID));
$UserMetadata = Get-IcingaWindowsUserMetadata;
if ($null -eq $UserConfig -Or $UserConfig.FullName -ne $UserMetadata.FullName -Or $UserConfig.Description -ne $UserMetadata.Description) {
return $FALSE;
}
return $TRUE;
} }

View file

@ -10,9 +10,8 @@ function Update-IcingaServiceUser()
return; return;
} }
$SID = Get-IcingaUserSID -User $IcingaUser; $UserConfig = Get-IcingaWindowsUserConfig -UserName $IcingaUser;
$UserConfig = Get-IcingaWindowsInformation -Class 'Win32_UserAccount' -Filter ([string]::Format("SID = '{0}'", $SID)); $User = New-IcingaWindowsUser -IcingaUser $UserConfig.Name;
$User = New-IcingaWindowsUser -IcingaUser $UserConfig.Name;
Set-IcingaServiceUser -User $IcingaUser -Password $Global:Icinga.ServiceUserPassword -Service 'icinga2' | Out-Null; Set-IcingaServiceUser -User $IcingaUser -Password $Global:Icinga.ServiceUserPassword -Service 'icinga2' | Out-Null;
Set-IcingaServiceUser -User $IcingaUser -Password $Global:Icinga.ServiceUserPassword -Service 'icingapowershell' | Out-Null; Set-IcingaServiceUser -User $IcingaUser -Password $Global:Icinga.ServiceUserPassword -Service 'icingapowershell' | Out-Null;