test: extend the live tests in the lab to all cmdlet groups
Add the cases 4b (orphaned audit entry), 5 (owner), 6 (audit inheritance,
Clear-NTFSAudit, Get-NTFSInheritance), 7 (item cmdlets on the share),
8 (link cmdlets on the share), and 9 (Get-NTFSSimpleAccess), and the
accounts of three other domains and forests (-ForeignDomainController).
The fixture writes the folders with SetAccessControl instead of Set-Acl,
which also wrote an empty SACL and dropped the inherited audit entries.
The delegated account expects the denial of Get-NTFSEffectiveAccess
-ServerName, which the file server answers only for its administrators
and the members of Access Control Assistance Operators.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
$null=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Remove the share and the folders'-ScriptBlock$removeFileServerScript-ArgumentList$shareName,$shareLocalPath,$payloadPath,$localGroupName,$accountSids@labCommand
$null=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Remove the share and the folders'-ScriptBlock$removeFileServerScript-ArgumentList$shareName,$shareLocalPath,$payloadPath,$localGroupName,$accountSids@labCommand
$null=Invoke-LabCommand-ComputerName$Client-ActivityName'Remove the members and the folder'-ScriptBlock$removeClientScript-ArgumentList$payloadPath,$accountSids@labCommand
$null=Invoke-LabCommand-ComputerName$Client-ActivityName'Remove the members and the folder'-ScriptBlock$removeClientScript-ArgumentList$payloadPath,$accountSids@labCommand
$null=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Remove the accounts'-ScriptBlock$removeAccountScript-ArgumentList$organizationalUnitName@labCommand
$null=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Remove the accounts'-ScriptBlock$removeAccountScript-ArgumentList$organizationalUnitName@labCommand
foreach($computerin$ForeignDomainController){
$null=Invoke-LabCommand-ComputerName$computer-ActivityName'Remove the account of another domain'-ScriptBlock$removeAccountScript-ArgumentList$organizationalUnitName@labCommand
}
Write-LabProgress"Removed the live tests from the lab '$LabName'."
Write-LabProgress"Removed the live tests from the lab '$LabName'."
$directory=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Prepare the accounts'-ScriptBlock$accountScript-ArgumentList$organizationalUnitName,$passwords,$groupMembers@labCommand
$directory=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Prepare the accounts'-ScriptBlock$accountScript-ArgumentList$organizationalUnitName,$passwords,$groupMembers@labCommand
$account=Invoke-LabCommand-ComputerName$ForeignDomainController[$index]-ActivityName'Prepare the account of another domain'-ScriptBlock$foreignAccountScript-ArgumentList$organizationalUnitName,$foreignAccount,(New-LabPassword)@labCommand
$localGroupSid=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Prepare the file server'-ScriptBlock$fileServerSetupScript-ArgumentList$shareName,$shareLocalPath,$payloadPath,$localGroupName,$sids[$subjectAccount],@($sids['NtfsLiveServerAdmin'],$sids['NtfsLiveAdmin']),$sids['NtfsLiveDelegates']@labCommand
$localGroupSid=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Prepare the file server'-ScriptBlock$fileServerSetupScript-ArgumentList$shareName,$shareLocalPath,$payloadPath,$localGroupName,$sids[$subjectAccount],@($sids['NtfsLiveServerAdmin'],$sids['NtfsLiveAdmin']),$sids['NtfsLiveDelegates']@labCommand
$null=Invoke-LabCommand-ComputerName$Client-ActivityName'Prepare the client'-ScriptBlock$clientSetupScript-ArgumentList$payloadPath,@($sids['NtfsLiveDelegate'],$sids['NtfsLiveAdmin']),@($sids['NtfsLiveServerAdmin'])@labCommand
$null=Invoke-LabCommand-ComputerName$Client-ActivityName'Prepare the client'-ScriptBlock$clientSetupScript-ArgumentList$payloadPath,@($sids['NtfsLiveDelegate'],$sids['NtfsLiveAdmin']),@($sids['NtfsLiveServerAdmin'])@labCommand
foreach($computerin$Client,$FileServer){
foreach($computerin$Client,$FileServer){
@ -880,8 +1034,9 @@ foreach ($module in $modules) {
NtfsLiveOuter=$sids['NtfsLiveOuter']
NtfsLiveOuter=$sids['NtfsLiveOuter']
LocalGroup=[string]$localGroupSid
LocalGroup=[string]$localGroupSid
Orphan=$orphan.Sid
Orphan=$orphan.Sid
Subject=$sids[$subjectAccount]
}
}
$fixture=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Create the folders of the run'-ScriptBlock$fixtureScript-ArgumentList$helperScript,$shareLocalPath,$runId,$fixtureSids,$subjectPrincipalName,$longPathSegments@labCommand
$fixture=Invoke-LabCommand-ComputerName$FileServer-ActivityName'Create the folders of the run'-ScriptBlock$fixtureScript-ArgumentList$helperScript,$shareLocalPath,$runId,$fixtureSids,$subjectPrincipalName,$longPathSegments,$foreignAccounts@labCommand
$null=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Delete the orphan account'-ScriptBlock$removeOrphanScript-ArgumentList$orphan.Guid@labCommand
$null=Invoke-LabCommand-ComputerName$DomainController-ActivityName'Delete the orphan account'-ScriptBlock$removeOrphanScript-ArgumentList$orphan.Guid@labCommand
$oracle=Invoke-LabCommand-ComputerName$Client-ActivityName'Calculate the rights on the client'-ScriptBlock$clientOracleScript-ArgumentList$helperScript,$fixture.EffectiveAccessSddl,$subjectPrincipalName,$orphan.Sid@labCommand
$oracle=Invoke-LabCommand-ComputerName$Client-ActivityName'Calculate the rights on the client'-ScriptBlock$clientOracleScript-ArgumentList$helperScript,$fixture.EffectiveAccessSddl,$subjectPrincipalName,$orphan.Sid@labCommand
if($oracle.OrphanResolved){
if($oracle.OrphanResolved){
@ -911,6 +1066,17 @@ foreach ($module in $modules) {
@ -13,11 +13,16 @@ without a lab they skip every test.
| --- | --- | --- |
| --- | --- | --- |
| 1, [#34][issue-34] | Delegate | `Add-NTFSAccess`, `Remove-NTFSAccess`, `Clear-NTFSAccess`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAccessInheritance`, `Set-NTFSInheritance`, and `Set-NTFSSecurityDescriptor` on share folders that Administrators own and on which a domain group has Full Control, run by a member of that group who isn't an administrator of the file server. They succeed and keep the owner. |
| 1, [#34][issue-34] | Delegate | `Add-NTFSAccess`, `Remove-NTFSAccess`, `Clear-NTFSAccess`, `Disable-NTFSAccessInheritance`, `Enable-NTFSAccessInheritance`, `Set-NTFSInheritance`, and `Set-NTFSSecurityDescriptor` on share folders that Administrators own and on which a domain group has Full Control, run by a member of that group who isn't an administrator of the file server. They succeed and keep the owner. |
| 2 | Admin, ServerAdmin, Delegate | `Get-NTFSAudit`, `Add-NTFSAudit`, and `Remove-NTFSAudit` on share folders. Over SMB, the file server checks the Security privilege of the account. The administrators of the file server read and change the audit entries; the delegated account gets the errors that the cmdlet pages describe, and the folders stay unchanged. |
| 2 | Admin, ServerAdmin, Delegate | `Get-NTFSAudit`, `Add-NTFSAudit`, and `Remove-NTFSAudit` on share folders. Over SMB, the file server checks the Security privilege of the account. The administrators of the file server read and change the audit entries; the delegated account gets the errors that the cmdlet pages describe, and the folders stay unchanged. |
| 3 | Admin | `Get-NTFSEffectiveAccess` for a domain account with rights through two nested domain groups and through a local group of the file server. With `-ServerName`, the result includes the local group, without a warning; without it, the client doesn't know that group. With an unreachable server, the cmdlet falls back to the client and warns. |
| 3 | Admin, Delegate | `Get-NTFSEffectiveAccess` for a domain account with rights through two nested domain groups and through a local group of the file server. With `-ServerName`, the result includes the local group, without a warning; without it, the client doesn't know that group. With an unreachable server, the cmdlet falls back to the client and warns. The authorization manager of the file server refuses the delegated account, which isn't an administrator there, and the cmdlet reports that as an error, not as no access. |
| 4 | Admin | `Get-NTFSOrphanedAccess` returns the entry of a deleted domain account with its SID, on the folder and as inherited entry on a file in it. |
| 4 | Admin | `Get-NTFSOrphanedAccess` returns the entry of a deleted domain account with its SID, on the folder and as inherited entry on a file in it; `Get-NTFSOrphanedAudit` returns the audit entry of that account. |
| 5 | Admin, ServerAdmin, Delegate | `Get-NTFSOwner` and `Set-NTFSOwner` on share folders that Administrators own. Every role makes itself the owner; only the administrators of the file server, which hold the Restore privilege there, assign another account. The delegated account gets a `SetOwnerError`, and the owner stays. |
| 6 | Admin, ServerAdmin, Delegate | `Disable-NTFSAuditInheritance`, `Enable-NTFSAuditInheritance`, `Clear-NTFSAudit`, and `Get-NTFSInheritance` on share folders that inherit an audit entry. The administrators of the file server change the audit entries; the delegated account gets the errors that the cmdlet pages describe, and `Get-NTFSInheritance` reports no audit state for it. |
| 7 | Delegate | `Get-Item2`, `Test-Path2`, `Get-FileHash2`, `Copy-Item2`, `Move-Item2`, `Remove-Item2`, and `Get-ChildItem2` in a share folder. |
| 8 | Admin | `New-NTFSHardLink`, `Get-NTFSHardLink`, and `New-NTFSSymbolicLink` in a share folder. Windows can't list the names of a file on a share, so `Get-NTFSHardLink` and `New-NTFSHardLink -PassThru` write the `GetHardLinkError` that their pages describe. |
| 9 | Delegate, Admin | `Get-NTFSSimpleAccess` compares a share folder with its parent. For the accounts of another domain and of other forests, `Get-NTFSAccess` returns their names, `Get-NTFSOrphanedAccess` doesn't report them, `Add-NTFSAccess` and `Remove-NTFSAccess` find them by name, and `Get-NTFSEffectiveAccess -ServerName` returns the rights that the file server's own token of each account gets. |
| Long paths | Admin | `Get-ChildItem2` and `Get-NTFSAccess` with a share path longer than 260 characters. |
| Long paths | Admin | `Get-ChildItem2` and `Get-NTFSAccess` with a share path longer than 260 characters. |
| [#108][issue-108] | Admin | `Copy-Item2` and `Move-Item2` with `-WhatIf` onto an existing file on the share write no error. |
| [#108][issue-108] | Admin | `Copy-Item2` and `Move-Item2` with `-WhatIf` onto an existing file on the share write no error. |
| State | Server | After the runs on the client, the file server checks the owners and the audit entries of the folders itself, without the module. |
| State | Server | After the runs on the client, the file server checks the owners, the audit entries, the items, the links, and the entries of the foreign accounts itself, without the module. |
Case 1 uses two kinds of folders. Before 5.0.0-rc3, the cmdlets wrote back the
Case 1 uses two kinds of folders. Before 5.0.0-rc3, the cmdlets wrote back the
owner that Windows returns with a DACL without the auto-inherit flag, and the
owner that Windows returns with a DACL without the auto-inherit flag, and the
@ -29,7 +34,8 @@ Windows 2000. `Set-NTFSSecurityDescriptor` wrote the owner on both kinds.
The expected rights of case 3 come from the tokens that the file server and the
The expected rights of case 3 come from the tokens that the file server and the
client create for the account with a Kerberos S4U logon, the way the Effective
client create for the account with a Kerberos S4U logon, the way the Effective
Access tab of the advanced security settings does.
Access tab of the advanced security settings does. Case 9 calculates the rights
of the foreign accounts the same way, on the file server.
## Roles
## Roles
@ -43,7 +49,8 @@ Access tab of the advanced security settings does.
The script also creates `NtfsLiveSubject`, the account of case 3, which is a
The script also creates `NtfsLiveSubject`, the account of case 3, which is a
member of `NtfsLiveInner`, a member of `NtfsLiveOuter`, and of the local group
member of `NtfsLiveInner`, a member of `NtfsLiveOuter`, and of the local group
`NtfsLiveLocal` of the file server, and `NtfsLiveOrphan`, which it deletes in
`NtfsLiveLocal` of the file server, and `NtfsLiveOrphan`, which it deletes in
every run.
every run. For case 9, it creates `NtfsLiveForeign` in the organizational unit
`NTFSSecurityLive` of each domain of `-ForeignDomainController`.
## Lab
## Lab
@ -55,11 +62,15 @@ use the lab of
`tests/Lab/Deploy-WindowsAccessControlLab.ps1` in that repository deploys:
`tests/Lab/Deploy-WindowsAccessControlLab.ps1` in that repository deploys:
`F1ADC1` as domain controller, `F1AFile2` as file server, and `F1AFile1` as
`F1ADC1` as domain controller, `F1AFile2` as file server, and `F1AFile1` as
client, all in `a.forest1.net`. `-DomainController`, `-FileServer`, and
client, all in `a.forest1.net`. `-DomainController`, `-FileServer`, and
`-Client` select other machines.
`-Client` select other machines. Case 9 uses `F1BDC1` of `b.forest1.net`, a
domain of the same forest, and `F2DC1` and `F3DC1` of the forests
`forest2.net` and `forest3.net`, which have forest trusts with `forest1.net`;
`-ForeignDomainController @()` leaves it out.
The script adds to the lab:
The script adds to the lab:
- the organizational unit `NTFSSecurityLive` with the accounts and groups
- the organizational unit `NTFSSecurityLive` with the accounts and groups, and
with `NtfsLiveForeign` in the domains of the foreign domain controllers
- the local group `NtfsLiveLocal` and members of Administrators on the file
- the local group `NtfsLiveLocal` and members of Administrators on the file
server, and members of Administrators and Remote Management Users on the
server, and members of Administrators and Remote Management Users on the