Merge pull request #149 from Icinga/feature/add_wmi_permission_setter

Feature: Adds support to add/remove/test Wmi permissions

You can now use 'Add-IcingaWmiPermissions' to add permissions for a specific user and namespace and remove them with
'Remove-IcingaWmiPermissions'
This commit is contained in:
Lord Hepipud 2020-11-18 14:49:43 +01:00 committed by GitHub
commit b31cd04a97
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 566 additions and 16 deletions

View file

@ -18,6 +18,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic
* [#139](https://github.com/Icinga/icinga-powershell-framework/pull/139) Add Cmdlet `Start-IcingaShellAsUser` to open an Icinga Shell as different user for testing * [#139](https://github.com/Icinga/icinga-powershell-framework/pull/139) Add Cmdlet `Start-IcingaShellAsUser` to open an Icinga Shell as different user for testing
* [#141](https://github.com/Icinga/icinga-powershell-framework/pull/141) Adds Cmdlet `Convert-IcingaPluginThresholds` as generic approach to convert Icinga Thresholds with units to the lowest unit of this type. * [#141](https://github.com/Icinga/icinga-powershell-framework/pull/141) Adds Cmdlet `Convert-IcingaPluginThresholds` as generic approach to convert Icinga Thresholds with units to the lowest unit of this type.
* [#134](https://github.com/Icinga/icinga-powershell-framework/pull/134) Adds Cmdlet `Test-IcingaWindowsInformation` to check if a WMI class exist and if we can fetch data from it. In addition we add support for binary value comparison with the new Cmdlet `Test-IcingaBinaryOperator` * [#134](https://github.com/Icinga/icinga-powershell-framework/pull/134) Adds Cmdlet `Test-IcingaWindowsInformation` to check if a WMI class exist and if we can fetch data from it. In addition we add support for binary value comparison with the new Cmdlet `Test-IcingaBinaryOperator`
* [#149](https://github.com/Icinga/icinga-powershell-framework/pull/149) Adds support to add Wmi permissions for a specific user and namespace with `Add-IcingaWmiPermissions`. In addition you can remove users from Wmi namespaces by using `Remove-IcingaWmiPermissions`
### Bugfixes ### Bugfixes

View file

@ -8,20 +8,10 @@ function Get-IcingaUserSID()
$User = 'NT Authority\SYSTEM'; $User = 'NT Authority\SYSTEM';
} }
[string]$Username = ''; $UserData = Split-IcingaUserDomain -User $User;
[string]$Domain = '';
if ($User.Contains('\')) {
$TmpArray = $User.Split('\');
$Domain = $TmpArray[0];
$Username = $TmpArray[1];
} else {
$Domain = Get-IcingaNetbiosName;
$Username = $User;
}
try { try {
$NTUser = New-Object System.Security.Principal.NTAccount($Domain, $Username); $NTUser = New-Object System.Security.Principal.NTAccount($UserData.Domain, $UserData.User);
$SecurityData = $NTUser.Translate([System.Security.Principal.SecurityIdentifier]); $SecurityData = $NTUser.Translate([System.Security.Principal.SecurityIdentifier]);
} catch { } catch {
throw $_.Exception; throw $_.Exception;

View file

@ -0,0 +1,80 @@
<#
.SYNOPSIS
Splits a username containing a domain into a hashtable to easily use both values independently.
If no domain is specified the hostname will used as "local domain"
.DESCRIPTION
Splits a username containing a domain into a hashtable to easily use both values independently.
If no domain is specified the hostname will used as "local domain"
.PARAMETER User
A user object either containing only the user or domain information
.EXAMPLE
PS>Split-IcingaUserDomain -User 'icinga';
Name Value
---- -----
User icinga
Domain icinga-win
.EXAMPLE
PS>Split-IcingaUserDomain -User 'ICINGADOMAIN\icinga';
Name Value
---- -----
User icinga
Domain ICINGADOMAIN
.EXAMPLE
PS>Split-IcingaUserDomain -User 'icinga@ICINGADOMAIN';
Name Value
---- -----
User icinga
Domain ICINGADOMAIN
.EXAMPLE
PS>Split-IcingaUserDomain -User '.\icinga';
Name Value
---- -----
User icinga
Domain icinga-win
.INPUTS
System.String
.OUTPUTS
System.Hashtable
#>
function Split-IcingaUserDomain()
{
param (
$User
);
if ([string]::IsNullOrEmpty($User)) {
Write-IcingaConsoleError 'Please enter a valid username';
return '';
}
[array]$UserData = @();
if ($User.Contains('\')) {
$UserData = $User.Split('\');
} elseif ($User.Contains('@')) {
[array]$Split = $User.Split('@');
$UserData = @(
$Split[1],
$Split[0]
);
} else {
$UserData = @(
(Get-IcingaNetbiosName),
$User
);
}
if ([string]::IsNullOrEmpty($UserData[0]) -Or $UserData[0] -eq '.' -Or $UserData[0] -eq 'BUILTIN') {
$UserData[0] = (Get-IcingaNetbiosName);
}
return @{
'Domain' = $UserData[0];
'User' = $UserData[1];
};
}

View file

@ -0,0 +1,113 @@
<#
.SYNOPSIS
Sets permissions for a specific Wmi namespace for a user. You can grant basic permissions based
on the arguments available and grant additional ones with the `-Flags` argument.
.DESCRIPTION
Sets permissions for a specific Wmi namespace for a user. You can grant basic permissions based
on the arguments available and grant additional ones with the `-Flags` argument.
.PARAMETER User
The user to set permissions for. Can either be a local or domain user
.PARAMETER Namespace
The Wmi namespace to grant permissions for. Required namespaces are listed within each plugin documentation
.PARAMETER Enable
Enables the account and grants the user read permissions. This is a default access right for all users and corresponds to the Enable Account permission on the Security tab of the WMI Control. For more information, see Setting Namespace Security with the WMI Control.
.PARAMETER RemoteAccess
Allows a user account to remotely perform any operations allowed by the permissions described above. Only members of the Administrators group have this right. WBEM_REMOTE_ACCESS corresponds to the Remote Enable permission on the Security tab of the WMI Control.
.PARAMETER Recurse
Applies a container inherit flag and grants permission not only on the specific Wmi tree but also objects within this namespace (recommended)
.PARAMETER DenyAccess
Blocks the user from having access to this Wmi and or subnamespace tree.
.PARAMETER Flags
Allows to specify additional flags for permssion granting: PartialWrite, Subscribe, ProviderWrite,ReadSecurity, WriteSecurity, Publish, MethodExecute, FullWrite
.EXAMPLE
PS>Add-IcingaWmiPermissions -Namespace 'root\cimv2' -User icinga -Enable;
.EXAMPLE
PS>Add-IcingaWmiPermissions -Namespace 'root\cimv2' -User 'ICINGADOMAIN\icinga' -Enable -RemoteAccess;
.EXAMPLE
PS>Add-IcingaWmiPermissions -Namespace 'root\cimv2' -User 'ICINGADOMAIN\icinga' -Enable -RemoteAccess -Recurse;
.EXAMPLE
PS>Add-IcingaWmiPermissions -Namespace 'root\cimv2' -User 'ICINGADOMAIN\icinga' -Enable -RemoteAccess -Flags 'ReadSecurity', 'MethodExecute' -Recurse;
.INPUTS
System.String
.OUTPUTS
System.Boolean
#>
function Add-IcingaWmiPermissions()
{
param (
[string]$User,
[string]$Namespace,
[switch]$Enable,
[switch]$RemoteAccess,
[switch]$Recurse,
[switch]$DenyAccess,
[array]$Flags
);
if ([string]::IsNullOrEmpty($User)) {
Write-IcingaConsoleError 'Please enter a valid username';
return $FALSE;
}
if ([string]::IsNullOrEmpty($Namespace)) {
Write-IcingaConsoleError 'You have to specify a Wmi namespace to grant permissions for';
return $FALSE;
}
[int]$PermissionMask = New-IcingaWmiPermissionMask -Enable:$Enable -RemoteAccess:$RemoteAccess -Flags $Flags;
if ($PermissionMask -eq 0) {
Write-IcingaConsoleError 'You have to specify permissions to grant for a specific user';
return $FALSE;
}
if (Test-IcingaWmiPermissions -User $User -Namespace $Namespace -Enable:$Enable -RemoteAccess:$RemoteAccess -Recurse:$Recurse -DenyAccess:$DenyAccess -Flags $Flags) {
Write-IcingaConsoleNotice 'Wmi permissions for user "{0}" are already set.' -Objects $User;
return $TRUE;
} else {
Write-IcingaConsoleNotice 'Removing possible existing configuration for this user before continuing';
Remove-IcingaWmiPermissions -User $User -Namespace $Namespace | Out-Null;
}
$WmiSecurity = Get-IcingaWmiSecurityData -User $User -Namespace $Namespace;
if ($null -eq $WmiSecurity) {
return $FALSE;
}
$WmiAce = (New-Object System.Management.ManagementClass("Win32_Ace")).CreateInstance();
$WmiAce.AccessMask = $PermissionMask;
if ($Recurse) {
$WmiAce.AceFlags = $IcingaWBEM.AceFlags.Container_Inherit;
} else {
$WmiAce.AceFlags = 0;
}
$WmiTrustee = (New-Object System.Management.ManagementClass("Win32_Trustee")).CreateInstance();
$WmiTrustee.SidString = Get-IcingaUserSID -User $User;
$WmiAce.Trustee = $WmiTrustee
if ($DenyAccess) {
$WmiAce.AceType = $IcingaWBEM.AceFlags.Access_Denied;
} else {
$WmiAce.AceType = $IcingaWBEM.AceFlags.Access_Allowed;
}
$WmiSecurity.WmiAcl.DACL += $WmiAce.PSObject.immediateBaseObject;
$WmiSecurity.WmiArguments.Name = 'SetSecurityDescriptor';
$WmiSecurity.WmiArguments.Add('ArgumentList', $WmiSecurity.WmiAcl.PSObject.immediateBaseObject);
$WmiArguments = $WmiSecurity.WmiArguments;
$WmiSecurityData = Invoke-WmiMethod @WmiArguments;
if ($WmiSecurityData.ReturnValue -ne 0) {
Write-IcingaConsoleError 'Failed to set Wmi security descriptor information with error {0}' -Objects $WmiSecurityData.ReturnValue;
return $FALSE;
}
Write-IcingaConsoleNotice 'Wmi permissions for Namespace "{0}" and user "{1}" have been set successfully' -Objects $Namespace, $User;
return $TRUE;
}

View file

@ -1,3 +1,34 @@
<#
.SYNOPSIS
Allows to query Wmi information by either using Wmi directly or Cim. This provides a save handling
to call Wmi classes, as we are catching possible errors including missing permissions for better
and improved error output during plugin execution.
.DESCRIPTION
Allows to query Wmi information by either using Wmi directly or Cim. This provides a save handling
to call Wmi classes, as we are catching possible errors including missing permissions for better
and improved error output during plugin execution.
.PARAMETER ClassName
The Wmi class to fetch information from
.PARAMETER Filter
Allows to filter only for specific Wmi information. The syntax is identical to Get-WmiObject and Get-CimInstance
.PARAMETER Namespace
The Wmi namespace to lookup additional information. The syntax is identical to Get-WmiObject and Get-CimInstance
.PARAMETER ForceWMI
Forces the usage of `Get-WmiObject` instead of `Get-CimInstance`
.EXAMPLE
PS>Get-IcingaWindowsInformation -ClassName Win32_Service;
.EXAMPLE
PS>Get-IcingaWindowsInformation -ClassName Win32_Service -ForceWMI;
.EXAMPLE
PS>Get-IcingaWindowsInformation -ClassName MSFT_NetAdapter -NameSpace 'root\StandardCimv2';
.EXAMPLE
PS>Get-IcingaWindowsInformation Win32_LogicalDisk -Filter 'DriveType = 3';
.INPUTS
System.String
.OUTPUTS
System.Boolean
#>
function Get-IcingaWindowsInformation() function Get-IcingaWindowsInformation()
{ {
param ( param (

View file

@ -0,0 +1,60 @@
<#
.SYNOPSIS
Returns several information about the Wmi namespace and the provided user data to
work with them while adding/testing/removing Wmi permissions
.DESCRIPTION
Returns several information about the Wmi namespace and the provided user data to
work with them while adding/testing/removing Wmi permissions
.PARAMETER User
The user to set permissions for. Can either be a local or domain user
.PARAMETER Namespace
The Wmi namespace to grant permissions for. Required namespaces are listed within each plugin documentation
.INPUTS
System.String
.OUTPUTS
System.Hashtable
#>
function Get-IcingaWmiSecurityData()
{
param (
[string]$User,
[string]$Namespace
);
[hashtable]$WmiArguments = @{
'Name' = 'GetSecurityDescriptor';
'Namespace' = $Namespace;
'Path' = "__systemsecurity=@";
}
$WmiSecurityData = Invoke-WmiMethod @WmiArguments;
if ($WmiSecurityData.ReturnValue -ne 0) {
Write-IcingaConsoleError 'Fetching Wmi security descriptor information failed with error {0}' -Objects $WmiSecurityData.ReturnValue;
return $null;
}
$UserData = Split-IcingaUserDomain -User $User;
$UserSID = Get-IcingaUserSID -User $User;
$WmiAcl = $WmiSecurityData.Descriptor;
$WmiAccount = Get-IcingaWindowsInformation -ClassName Win32_Account -Filter ([string]::Format("Domain='{0}' and Name='{1}'", $UserData.Domain, $UserData.User));
if ($null -eq $WmiAccount) {
Write-IcingaConsoleError 'The specified user could not be found on the system: "{0}\{1}"' -Objects $UserData.Domain, $UserData.User;
return $null;
}
if ([string]::IsNullOrEmpty($UserSID)) {
Write-IcingaConsoleError 'Unable to load the SID for user "{0}"' -Objects $User;
return $null;
}
return @{
'WmiArguments' = $WmiArguments;
'UserData' = $UserData;
'UserSID' = $UserSID;
'WmiAcl' = $WmiAcl;
}
}

View file

@ -0,0 +1,59 @@
<#
# WMI WBEM_SECURITY_FLAGS
# https://docs.microsoft.com/en-us/windows/win32/api/wbemcli/ne-wbemcli-wbem_security_flags
# https://docs.microsoft.com/en-us/windows/win32/secauthz/standard-access-rights
#>
[hashtable]$SecurityFlags = @{
'WBEM_Enable' = 1;
'WBEM_Method_Execute' = 2;
'WBEM_Full_Write_Rep' = 4;
'WBEM_Partial_Write_Rep' = 8;
'WBEM_Write_Provider' = 0x10;
'WBEM_Remote_Access' = 0x20;
'WBEM_Right_Subscribe' = 0x40;
'WBEM_Right_Publish' = 0x80;
'Read_Control' = 0x20000;
'Write_DAC' = 0x40000;
};
[hashtable]$SecurityDescription = @{
1 = 'Enables the account and grants the user read permissions. This is a default access right for all users and corresponds to the Enable Account permission on the Security tab of the WMI Control. For more information, see Setting Namespace Security with the WMI Control.';
2 = 'Allows the execution of methods. Providers can perform additional access checks. This is a default access right for all users and corresponds to the Execute Methods permission on the Security tab of the WMI Control.';
4 = 'Allows a user account to write to classes in the WMI repository as well as instances. A user cannot write to system classes. Only members of the Administrators group have this permission. WBEM_FULL_WRITE_REP corresponds to the Full Write permission on the Security tab of the WMI Control.';
8 = 'Allows you to write data to instances only, not classes. A user cannot write classes to the WMI repository. Only members of the Administrators group have this right. WBEM_PARTIAL_WRITE_REP corresponds to the Partial Write permission on the Security tab of the WMI Control.';
0x10 = 'Allows writing classes and instances to providers. Note that providers can do additional access checks when impersonating a user. This is a default access right for all users and corresponds to the Provider Write permission on the Security tab of the WMI Control.';
0x20 = 'Allows a user account to remotely perform any operations allowed by the permissions described above. Only members of the Administrators group have this right. WBEM_REMOTE_ACCESS corresponds to the Remote Enable permission on the Security tab of the WMI Control.';
0x40 = 'Specifies that a consumer can subscribe to the events delivered to a sink. Used in IWbemEventSink::SetSinkSecurity.';
0x80 = 'Specifies that the account can publish events to the instance of __EventFilter that defines the event filter for a permanent consumer. Available in wbemcli.h.';
0x20000 = 'The right to read the information in the objects security descriptor, not including the information in the system access control list (SACL).';
0x40000 = 'The right to modify the discretionary access control list (DACL) in the objects security descriptor.';
};
[hashtable]$SecurityNames = @{
'Enable' = 'WBEM_Enable';
'MethodExecute' = 'WBEM_Method_Execute';
'FullWrite' = 'WBEM_Full_Write_Rep';
'PartialWrite' = 'WBEM_Partial_Write_Rep';
'ProviderWrite' = 'WBEM_Write_Provider';
'RemoteAccess' = 'WBEM_Remote_Access';
'Subscribe' = 'WBEM_Right_Subscribe';
'Publish' = 'WBEM_Right_Publish';
'ReadSecurity' = 'Read_Control';
'WriteSecurity' = 'Write_DAC';
};
[hashtable]$AceFlags = @{
'Access_Allowed' = 0x0;
'Access_Denied' = 0x1;
'Container_Inherit' = 0x2;
}
[hashtable]$IcingaWBEM = @{
SecurityFlags = $SecurityFlags;
SecurityDescription = $SecurityDescription
SecurityNames = $SecurityNames;
AceFlags = $AceFlags;
}
Export-ModuleMember -Variable @( 'IcingaWBEM' );

View file

@ -0,0 +1,54 @@
<#
.SYNOPSIS
Generates a permission mask based on the set and provided flags which are used
for adding/testing Wmi permissions
.DESCRIPTION
Generates a permission mask based on the set and provided flags which are used
for adding/testing Wmi permissions
.PARAMETER Enable
Enables the account and grants the user read permissions. This is a default access right for all users and corresponds to the Enable Account permission on the Security tab of the WMI Control. For more information, see Setting Namespace Security with the WMI Control.
.PARAMETER RemoteAccess
Allows a user account to remotely perform any operations allowed by the permissions described above. Only members of the Administrators group have this right. WBEM_REMOTE_ACCESS corresponds to the Remote Enable permission on the Security tab of the WMI Control.
.PARAMETER Flags
Allows to specify additional flags for permssion granting: PartialWrite, Subscribe, ProviderWrite,ReadSecurity, WriteSecurity, Publish, MethodExecute, FullWrite
.INPUTS
System.String
.OUTPUTS
System.Int
#>
function New-IcingaWmiPermissionMask()
{
param (
[switch]$Enable,
[switch]$RemoteAccess,
[array]$Flags
);
[int]$PermissionMask = 0;
if ($Enable) {
$PermissionMask += $IcingaWBEM.SecurityFlags.WBEM_Enable;
}
if ($RemoteAccess) {
$PermissionMask += $IcingaWBEM.SecurityFlags.WBEM_Remote_Access;
}
foreach ($flag in $Flags) {
if ($flag -like 'Enable' -And $Enable) {
continue;
}
if ($flag -like 'RemoteAccess' -And $RemoteAccess) {
continue;
}
if ($IcingaWBEM.SecurityNames.ContainsKey($flag) -eq $FALSE) {
Write-IcingaConsoleError 'Invalid Security flag "{0}" . Supported flags: {1}' -Objects $flag, $IcingaWBEM.SecurityNames.Keys;
return $FALSE;
}
$PermissionMask += $IcingaWBEM.SecurityFlags[$IcingaWBEM.SecurityNames[$flag]];
}
return $PermissionMask;
}

View file

@ -0,0 +1,70 @@
<#
.SYNOPSIS
Removes a user from a specific Wmi namespace
.DESCRIPTION
Removes a user from a specific Wmi namespace
.PARAMETER User
The user to set permissions for. Can either be a local or domain user
.PARAMETER Namespace
The Wmi namespace to grant permissions for. Required namespaces are listed within each plugin documentation
.INPUTS
System.String
.OUTPUTS
System.Boolean
#>
function Remove-IcingaWmiPermissions()
{
param (
[string]$User,
[string]$Namespace
);
if ([string]::IsNullOrEmpty($User)) {
Write-IcingaConsoleError 'Please enter a valid username';
return $FALSE;
}
if ([string]::IsNullOrEmpty($Namespace)) {
Write-IcingaConsoleError 'You have to specify a Wmi namespace to grant permissions for';
return $FALSE;
}
$WmiSecurity = Get-IcingaWmiSecurityData -User $User -Namespace $Namespace;
if ($null -eq $WmiSecurity) {
return $FALSE;
}
[System.Management.ManagementBaseObject[]]$RebasedDACL = @()
[bool]$UserPresent = $FALSE;
foreach ($entry in $WmiSecurity.WmiAcl.DACL) {
if ($entry.Trustee.SidString -ne $WmiSecurity.UserSID) {
$RebasedDACL += $entry.PSObject.immediateBaseObject;
} else {
$UserPresent = $TRUE;
}
}
if ($UserPresent -eq $FALSE) {
Write-IcingaConsoleNotice 'User "{0}" is not configured for namespace "{1}"' -Objects $User, $Namespace;
return $TRUE;
}
$WmiSecurity.WmiAcl.DACL = $RebasedDACL.PSObject.immediateBaseObject;
$WmiSecurity.WmiArguments.Name = 'SetSecurityDescriptor';
$WmiSecurity.WmiArguments.Add('ArgumentList', $WmiSecurity.WmiAcl.PSObject.immediateBaseObject);
$WmiArguments = $WmiSecurity.WmiArguments
$WmiSecurityData = Invoke-WmiMethod @WmiArguments;
if ($WmiSecurityData.ReturnValue -ne 0) {
Write-IcingaConsoleError 'Failed to set Wmi security descriptor information with error {0}' -Objects $WmiSecurityData.ReturnValue;
return $FALSE;
}
Write-IcingaConsoleNotice 'Removed user "{0}" from Namespace "{1}" successfully' -Objects $User, $Namespace;
return $TRUE;
}

View file

@ -1,10 +1,10 @@
<# <#
.SYNOPSIS .SYNOPSIS
Tests if a specific WMI class including the Namespace can be accessed and returns status codes for possible errors/exceptions taht might occure. Tests if a specific WMI class including the Namespace can be accessed and returns status codes for possible errors/exceptions that might occur.
Returns binary operator values for easier comparison. In case no errors occured it will return $TestIcingaWindowsInfoEnums.TestIcingaWindowsInfo.Ok Returns binary operator values for easier comparison. In case no errors occurred it will return $TestIcingaWindowsInfoEnums.TestIcingaWindowsInfo.Ok
.DESCRIPTION .DESCRIPTION
Tests if a specific WMI class including the Namespace can be accessed and returns status codes for possible errors/exceptions taht might occure. Tests if a specific WMI class including the Namespace can be accessed and returns status codes for possible errors/exceptions that might occur.
Returns binary operator values for easier comparison. In case no errors occured it will return $TestIcingaWindowsInfoEnums.TestIcingaWindowsInfo.Ok Returns binary operator values for easier comparison. In case no errors occurred it will return $TestIcingaWindowsInfoEnums.TestIcingaWindowsInfo.Ok
.ROLE .ROLE
### WMI Permissions ### WMI Permissions

View file

@ -0,0 +1,92 @@
<#
.SYNOPSIS
Tests the current set permissions for a user on a specific namespace and returns true if the
current configuration is matching the intended configuration and returns false if either no
permissions are set yet or the intended configuration is not matching the current configuration
.DESCRIPTION
Tests the current set permissions for a user on a specific namespace and returns true if the
current configuration is matching the intended configuration and returns false if either no
permissions are set yet or the intended configuration is not matching the current configuration
.PARAMETER User
The user to set permissions for. Can either be a local or domain user
.PARAMETER Namespace
The Wmi namespace to grant permissions for. Required namespaces are listed within each plugin documentation
.PARAMETER Enable
Enables the account and grants the user read permissions. This is a default access right for all users and corresponds to the Enable Account permission on the Security tab of the WMI Control. For more information, see Setting Namespace Security with the WMI Control.
.PARAMETER RemoteAccess
Allows a user account to remotely perform any operations allowed by the permissions described above. Only members of the Administrators group have this right. WBEM_REMOTE_ACCESS corresponds to the Remote Enable permission on the Security tab of the WMI Control.
.PARAMETER Recurse
Applies a container inherit flag and grants permission not only on the specific Wmi tree but also objects within this namespace (recommended)
.PARAMETER DenyAccess
Blocks the user from having access to this Wmi and or subnamespace tree.
.PARAMETER Flags
Allows to specify additional flags for permssion granting: PartialWrite, Subscribe, ProviderWrite,ReadSecurity, WriteSecurity, Publish, MethodExecute, FullWrite
.INPUTS
System.String
.OUTPUTS
System.Boolean
#>
function Test-IcingaWmiPermissions()
{
param (
[string]$User,
[string]$Namespace,
[switch]$Enable,
[switch]$RemoteAccess,
[switch]$Recurse,
[switch]$DenyAccess,
[array]$Flags
);
if ([string]::IsNullOrEmpty($User)) {
Write-IcingaConsoleError 'Please enter a valid username';
return $FALSE;
}
if ([string]::IsNullOrEmpty($Namespace)) {
Write-IcingaConsoleError 'You have to specify a Wmi namespace to grant permissions for';
return $FALSE;
}
[int]$PermissionMask = [int]$PermissionMask = New-IcingaWmiPermissionMask -Enable:$Enable -RemoteAccess:$RemoteAccess -Flags $Flags;
if ($PermissionMask -eq 0) {
Write-IcingaConsoleError 'You have to specify permissions to grant for a specific user';
return $FALSE;
}
$WmiSecurity = Get-IcingaWmiSecurityData -User $User -Namespace $Namespace;
if ($null -eq $WmiSecurity) {
return $FALSE;
}
[System.Management.ManagementBaseObject]$UserACL = $null;
foreach ($entry in $WmiSecurity.WmiAcl.DACL) {
if ($entry.Trustee.SidString -eq $WmiSecurity.UserSID) {
$UserACL = $entry.PSObject.immediateBaseObject;
break;
}
}
# No permissions granted for this user
if ($null -eq $UserACL) {
return $FALSE;
}
[bool]$RecurseMatch = $TRUE;
if ($Recurse -And $UserACL.AceFlags -ne $IcingaWBEM.AceFlags.Container_Inherit) {
$RecurseMatch = $FALSE;
} elseif ($Recurse -eq $FALSE -And $UserACL.AceFlags -ne 0) {
$RecurseMatch = $FALSE;
}
if ($UserACL.AccessMask -ne $PermissionMask -Or $RecurseMatch -eq $FALSE) {
return $FALSE;
}
return $TRUE;
}