Невозможно удалить ACE из ACL - PullRequest
0 голосов
/ 23 января 2020

Мы хотим полностью очистить NTFS ACL папки, и только ACL заполняется ACE Builtin\Administrator : Full Control. Приведенный ниже код отлично работает для большинства папок, но не работает в одной указанной c папке:

$Path = 'E:\DEPARTMENTS\Gemensam'

$BuiltinAdmin = [System.Security.Principal.NTAccount]'Builtin\Administrators'
$AdminFullControlAce = New-Object System.Security.AccessControl.FileSystemAccessRule(
    $BuiltinAdmin,
    [System.Security.AccessControl.FileSystemRights]::FullControl,
    [System.Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit',
    [System.Security.AccessControl.PropagationFlags]::None,
    [System.Security.AccessControl.AccessControlType]::Allow
)

(Get-Acl $Path).Access

$FolderItem = Get-Item -Path $Path -EA Stop
$Acl = $FolderItem.GetAccessControl()

Write-Verbose 'Set owner'
$Acl.SetOwner($BuiltinAdmin)
$FolderItem.SetAccessControl($Acl)

Write-Verbose 'Disable inheritance'
$Acl = $FolderItem.GetAccessControl()
$Acl.SetAccessRuleProtection($True, $False)
$FolderItem.SetAccessControl($Acl)

Write-Verbose 'Remove all ACEs from the ACL'
$Acl = $FolderItem.GetAccessControl()
$Acl.Access.ForEach({$Acl.RemoveAccessRule($_)})

Write-Verbose 'Add Admin and set the new ACL'
$acl.AddAccessRule($AdminFullControlAce)
$FolderItem.SetAccessControl($Acl)

Write-Verbose 'ACL corrected'
(Get-Acl $Path).Access

Вывод этого кода:

FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : Modify, Synchronize
AccessControlType : Allow
IdentityReference : GROUPHC\SWE CEM KVB EV
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

VERBOSE: Set owner
VERBOSE: Disable inheritance
VERBOSE: Remove all ACEs from the ACL
True
True
VERBOSE: Add Admin and set the new ACL
VERBOSE: ACL corrected
FileSystemRights  : FullControl
AccessControlType : Allow
IdentityReference : BUILTIN\Administrators
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

FileSystemRights  : Modify, Synchronize
AccessControlType : Allow
IdentityReference : GROUPHC\SWE CEM KVB EV
IsInherited       : False
InheritanceFlags  : ContainerInherit, ObjectInherit
PropagationFlags  : None

По той или иной причине кажется быть невозможно удалить ACE из GROUPHC\SWE CEM KVB EV. Даже с Get-ACL и Set-ACL это не работает. Мы также пытались набрать sh ACL после каждого изменения, как указано здесь , но это тоже не работает. Согласно документам наследство должным образом удалено, поэтому оно не может быть унаследованным ACE.

enter image description here enter image description here enter image description here

Любая помощь будет принята с благодарностью.

Чтобы избежать проблем с владением, мы сначала запускаем следующий код:

#region Get super powers
    $AdjustTokenPrivileges = @"
using System;
using System.Runtime.InteropServices;

public class TokenManipulator
{
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool AdjustTokenPrivileges(IntPtr htok, bool disall,
ref TokPriv1Luid newst, int len, IntPtr prev, IntPtr relen);
[DllImport("kernel32.dll", ExactSpelling = true)]
internal static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)]
internal static extern bool OpenProcessToken(IntPtr h, int acc, ref IntPtr
phtok);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool LookupPrivilegeValue(string host, string name,
ref long pluid);
[StructLayout(LayoutKind.Sequential, Pack = 1)]
internal struct TokPriv1Luid
{
public int Count;
public long Luid;
public int Attr;
}
internal const int SE_PRIVILEGE_DISABLED = 0x00000000;
internal const int SE_PRIVILEGE_ENABLED = 0x00000002;
internal const int TOKEN_QUERY = 0x00000008;
internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020;
public static bool AddPrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_ENABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
public static bool RemovePrivilege(string privilege)
{
try
{
bool retVal;
TokPriv1Luid tp;
IntPtr hproc = GetCurrentProcess();
IntPtr htok = IntPtr.Zero;
retVal = OpenProcessToken(hproc, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, ref htok);
tp.Count = 1;
tp.Luid = 0;
tp.Attr = SE_PRIVILEGE_DISABLED;
retVal = LookupPrivilegeValue(null, privilege, ref tp.Luid);
retVal = AdjustTokenPrivileges(htok, false, ref tp, 0, IntPtr.Zero, IntPtr.Zero);
return retVal;
}
catch (Exception ex)
{
throw ex;
}
}
}
"@

Try {
    Write-Verbose 'Get super powers'
    Add-Type $AdjustTokenPrivileges
    [void][TokenManipulator]::AddPrivilege('SeRestorePrivilege')
    [void][TokenManipulator]::AddPrivilege('SeBackupPrivilege')
    [void][TokenManipulator]::AddPrivilege('SeTakeOwnershipPrivilege')
}
Catch {
    throw "Failed getting super powers: $_"
}
#endregion

Ответы [ 2 ]

0 голосов
/ 23 января 2020

Благодаря Тео из комментариев мы нашли решение этой проблемы. Нам просто нужно создать пустой ACL и затем добавить наши свойства к объекту, после чего его можно просто применить:

$Path = 'E:\DEPARTMENTS\Gemensam'

$BuiltinAdmin = [System.Security.Principal.NTAccount]'Builtin\Administrators'
$AdminFullControlAce = New-Object System.Security.AccessControl.FileSystemAccessRule(
    $BuiltinAdmin,
    [System.Security.AccessControl.FileSystemRights]::FullControl,
    [System.Security.AccessControl.InheritanceFlags]'ContainerInherit,ObjectInherit',
    [System.Security.AccessControl.PropagationFlags]::None,
    [System.Security.AccessControl.AccessControlType]::Allow
)

#region Create new ACL
$NewAcl = New-Object System.Security.AccessControl.DirectorySecurity
$NewAcl.SetOwner($BuiltinAdmin)
$NewAcl.SetAccessRuleProtection($true,$false)
$NewAcl.AddAccessRule($AdminFullControlAce)
#endregion

$FolderItem = Get-Item -Path $Path -EA Stop
$FolderItem.SetAccessControl($NewAcl)


$FolderAcl = $FolderItem.GetAccessControl()
$FolderAcl.Access | select IdentityReference, FileSystemRights

Или применить ACL дважды:

$M = Get-Item -Path 'C:\YourFolder'
$Acl = $M.GetAccessControl()

$BuiltinAdmin = [System.Security.Principal.NTAccount]'Builtin\Administrators'
$InheritedDirAcl = New-Object System.Security.AccessControl.DirectorySecurity
$InheritedDirAcl.SetOwner($BuiltinAdmin)
$InheritedDirAcl.SetAccessRuleProtection($false,$false)

# This is a workaround for non inherited permissions
# that do not get removed when simply applying the new ACL
$Acl.Access | ForEach-Object {
    $Acl.RemoveAccessRuleSpecific($_)
}
$M.SetAccessControl($Acl)
$M.SetAccessControl($InheritedDirAcl)

Связанная проблема здесь .

0 голосов
/ 23 января 2020

См. Мой комментарий выше:

Import-Module PSCX

Set-Privilege (new-object Pscx.Interop.TokenPrivilege "SeRestorePrivilege", $true) # Necessary to set Owner Permissions
Set-Privilege (new-object Pscx.Interop.TokenPrivilege "SeBackupPrivilege", $true) # Necessary to bypass Traverse Checking
Set-Privilege (new-object Pscx.Interop.TokenPrivilege "SeTakeOwnershipPrivilege", $true) # Necessary to override FilePermissions & take Ownership

Теперь рекурсивно используйте команды Get / Set ACL для цели

...