Description of the new 'ntsec' feature

Corinna Vinschen
Tue Aug 17 15:19:00 GMT 1999


The following text is a description of a new feature in cygwin1.dll.
It's already part of the snapshots and it will be part of the official
B21 version.

The following document is part of the winsup sources (doc/ntsec.sgml).
The reason for publishing it now is that many people on the net are
trying snapshots and that this feature requires well defined
/etc/passwd and /etc/group files. Later versions possibly are able
to deal completely without these files but in the meantime...

The main part in the document is, to describe in simple words the
Windows NT security basics. Note, that my knowledge in NT security
is arised thru M$ compiler help texts and 'learning by doing'. So,
please, don't judge to hard.

Some parts are decriptions, where to find the corresponding code.
If you are not interested in sources, simply ignore these parts.

The document itself is provided as is. I don't give any guarantee
that it's error free. Corrections are welcome.

Ok, the documentation follows,
Best Regards,

----------- SNIP ------------

NTSEC Documentation

The design goal of the ntsec patch was to get a more UNIX like
permission structure based upon the security features of Windows NT.
To describe the changes, I will give a short overview of NT security in
chapter one.
Chapter two discusses the changes in ntsec related to privileges on
Chapter three shows the UNIX like setting of file permissions.

The setting of UNIX like object permissions is controlled by the new
CYGWIN variable setting (no)ntsec.

On NT ntsec is now turned on by default.

1. NT security

The NT security allows a process to allow or deny access of different
kind to `objects'. `Objects' are files, processes, threads, semaphores,

The main data structure of NT security is the `security descriptor'
(SD) structure. It explains the permissions, that are granted (or
denied) to an object and contains information, that is related to so
called `security identifiers' (SID).

An SID is a unique identifier for users, groups and domains. 
SIDs are comparable to UNIX UIDs and GIDs, but are more complicated
because they are unique across networks. Example:

SID of a system `foo':


SID of a user `johndoe' of the system `foo':


The above example shows the convention for printing SIDs. The leading
`S' should show that it is a SID. The next number is a version number
which is always 1. The next number is the so called `top-level
authority' that identifies the source that issued the SID.

While each system in a NT network has it's own SID, the situation
is modified in NT domains: The SID of the domain controller is the
base SID for each domain user. If an NT user has one account as domain
user and another account on his local machine, this accounts are under
any circumstances DIFFERENT, regardless of the usage of the same user
name and password! 

SID of a domain `bar':


SID of a user `johndoe' in the domain `bar':


The last part of the SID, the so called `relative identifier' (RID),
is used as UID and/or GID under cygwin. As the name and the above
example implies, this id is unique only relative to one system or

Note, that it's possible, that an user has the same RID on two
different systems. The resulting SIDs are nevertheless different, so
the SIDs are representing different users in an NT network.

There is a big difference between UNIX IDs and NT SIDs, the existence
of the so called `well known groups'. For example UNIX has no GID for
the group of `all users'. NT has an SID for them, called `Everyone' in
the English versions. The SIDs of well-known groups are not unique
across an NT network but their meanings are unmistakable.
Examples of well-known groups:

everyone                        S-1-1-0
creator/owner                   S-1-3-0
batch process (via `at')        S-1-5-3
authenticated users             S-1-5-11
system                          S-1-5-18

The last important group of SIDs are the `predefined groups'. This
groups are used mainly on systems outside of domains to simplify the 
administration of user permissions. The corresponding SIDs are not
unique across the network so they are interpreted only locally:

administrators                  S-1-5-32-544
users                           S-1-5-32-545
guests                          S-1-5-32-546

Now, how are permissions given to objects? A process may assign an SD
to the object. The SD of an object consists of three parts:

- the SID of the owner 
- the SID of the group 
- a list of SIDs with their permissions, called `access control list'

UNIX is able to create three different permissions, the permissions
for the owner, for the group and for the world. In contrast the ACL
has a potentially infinite number of members. Every member is a so
called `access control element' (ACE). An ACE contains three parts:

- the type of the ACE 
- permissions, described with a DWORD 
- the SID, for which the above mentioned permissions are set 

The two important types of ACEs are the `access allowed ACE' and the
`access denied ACE'. The ntsec patch only uses `access allowed ACEs'.

The possible permissions on objects are more complicated than in
UNIX. For example, the permission to delete an object is different
from the write permission.

With the aforementioned method NT is able to grant or revoke
permissions to objects in a far more specific way. But what about
cygwin? In a POSIX environment it would be fine to have the security
behaviour of a POSIX system. The NT security model is able to reproduce
the POSIX model. The ntsec patch tries to do this in cygwin.

The creation of explicit object security is a bit complicated, so
typically only two simple variations are used:

- default permissions, computed by the operating system 
- each permission to everyone 

For parameters to functions that create or open securable objects
another data structure is used, the `security attributes' (SA). This
structure contains an SD and a flag, that specifies whether the
returned handle to the created or opened object is inherited to child
processes or not. This property is not important for the ntsec patch
description, so in this document SDs and SAs are more or less identical.

2. Process privileges

Any process started under control of cygwin has a semaphore attached
to it, that is used for signaling purposes. The creation of this
semaphore can be found in, function `getsem'. The first
parameter to the function call `CreateSemaphore' is an SA. Without
ntsec patch this SA assigns default security to the semaphore. There
is a simple disadvantage: Only the owner of the process may send
signals to it. Or, in other words, if the owner of the process is not
a member of the administrators' group, no administrator may kill the
process! This is especially annoying, if processes are started via
service manager.

The ntsec patch now assigns an SA to the process control semaphore,
that has each permission set for the user of the process, for the
administrators' group and for `system', which is a synonym for the
operating system itself. The creation of this SA is done by the
function `sec_user', that can be found in `'. Each member of
the administrators' group is now allowed to send signals to any process
created in cygwin, regardless of the process owner.

Moreover, each process now has the appropriate security settings, when
it is started via `CreateProcess'. You will find this in function
`spawn_guts' in module `'. The security settings for starting a
process in another user context have to add the sid of the new user,
too. In the case of the `CreateProcessAsUser' call, sec_user creates
an SA with an additional entry for the sid of the new user.

3. File permissions

If ntsec is turned on, file permissions are set as in UNIX. An SD is
assigned to the file containing the owner and group and ACEs for the
owner, the group and `Everyone'. If the group of the file is not the
administrators' group, the administrators' group gets the permissions
to read the permissions (yes, this is an own permission flag
:-)) and to take the ownership on this file.
If the file's group is the administrators group itself, this behaviour
is modified to support the typical behaviour of NT better:
As you know, if one is member of admin group, all her files are owned
by the group instead of by her. This is not the case with ntsec but the
other admins should have easier access to the administrative files.
So in this case the admin group gets additionally the permissions to
write permissions and to write extended attributes, also in the case
where group permissions are set to 0.

The complete settings of UNIX like permissions can be found in the
file `'. The two functions `get_nt_attribute' and
`set_nt_attribute' are the main code. The reading and writing of the
SDs is done by the functions `ReadSD' and `WriteSD'. They are using
the Backup API functions `BackupRead' and `BackupWrite', that have the
advantage not to crash, if they are used on non NTFS file systems!
These crashes are the default behavior of the security API, if it's
used on, e.g., FAT or SAMBA file systems :-(

Unfortunately, the settings of NT file security are only available
on NTFS. SAMBA doesn't support them.

If you are creating a file `foo' outside of cygwin, you will see
something like the following on ls -ln:

If your login is member of the administrators' group:

  rwxrwxrwx 1  544  513  ... foo

if not:

  rwxrwxrwx 1  1000  513  ... foo

Note the user and group IDs. 544 is the UID of the administrators'
group. This is a `feature' :-P of WinNT. If one is a member of the
administrators' group, every file, that he has created is owned by the
administrators' group, instead by him.

The second example shows the UID of the first user, that has been
created with NT's the user administration tool. The users and groups
are sequentially numbered, starting with 1000. Users and groups are
using the same numbering scheme, so a user and a group don't share the
same ID.

In both examples the GID 513 is of special interest. This GID is a
well known group with different naming in local systems and domains.
Outside of domains the group is named 'None' (`Kein' in German, `Aucun'
in French, etc.), in domains it is named 'Domain Users'. 
Unfortunately, the group `None' is never shown in the user admin tool
outside of domains! This is very confusing but it seems that this has
no negativ influences.

To work correctly the ntsec patch depends on reasoned files
/etc/passwd/ and /etc/group.  The names and the IDs must correspond to
the appropriate NT IDs! The IDs used in cygwin are the RID of the
NT SID, as aforementioned.
An SID of e.g. the user `corinna' on my NT workstation:


Note the last number: It's the RID 1000, the cygwin's UID.

Unfortunately, workstations and servers outside of domains are not
able to set primary groups! In these cases, where there is no
correlation of users to primary groups, NT returns 513 (None) as
primary group, regardless of the membership to regular groups of
these users.

when using mkpasswd  -l -g on such systems, you have to change the
primary group by hand if `None' as primary group is not what you want
(and I'm sure, it's not what you want!)

To get help in creating correct passwd and group files, look at
the following examples, that are part of my files. With the exception
of my personal user entry, all entries are well known entries. For a
better understanding, the names are translated to the equivalents of
the English NT version:


corinna::1000:547:Corinna Vinschen:/home/corinna:/bin/tcsh



Groups may be mentioned in the passwd file, too. This has two

- Because NT assigns them to files as owners, a ls -l is often better
- Moreover it's possible to assigned them to files as owners with chown. 

The group `system' is the aforementioned synonym for the operating
system itself and is normally the owner of processes, that are started
through service manager. The same is true for files, that are created
by processes, which are started through service manager.

Want to unsubscribe from this list?
Send a message to

More information about the Cygwin mailing list