Reset ACL/SDDL to deal with authorization problems in ReFS or NTFS
This article records my procedures for dealing with authorization
problems in ReFS
or NTFS with Windows
system. In this article, we do not talk about the relationship between
Authorization
and File System
. And we do not
differentiate which File System
can support the
corresponding operations and rules about Authorization
.
That is, if we encounter authorization problems, we almost can follow
the actions in this article, since if a File System
does
not support authorization operations, it may not bring us authorization
problems.
Some crucial codes can be found in Authorization.ps1
and Manager.Authorization.ps1,
which have been integrated in Zhaopudark/PSComputerManagementZp,
one of my customized PowerShell Modules. But for direct usage, you just
need to install this module and use its public API Reset-Authorization
.
This article, as well as Reset-Authorization
,
does have some limitations,
and the 2 key points of them are:
- Do not distinguish between multiple users. You should be very
careful when using
Reset-Authorization
when it works on other user’s items. - Do not work on all types of items. Only works on some common types of items.
Please take care of these limitations to protect your data safety. The following will give out details.
Motivation
When we use an operating system to process some resources that existed before this system, we may encounter some authorization problems. Because these pre-existing resources may retain previous authorization information, which will not necessarily be identified or managed correctly by the new system as our expectation.
For example, consider re-installing a new Windows system, and
maintaining the files in a non-system drive. Then, we may find some of
our user files in a non-system drive may belong to an unknown account
because our user ID has changed, even though we log in to the new system
with the same account as before. This phenomenon may incur authorization
problems when later usage, such as Git
will report a warning
that the current user is different from the before one that established
a local repository.
To deal with the above authorization problems, we can recover the default authorization state for those resources. From the aspect of technology, these are problems and solutions related to Computer security - Wikipedia, which is a big, important, and complex topic that I am unable to fully understand or elaborate on clearly. But from the experience aspect, I share my operations about recovering some non-system files on my PC when authorization problems occur. In this article, I post some elementary explanations of the concepts and principles of the used operations.
Personal view: I’m tired of the complexity of the GUI of the Window
system. Even though GUI is usually considered a simple and easy-learning
method to use a computer, for Automation
, the CLI is a
better way. In this article, almost all the operations are done through
PowerShell. This article is very suitable for those using and managing
an individual PC.
WARNING: For those who share a PC with others, you should take care of the operations and ensure they only affect the resources that belong to yourself, without influencing others’ items.
Precedent Concepts and Analization:
Authorization on Windows: Authorization is the right granted an individual to use the system and the data stored on it. Authorization is typically set up by a system administrator and verified by the computer based on some form of user identification, such as a code number or password. Microsoft authorization technologies include Authorization Manager and the Authz API. 1
Access Control (Authorization on Windows): Access control refers to security features that control who can access resources in the operating system. Applications call access control functions to set who can access specific resources or control access to resources provided by the application.2 Authorization includes Access Control, Access Control Editor, Client/Server Access Control, Access Control for Application Resources, Mandatory Integrity Control and User Account Control.
Access Control Model: The access control model enables you to control the ability of a process to access securable objects or to perform various system administration tasks.3 There are two basic parts of the access control model: Access tokens and Security descriptors 4
Access tokens, which contain information about a logged-on user. 5An access token is an object that describes the security context of a process or thread. The information in a token includes the identity and privileges of the user account associated with the process or thread. When a user logs on, the system verifies the user’s password by comparing it with information stored in a security database. If the password is authenticated, the system produces an access token. Every process executed on behalf of this user has a copy of this access token. 6
Security descriptors, which contain the security information that protects a securable object.7 A security descriptor contains the security information associated with a securable object. A security descriptor consists of a SECURITY_DESCRIPTOR structure and its associated security information. A security descriptor can include the following security information:8
- Security identifiers (SIDs) for the owner and primary group of an object.9
- A DACL that specifies the access rights allowed or denied to particular users or groups.10
- A SACL that specifies the types of access attempts that generate audit records for the object.11
- A set of control bits that qualify the meaning of a security descriptor or its individual members.12
Securable objects: A securable object is an object that can have a security descriptor. All named Windows objects are securable. Some unnamed objects, such as process and thread objects, can have security descriptors too. 13
SID: A security identifier (SID) is a unique value of variable length used to identify a trustee. Each account has a unique SID issued by an authority, such as a Windows domain controller, and stored in a security database. Each time a user logs on, the system retrieves the SID for that user from the database and places it in the access token for that user. The system uses the SID in the access token to identify the user in all subsequent interactions with Windows security. When a SID has been used as the unique identifier for a user or group, it cannot ever be used again to identify another user or group.14
ACL: In computer security, an access-control list (ACL) is a list of permissions associated with a system resource (object). An ACL specifies which users or system processes are granted access to objects, as well as what operations are allowed on given objects. Each entry in a typical ACL specifies a subject and an operation. For instance, if a file object has an ACL that contains (Alice: read,write; Bob: read), this would give Alice permission to read and write the file and give Bob permission only to read it.15On Windows system, An ACL is a list of access control entries (ACE). Each ACE in an ACL identifies a trustee and specifies the access rights allowed, denied, or audited for that trustee. The security descriptor for a securable object can contain two types of ACLs: a DACL and an SACL.16
ACE: An access control entry (ACE) is an element in an access control list (ACL). An ACL can have zero or more ACEs. Each ACE controls or monitors access to an object by a specified trustee. 17
DACL: A discretionary access control list (DACL) identifies the trustees that are allowed or denied access to a securable object. When a process tries to access a securable object, the system checks the ACEs in the object’s DACL to determine whether to grant access to it. If the object doesn’t have a DACL, the system grants full access to everyone. If the object’s DACL has no ACEs, the system denies all attempts to access the object because the DACL doesn’t allow any access rights. The system checks the ACEs in sequence until it finds one or more ACEs that allow all the requested access rights, or until any of the requested access rights are denied.18
SACL: A system access control list (SACL) allows administrators to log attempts to access a secured object. Each ACE specifies the types of access attempts by a specified trustee that cause the system to generate a record in the security event log. An ACE in an SACL can generate audit records when an access attempt fails, when it succeeds, or both. 19
Access Check: When a thread tries to access a securable object, the system either grants or denies access. If the object does not have a discretionary access control list (DACL), the system grants access; otherwise, the system looks for Access Control Entries (ACEs) in the object’s DACL that apply to the thread. Each ACE in the object’s DACL specifies the access rights allowed or denied for a trustee, which can be a user account, a group account, or a logon session.20
- When a thread attempts to use a securable object, the system performs an access check before allowing the thread to proceed. In an access check, the system compares the security information in the thread’s access token against the security information in the object’s security descriptor. The system checks the object’s DACL, looking for ACEs that apply to the user and group SIDs from the thread’s access token. The system checks each ACE until access is either granted or denied or until there are no more ACEs to check. Conceivably, an access control list (ACL) could have several ACEs that apply to the token’s SIDs. And, if this occurs, the access rights granted by each ACE accumulate. For example, if one ACE grants read access to a group and another ACE grants write access to a user who is a member of the group, the user can have both read and write access to the object.21
- If a Windows object does not have a discretionary access control list (DACL), the system allows everyone full access to it. If an object has a DACL, the system allows only the access that is explicitly allowed by the access control entries (ACEs) in the DACL. If there are no ACEs in the DACL, the system does not allow access to anyone. Similarly, if a DACL has ACEs that allow access to a limited set of users or groups, the system implicitly denies access to all trustees not included in the ACEs. In most cases, you can control access to an object by using access-allowed ACEs; you do not need to explicitly deny access to an object. The exception is when an ACE allows access to a group and you want to deny access to a member of the group. To do this, place an access-denied ACE for the user in the DACL ahead of the access-allowed ACE for the group. Note that the order of the ACEs is important because the system reads the ACEs in sequence until access is granted or denied. The user’s access-denied ACE must appear first; otherwise, when the system reads the group’s access allowed ACE, it will grant access to the restricted user.22
- If the discretionary access control list (DACL) that belongs to an object’s security descriptor is set to NULL, a null DACL is created. A null DACL grants full access to any user that requests it; normal security checking is not performed with respect to the object. A null DACL should not be confused with an empty DACL. An empty DACL is a properly allocated and initialized DACL that contains no access control entries (ACEs). An empty DACL grants no access to the object it is assigned to.23
Security Descriptor Definition Language (SDDL): The security descriptor definition language (SDDL) defines the string format that the ConvertSecurityDescriptorToStringSecurityDescriptor and ConvertStringSecurityDescriptorToSecurityDescriptor functions use to describe a security descriptor as a text string. The language also defines string elements for describing information in the components of a security descriptor.24 The format is a null-terminated string with tokens to indicate each of the four main components of a security descriptor: owner
(O:)
, primary group(G:)
, DACL(D:)
, and SACL(S:)
.25
O:owner_sid
- A SID string that identifies the object’s owner.
G:group_sid
- A SID string that identifies the object’s primary group.
D:dacl_flags(string_ace1)(string_ace2)… (string_acen)
Security descriptor control flags that apply to the DACL. For a description of these control flags, see the SetSecurityDescriptorControl function. The dacl_flags string can be a concatenation of zero or more of the following strings.
ontrol Constant in Sddl.h Meaning “P” SDDL_PROTECTED The SE_DACL_PROTECTED flag is set. “AR” SDDL_AUTO_INHERIT_REQ The SE_DACL_AUTO_INHERIT_REQ flag is set. “AI” SDDL_AUTO_INHERITED The SE_DACL_AUTO_INHERITED flag is set. “NO_ACCESS_CONTROL” SDDL_NULL_ACL The ACL is null. Windows Server 2008, Windows Vista and Windows Server 2003: Not available. S:sacl_flags(string_ace1)(string_ace2)… (string_acen)
- Security descriptor control flags that apply to the SACL. The sacl_flags string uses the same control bit strings as the dacl_flags string.
- string_ace: A string that describes an ACE in the security descriptor’s DACL or SACL. For a description of the ACE string format, see ACE strings. Each ACE string is enclosed in parentheses. The syntax is
ace_type;ace_flags;rights;object_guid;inherit_object_guid;account_sid;(resource_attribute)
26
In the following content, we will treat SDDL
and
SDDL
string as the same thing.
So, basing on the above concepts, on Windows, to solve authorization
problems mentioned in the first section, i.e., how to recover the
default authorization state of problem resources, is mainly about how to
realize Access Control
. Generally, we cannot change our
access tokens
when we have logged on. Hence the only way
may be to change the security descriptors of target resources to default
state, i.e., to change SDDLs
of target files and
directories to default values. Here are some methods to realize the
modification of SDDLs
:
- icacls tool: Displays or modifies discretionary access control lists (DACLs) on specified files, and applies stored DACLs to files in specified directories.27
- Indirect PowerShell command with
.NET
ObjectSecurity Class (System.Security.AccessControl) - Direct PowerShell command with
.NET
ObjectSecurity Class (System.Security.AccessControl) - Other APIs or languages, such as C++, VB, Java, Python and JavScript.
My Solution
In this article, my solution is the third one in the above methods,
i.e., “Direct PowerShell command with .NET
object
System.Security.AccessControl
”. since it may be the easiest
and simplest way. To realize it, we only need to know the default
SDDLs
instead of learning specific items in the concept of
SDDLs
. With the help of reverse engineering, we even do not
need to know how SDDLs
are compatible with different type
of items in our normal scenarios, but just get a default system, build
types of items, test, and get the corresponding default
SDDLs
of them. For example, if we establish a native and
new Windows system and make a new file or directory in a target
location, the SDDLs
of these created items will be the
default one we need.
Take the following steps:
(Optional) Make sure the PC is not used by 2 or more than 2 people in
User
level. This is an important premise of this article. Why?- In the following definition about common types of items, we hold the view that any non-system drives (disks) are possessed by a same single user.
- In the system drive, usually
C:
, we make use of$Home
to differentiate users automatically. But when it comes to non-system drives (disks), there is no such mechanism. - In this article, we will check/modify any items in
$Home
and non-system drives (disks), which means we should totally control$Home
and non-system drives. - If a PC has 2 or more than 2 people in
User
level, we cannot guarantee the items in non-system drives (disks) are all possessed by the current user. - We should not change any authorization information on the items possessed by others, even though we have access to change.
If there is actually more than 1 user, all items of other users should be manually and carefully isolated to some directories or drives that won’t be involved.
Define an item type list that contains some common types of items for reverse engineering.
- It may be impossible to test all types of items since there are too many types of items and there are too many factors that influence items’ types, such as drive formats, FileAttributes (System.IO) and special usages.
- So, actually, we can only test on a limited number of types of items
and get a limited number of default
SDDLs
. - But as long as we cover common types of items, the method in this article is also practiced. Because for us, common users, most of the user data are just within common types.
Get these items’ default
SDDLs
.Reset these items’ default
SDDLs
.If an item appears in the item type list, we forcedly modify its
SDDL
to defaultSDDL
If an item does not appear in the item type list, we skip it.
These steps has been integrated in a public API Reset-Authorization
of PowerShell Module Zhaopudark/PSComputerManagementZp.
For normal usage, if you want to reset items in drive D:\
,
you can install the model and do as:
1 | #Requires -Version 7.0 |
For more details, you can check Appendix for 3 key points:
- How to define an item type list that contains some common types of items. See A.2 Types of Items
- How to get these items’ default
SDDLs
. See A.3 GetSDDL
- How to reset these items’
SDDLs
to default status. See A.4 ResetSDDL
Conclusion
In this article, we introduce some basic aspects of Authorization on Windows and give out a personal experience to reset authorization (ACL/SDDL) of items in Windows file system ReFS or NTFS. The simple usage of the article is:
- In stall a PowerShell Module Zhaopudark/PSComputerManagementZp.
- Run a PowerShell with
Administrator
privilege. - Use a public API
Reset-Authorization
of the installed module to reset target items’ authorizations.
Advantages
In the article, we use the most direct method, which is also a way of reverse engineering:
- Define some common types of items.
- Testing to get default
SDDLs
of these items. - Apply
SDDLs
on these items to achieve the “Reset” purpose.
So, there is no need to fully understand all the things about Authorization on Windows, ACL, Security Descriptor Definition Language (SDDL) and so on.
With the most introductory mastery of PowerShell and Windows development, we can deal with normal authorization problems in our daily usage.
That is to say, in this article, when encountering the big problem, Computer security - Wikipedia, we use indirect strategies and reverse engineering with the ideas of empiricism and pragmatism to handle it while avoiding escalating it into a big problem that we don’t need to fully wade through in our daily life.
Limitations
What you make is what you lose:
- The method in this article only suggested single-user scenarios, unless one fully understands Authorization on Windows and knows how to do it. This method is not designed to be very suitable for multi-user scenarios
- But, if one knows how to do and understands much about authorization on Windows, this article would have less reference to him/her.
- The method in this article is suitable for only the 28
common types of items. For those out of the defined items, we can do
nothing. Such as:
- Items in FAT32 file system. Because it does not support ACL.
- Uncommon item types in FileAttributes (System.IO).
- Any items within
<drive_letter>:\$('$Recycle.Bin')
and<drive_letter>:\System Volume Information
.- We have not yet known the relationship between the authorization
information of an item in
Recycle Bin
and the one of this item before it has been deleted. And, if we can change (we have not tested whether we can do it) the authorization information of items inRecycle Bin
, what specific authorization information they will have after restoring them fromRecycle Bin
? We have not known it. - And, for those items in
<drive_letter>:\System Volume Information
, we have almost no access to get into them and this may bringerrors
. We allow this error to occur without fixing it, because it will not affect other things, and it better reflects the importance of authorization issues. - So, we bypass any items in
<drive_letter>:\$('$Recycle.Bin')
and<drive_letter>:\System Volume Information
. See theReset-Authorization
function. - This may become a bug so we put it as a limitation here to inform all readers.
- We have not yet known the relationship between the authorization
information of an item in
- …
- For more complex using cases, the reference value of this paper is greatly reduced.
- For a single directory, the
Reset-Authorization
function can only support single-threaded jobs. Even though it can show the progress bar, when the number of items is large, it is still quite long to process. So it is needed to hang up to run for a long time.
Tips and References
Get-LocalUser (Microsoft.PowerShell.LocalAccounts) - PowerShell | Microsoft Learn
Properly checking if an item in a folder is a Directory or not in PowerShell (koskila.net)
Use a PowerShell Cmdlet to Work with File Attributes - Scripting Blog (microsoft.com)
Get-LocalUser (Microsoft.PowerShell.LocalAccounts) - PowerShell | Microsoft Learn
Properly checking if an item in a folder is a Directory or not in PowerShell (koskila.net)
Use a PowerShell Cmdlet to Work with File Attributes - Scripting Blog (microsoft.com)
Appendix
Details about my solution.
A.1 Generate types of paths
First, we can make a native Window System and make an extra NTFS drive
D:
and ReFS driveE:
. We can achieve this by Hyper-V with Window-11 system. Here is a example:NOTICE: We suggest using a normal Microsoft Account to log in to this Windows system. Because:
When we log in with local account and check an items’ authorization information in
$Home
, we may find the following situation:It may be too difficult to explain this phenomenon, but it must not the most common scenario.
In normal usage, the items created in
$Home
usually have the sameOwner
andGroup
, i.e., the current user, instead ofNone
with an SID, which cannot be associated to any known users or groups.So, to simulate real usage scenarios, we have better login the system with a normal Microsoft Account at the beginning(initialization).
Second, we should remove(delete)
Account Unkown
of$Home
in advance. Because when we install the operating system or upgrade the operating system, some temporary accounts will be created. And these accounts are likely to leave traces in the file system since the file system itself can exist independently of the operating system.Thirdly, the directory
D:\$('$Recycle.Bin')
andE:\$('$Recycle.Bin')
may not exist when driveD:
andE:
are initialing. We have better create aD:\New Text Document.txt
andE:\New Text Document.txt
, and then remove them toRecycle Bin
in advance to ensureD:\$('$Recycle.Bin')
andE:\$('$Recycle.Bin')
initialized.Then, we can generate the path examples that do not need administrator privileges as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74#Requires -Version 7.0
# $guid = [guid]::NewGuid()
$guid = "ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e"
New-Item -Path "${Home}\${guid}" -ItemType Directory | Out-Null
New-Item -Path "D:\${guid}" -ItemType Directory | Out-Null
New-Item -Path "E:\${guid}" -ItemType Directory | Out-Null
# NonSystemDisk[NTFS]\Root
# D:\
# NonSystemDisk[RTFS]\Root
# E:\
# Home\Root
# ${Home}\
# NonSystemDisk[NTFS]\System Volume Information
# D:\System Volume Information
# NonSystemDisk[NTFS]\$Recycle.Bin
# D:\$Recycle.Bin
# NonSystemDisk[ReFS]\System Volume Information
# E:\System Volume Information
# NonSystemDisk[ReFS]\$Recycle.Bin
# E:\$Recycle.Bin
# Home\Directory
# NonSystemDisk[NTFS]\Directory
# NonSystemDisk[ReFS]\Directory
New-Item -Path "${Home}\${guid}\test_dir" -ItemType Directory | Out-Null
New-Item -Path "D:\${guid}\test_dir" -ItemType Directory | Out-Null
New-Item -Path "E:\${guid}\test_dir" -ItemType Directory | Out-Null
# Home\Junction
# NonSystemDisk[NTFS]\Junction
# NonSystemDisk[ReFS]\Junction
New-Item -Path "${Home}\${guid}\test_dir_for_junction" -ItemType Directory | Out-Null
New-Item -Path "D:\${guid}\test_dir_for_junction" -ItemType Directory | Out-Null
New-Item -Path "E:\${guid}\test_dir_for_junction" -ItemType Directory | Out-Null
New-Item -Path "${Home}\${guid}\junction" -ItemType Junction -Target "${Home}\${guid}\test_dir_for_junction" | Out-Null
New-Item -Path "D:\${guid}\junction" -ItemType Junction -Target "D:\${guid}\test_dir_for_junction" | Out-Null
New-Item -Path "E:\${guid}\junction" -ItemType Junction -Target "E:\${guid}\test_dir_for_junction" | Out-Null
# Home\desktop.ini
# NonSystemDisk[NTFS]\desktop.ini
# NonSystemDisk[ReFS]\desktop.ini
Copy-Item -Path "${Home}\desktop\desktop.ini" -Destination "${Home}\${guid}\desktop.ini"
Copy-Item -Path "${Home}\desktop\desktop.ini" -Destination "D:\${guid}\desktop.ini"
Copy-Item -Path "${Home}\desktop\desktop.ini" -Destination "E:\${guid}\desktop.ini"
# Home\File
# NonSystemDisk[NTFS]\File
# NonSystemDisk[ReFS]\File
New-Item -Path "${Home}\${guid}\test_file.txt" -ItemType File | Out-Null
New-Item -Path "D:\${guid}\test_file.txt" -ItemType File | Out-Null
New-Item -Path "E:\${guid}\test_file.txt" -ItemType File | Out-Null
# Home\HardLink
# NonSystemDisk[NTFS]\HardLink
# NonSystemDisk[ReFS]\HardLink
New-Item -Path "${Home}\${guid}\test_file_for_hardlink.txt" -ItemType File | Out-Null
New-Item -Path "D:\${guid}\test_file_for_hardlink.txt" -ItemType File | Out-Null
New-Item -Path "E:\${guid}\test_file_for_hardlink.txt" -ItemType File | Out-Null
New-Item -Path "${Home}\${guid}\hardlink" -ItemType HardLink -Target "${Home}\${guid}\test_file_for_hardlink.txt" | Out-Null
New-Item -Path "D:\${guid}\hardlink"-ItemType HardLink -Target "D:\${guid}\test_file_for_hardlink.txt" | Out-Null
New-Item -Path "E:\${guid}\hardlink"-ItemType HardLink -Target "E:\${guid}\test_file_for_hardlink.txt" | Out-Null
# prepare for symbolic link
New-Item -Path "${Home}\${guid}\test_dir_for_symbolic_link" -ItemType Directory | Out-Null
New-Item -Path "D:\${guid}\test_dir_for_symbolic_link" -ItemType Directory | Out-Null
New-Item -Path "E:\${guid}\test_dir_for_symbolic_link" -ItemType Directory | Out-Null
New-Item -Path "${Home}\${guid}\test_file_for_symbolic_link.txt" -ItemType File | Out-Null
New-Item -Path "D:\${guid}\test_file_for_symbolic_link.txt" -ItemType File | Out-Null
New-Item -Path "E:\${guid}\test_file_for_symbolic_link.txt" -ItemType File | Out-NullThen, we can generate the path examples that need administrator privileges as:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#Requires -Version 5.0
#Requires -RunAsAdministrator
# $guid = [guid]::NewGuid()
$guid = "ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e"
New-Item -Path "${Home}\${guid}" -ItemType Directory | Out-Null
New-Item -Path "D:\${guid}" -ItemType Directory | Out-Null
New-Item -Path "E:\${guid}" -ItemType Directory | Out-Null
# Home\SymbolicLinkDirectory
New-Item -Path "${Home}\${guid}\symbolic_link" -ItemType SymbolicLink -Target "${Home}\${guid}\test_dir_for_symbolic_link" | Out-Null
# NonSystemDisk[NTFS]\SymbolicLinkDirectory
New-Item -Path "D:\${guid}\symbolic_link" -ItemType SymbolicLink -Target "D:\${guid}\test_dir_for_symbolic_link" | Out-Null
# NonSystemDisk[ReFS]\SymbolicLinkDirectory
New-Item -Path "E:\${guid}\symbolic_link" -ItemType SymbolicLink -Target "E:\${guid}\test_dir_for_symbolic_link" | Out-Null
# Home\SymbolicLinkFile
New-Item -Path "${Home}\${guid}\symbolic_link_txt" -ItemType SymbolicLink -Target "${Home}\${guid}\test_file_for_symbolic_link.txt" | Out-Null
# NonSystemDisk[NTFS]\SymbolicLinkFile
New-Item -Path "D:\${guid}\symbolic_link_txt" -ItemType SymbolicLink -Target "D:\${guid}\test_file_for_symbolic_link.txt" | Out-Null
# NonSystemDisk[ReFS]\SymbolicLinkFile
New-Item -Path "E:\${guid}\symbolic_link_txt" -ItemType SymbolicLink -Target "E:\${guid}\test_file_for_symbolic_link.txt" | Out-NullAt last, we get the following 28 specific paths.
Types Description Specific Path Example NonSystemDisk[NTFS]\Root
D:\
NonSystemDisk[ReFS]\Root
E:\
Home\Root
${Home}
NonSystemDisk[NTFS]\System Volume Information
D:\System Volume Information
NonSystemDisk[NTFS]\$Recycle.Bin
D:\$('$Recycle.Bin')
NonSystemDisk[ReFS]\System Volume Information
E:\System Volume Information
NonSystemDisk[ReFS]\$Recycle.Bin
E:\$('$Recycle.Bin')
Home\Directory
${Home}\${guid}\test_dir
Home\SymbolicLinkDirectory
${Home}\${guid}\symbolic_link
Home\Junction
${Home}\${guid}\junction
NonSystemDisk[NTFS]\Directory
D:\${guid}\test_dir
NonSystemDisk[NTFS]\SymbolicLinkDirectory
D:\${guid}\symbolic_link
NonSystemDisk[NTFS]\Junction
D:\${guid}\junction
NonSystemDisk[ReFS]\Directory
E:\${guid}\test_dir
NonSystemDisk[ReFS]\SymbolicLinkDirectory
E:\${guid}\symbolic_link
NonSystemDisk[ReFS]\Junction
E:\${guid}\junction
Home\desktop.ini
${Home}\${guid}\desktop.ini
Home\SymbolicLinkFile
${Home}\${guid}\symbolic_link_txt
Home\File
${Home}\${guid}\test_file.txt
Home\HardLink
${Home}\${guid}\hardlink
NonSystemDisk[NTFS]\desktop.ini
D:\${guid}\desktop.ini
NonSystemDisk[NTFS]\SymbolicLinkFile
D:\${guid}\symbolic_link_txt
NonSystemDisk[NTFS]\File
D:\${guid}\test_file.txt
NonSystemDisk[NTFS]\HardLink
D:\${guid}\hardlink
NonSystemDisk[ReFS]\desktop.ini
E:\${guid}\desktop.ini
NonSystemDisk[ReFS]\SymbolicLinkFile
E:\${guid}\symbolic_link_txt
NonSystemDisk[ReFS]\File
E:\${guid}\test_file.txt
NonSystemDisk[ReFS]\HardLink
E:\${guid}\hardlink
A.2 Types of Items
The PowerShell command
[enum]::GetValues([System.IO.FileAttributes])
can help us
to know the FileAttributes
(System.IO). There are 16 types of file attributes, i.e.,
ReadOnly
, Hidden
, System
,
Directory
, Archive
, Device
,
Normal
, Temporary
, SparseFile
,
ReparsePoint
, Compressed
,
Offline
, NotContentIndexed
,
Encrypted
, IntegrityStream
,
NoScrubData
. But from my experience, these attributes
usually appear in combination not individually except
Archive
. There are only 5 attribute combinations we may
encounter often in normal usage:
Attributes | Path Example |
---|---|
Hidden, System, Directory | D:\ or D:\System Volume Information\ or
D:\$Recycle.Bin\ |
Directory, ReparsePoint | D:\*some_symbolic_link_dir\ or
D:\*some_junction\ |
Hidden, System, Archive | D:\*desktop.ini |
Archive, ReparsePoint | D:\*some_symbolic_link_file |
Archive | D:\*some_hardlink |
And, a file system may also influence items’ SDDLs
in a
certain way. In this article, we only concern about those items that
hold in NTFS
and ReFS
since these 2 file systems are the most common two.
Therefore, here we define 28 common types of files, links or
directories as following (consider D:\
’s format is NTFS
while E:\
’s format is ReFS while):
Types Description | Path Example |
---|---|
NonSystemDisk[NTFS]\Root |
D:\ |
NonSystemDisk[RTFS]\Root |
E:\ |
Home\Root |
$Home\ |
NonSystemDisk[NTFS]\System Volume Information |
D:\System Volume Information |
NonSystemDisk[NTFS]\$Recycle.Bin |
D:\$Recycle.Bin |
NonSystemDisk[ReFS]\System Volume Information |
E:\System Volume Information |
NonSystemDisk[ReFS]\$Recycle.Bin |
E:\$Recycle.Bin |
Home\Directory |
$Home\*some_nomrmal_dir\ |
Home\SymbolicLinkDirectory |
$Home\*some_symbolic_link_dir\ |
Home\Junction |
$Home\*some_junction\ |
NonSystemDisk[NTFS]\Directory |
D:\*some_nomrmal_dir\ |
NonSystemDisk[NTFS]\SymbolicLinkDirectory |
D:\*some_symbolic_link_dir\ |
NonSystemDisk[NTFS]\Junction |
D:\*some_junction\ |
NonSystemDisk[ReFS]\Directory |
E:\*some_nomrmal_dir\ |
NonSystemDisk[ReFS]\SymbolicLinkDirectory |
E:\*some_symbolic_link_dir\ |
NonSystemDisk[ReFS]\Junction |
E:\*some_junction\ |
Home\desktop.ini |
$Home\*desktop.ini |
Home\SymbolicLinkFile |
$Home\*some_symbolic_link_file |
Home\File |
$Home\*some_normal_file or InHome\*some_sparse_file |
Home\HardLink |
$Home\*some_hardlink |
NonSystemDisk[NTFS]\desktop.ini |
D:\*desktop.ini |
NonSystemDisk[NTFS]\SymbolicLinkFile |
D:\*some_symbolic_link_file |
NonSystemDisk[NTFS]\File |
D:\*some_normal_file or D:\*some_sparse_file |
NonSystemDisk[NTFS]\HardLink |
D:\*some_hardlink |
NonSystemDisk[ReFS]\desktop.ini |
D:\*desktop.ini |
NonSystemDisk[ReFS]\SymbolicLinkFile |
D:\*some_symbolic_link_file |
NonSystemDisk[ReFS]\File |
D:\*some_normal_file or D:\*some_sparse_file |
NonSystemDisk[ReFS]\HardLink |
D:\*some_hardlink |
But, why the above 28 types are the common ones ? I think the reasons are (on Windows):
- Even though Personal Computers (PC) and Operating Systems (OS) can
support multiple users. But in our daily lives, the PC is more about its
personalization. So,
$Home
and non-system drives (disks) are the main region at user’s active disposal. There is a point of view that after a normal user logging in, most files or directories that are generated in the user folder or non-system drive should belong to this user. - Programs will not be installed outside of
C:\
without the permission of users. - The files of users, are mainly in the form of archives.
- For better usage of our files, we use links, i.e., Hard links, Junctions, and Symbolic Links.
- For better control of the appearance, we use
desktop.ini
.
NOTICE: These types are classified from the user’s
usage, and it is not necessary to guarantee that their
SDDLs
are mutually exclusive. For safety, the types out of
the above 28 ones are not mentioned, changed, modified, or
influenced.
See appendix A.1 to generate the above 28 path examples.
See function Get-PathType
for the codes to identify the above 28 types.
A.3 Get
SDDL
Consider we have the Get-PathType
function already, we can use the following Get-Sddl
function
to get a SDDL
as:
1 | #Requires -Version 7.0 |
NOTICE: The line
Set-Acl -Path $Path (Get-Acl $Path)
in
Get-Sddl
function is needed. Because a path’s
SDDL
may have a not initialized state, which is not the
same as the one set by Set-Acl -Path $Path (Get-Acl $Path)
,
even though this command seems to do nothing:
- Objectively speaking, it’s just a certain mechanism or a certain characteristic.
- But, in this article, we actually use PowerShell commands
Get-Acl
andSet-Acl
with.NET
ObjectSecurity Class (System.Security.AccessControl) to deal with authorization problems. - If a path’s
SDDL
has different states before and after usingSet-Acl -Path $Path (Get-Acl $Path)
, it means its initial state is not our target in this article, even though this state can still be explained as a default one on a broader level. - So, in this article, we consider
Set-Acl -Path $Path (Get-Acl $Path)
as a kind of initialization.
Therefore, we take the SDDL
of a path as a default one,
if:
- The path is a native path that is created by the current user, where the creation is a broad concept that any items that appear by the current user operations or commands can be considered as a created one.
- The path has been initialized by
Set-Acl -Path $Path (Get-Acl $Path)
- The path is without any other modification except the above operations.
Then, we get the SDDLs
of the 28 specific path examples
in appendix
A.1 as:
1 | Get-Sddl "D:\" |
Finally, we collect the above outputs to reveal the correct
SDDLs
as the following table, where
the$UserSid = (Get-LocalUser -Name ([Environment]::UserName)).SID.Value
Type | Example Path | SDDL |
---|---|---|
NonSystemDisk[NTFS]\Root |
D:\ |
O:SYG:SYD:AI(A;OICIIO;SDGXGWGR;;;AU)(A;;0x1301bf;;;AU)(A;;FA;;;SY)(A;OICIIO;GA;;;SY)(A;OICIIO;GA;;;BA)(A;;FA;;;BA)(A;;0x1200a9;;;BU)(A;OICIIO;GXGR;;;BU) |
NonSystemDisk[ReFS]\Root |
E:\ |
O:BAG:SYD:AI(A;OICIIO;SDGXGWGR;;;AU)(A;;0x1301bf;;;AU)(A;OICIIO;GA;;;SY)(A;;FA;;;SY)(A;OICI;FA;;;BA)(A;;0x1200a9;;;BU)(A;OICIIO;GXGR;;;BU) |
Home\Root |
C:\Users\User |
O:BAG:SYD:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;FA;;;${UserSid}) |
NonSystemDisk[NTFS]\System Volume Information |
D:\System Volume Information |
O:BAG:SYD:PAI(A;OICI;FA;;;SY) |
NonSystemDisk[NTFS]\$Recycle.Bin |
D:\$Recycle.Bin |
O:${UserSid}G:${UserSid}D:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;;0x1201ad;;;BU) |
NonSystemDisk[ReFS]\System Volume Information |
E:\System Volume Information |
O:BAG:SYD:PAI(A;OICI;FA;;;SY) |
NonSystemDisk[ReFS]\$Recycle.Bin |
E:\$Recycle.Bin |
O:${UserSid}G:${UserSid}D:PAI(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;;0x1201ad;;;BU) |
Home\Directory |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_dir |
O:${UserSid}G:${UserSid}D:AI(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;${UserSid}) |
Home\SymbolicLinkDirectory |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link |
O:BAG:${UserSid}D:AI(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;${UserSid}) |
Home\Junction |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\junction |
O:${UserSid}G:${UserSid}D:AI(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;FA;;;${UserSid}) |
NonSystemDisk[NTFS]\Directory |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_dir |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
NonSystemDisk[NTFS]\SymbolicLinkDirectory |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link |
O:BAG:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
NonSystemDisk[NTFS]\Junction |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\junction |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;ID;FA;;;BA)(A;OICIIOID;GA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
NonSystemDisk[ReFS]\Directory |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_dir |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;OICIID;FA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
NonSystemDisk[ReFS]\SymbolicLinkDirectory |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link |
O:BAG:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;OICIID;FA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
NonSystemDisk[ReFS]\Junction |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\junction |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;OICIIOID;SDGXGWGR;;;AU)(A;ID;FA;;;SY)(A;OICIIOID;GA;;;SY)(A;OICIID;FA;;;BA)(A;ID;0x1200a9;;;BU)(A;OICIIOID;GXGR;;;BU) |
Home\desktop.ini |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\desktop.ini |
O:${UserSid}G:${UserSid}D:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;FA;;;${UserSid}) |
Home\SymbolicLinkFile |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link_txt |
O:BAG:${UserSid}D:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;FA;;;${UserSid}) |
Home\File |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_file.txt |
O:${UserSid}G:${UserSid}D:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;FA;;;${UserSid}) |
Home\HardLink |
C:\Users\User\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\hardlink |
O:${UserSid}G:${UserSid}D:AI(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;FA;;;${UserSid}) |
NonSystemDisk[NTFS]\desktop.ini |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\desktop.ini |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[NTFS]\SymbolicLinkFile |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link_txt |
O:BAG:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[NTFS]\File |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_file.txt |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[NTFS]\HardLink |
D:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\hardlink |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[ReFS]\desktop.ini |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\desktop.ini |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[ReFS]\SymbolicLinkFile |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\symbolic_link_txt |
O:BAG:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[ReFS]\File |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\test_file.txt |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
NonSystemDisk[ReFS]\HardLink |
E:\ac6120eb-6f9e-4e75-9f4c-a41b576ffe3e\hardlink |
O:${UserSid}G:${UserSid}D:AI(A;ID;0x1301bf;;;AU)(A;ID;FA;;;SY)(A;ID;FA;;;BA)(A;ID;0x1200a9;;;BU) |
See function Get-DefaultSddl
for the codes that record and map the default SDDLs
the
above 28 types. We can use this function as
1 | #Requires -Version 7.0 |
So, by the codes in Get-DefaultSddl
,
there is no need to generate the above 28 path examples and get there
SDDLs
again.
A.4 Reset
SDDL
Even though items’ attributes in a file system, such as
Hidden
, Archive
, are not directly related to
SDDLs
, these attributes are still user-concerning and
sometimes in non-default status. Which may also bring unprespected
effects to users. For example, you may find a non-hidden
desktop.ini
occasionally within drive D:\
. In
order to address these issues together, we can use the Reset-PathAttribute
function to reset any items as long as they meet the following 8
types:
Type | Specific Path Example | Default Attributes |
---|---|---|
Directory | X:\ |
Hidden, System, Directory |
Directory | X:\System Volume Information\ |
Hidden, System, Directory |
Directory | X:\$Recycle.Bin\ |
Hidden, System, Directory |
Directory | X:\*some_symbolic_link_dir\ |
Directory, ReparsePoint |
Directory | X:\*some_junction\ |
Directory, ReparsePoint |
File | X:\*desktop.ini |
Hidden, System, Archive |
File | X:\*some_symbolic_link_file |
Archive, ReparsePoint |
File | X:\*some_hardlink |
Archive |
Here the X
represents any drive disk letter. And, if
X
represents the system disk drive letter, such as
C
, the path should only be or in ${Home}
.
Other directories’ attriibuts will not be reset. Other files’ attriibuts
will not be reset as well.
Then, the follwing are the main procedures of reseting the
SDDLs
of the items that appear A.2
Types of Items (Supposing we have the Get-PathType
function and Get-DefaultSddl
function already.):
1 | $path_type = Get-PathType $some_path |
See function Reset-Authorization
for a whole procedure to deal with authorization problems.
(2023, March 19). Authorization. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/authorization-portal ↩︎
(2023, March 19). Access Control (Authorization). Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control ↩︎
(2023, March 20). Access Control Model. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-model ↩︎
(2023, March 21). Parts of the Access Control Model. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-components ↩︎
(2023, March 21). Parts of the Access Control Model. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-components ↩︎
(2023, March 21). Access Tokens. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-tokens ↩︎
(2023, March 21). Parts of the Access Control Model. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-components ↩︎
(2023, March 21). Security Descriptors. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptors ↩︎
(2023, March 21). Security Descriptors. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptors ↩︎
(2023, March 21). Security Descriptors. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptors ↩︎
(2023, March 21). Security Descriptors. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptors ↩︎
(2023, March 21). Security Descriptors. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptors ↩︎
(2023, March 21). Securable Objects. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/securable-objects ↩︎
(2023, March 21). Security Identifiers. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-identifiers ↩︎
(2023, March 19). Access-control list - Wikipedia. En. https://en.wikipedia.org/wiki/Access-control_list ↩︎
(2023, March 21). Access control lists. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists ↩︎
(2023, March 21). Access Control Entries. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-entries ↩︎
(2023, March 21). Access control lists. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists ↩︎
(2023, March 21). Access control lists. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/access-control-lists ↩︎
(2023, March 21). How AccessCheck Works. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/how-dacls-control-access-to-an-object ↩︎
(2023, March 21). Interaction Between Threads and Securable Objects. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/interaction-between-threads-and-securable-objects ↩︎
(2023, March 21). DACLs and ACEs. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/dacls-and-aces ↩︎
(2023, March 21). Null DACLs and Empty DACLs (Authorization). Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/null-dacls-and-empty-dacls ↩︎
(2023, March 20). Security Descriptor Definition Language. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-definition-language ↩︎
(2023, March 21). Security Descriptor String Format. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/security-descriptor-string-format ↩︎
(2023, March 21). ACE Strings. Learn. https://learn.microsoft.com/en-us/windows/win32/secauthz/ace-strings ↩︎
(2023, March 21). icacls. Learn. https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/icacls ↩︎