<sect1 id="ntsec"><title>NT security and usage of <literal>ntsec</literal></title>

<para>The setting of UNIX like object permissions is controlled by the 
<link linkend="using-cygwinenv"><envar>CYGWIN</envar> environment
variable</link> setting <literal>(no)ntsec</literal> which is set to
<literal>ntsec</literal> by default.</para>

<para>The design goal of <literal>ntsec</literal> is to get a more UNIX-like
permission structure based upon the security features of Windows NT.
To describe the changes, I will first give a short overview in
<xref linkend="ntsec-common"></xref>.
</para>
<para><link linkend="ntsec-processes" endterm="ntsec-processes.title"></link>
discusses the changes in ntsec related to privileges on processes.</para>

<para><link linkend="ntsec-files" endterm="ntsec-files.title"></link> shows
the basics of UNIX-like setting of file permissions.</para>

<para><link linkend="ntsec-sids" endterm="ntsec-sids.title"></link>
talks about using SIDs in <filename>/etc/passwd</filename> and
<filename>/etc/group</filename>.</para>

<para><link linkend="ntsec-mapping" endterm="ntsec-mapping.title"></link>
illustrates the permission mapping leak of Windows NT.</para>

<para><link linkend="ntsec-aclfuncs" endterm="ntsec-aclfuncs.title"></link>
describes in short the ACL API since release 1.1.</para>

<para><link linkend="ntsec-setuid" endterm="ntsec-setuid.title"></link>
describes the new support of a setuid concept introduced with release
1.1.3.</para>

<para><link linkend="ntsec-switch" endterm="ntsec-switch.title"></link>
gives the basics of using the SYSTEM user to switch user context.
</para>

<para><link linkend="ntsec-ids" endterm="ntsec-ids.title"></link>
explains the way Cygwin shows users and groups that are not in 
<filename>/etc/passwd</filename> or <filename>/etc/group</filename>.
</para>

<sect2 id="ntsec-common"><title>NT security</title>

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

<para>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).</para>

<para>A 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:</para>

<para>SID of a system `foo':</para>

<screen>
  S-1-5-21-165875785-1005667432-441284377
</screen>

<para>SID of a user `johndoe' of the system `foo':</para>

<screen>
  S-1-5-21-165875785-1005667432-441284377-1023
</screen>

<para>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.</para>

<para>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, these accounts are under
any circumstances DIFFERENT, regardless of the usage of the same user
name and password!</para>

<para>SID of a domain `bar':</para>

<screen>
  S-1-5-21-186985262-1144665072-740312968
</screen>

<para>SID of a user `johndoe' in the domain `bar':</para>

<screen>
  S-1-5-21-186985262-1144665072-740312968-1207
</screen>

<para>The last part of the SID, the so called `relative identifier' (RID),
is by default 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
domain.</para>

<para>Note, that it's possible that a 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.</para>

<para>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:</para>

<screen>
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
</screen>

<para>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:</para>

<screen>
administrators                  S-1-5-32-544
users                           S-1-5-32-545
guests                          S-1-5-32-546
...
</screen>

<para>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:</para>

<itemizedlist spacing="compact">
<listitem><para>the SID of the owner </para></listitem>
<listitem><para>the SID of the group </para></listitem>
<listitem><para>a list of SIDs with their permissions, called
`access control list' (ACL) </para></listitem>
</itemizedlist>

<para>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:</para>

<itemizedlist spacing="compact">
<listitem><para>the type of the ACE </para></listitem>
<listitem><para>permissions, described with a DWORD </para></listitem>
<listitem><para>the SID, for which the above mentioned permissions are
set </para></listitem>
</itemizedlist>

<!-- Is the historical note really important here? we're at version 1.5.9, after all.. -->
<para>The two important types of ACEs are the `access allowed ACE' and the
`access denied ACE'. The ntsec functionality only used `access allowed ACEs' up
to Cygwin version 1.1.0. Later versions also use `access denied ACEs' 
to reflect the UNIX permissions as well as possible.</para>

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

<para>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 behavior of a POSIX
system. The NT security model is MOSTLY able to reproduce the POSIX model.
The ntsec method tries to do this in cygwin.</para>

<para>You ask "Mostly? Why mostly???" Because there's a leak in the NT model.
I will describe that in detail in chapter 5.</para>

<para>Creating  explicit object security is not that easy so you will often
see only two simple variations in use:</para>

<itemizedlist spacing="compact">
<listitem><para>default permissions, computed by the operating system </para></listitem>
<listitem><para>each permission to everyone </para></listitem>
</itemizedlist>

<para>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 object is inherited to child processes or not.
This property is not important for ntsec so in
this document the difference between SDs and SAs is ignored.</para>

</sect2>

<sect2 id="ntsec-processes"><title id="ntsec-processes.title">Process privileges</title>

<para>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 sigproc.cc, function `getsem'. The first parameter to the
function call `CreateSemaphore' is an SA. Without ntsec 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.</para>

<para>Ntsec 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 `shared.cc'. Each member of the
administrators' group is now allowed to send signals to any process
created in Cygwin, regardless of the process owner.</para>

<para>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 `spawn.cc'. 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.</para>

</sect2>

<sect2 id="ntsec-files"><title id="ntsec-files.title">File permissions</title>

<para>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'.</para>

<para>The complete settings of UNIX like permissions can be found in the file
`security.cc'. 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 `read_sd' and `write_sd'. `write_sd' uses the function `BackupRead'
instead of the simpler function `SetFileSecurity' because the latter is
unable to set owners different from the caller.</para>

<para>If you are creating a file `foo' outside of Cygwin, you will see something
like the following on <command>ls -ln</command>:</para>

<para>If your login is member of the administrators' group:</para>
<screen>
  rwxrwxrwx 1  544  513  ... foo
</screen>
<para>if not:</para>
<screen>
  rwxrwxrwx 1  1000  513  ... foo
</screen>

<para>Note the user and group IDs. 544 is the UID of the administrators' group.
This is a `feature' <literal>:-P</literal> of WinNT. If you are a member of
the administrators' group, every file that you create is owned by the
administrators' group, instead of by you.</para>

<para>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.</para>

<para>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 this seems to have no negative consequences.</para>

<para>To work correctly, ntsec depends on the files
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>.
In Cygwin release 1.0 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
mentioned earlier.
A SID of e.g. the user `corinna' on my NT workstation:</para>

<screen>
  S-1-5-21-165875785-1005667432-441284377-1000
</screen>

<para>Note the last number: It's the RID 1000, Cygwin's UID.</para>

<para>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 existing local groups.</para>

<para>When using <command>mkpasswd  -l -g</command> 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!)</para>

<para>Look at the following examples, which were parts of my files before
storing SIDs in /etc/passwd and /etc/group had been introduced (See next
chapter for details).  With the exception of my personal user entry, all
entries are well known entries.</para> 

<example>
<title>/etc/passwd</title>
<screen>
everyone:*:0:0:::
system:*:18:18:::
administrator::500:544::/home/root:/bin/bash
guest:*:501:546:::
administrators:*:544:544::/home/root:
corinna::1000:547:Corinna Vinschen:/home/corinna:/bin/tcsh
</screen>
</example>

<example>
<title>/etc/group</title>
<screen>
everyone::0:
system::18:
none::513:
administrators::544:
users::545:
guests::546:
powerusers::547:
</screen>
</example>

<para>As you can see, I changed my primary group membership from 513 (None)
to 547 (powerusers).  So all files I created inside of Cygwin were now owned
by the powerusers group instead of None.  This is the way I liked it.</para>

<para>Groups may be mentioned in the passwd file, too. This has two
advantages:</para>

<itemizedlist spacing="compact">
<listitem><para>Because NT assigns them to files as owners, a
<command>ls -l</command> is often more readable.</para></listitem>
<listitem><para>Moreover it's possible to assigned them to files as
owners with Cygwin's <command>chown</command>.</para></listitem>
</itemizedlist>

<para>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.</para>

</sect2>

<sect2 id="ntsec-sids"><title id="ntsec-sids.title">NT SIDs in Cygwin</title>

<para>In Cygwin release 1.1 a new technique of using the 
<filename>/etc/passwd</filename> and <filename>/etc/group</filename>
 was introduced.</para>

<para>Both files may now contain SIDs of users and groups. They
are saved in the last field of pw_gecos in <filename>/etc/passwd</filename>
and in the gr_passwd field in <filename>/etc/group</filename>.</para>

<para>This has the following advantages:</para>
<itemizedlist spacing="compact">
<listitem><para>ntsec works better in domain environments.</para></listitem>
<listitem><para>Accounts (users and groups) may get another name in
Cygwin than their NT account name. The name in <filename>/etc/passwd</filename>
or <filename>/etc/group</filename> is transparently used by Cygwin
applications (e.g. <command>chown</command>, <command>chmod</command>,
<command>ls</command>):</para>

<screen>
root::500:513::/home/root:/bin/sh
</screen>

<para>instead of</para>

<screen>
adminstrator::500:513::/home/root:/bin/sh
</screen>

<para>Caution: If you like to use the account as login account via
<command>telnet</command> etc. you have to remain the name unchanged or
you have to use the special version of <command>login</command> which is
part of the standard Cygwin distribution since 1.1.</para></listitem>
<listitem><para>Cygwin UIDs and GIDs are now not necessarily the RID
part of the NT SID:</para>

<screen>
root::0:513:S-1-5-21-54355234-56236534-345635656-500:/home/root:/bin/sh
</screen>

<para>instead of</para>

<screen>
root::500:513::/home/root:/bin/sh
</screen>

</listitem>
<listitem><para>As in U*X systems UIDs and GIDs numbering scheme now
don't influence each other. So it's possible to have same Id's for a
user and a group:</para>
<example>
<title>/etc/passwd:</title>
<screen>
root::0:0:S-1-5-21-54355234-56236534-345635656-500:/home/root:/bin/sh
</screen>
</example>

<example>
<title>/etc/group:</title>
<screen>
root:S-1-5-32-544:0:
</screen>
</example>
</listitem>
</itemizedlist>

<para>The tools <command>mkpasswd</command> and <command>mkgroup</command>
create the needed entries by default. If you don't want that you can use
the options <literal>-s</literal> or <literal>--no-sids</literal>. I suggest
not to do this since ntsec works better when having the SIDs available.</para>

<para>Please note that the pw_gecos field in <filename>/etc/passwd</filename>
is defined as a comma separated list. The SID has to be the last field!</para>

<para>As aforementioned you are able to use Cygwin account names different
from the NT account names. If you want to login through `telnet' or something
else you have to use the special <command>login</command>. You may then
add another field to pw_gecos which contains the NT user name including
it's domain. So you are able to login as each domain user. The syntax
is easy: Just add an entry of the form U-ntdomain\ntusername to the pw_gecos
field. Note that the SID must still remain the last field in pw_gecos!</para>

<screen>
the_king::1:1:Elvis Presley,U-STILLHERE\elvis,S-1-5-21-1234-5678-9012-1000:/bin/sh
</screen>

<para>For a local user just drop the domain:</para>

<screen>
the_king::1:1:Elvis Presley,U-elvis,S-1-5-21-1234-5678-9012-1000:/bin/sh
</screen>

<para>In either case the password of the user is taken from the NT user
database, NOT from the passwd file!</para>

<para>As in the previous chapter I give my personal
<filename>/etc/passwd</filename> and <filename>/etc/group</filename> as
examples.  Please note that I've changed these files heavily!  There's no
need to change them that way, it's just for testing purposes and...
for fun.</para>

<example>
<title>/etc/passwd</title>
<screen>
root:*:0:0:Administrators group,S-1-5-32-544::
SYSTEM:*:18:18:,S-1-5-18:/home/system:/bin/bash
admin:*:500:513:,S-1-5-21-1844237615-436374069-1060284298-500:/home/Administrator:/bin/bash
corinna:*:100:0:Corinna Vinschen,S-1-5-21-1844237615-436374069-1060284298-1003:/home/corinna:/bin/tcsh
Guest:*:501:546:,S-1-5-21-1844237615-436374069-1060284298-501:/home/Guest:/bin/bash
</screen>
</example>

<example>
<title>/etc/group</title>
<screen>
root:S-1-5-32-544:0:
local:S-1-2-0:2:
network:S-1-5-2:3:
interactive:S-1-5-4:4:
authenticatedusers:S-1-5-11:5:
SYSTEM:S-1-5-18:18:
local_svc:S-1-5-19:19:
netwrk_svc:S-1-5-20:20:
none:S-1-5-21-1844237615-436374069-1060284298-513:513:
bckup_op:S-1-5-32-551:551:
guests:S-1-5-32-546:546:
pwrusers:S-1-5-32-547:547:
replicator:S-1-5-32-552:552:
users:S-1-5-32-545:545:
</screen>
</example>

<para>If you want to do similar changes to your files, please do that only
if you're feeling comfortably with the concepts.  Otherwise don't be surprised
if some stuff doesn't work anymore.  If you screwed up things, revert to files
created by mkpasswd and mkgroup.  Especially don't change the UID or the name
of user SYSTEM.  Even if that works mostly, some Cygwin applications running
as local service under that account could suddenly start behaving strangely.
</para>

</sect2>

<sect2 id="ntsec-mapping"><title id="ntsec-mapping.title">The mapping leak</title>

<para>Now its time to point out the leak in the NT permissions.
The official documentation explains in short the following:</para>
<itemizedlist spacing="compact">
<listitem><para>access allow ACEs are accumulated regarding to the
group membership of the caller.</para></listitem>
<listitem><para>The order of ACEs is important. The system reads them
in sequence until either any needed right is denied or all needed rights
are granted. Later ACEs are then not taken into account.</para></listitem>
<listitem><para>All access denied ACEs _should_ precede any
access allowed ACE.</para></listitem>
</itemizedlist>

<para>Note that the last rule is a preference, not a law. NT will correctly
deal with the ACL regardless of the sequence order. The second rule is
not modified to get the ACEs in the preferred order.</para>

<para>Unfortunately the security tab of the NT4 explorer is completely
unable to deal with access denied ACEs while the explorer of W2K rearranges
the order of the ACEs before you can read them. Thank God, the sort order
remains unchanged if one presses the Cancel button.</para>

<para>You still ask "Where is the leak?" NT ACLs are unable to reflect each
possible combination of POSIX permissions. Example:</para>

<screen>
rw-r-xrw-
</screen>

<para>1st try:</para>

<screen>
UserAllow:   110
GroupAllow:  101
OthersAllow: 110
</screen>

<para>Hmm, because of the accumulation of allow rights the user may
execute because the group may execute.</para>

<para>2st try:</para>

<screen>
UserDeny:    001
GroupAllow:  101
OthersAllow: 110
</screen>

<para>Now the user may read and write but not execute. Better? No!
Unfortunately the group may write now because others may write.</para>

<para>3rd try:</para>

<screen>
UserDeny:    001
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110
</screen>

<para>Now the group may not write as intended but unfortunately the user may
not write anymore, either. How should this problem be solved? According to
the official rules a UserAllow has to follow the GroupDeny but it's
easy to see that this can never be solved that way.</para>

<para>The only chance:</para>

<screen>
UserDeny:    001
UserAllow:   010
GroupDeny:   010
GroupAllow:  001
OthersAllow: 110
</screen>

<para>Again: This works for both, NT4 and W2K. Only the GUIs aren't
able to deal with that order.</para>

</sect2>

<sect2 id="ntsec-aclfuncs"><title id="ntsec-aclfuncs.title">The ACL API</title>

<para>For dealing with ACLs Cygwin now has the ACL API as it's
implemented in newer versions of Solaris. The new data structure
for a single ACL entry (ACE in NT terminology) is defined in
<filename>sys/acl.h</filename> as:</para>

<screen>
typedef struct acl {
  int     a_type;  /* entry type */
  uid_t   a_id;    /* UID | GID */
  mode_t  a_perm;  /* permissions */
} aclent_t;
</screen>

<para>The a_perm member of the aclent_t type contains only the bits
for read, write and execute as in the file mode. If e.g. read permission
is granted, all read bits (S_IRUSR, S_IRGRP, S_IROTH) are set.
CLASS_OBJ or MASK ACL entries are not fully implemented yet.</para>

<para>The new API calls are</para>

<screen>
acl(2), facl(2)
aclcheck(3),
aclsort(3),
acltomode(3), aclfrommode(3),
acltopbits(3), aclfrompbits(3),
acltotext(3), aclfromtext(3)
</screen>

<para>Like in Solaris, Cygwin has two new commands for working with
ACLs on the command line: <command>getfacl</command> and
<command>setfacl</command>.</para>

<para>Online man pages for the aforementioned commands and API calls can be
found on <ulink url="http://docs.sun.com">http://docs.sun.com</ulink> </para>

</sect2>

<sect2 id="ntsec-setuid"><title id="ntsec-setuid.title">New setuid concept</title>

<para>UNIX applications which have to switch the user context are using
the <command>setuid</command> and <command>seteuid</command> calls which
are not part of the Windows API.
Nevertheless these calls are supported under Windows NT/W2K since Cygwin
release 1.1.3.  Because of the nature of NT security an application which
needs the ability has to be patched, though.</para>

<para>NT uses so-called `access tokens' to identify a user and it's
permissions. To switch the user context the application has to request
such an `access token'. This is typically done by calling the NT API
function <command>LogonUser</command>. The access token is returned and
either used in <command>ImpersonateLoggedOnUser</command> to change user
context of the current process or in <command>CreateProcessAsUser</command>
to change user context of a spawned child process. An important restriction
is that the application using <command>LogonUser</command> must have special
permissions:</para>

<screen>
"Act as part of the operating system"
"Replace process level token"
"Increase quotas"
</screen>

<para>Note that administrators do not have all these user rights set 
by default.</para>

<para>Two new Cygwin calls are introduced to support porting
<command>setuid</command> applications with a minimum of effort. You only
give Cygwin the right access token and then you can call
<command>seteuid</command> or <command>setuid</command> as usual in POSIX
applications. The call to <command>sexec</command> is not needed
anymore. Porting a <command>setuid</command> application is illustrated by
a short example:</para>

<screen>
<![CDATA[
/* First include all needed cygwin stuff. */
#ifdef __CYGWIN__
#include <windows.h>
#include <sys/cygwin.h>
/* Use the following define to determine the Windows version */
#define is_winnt        (GetVersion() < 0x80000000)
#endif

[...]

  struct passwd *user_pwd_entry = getpwnam (username);
  char *cleartext_password = getpass ("Password:");

[...]

#ifdef __CYGWIN__
  /* Patch the typical password test. */
  if (is_winnt)
    {
      HANDLE token;

      /* Try to get the access token from NT. */
      token = cygwin_logon_user (user_pwd_entry, cleartext_password);
      if (token == INVALID_HANDLE_VALUE)
         error_exit;
      /* Inform Cygwin about the new impersonation token.
         Cygwin is able now, to switch to that user context by
         setuid or seteuid calls. */
      cygwin_set_impersonation_token (token);
    }
  else
#endif /* CYGWIN */
    /* Use standard method for W9X as well. */
    hashed_password = crypt (cleartext_password, salt);
    if (!user_pwd_entry ||
        strcmp (hashed_password, user_pwd_entry->pw_password))
      error_exit;

[...]

  /* Everything else remains the same! */

  setegid (user_pwd_entry->pw_gid);
  seteuid (user_pwd_entry->pw_uid);
  execl ("/bin/sh", ...);
]]>

</screen>

<para>The new Cygwin call to retrieve an access token is defined as follows:</para>

<screen>
#include &lt;windows.h&gt;
#include &lt;sys/cygwin.h&gt;

HANDLE
cygwin_logon_user (struct passwd *pw, const char *cleartext_password)
</screen>

<para>You can call that function as often as you want for different user
logons and remember the access tokens for further calls to the second function.</para>

<screen>
#include &lt;windows.h&gt;
#include &lt;sys/cygwin.h&gt;

void
cygwin_set_impersonation_token (HANDLE hToken);
</screen>

<para> is the call to inform Cygwin about the user context to which further
calls to <command>setuid</command>/<command>seteuid</command> should switch to.
While you always need the correct access token to do a
<command>setuid</command>/<command>seteuid</command> to another user's context,
you are always able to use <command>setuid</command>/<command>seteuid</command>
to return to your own user context by giving your own uid as parameter.</para>

<para>If you have remembered several access tokens from calls to
<command>cygwin_logon_user</command> you can switch to different user
contexts by observing the following order:</para>

<screen>

  cygwin_set_impersonation_token (user1_token);
  seteuid (user1_uid);

[...]

  seteuid (own_uid);
  cygwin_set_impersonation_token (user2_token);
  seteuid (user2_uid);

[...]

  seteuid (own_uid);
  cygwin_set_impersonation_token (user1_token);
  seteuid (user1_uid);

etc.

</screen>

</sect2>

<sect2 id="ntsec-switch"><title id="ntsec-switch.title">Switching User
Context</title>

<para>
Since Cygwin release 1.3.3, applications that are members of the
Administrators group and have the <command>Create a token
object</command>, <command>Replace a process level token</command> and
<command>Increase Quota</command> user rights can switch user
context without giving a password by just calling the usual
<command>setuid</command>, <command>seteuid</command>,
<command>setgid</command> and <command>setegid</command> functions.  
</para>
<para>
On NT and Windows 2000 the <systemitem
class="username">SYSTEM</systemitem> user has these privileges and can
run services such as <command>sshd</command>. However, on Windows 2003
<systemitem class="username">SYSTEM</systemitem> lacks the
<command>Create a token object</command> right, so it is necessary to
create a special user with all the necessary rights, as
well as <command>Logon as a service</command>, to run such services.
For security reasons this user should be denied the rights to logon
interactively or over the network. All this is done by configuration
scripts such as <command>ssh-host-config</command>.
</para>
<para>
An important restriction of this method is that a process started
without a password cannot access network shares which require
authentication.  This also applies to subprocesses which switched user
context without a password.  Therefore, when using
<command>ssh</command> or <command>rsh</command> without a password, it
is typically not possible to access network drives.
</para>

</sect2>

<sect2 id="ntsec-ids"><title id="ntsec-ids.title">Special values of user and group
ids</title>

<para>
If the current user is not present in <filename>/etc/passwd</filename>,
that user's user id is set to a special value of 400.  The user name for
the current user will always be shown correctly.  If another user
(or a Windows group, treated as a user) is not present in
<filename>/etc/passwd</filename>, the user id of that user will have a
special value of -1 (which would be shown by <command>ls</command> as
65535).  The user name shown in this case will be '????????'.
</para>

<para>
If the current user is not present in <filename>/etc/passwd</filename>,
that user's login group id is set to a special value of 401.  If another
user is not present in <filename>/etc/passwd</filename>, that user's login
group id is set to a special value of -1.  If the user is present in
<filename>/etc/passwd</filename>, but that user's group is not in
<filename>/etc/group</filename> and is not the login group of that user,
the group id is set to a special value of -1.  The name of this group
(id -1) will be shown as '????????'.
In releases of Cygwin before 1.3.20, the group id 401 had a group name
'None'.  Since Cygwin release 1.3.20, the group id 401 is shown as
'mkpasswd', indicating the command that should be run to alleviate the
situation.
</para>

<para>
Also, since Cygwin release 1.3.20, if the current user is present in
<filename>/etc/passwd</filename>, but that user's login group is not
present in <filename>/etc/group</filename>, the group name will be shown
as 'mkgroup', again indicating the appropriate command.
</para>

<para>To summarize:</para>
<itemizedlist spacing="compact">

<listitem><para>If the current user doesn't show up in
<filename>/etc/passwd</filename>, it's <emphasis>group</emphasis> will
be named 'mkpasswd'.</para></listitem>

<listitem><para>Otherwise, if the login group of the current user isn't
in <filename>/etc/group</filename>, it will be named 'mkgroup'.</para>
</listitem>

<listitem><para>Otherwise a group not in <filename>/etc/group</filename>
will be shown as '????????' and a user not in
<filename>/etc/passwd</filename> will be shown as "????????".</para>
</listitem>

</itemizedlist>

<para>
Note that, since the special user and group names are just indicators,
nothing prevents you from actually having a user named `mkpasswd' in
<filename>/etc/passwd</filename> (or a group named `mkgroup' in
<filename>/etc/group</filename>).  If you do that, however, be aware of
the possible confusion.
</para>

</sect2>

</sect1>
