A Win32 operating system is capable of creating several different types of objects. These are basically chunks of memory which represent something. Examples of objects are:
The nature of a Win32 object is that they are simply descrete pieces of data that the OS can store in some memory somewhere (such as store it in RAM, save it onto a floppy or hard disk, stick it into a remote network drive, send it to another computer on a network, etc).
A perfect example of an object is a file. When you create a file (let's say a Microsoft Word document) the operating system considers it an file object. You may want to save the file onto a drive so that you can access it later. Win32 does not care if you save the object to a drive or not, it only knows (and cares) that it takes up memory (either in RAM or somewhere else).
When an object is stored onto some long term memory device (such as a hard disk) in such a way that the data can later be retrieved it is considered to be a persistent object. Note that sending data to a printer or soundcard does not create a persistent object since Win32 can not later retrieve the data.
The Win32 operating system routinely handles tens of thousands of objects a day. Pretty much a Win32 OS is just a complex object manager. Objects are one of the things that Win32 does best. Since the OS is so intimate with objects it knows that there are times when objects need to be secured. For example when saving a sensitive document to a hard drive it should be secured from non authorized users.
Win32 provides a mechanism to secure many types of objects. Securing an object simply means providing a set of permissions that will be associated with the given object. Each and every object can have it's own set of permissions. If you have a hard drive with 10,000 files scattered about on it in 5,000 directories then the hard drive can have 15,000 ( 10,000 file objects plus 5,000 directory objects) different sets of permissions.
So far it is rather quite simple and pretty obvious. Here is where it starts becoming a bit abstract and hard to follow so pay close attention... At the heart of Win32's security system is what is known as an account. This is what one specifies when logging onto a machine. This is known as a user account; it is simply a profile of one particular user. It contains a identiying name (a userid), a password, and a bunch of other information that pertains only to that specific user.
What is not so commonly known is that there are other types of accounts. These accounts are the same as a user account except that they represent not a user but some other thing. The types of accounts are:
Every machine in a domain has machine account in the domain. Just as a user must log onto a computer to use it a machine must logon to a domain in order to use the domain. This is normally done without a user ever knowning it.
Just as a machine has a machine account in a domain a domain has a domain account in other domains. This is what an administrator commonly knows as a interdomain trust.
User, machine and domain accounts all have passwords. User and domain account passwords must be managed; typically by an administrator. A machine account's password is managed automatically by a domain's Primary Domain Controller (PDC) and the machine.
The last account is a group account. Unlike other accounts this one does not have a password. There are two different types of group accounts, however: local and global groups. The difference between these two are beyond the scope of this paper but for all practical purposes just be aware that a there is such a thing as a group account which has no password.
Typically accounts are referred to by name such as:
Group accounts are also referred to by name such as:
There are a couple of system accounts that can not be managed and have special meanings:
If you are referring to an account in a different domain you can prepend the domain name and backslash to the account name:
There are two predefined domains which can not be modified and have special meanings:
Whenever a new account (or group) is created it must be unique; different from any other account. If an account is created with a userid of Joel when an account already exists with that userid creation of the account will fail. If the account is successfully created Win32 will create a Security Identifier (SID). A SID (ryhmes with kid) is a data structure which identifies a particular account in a particular domain. This is the most simplistic way of describing a SID but unless you are programming low level security code you only need to know that a SID represents a particular account (or group) in a particular domain.
Each SID is unique and Win32 guarantees that no two SIDs will be the same. If you have an account called Joel in two different domains you can be assured that domain1\Joel and domain2\Joel will have different SIDs.
When a Win32 operating system refers to a user account, machine account, domain account or group (both local and global) it refers to it's SID. Us humans refer to the account or group with text such as domain1\Joel but Win32 will lookup the SID for that particular domain and account and internally use only the SID. To make things easier on us non computers Win32 will describe a SID by a long text string such as:
This particular string represents a particular user account in the 'Roth Consulting' NT domain.
A SID is simply what Win32 uses internally to represent an account in a given domain.
So we now understand that a SID is simply the way Win32 internally refers to an account. But how does one associate a user account (a SID) with a set of permissions? Win32 refers to permissions as Access Control. If you have an object (let's say a file on a hard drive) and you need to control a trouble maker in your Managers domain (let's say the user Joel) so that he can only read the file. You would want to tell Win32 that the user account Managers\Joel has access to the file only for reading. You would do this by creating an Access Control Entry (ACE).
An ACE is simply a way of mapping an account (a SID) to a set of permissions. An ACEs set of permissions is known as a permission mask (or just mask for short). Internally Win32 stores the permission mask as a DWORD which is basically a four byte (32 bit) value. Each permission cooresponds to an individual bit. This means that when an ACE is being created its permissions mask is created by logically OR'ing the different permission constants (more about permissions later):
$Permission = READ | WRITE | DELETE;
So if you wanted to allow the account Managers\Joel to read, write and delete a file you would create an ACE that consists of a SID (Managers\Joel) and a permission mask (READ | WRITE | DELETE).
Any administrator who manages fileservers can tell you that many permissions are placed on a file. For example a file may contain the following permission sets:
It just so happens that each of these user account/permission set has all of the information needed to create a single ACE. Let's say that you took the time to create several ACEs, one for each of the account permission set described in List . In order for those ACEs to actually be useful they would have to be grouped together so that they can be applied to some object such as a file.
A grouping of ACEs is known as an Access Control List (ACL). The Win32 platforms use ACLs to logically group together ACEs so that they can easily applied to an object. This is rather quite simple. Just as a directory can contain a grouping of files an ACL (pronounced "ack-el", which rhymes with jackel) can contain a grouping of Access Control Entries (ACEs). Each Win32 object that can be secured uses ACLs to determine who is and is not allowed access to the object.
So there you have it. You create a bunch of ACEs which map a user account (SID) to a set of permissions (permission mask). Then you bundle the ACEs together into a list of Access Control Entries (aka an Access Control List). Before you get too excited thinking that all is crystal clear, however, there is a slight complication...
There are two types of ACLs. The first (and most commonly used) type is a Discretionary Access Control List (DACL) and the second (less commonly used) type is a System Access Control List (SACL).
The differences between the two types of ACLs are listed in Table .
For the most part users are more concerned with DACLs and less concerned with SACLs, unless you are an administrator who needs to monitor exactly which users attempt to access particular objects.
So a DACL represents which users have a particular access as opposed to a SACL which represents which events are logged for which users.
An ACL is a list of ACEs. A DACL represents which users have a particular access. A SACL represents which events are logged for which users.
Aside from ACEs and ACLs most objects can have an owner and group. The object's owner is simply the user account which created the object. It is possible to reassign an owner to an object but the premise behind the owner is so the user who creates an object can be tracked.
The object's group is simply a global group which which represents the default group of the creator. Win32 really does not make use of this but it exists for the sake of POSIX compatibility.
The owner and group simply represents a user account and global group, repectively. There is no permission associated with the account and group. They simply refer to which account and group is responsible the object. For the most part this information is not used except by administrators.
Any object which has an associated owner and group will use the SIDs that represent the account and group.
An owner and group are SIDs that repesent a user account and group who is responsible for the object.
At this point it should be obvious that securing an object involves creating a bunch of ACEs (mapping userids to permission masks) and grouping them into a list (either a DACL, SACL or both). If the object needs an owner and group then SIDs representing a user account and global group needs to be gathered. Once all these are obtained they can be neatly packed into one big structure called a Security Descriptor (SD).
Once an SD has been generated it can be used on any securable object. The SD can be extracted from file A, for example, then be applied to another file B. This would totally replace the DACL and SACL for file B.
An SD can be obtained by extracting it from an existing securable object or it can be created from scratch. Likewise an object can be obtained from an existing object (such as a file), modified and then reapplied to another securable object (even the object which it was originally obtained). Modifications could be anything from adding new ACEs, changing the permission mask within an existing ACE or removing ACEs.