2012-06-10 5 views
5

Cuando me puse una nueva regla filesystemaccess con PowerShell y fijar-acl, me puse los indicadores de herencia se propaguen a los niños y objetos hojaEl cambio de permisos con PowerShell no propagan a los niños

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
    "username","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))) 
Set-Acl -path $filename -aclObject $acl 

Cuando miro el permiso en el explorador ... en la pestaña de seguridad ... avanzado ... la propagación está configurada correctamente. Pero si miro a los propios niños, NO muestran la nueva regla de seguridad.

Si estoy en el explorador, agrego otra regla con un SID diferente ... y la guardo (sin forzar la opción de 'reemplazar todos los permisos de objetos secundarios ...'). Luego, tanto el manual como la regla de powershell aparecen en los niños. Es como si hubiera algún tipo de kickstart necesario para hacer que los niños recojan la nueva regla propagada. ¿Qué me hace falta para que los objetos secundarios muestren la nueva regla agregada?

+0

¿Qué es $ acl? ¿Estás tratando de copiar el descriptor de seguridad de ** $ filename ** a ** $ acl **? –

Respuesta

1

Eso es muy extraño. Tengo un código similar que establece permisos de la misma manera. Sin embargo, nunca he comprobado si los permisos de los niños se han establecido o no. Podría ser una rareza en la interfaz de usuario de Windows Explorer. ¿Ha usado PowerShell para obtener las ACL de uno de los niños para verificar si los permisos están siendo aplicados o no?

Como referencia, aquí está the code I use to grant permissions:

foreach($permission in $Permissions) 
{ 
    $right = ($permission -as "Security.AccessControl.FileSystemRights") 
    if(-not $right) 
    { 
     throw "Invalid FileSystemRights: $permission. Must be one of $([Enum]::GetNames("Security.AccessControl.FileSystemRights"))." 
    } 
    $rights = $rights -bor $right 
} 

Write-Host "Granting $Identity $Permissions on $Path." 
# We don't use Get-Acl because it returns the whole security descriptor, which includes owner information. 
# When passed to Set-Acl, this causes intermittent errors. So, we just grab the ACL portion of the security descriptor. 
# See http://www.bilalaslam.com/2010/12/14/powershell-workaround-for-the-security-identifier-is-not-allowed-to-be-the-owner-of-this-object-with-set-acl/ 
$currentAcl = (Get-Item $Path).GetAccessControl("Access") 

$inheritanceFlags = [Security.AccessControl.InheritanceFlags]::None 
if(Test-Path $Path -PathType Container) 
{ 
    $inheritanceFlags = ([Security.AccessControl.InheritanceFlags]::ContainerInherit -bor ` 
         [Security.AccessControl.InheritanceFlags]::ObjectInherit) 
} 
$propagationFlags = [Security.AccessControl.PropagationFlags]::None 
$accessRule = New-Object "Security.AccessControl.FileSystemAccessRule" $identity,$rights,$inheritanceFlags,$propagationFlags,"Allow"  
$currentAcl.SetAccessRule($accessRule) 
Set-Acl $Path $currentAcl 
5

he tenido el mismo problema lógico ...

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"username","FullControl", "ContainerInherit, ObjectInherit", "None", "Allow"))) 

Con ese último 'ninguno' que está diciendo: no propagar ... Cambiar a:

$acl.AddAccessRule((New-Object System.Security.AccessControl.FileSystemAccessRule(
"username","FullControl", "ContainerInherit, ObjectInherit", "InheritOnly", "Allow"))) 

y se propagará la configuración. cuanto a las opciones de regla de acceso aquí: http://msdn.microsoft.com/en-us/library/ms147785.aspx

Estas son las banderas de propagación: http://msdn.microsoft.com/en-us/library/system.security.accesscontrol.propagationflags.aspx

0

He estado buscando en las preguntas de Internet y varios StackOverflow tratando de descifrar esto. Puede que no tenga la mejor solución, pero creo que satisface la pregunta. De acuerdo con mi investigación, Powershell's Set-Acl simplemente no maneja la herencia adecuadamente. La clave del código siguiente es dos cosas: el objeto System.Security.AccessControl.DirectorySecurity y el método alternativo para configurar la ACL $dir.SetAccessControl() Los elementos secundarios de la carpeta de destino (tanto carpetas como archivos) heredarán correctamente los permisos adjuntos a la carpeta de destino.

Calling ejemplo:

[email protected]() 
$newACL+=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @("MyLocalGroup1","ReadAndExecute,Synchronize","ContainerInherit,ObjectInherit","None","Allow") 
$newACL+=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @("MyLocalGroup2","FullControl","ContainerInherit,ObjectInherit","None","Allow") 
Set-FolderPermissions -Path $Path -KeepDefault -ResetOwner -AccessRuleList $newACL 

Función:

function Set-FolderPermissions { 
    # The whole point of this script is because Set-Acl bungles inheritance 
    [CmdletBinding(SupportsShouldProcess=$false)] 
    Param ([Parameter(Mandatory=$true, ValueFromPipeline=$false)] [ValidateNotNullOrEmpty()] [string]$Path, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$KeepExisting, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$KeepDefault, 
     [Parameter(Mandatory=$false, ValueFromPipeline=$false)] [switch]$ResetOwner, 
     [Parameter(Mandatory=$true, ValueFromPipeline=$false)] [System.Security.AccessControl.FileSystemAccessRule[]]$AccessRuleList) 

    Process { 
    $aryDefaultACL="NT AUTHORITY\SYSTEM","CREATOR OWNER","BUILTIN\Administrators" 
    [email protected]() 
    $owner=New-Object System.Security.Principal.NTAccount("BUILTIN","Administrators") 
    $acl=Get-Acl -Path $Path 

    # Save only needed individual rules. 
    if ($KeepExisting.IsPresent) { 
     if ($KeepDefault.IsPresent) { 
     # Keep everything 
     $acl.Access | ForEach-Object { $tempACL+=$_ } 
     } 
     else { 
     # Remove the defaults, keep everything else 
     for ($i=0; $i -lt $acl.Access.Count; $i++) { 
     if (!$aryDefaultACL.Contains($acl.Access[$i].IdentityReference.Value)) { $tempACL+=$acl.Access[$i] } 
     } 
     } 
    } 
    else { 
     if ($KeepDefault.IsPresent) { 
     # Keep only the default, drop everything else 
     for ($i=0; $i -lt $acl.Access.Count; $i++) { 
     if ($aryDefaultACL.Contains($acl.Access[$i].IdentityReference.Value)) { $tempACL+=$acl.Access[$i] } 
     } 
     } 
     #else { # Do nothing, because $TempACL is already empty. } 
    } 

    # Add the new rules 
    # I could have been modifying $acl this whole time, but it turns out $tempACL=$acl doesn't work so well. 
    # As the rules are removed from $acl, they are also removed from $tempACL 
    for ($i=0; $i -lt $AccessRuleList.Count; $i++) { $tempACL+=$AccessRuleList[$i] } 

    # This is the object that you're looking for... 
    $aclDS=New-Object System.Security.AccessControl.DirectorySecurity -ArgumentList @($Path,[System.Security.AccessControl.AccessControlSections]::None) 
    # The object, apparently, comes with a bonus rule... 
    $aclDS.RemoveAccessRuleSpecific($aclDS.Access[0]) 
    # Add the rules to our new object 
    for ($i=0; $i -lt $tempACL.Count; $i++) { 
     # I tried adding the rules directly but they didn't work. I have to re-create them. 
     $tempRule=New-Object System.Security.AccessControl.FileSystemAccessRule -ArgumentList @($tempACL[$i].IdentityReference,$tempACL[$i].FileSystemRights,$tempACL[$i].InheritanceFlags,$tempACL[$i].PropagationFlags,$tempACL[$i].AccessControlType) 
     $aclDS.AddAccessRule($tempRule) 
    } 
    # This has to be done after all the rules are added, otherwise it doesn't work 
    $aclDS.SetAccessRuleProtection($true,$false) 

    if ($ResetOwner.IsPresent) { 
     # Often, the default owner is SYSTEM. This ownership will prevent you from making any changes. 
     # So, we change owner to the local Administrator 
     $acl.SetOwner($owner) 
     # We have to apply it now because we are applying our ACLs in two stages. We won't be using Set-Acl again. 
     Set-Acl -Path $Path -AclObject $acl 
    } 

    # Lastly, apply our ACls 
    $dir=Get-Item -Path $Path 
    $dir.SetAccessControl($aclDS) 
    } 
} 
Cuestiones relacionadas