Uploaded image for project: 'Modules'
  1. Modules
  2. MODULES-4934

ACL propagation (affects => 'all') does not work well on Win 2012R2/2016

    XMLWordPrintable

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Done
    • None
    • None
    • acl
    • Needs Assessment

    Description

      When using the acl module in different OS (Windows Server 2008 R2; 2012 R2; 2016) and specifying the affects property, the module behaves differently. For 2012 R2 and 2016 it does not propagate the permissions on sub-folders and its sub-files.
      Note: My end goal is to copy a folder structure from a network shared folder to a local path.

      All the machines are running PowerShell >= 5.0; Puppet agent 4.8.2.

      I tested using a simple folder structure which I manually created (also tried in two different ways: via explorer and PowerShell - same results though).

      To set the following permissions works fine on Windows Server 2008 R2, but not on the remaining OS versions.

        acl { 'test Permissions explorer':
          target                     => 'c:/test-copy-explorer',
          purge                      => true,
          permissions                => [
            { identity => 'SYSTEM', rights => ["full"], child_types => 'all', affects => 'all' },
            { identity => 'Administrators', rights => ["full"], child_types => 'all', affects => 'all' },
          ],
          owner                      => 'SYSTEM',
          inherit_parent_permissions => false,
        }
      

      Results on Windows Server 2008 R2:

      Results on Windows Server 2012 R2/2016:

      Since my goal is to copy from a network shared folder to a local path and then set the ACL I tried two different scenarios:

      1. Using the file resource:

      file { 'c:/test-file':
            ensure  => directory,
            recurse => true,
            purge   => true,
            source  => '//server/share/test-folder'
        }
       
        acl { 'Permissions test-file':
          target                     => 'c:/test-file',
          purge                     => true,
          permissions           => [
            { identity => 'SYSTEM', rights => ["full"], child_types => 'all', affects => 'all' },
            { identity => 'Administrators', rights => ["full"], child_types => 'all', affects => 'all' },
          ],
          owner                      => 'SYSTEM',
          inherit_parent_permissions => false,
          require                    => File['c:/test-file'],
        }
      

      This solution works on both platforms. The problem is that I want to sync the folders, and the file resource doesn't do this correctly (when a folder is renamed, it just deletes its contents but not the folder itself).

      1. Using a PowerShell script to sync the folders and then apply the ACLs

        $test_source_dir = '//server/share/test-folder'
        $test_target_dir = 'C:/test-psscript'
       
        # This script syncs the content of source_dir to target_dir. It considers source as the master (always correct) and deletes target_dir whenever there are differences
        exec { 'Sync test-folder':
          command  => "\\\\server\\share\\scripts\\Sync-Files.ps1 ${test_source_dir} ${test_target_dir}",
          provider => powershell
        }
       
        acl { 'Permissions test-psscript':
          target                     => 'c:/test-psscript',
          purge                     => true,
          permissions           => [
            { identity => 'SYSTEM', rights => ['full'], child_types => 'all', affects => 'all' },
            { identity => 'Administrators', rights => ['full'], child_types => 'all', affects => 'all' },
              ],
          owner                     => 'SYSTEM',
          inherit_parent_permissions => false,
          require                   => Exec['Sync test-folder'],
        }
      
      

      As the first examples with the creation of new folders, this solution only works on Windows Server 2008 R2. For the others it doesn't set the ACLs on the subfolders.

      Here is the PowerShell Script:

      Param(
      [Parameter(Mandatory=$true)][string]$SourceDirPath,
      [Parameter(Mandatory=$true)][string]$TargetDirPath
      )
      # Exit codes for Puppet: Exit 0 - Success (no errors); Exit 1 - Failed (errors)
       
      Function Compute-Hash {
          
      Param($Path, $Algorithm )
       
          if ($PSVersionTable.PSVersion.Major -ge 4) {
              return $(Get-FileHash -Path $Path -Algorithm $Algorithm).Hash
          } else {
              $hash = [Security.Cryptography.HashAlgorithm]::Create( $Algorithm )
              $stream = ([IO.StreamReader]"$Path").BaseStream
              $output = -join ($hash.ComputeHash($stream) | ForEach { "{0:x2}" -f $_ })
              $stream.Close()
              $object = New-Object -TypeName psobject -Property @{
                  Algorithm = $Algorithm
                  Hash = $output.ToUpper()
                  Path = $Path
              }
              return $object
          }
       
      }
       
      #source dir must exist
      if(!(Test-Path $SourceDirPath)){
          exit 1
      }
       
      # ! $_.PSIsContainer ignores directories
      $SourceDirFiles = Get-ChildItem -Recurse -Path $SourceDirPath | where { ! $_.PSIsContainer } 
       
      #SourceDirFileHashes = $SourceDirFiles| foreach  {Compute-Hash -Path $_.FullName -Algorithm MD5}
      #Write-Host "SourceDir File Hashes:" # TODO DEBUG
      #$SourceDirFileHashes # TODO DEBUG
       
      # target dir exists
      if(Test-Path $TargetDirPath){
          $TargetDirFiles = Get-ChildItem -Recurse -Path $TargetDirPath | where { ! $_.PSIsContainer } 
          $TargetDirFiles
          $TargetDirFileHashes = $TargetDirFiles| foreach  {Compute-Hash -Path $_.FullName -Algorithm MD5}
          #Write-Host "TargetDir File Hashes:" # TODO DEBUG
          #$TargetDirFileHashes # TODO DEBUG
          
          # Compares file names 
          $FilesDiff = Compare-Object -ReferenceObject $SourceDirFiles -DifferenceObject $TargetDirFiles
          #Write-Host "FilesDiff:" # TODO DEBUG
          #$FilesDiff # TODO DEBUG
          
          # Compares file contents
          # $FileHashesDiff = Compare-Object -ReferenceObject $SourceDirFileHashes.Hash -DifferenceObject $TargetDirFileHashes.Hash -IncludeEqual
          $FileHashesDiff = Compare-Object -ReferenceObject $SourceDirFileHashes -DifferenceObject $TargetDirFileHashes
          #Write-Host "FileHashesDiff:" # TODO DEBUG
          #$FileHashesDiff # TODO DEBUG
       
          if(($FilesDiff.SideIndicator.Length -eq 0) -and ($FileHashesDiff.SideIndicator.Length -eq 0)){
              #echo 'empty - no diffs! Do nothing! exiting...' #TODO DEBUG
              exit 0
          } else {
              #echo 'different trees. Deleting dir ...' #TODO DEBUG
              Remove-Item $TargetDirPath -Recurse -Force
          }
      }
      #echo 'copying source dir...' #TODO DEBUG
      Copy-Item $SourceDirPath -Destination $TargetDirPath -Recurse
      exit 0
      

      Attachments

        Issue Links

          Activity

            People

              ethan Ethan Brown
              ricardogaspar2 Ricardo Gaspar
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Zendesk Support