diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog index 7518a9767..b548f04b6 100644 --- a/winsup/doc/ChangeLog +++ b/winsup/doc/ChangeLog @@ -1,3 +1,16 @@ +2014-07-30 Corinna Vinschen + + * cygwin.xsl: Allow 3 section levels in TOC. + * new-features.xml: (ov-new1.7.32): Add new section. + * ntsec.xml: Rename top-level section to reflect extension of topics. + Remove old /etc/passwd, /etc/group considerations. Add new sections + explaining Windows to POSIX account mapping. Make setuid sections + third level sections. + * pathnames.xml: Note new method of account mapping for fstab.d/$USER. + * faq-setup.xml: Rework references to /etc/passwd and /etc/group to + reflect changes to account handling. + * faq-using.xml: Ditto. + 2014-07-21 Corinna Vinschen * new-features.xml: (ov-new1.7.31): Add new section. diff --git a/winsup/doc/cygwin.xsl b/winsup/doc/cygwin.xsl index 23512934a..157f6f2ed 100644 --- a/winsup/doc/cygwin.xsl +++ b/winsup/doc/cygwin.xsl @@ -8,5 +8,6 @@ + diff --git a/winsup/doc/faq-setup.xml b/winsup/doc/faq-setup.xml index d2a0f1cc0..b8ec06195 100644 --- a/winsup/doc/faq-setup.xml +++ b/winsup/doc/faq-setup.xml @@ -377,8 +377,9 @@ you are much better off if you can avoid the problem entirely. run mkpasswd. -You can simply edit the /etc/passwd file and change the Cygwin user name -(first field). It's also a good idea to avoid spaces in the home directory. +If you already have an /etc/passwd file, you can simply edit +your Cygwin user name (first field). It's also a good idea to avoid spaces in +the home directory. @@ -396,7 +397,7 @@ in order of decreasing priority: HOME from the Windows environment, translated to POSIX form. -The entry in /etc/passwd +The pw_home field from the passwd entry as returned by getent passwd. /home/USERNAME @@ -404,8 +405,7 @@ in order of decreasing priority: -When using Cygwin from the network (telnet, ssh,...), HOME is set -from /etc/passwd. +When using Cygwin from the network (telnet, ssh,...), HOME is taken from the passwd entry. If your HOME is set to a value such as /cygdrive/c, it is likely that it was set in Windows. Start a DOS Command Window and type @@ -413,8 +413,9 @@ that it was set in Windows. Start a DOS Command Window and type Access to shared drives is often restricted when starting from the network, thus Domain users may wish to have a different HOME in the -Windows environment (on shared drive) than in /etc/passwd (on local drive). -Note that ssh only considers /etc/passwd, disregarding HOME. +Windows environment (on shared drive) than in Cygwin (on local drive). +Note that ssh only considers the account information as retrieved by +getpwnam(3), disregarding HOME. diff --git a/winsup/doc/faq-using.xml b/winsup/doc/faq-using.xml index 19e381624..1b83ef950 100644 --- a/winsup/doc/faq-using.xml +++ b/winsup/doc/faq-using.xml @@ -137,7 +137,7 @@ as such. Your .bashrc is read from your home directory specified by the HOME environment variable. It uses /.bashrc if HOME is not set. So you need -to set HOME (and the home dir in your /etc/passwd entry) correctly. +to set HOME (and the home dir in your passwd account information) correctly. @@ -265,12 +265,6 @@ must create the whatis database. Just run the command Why doesn't chmod work? -The most common case is that your /etc/passwd -or /etc/group files are not properly set up. If -ls -l shows a group of mkpasswd -or mkgroup, you need to run one or both of those -commands. - If you're using FAT32 instead of NTFS, chmod will fail since FAT32 does not provide any permission information. You should really consider converting the drive to NTFS with @@ -1031,19 +1025,6 @@ If everything looks ok, run bash. Starting with Windows Vista, make sure you're running bash elevated. - -If "cyg_server" is not already in /etc/passwd, add it -using mkpasswd. Make sure all domain accounts which are -supposed to be able to logon via ssh are in /etc/passwd. -Also make sure that all important domain groups are in -/etc/group. If in doubt, call - - - - $ mkpasswd -l -d your_domain > /etc/passwd - $ mkgroup -l -d your_domain > /etc/group - - Then run ssh-host-config. Answer all questions so that "cyg_server" is used to run the service. When done, check ownership of diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml index 0c24c2650..862fd8d09 100644 --- a/winsup/doc/new-features.xml +++ b/winsup/doc/new-features.xml @@ -4,6 +4,20 @@ What's new and what changed in Cygwin 1.7 +What's new and what changed from 1.7.31 to 1.7.32 + + + + +Introduce reading passwd/group entries directly from SAM/AD, thus allowing +to do without /etc/passwd and /etc/group files. Introduce /etc/nsswitch.conf +file to configure passwd/group handling. + + + + + + What's new and what changed from 1.7.30 to 1.7.31 diff --git a/winsup/doc/ntsec.xml b/winsup/doc/ntsec.xml index 72cf7bb89..40609cfbc 100644 --- a/winsup/doc/ntsec.xml +++ b/winsup/doc/ntsec.xml @@ -2,12 +2,12 @@ -Using Windows security in Cygwin +POSIX accounts, permission, and security This section discusses how the Windows security model is -utilized in Cygwin to implement POSIX-like permissions, as well as how -the Windows authentication model is used to allow cygwin applications -to switch users in a POSIX-like fashion. +utilized in Cygwin to implement POSIX account information, POSIX-like +permissions, and how the Windows authentication model is used to allow +cygwin applications to switch users in a POSIX-like fashion. The setting of POSIX-like file and directory permissions is controlled by the mount option @@ -23,7 +23,7 @@ discussed here, but assumed to be understood by the reader. If you don't know the POSIX security model, search the web for beginner documentation. -Overview +Brief overview of Windows security In the Windows security model, almost any "object" is securable. "Objects" are files, processes, threads, semaphores, etc. @@ -117,13 +117,22 @@ treat these SIDs as identifying two separate accounts. One is "FOO\johndoe", the other one is "BAR\johndoe" or "johndoe@bar.local". Different SID, different account. Full stop. -The last part of the SID, the so called "Relative IDentifier" (RID), -is by default used as UID and/or GID under Cygwin when you create the -/etc/passwd and /etc/group -files using the mkpasswd and mkgroup -tools. Domain account UIDs and GIDs are offset by 10000 by default -which might be a bit low for very big organizations. Fortunately there's -an option in both tools to change the offset... +Starting with Cygwin 1.7.32, Cygwin uses an automatic, internal +translation from Windows SID to POSIX UID/GID. This mechanism, which is +the preferred method for the SID<=>UID/GID mapping, is described in +detail in . + +Up to Cygwin 1.7.31, the last part of the SID, the so called +"Relative IDentifier" (RID), was by default used as UID and/or GID +when you created the /etc/passwd and +/etc/group files using the +mkpasswd and +mkgroup tools. +These tools as well as reading accounts from /etc/passwd +and /etc/group files is still present in recent +versions of Cygwin, but you should switch to the aforementioned +automatic translation, unless you have very specific needs. Again, +see for the details. Do you still remember the SIDs with special meaning? In offical notation they are called "well-known SIDs". For example, POSIX has no GID @@ -221,200 +230,1339 @@ found on http://docs.sun.com. -File permissions +Mapping Windows accounts to POSIX accounts -On NTFS and if the noacl mount option is not -specified for a mount point, Cygwin sets file permissions as in POSIX. -Basically this is done by defining a SD with the matching owner and group -SIDs, and a DACL which contains ACEs for the owner, the group and for -"Everyone", which represents what POSIX calls "others". - -To use Windows security correctly, Cygwin depends on the files + +For as long as Cygwin has existed, it has stored user and group information in +/etc/passwd and /etc/group files. +Under the assumption that these files would never be too large, the first +process in a process tree, as well as every execing process within the tree +would parse them into structures in memory. Thus every Cygwin process would +contain an expanded copy of the full information from /etc/passwd and /etc/group. -These files define the translation between the Cygwin uid/gid and the -Windows SID. The SID is stored in the pw_gecos field in -/etc/passwd, and in the gr_passwd field in -/etc/group. Since the pw_gecos field can contain -more information than just a SID, there are some rules for the layout. -It's required that the SID is the last entry of the pw_gecos field, -assuming that the entries in pw_gecos are comma-separated. The -commands mkpasswd and mkgroup -usually do this for you. + -Another interesting entry in the pw_gecos field (which is also -usually created by running mkpasswd) is the Windows user -name entry. It takes the form "U-domain\username" and is sometimes used -by services to authenticate a user. Logging in through -telnet is a common scenario. + +This approach has a few downsides. One of them is that the idea to have +always small files is flawed. Another one is that reading the entire +file is most of the time entirely useless, since most processes only +need information on their own user and the primary group. Last but not +least, the passwd and group files have to be maintained separately from +the already existing Windows user databases, the local SAM and Active +Directory. + -A typical snippet from /etc/passwd: + +On the other hand, we have to have this mapping between Windows SIDs and +POSIX uid/gid values, so we rely on some mechanism to convert SIDs to uid/gid +values and vice versa. + - -/etc/passwd: - -SYSTEM:*:18:544:,S-1-5-18:: -Administrators:*:544:544:,S-1-5-32-544:: -Administrator:unused:500:513:U-FOO\Administrator,S-1-5-21-790525478-115176313-839522115-500:/home/Administrator:/bin/bash -corinna:unused:11001:11125:U-BAR\corinna,S-1-5-21-2913048732-1697188782-3448811101-1001:/home/corinna:/bin/tcsh - - + +Microsoft "Services for UNIX" (SFU) (deprecated since Windows 8/Server 2012) +never used passwd/group files. Rather, SFU used a fixed, computational mapping +between SIDs and POSIX uid/gid which even has Active Directory support. It +allows to generate uid/gid values from SIDs and vice versa. The mechanism is +documented, albeit in a confusing way and spread over multiple MSDN articles. + -The SYSTEM entry is usually needed by services. The Administrators -entry (Huh? A group in /etc/passwd?) is only here to allow -ls and similar commands to print some file ownerships -correctly. Windows doesn't care if the owner of a file is a user or a -group. In older versions of Windows NT the default ownership for files -created by an administrator account was set to the group Administrators -instead of to the creating user account. This has changed, but you can -still switch to this setting on newer systems. So it's convenient to -have the Administrators group in -/etc/passwd. + +Starting with Cygwin 1.7.32, Cygwin utilizes an approach inspired by the +mapping method as implemented by SFU, with a few differences for backward +compatibility and to handle some border cases differently. + -The really interesting entries are the next two. The Administrator -entry is for the local administrator, the corinna entry matches the corinna -account in the domain BAR. The information given in the pw_gecos field -are all we need to exactly identify an account, and to have a two way -translation, from Windows account name/SID to Cygwin account name uid and -vice versa. Having this complete information allows us to choose a Cygwin -user name and uid which doesn't have to match the Windows account at all. As -long as the pw_gecos information is available, we're on the safe side: +Mapping Windows SIDs to POSIX uid/gid values - -/etc/passwd, tweaked: - -root:unused:0:513:U-FOO\Administrator,S-1-5-21-790525478-115176313-839522115-500:/home/Administrator:/bin/bash -thursday_next:unused:11001:11125:U-BAR\corinna,S-1-5-21-2913048732-1697188782-3448811101-1001:/home/corinna:/bin/tcsh - - + +The following description assumes you're comfortable with the concept of +Windows SIDs and RIDs. For a brief introduction, see +. + - The above /etc/passwd will still work fine. -You can now login via ssh as the user "root", and -Cygwin dutifully translates "root" into the Windows user -"FOO\Administrator" and files owned by FOO\Administrator are shown to -have the uid 0 when calling ls -ln. All you do you're -actually doing as Administrator. Files created as root will be owned by -FOO\Administrator. And the domain user BAR\corinna can now happily -pretend to be Thursday Next, but will wake up sooner or later finding -out she's still actually the domain user BAR\corinna... + +Cygwin's mapping between SIDs and uid/gid values works in two ways. + -Do I have to mention that you can also rename groups in -/etc/group? As long as the SID is present and correct, -all is well. This allows you to, for instance, rename the "Administrators" -group to "root" as well: + +Read /etc/passwd and +/etc/group files, just as in the olden days, mainly for +backward compatibility. +If no files are present, or if an entry is missing in the files, +ask Windows. + - -/etc/group, tweaked: - -root:S-1-5-32-544:544: - - + +At least, that's the default behaviour now. It will be configurable +using a file /etc/nsswitch.conf, which is discussed in +. Let's explore the default +for now. + -Last but not least, you can also change the primary group of a user -in /etc/passwd. The only requirement is that the user -is actually a member of the new primary group in Windows. For instance, -normal users in a domain environment are members in the group "Domain Users", -which in turn belongs to the well-known group "Users". So, if it's -more convenient in your environment for the user's primary group to be -"Users", just set the user's primary group in /etc/passwd -to the Cygwin uid of "Users" (see in /etc/group, -default 545) and let the user create files with a default group ownership -of "Users". + +If files are present, they will be scanned on demand as soon as a +mapping from SIDs to uid/gid or account names is required. The new +mechanism will never read the entire file into memory, but only scan for +the requested entry and cache this one in memory. + - -If you wish to make these kind of changes to /etc/passwd and /etc/group, -do so only if you feel comfortable with the concepts. Otherwise, do not -be surprised if things break in either subtle or surprising ways! If you -do screw things up, revert to copies of /etc/passwd -and /etc/group files created by -mkpasswd and mkgroup. (Make -backup copies of these files before modifying them.) Especially, don't -change the UID or the name of the user SYSTEM. It may mostly work, but -some Cygwin applications running as a local service under that account -could suddenly start behaving strangely. - + +If no entry is found, or no passwd or group file was present, Cygwin +will ask the OS. + - + + +If the first process in a Cygwin process tree determines that no +/etc/passwd or /etc/group file is +present, no other process in the entire process tree will try to read the files +later on. This is done for self-preservation. It's rather bad if the uid +or gid of a user changes during the lifetime of a process tree. + -Special values of user and group ids + +For the same reason, if you delete the /etc/passwd +or /etc/group file, this will be ignored. The passwd +and group records read from the files will persist in memory until either a +new /etc/passwd or /etc/group +is created, or you exit all processes in the current process tree. + -If the current user is not present in -/etc/passwd, that user's uid 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 /etc/passwd, the uid of -that user will have a special value of -1 (which would be shown by -ls as 65535). The user name shown in this case will -be '????????'. + +See the note in for some +comprehensive examples. + + -If the current user is not present in -/etc/passwd, that user's login gid is set to a -special value of 401. The gid 401 is shown as 'mkpasswd', -indicating the command that should be run to alleviate the -situation. + +So if we've drawn a blank reading the files, we're going to ask the OS. +First thing, we ask the local machine for the SID or the username. The +OS functions +LookupAccountSid +and +LookupAccountName +are pretty intelligent. They have all the stuff built in to ask for any +account of the local machine, the Active Directory domain of the machine, +the Global Catalog of the forest of the domain, as well as any trusted +domain of our forest for the information. One OS call and we're +practically done... + -If another user is not present in -/etc/passwd, that user's login gid is set to a -special value of -1. If the user is present in -/etc/passwd, but that user's group is not in -/etc/group and is not the login group of that user, -the gid is set to a special value of -1. The name of this group -(id -1) will be shown as '????????'. + +Except, the calls only return the mapping between SID, account name and the +account's domain. We don't have a mapping to POSIX uid/gid and we're missing +information on the user's home dir and login shell. + -If the current user is present in -/etc/passwd, but that user's login group is not -present in /etc/group, the group name will be shown -as 'mkgroup', again indicating the appropriate command. + +Let's discuss the SID<=>uid/gid mapping first. Here's how it works. + -A special case is if the current user's primary group SID is noted -in the user's /etc/passwd entry using another group -id than the group entry of the same group SID in -/etc/group. This should be noted and corrected. -The group name printed in this case is -'passwd/group_GID_clash(PPP/GGG)', with PPP being the gid as noted -in /etc/passwd and GGG the gid as noted in -/etc/group. - -To summarize: -If the current user doesn't show up in -/etc/passwd, it's group will -be named 'mkpasswd'. + + +Well-known +SIDs +in the NT_AUTHORITY domain of the S-1-5-RID type, or aliases of the +S-1-5-32-RID type are mapped to the uid/gid value RID. Examples: + -Otherwise, if the login group of the current user isn't -in /etc/group, it will be named 'mkgroup'. + + "SYSTEM" S-1-5-18 <=> uid/gid: 18 + "Users" S-1-5-32-545 <=> uid/gid: 545 + -Otherwise a group not in /etc/group -will be shown as '????????' and a user not in -/etc/passwd will be shown as "????????". + + +Other well-known SIDs in the NT_AUTHORITY domain (S-1-5-X-RID): + + + + S-1-5-X-RID <=> uid/gid: 0x1000 * X + RID + + +Example: + + + "NTLM Authentication" S-1-5-64-10 <=> uid/gid: 0x4000A == 262154 + -If different group ids are used for a group with the same -SID, the group name is shown as 'passwd/group_GID_clash(PPP/GGG)' with -PPP and GGG being the different group ids. + +Other well-known SIDs: + + + + S-1-X-Y <=> uid/gid: 0x10000 + 0x100 * X + Y + + +Example: + + + "LOCAL" S-1-2-0 <=> uid/gid: 0x10200 == 66048 + "Creator Group" S-1-3-1 <=> uid/gid: 0x10301 == 66305 + + + + + +Logon SIDs: The own LogonSid is converted to the fixed uid 0xfff == 4095 and +named "CurrentSession". Any other LogonSid is converted to the fixed uid +0xffe == 4094 and named "OtherSession". + + + + + +Mandatory Labels: + + + + S-1-16-RID <=> uid/gid: 0x60000 + RID + + +Example: + + + "Medium Mandatory Level" S-1-16-8192 <=> uid/gid: 0x62000 == 401408 + + + + + +Accounts from the local machine's user DB (SAM): + + + + S-1-5-21-X-Y-Z-RID <=> uid/gid: 0x30000 + RID + + +Example: + + + "Administrator" S-1-5-21-X-Y-Z-500 <=> uid/gid: 0x301f4 == 197108 + + + + + +Accounts from the machine's primary domain: + + + + S-1-5-21-X-Y-Z-RID <=> uid/gid: 0x100000 + RID + + +Example: + + + "Domain Users" S-1-5-21-X-Y-Z-513 <=> uid/gid: 0x100201 == 1049089 + + + + + +Accounts from a trusted domain of the machine's primary domain: + + + + S-1-5-21-X-Y-Z-RID <=> uid/gid: trustPosixOffset(domain) + RID + + + +trustPosixOffset? This needs a bit of explanation. This +value exists in Windows domains already since before Active Directory days. +What happens is this. If you create a domain trust between two domains, a +trustedDomain entry will be added to both databases. It describes how +this domain trusts the other domain. +One attribute of a trust is a 32 bit value called +trustPosixOffset For each new trust, +trustPosixOffset will get some automatic value. In recent +AD domain implementations, the first trusted domain will get +trustPosixOffset set to 0x80000000. Following domains will +get lower values. Unfortunately the domain admins are allowed to set the +trustPosixOffset value for each trusted domain to some +arbitrary 32 bit value, no matter what the other +trustPosixOffset are set to, thus allowing any kind of +collisions between the trustPosixOffset values of domains. +That's not exactly helpful, but as the user of this value, we have to +trust the domain admins to set +trustPosixOffset to sensible values, or to keep it at the +system chosen defaults. + + + +So, for the first (or only) trusted domain of your domain, the automatic offset +is 0x80000000. An example for a user of that trusted domain is + + + + S-1-5-21-X-Y-Z-1234 <=> uid/gid 0x800004d2 == 2147484882 + + + +There's one problem with this approach. Assuming you're running in the context +of a local SAM user on a domain member machine. Local users don't have the +right to fetch this kind of domain information from the DC, they'll get +permission denied. In this case Cygwin will fake a sensible +trustPosixOffset value. + + + +Another problem is if the AD administrators chose an unreasonable small +trustPosixOffset value. Anything below the hexadecimal +value 0x100000 (the POSIX offset of the primary domain) is bound to produce +collisions with system accounts as well as local accounts. The right thing +to do in this case is to notify your administrator of the problem and to ask +for moving the offset to a more reasonable value. However, to reduce the +probability for collisions, Cygwin overrides this offset with a sensible +fixed replacement offset. + + + + + +Local accounts from another machine in the network: + + + +There's no SID<=>uid/gid mapping implemented for this case. The problem +is, there's no way to generate a bijective mapping. There's no central place +which keeps an analogue value of the trustPosixOffset, and +there's the additional problem that the +LookupAccountSid +and +LookupAccountName +functions cannnot resolve the SIDs, unless they know the name of the machine +this SID comes from. And even then it will probably suffer a +"Permission denied" when trying to ask the machine for its local account. + + + +Cygwin will map the account to the fake accounts "Unknown+User"/"Unknown+Group" +with uid/gid -1. + + -Note that, since the special user and group names are just indicators, -nothing prevents you from actually having a user named `mkpasswd' in -/etc/passwd (or a group named `mkgroup' in -/etc/group). If you do that, however, be aware of -the possible confusion. +Now we have a semi-bijective mapping between SIDs and POSIX uid/gid values, +but given that we have potentially users and groups in different domains having +the same name, how do we uniquely differ between them by name? Well, we can do +that by making their names unique in a per-machine way. Dependent on the +domain membership of the account, and dependent of the machine being a domain +member or not, the user and group names will be generated using a domain prefix +and a separator character between domain and account name. The default +separator character is the plus sign, +. + + + + +Well-known SIDs will have the separator character prepended: + + + + "+SYSTEM", "+LOCAL", "+Medium Mandatory Level", ... + + + + + +If the machine is no domain member machine, only local accounts can be resolved +into names, so for ease of use, just the account names are used as Cygwin +user/group names: + + + + "corinna", "bigfoot", "None", ... + + + + + +If the machine is a domain member machine, all accounts from the primary domain +of the machine are mapped to Cygwin names without domain prefix: + + + +"corinna", "bigfoot", "Domain Users", ... + + + +while accounts from other domains are prepended by their domain: + + + + "DOMAIN1+corinna", "DOMAIN2+bigfoot", "DOMAIN3+Domain Users", ... + + + + + +Local machine accounts of a domain member machine get a Cygwin user name the +same way as accounts from another domain: The local machine name gets +prepended: + + + + "MYMACHINE+corinna", "MYMACHINE+bigfoot", "MYMACHINE+None", ... + + + + + +If LookupAccountSid fails, Cygwin checks the accounts against the known trusted +domains. If the account is from one of the trusted domains, an artificial +account name is created. It consists of the domain name, and a special name +created from the account RID: + + + + "MY_DOM+User(1234)", "MY_DOM+Group(5678)" + + + +Otherwise we know nothing about this SID, so it will be mapped to the +fake accounts "Unknown+User"/"Unknown+Group" with uid/gid -1. + + + + + + + +Cygwin user names, home dirs, login shells + + +Obviously, if you don't maintain passwd and +group files, you need to have a way to maintain the other +fields of a passwd entry as well. Three things come to mind: + + + + + + +You want to use a Cygwin username different from your Windows username. + + + +Note: This is only supported via /etc/passwd and +/etc/group files. A Cygwin username maintained in +the Windows user databases would require very costly (read: slow) seach +operations. + + + + + +You want a home dir different from the default /home/$USER. + + + + + +You want to specify a different login shell than /bin/bash. + + + + + + +How this is done depends on your account being a domain account or a +local account. Let's start with the default. Assuming your Windows +account name is "bigfoot" and your domain is "MY_DOM". Your default +passwd entry in absence of anything I'll describe below looks like this: + + + + bigfoot:*:<uid>:<gid>:U-MY_DOM\bigfoot,S-1-5-....:/home/bigfoot:/bin/bash + + + +or, if your account is from a different domain than the primary domain of +the machine: + + + + MY_DOM+bigfoot:*:<uid>:<gid>:U-MY_DOM\bigfoot,S-1-5-....:/home/bigfoot:/bin/bash + + + +Yes, the default homedir is still /home/bigfoot. + + + +If your account is a domain account: + + + + + + +Either create an /etc/passwd and/or +/etc/group file with entries for your account and tweak +that, + + + + + +or Cygwin will utilize the +posixAccount/posixGroup attributes per +RFC 2307. These +attributes are by default available in Active Directory since Windows Server +2003 R2. They are "not set", unless utilized by the (deprecated since Server +2012 R2) Active Directory "Server for NIS" feature. The user attributes +utilized by Cygwin are: + + + + + unixHomeDirectory + If set, will be used as Cygwin home directory. + + + loginShell + If set, will be used as Cygwin login shell. + + + gecos + Content will be added to the pw_gecos field. + + + uidNumber + See . + + + The group attributes utilized by Cygwin are: + + + gidNumber + See . + + + + +Apart from power shell scripting or inventing new CLI tools, these attributes +can be changed using the Attribute Editor tab in the user +properties dialog of the Active Directory Users and Computers +MMC snap-in. Alternatively, if the Server for NIS +administration feature has been installed, there will be a +UNIX Attributes tab which contains the required fields, +except for the gecos field, which isn't really important anyway. Last resort +is ADSI Edit. + + + +The primary group of a user is always the Windows primary group set in +Active Directory and can't be changed. + + + + + + +If your machine is not a domain member machine or your account is a +local account for some reason: + + + + + + +Either create an /etc/passwd and/or +/etc/group file with entries for your account and tweak +that, + + + + + +or enter the information into the "Comment" field of your local user entry. +In the Local Users and Groups MMC snap-in it's called +Description. + + + +You can utilze this field even if you're running a "home edition" of +Windows, using the command line. The net user command +allows to set all values in the SAM, even if the GUI is crippled. + + + +A Cygwin SAM comment entry looks like this: + + + +<cygwin key="value" key="value" [...] /> + + + +The supported keys are: + + + + + home="value" + Sets the Cygwin home dir to value. + + + shell="value" + Sets the Cygwin login shell to value. + + + group="value" + Sets the Cygwin primary group of the account to value, provided that + the user *is* already a member of that group. This allows to override + the default "None" primary group for local accounts. One nice idea + here is, for instance group="Users". + + + unix="value" + Sets the NFS/Samba uid of the user to the decimal value. + See . + + + + +The <cygwin .../> string can start at any point in the comment, but +you have to follow the rules: + + + + +It starts with "<cygwin " and ends with "/>". + + +The "cygwin" string and the key names have to be lowercase. + + +No spaces between key and "value", just the equal sign. + + +The value must be placed within double quotes and it must not contain a double +quote itself. The double quotes are required for the decimal values as well! + + + + +CMD example: + + + +net user corinna /comment:"<cygwin home=\"/home/foo\"/<" + + + +Bash example (use single quotes): + + + +net user corinna /comment:'<cygwin home="/home/foo"/>' + + + +For changing group comments, use the `net localgroup' command. The supported +key/value pair for groups are: + + + + + unix="value" + Sets the NFS/Samba gid of the group to the decimal value. + See . + + + + + + + + + +Caching account information + + +The information fetched from file or the Windows account database is cached +by the process. The cached information is inherited by child processes. + + + +While usually working fine, this has some drawbacks. Consider a shell calling +id. id fetches all group information +from the current token and caches them. Unfortunately id +doesn't start any child processes, so the information is lost as soon as +id exits. + + + +But there's another caching mechanism available. If +cygserver is running +it will provide passwd and group entry caching for all processes in a Cygwin +process tree, which first process has been started after +cygserver. So, if +you start a Cygwin Terminal and +cygserver is running +at the time, mintty, the shell, and all child processes will +use cygserver caching. +If you start a Cygwin Terminal and +cygserver is not +running a the time, none of the processes started inside this terminal window +will use cygserver +caching. + + + +The advantage of +cygserver caching is +that it's system-wide and, as long as +cygserver is running, +unforgetful. Every Cygwin process on the system will have the +cygserver cache at +its service. Additionally, all information requested from +cygserver once, will +be cached inside the process itself and, again, propagated to child processes. + + + + +NFS account mapping + + +Microsoft's NFS client does not map the uid/gid values on the NFS shares +to SIDs. There's no such thing as a (fake) security descriptor returned +to the application. Rather, via an undocumented API an applications can +fetch RFC 1813 +compatible NFSv3 stat information from the share. This is what Cygwin is +using to show stat information for files on NFS shares. + + + +The problem is, while all other information in this stat record, like +timestamps, file size etc., can be used by Cygwin, Cygwin had no way to +map the values of the st_uid and st_gid members to a Windows SID for a +long time. So it just faked the file owner info and claimed that it's +you. + + + +However, SFU has, over time, developed multiple methods to map UNIX +uid/gid values on NFS shares to Windows SIDs. You'll find the full +documentation of the mapping methods in +NFS Identity Mapping in Windows Server 2012 + + + +Cygwin now utilizes the +RFC 2307 +mapping for this purpose. This is most of the time provided by an AD domain, +but it could also be a standalone LDAP mapping server. Per +RFC 2307, the uid is +in the attribute uidNumber. For groups, the gid is in the +gidNumber attribute. + + + +When Cygwin stat's files on an NFS share, it asks the mapping server via +LDAP in two different ways, depending on the role of the mapping server. + + + + + +If the server is an AD domain controller, it asks for an account with +uidNumber attribute == st_uid field of +the stat record returned by NFS. If an account matches, AD returns the +Windows SID, so we have an immediate mapping from UNIX uid to a Windows SID, +if the user account has a valid uidNumber attribute. For +groups, the method is the same, just that Cygwin asks for a group with +gidNumbe attribute == st_gid field of the +stat record. + + + +If the server is a standalone LDAP mapping server Cygwin asks for the +same uidNumber/gidNumber attributes, but +it can't expect that the LDAP server knows anything about Windows SIDs. +Rather, the mapping server returns the account name. Cygwin then asks the +DC for an account with this name, and if that succeeds, we have a mapping +between UNIX uid/gid and Windows SIDs. + + + + + +The mapping will be cached for the lifetime of the process, and inherited +by child processes. + + + + +Samba account mapping + + +A fully set up Samba with domain integration is running winbindd to +map Window SIDs to artificially created UNIX uids and gids, and this +mapping is transparent within the domain, so Cygwin doesn't have to do +anything special. + + + +However, setting up winbindd isn't for everybody, and it fails to map +Windows accounts to already existing UNIX users or groups. In contrast +to NFS, Samba returns security descriptors, but unmapped UNIX accounts +get special SIDs: + + + + + +A UNIX user account with uid X is mapped to the Windows SID S-1-22-1-X. + + + +A UNIX group account with gid X is mapped to SID S-1-22-2-X. + + + + + +As you can see, even though we have SIDs, they just reflect the actual +uid/gid values on the UNIX box in the RID value. It's only marginally +different from the NFS method, so why not just use the same method as +for NFS? + + + +That's what Cygwin will do. If it encounters a S-1-22-x-y SID, it +will perform the same +RFC 2307 +mapping as for NFS shares. + + + +For home users without any Windows domain or LDAP server per +RFC 2307, +but with a Linux machine running Samba, just add this information to +your SAM account. Assuming the uid of your Linux user account is 505 +and the gid of your primary group is, say, 100, just add the values to +your SAM user and group accounts. The following example assumes you +didn't already add something else to the comment field. + + + +To your user's SAM comment (remember: called Description +in the GUI), +add: + + + + <cygwin group="Users" unix="505"/> + + + +To the user's group SAM comment add: + + + + <cygwin unix="100"/> + + + +This should be sufficient to work on your Samba share and to see +all files owned by your Linux user account as your files. + + + + +The <filename>/etc/nsswitch.conf</filename> file + + +Last, but not least, let's talk about the way to configure how the +mapping works on your machine. On Linux and some other UNIXy OSes, we +have a file called +/etc/nsswitch.conf. +One part of it is to specify how the passwd and group entries are generated. +That's what Cygwin now provides as well. + + + +The /etc/nsswitch.conf file is optional. If you don't +have one, Cygwin uses sensible defaults. + + + + +The /etc/nsswitch.conf file is read exactly once by +the first process of a Cygwin process tree. If there was no +/etc/nsswitch.conf file when this first process started, +then no other process in the running Cygwin process tree will try to read the +file. + + + +If you create or change /etc/nsswitch.conf, you have to +restart all Cygwin processes that need to see the change. If the process +you want to see the change is a child of another process, you need to restart +all of that process's parents, too. + + + +For example, if you run vim inside the default Cygwin +Terminal, vim is a child of your shell, which is a child +of mintty. If you edit +/etc/nsswitch.conf in that vim +instance, your shell won't immediately see the change, nor will +vim if you restart it from that same shell instance. +This is because both are getting their nsswitch information from their +ancestor, mintty. You have to start a fresh terminal +window for the change to take effect. + + + +By contrast, if you leave that Cygwin Terminal window open after making the +change to /etc/nsswitch.conf, then restart a Cygwin +service like cron, cron will see the +change, because it is not a child of mintty or any other +Cygwin process. (Technically, it is a child of cygrunsrv, +but that instance also restarts when you restart the service.) + + + +The reason we point all this out is that the requirements for restarting +things are not quite as stringent as when you replace +cygwin1.dll. If you have three process trees, you have +three independent copies of the nsswitch information. If you start a fresh +process tree, it will see the changes. As long as any process in an existing +process tree remains running, all processes in that tree will continue to use +the old information. + + + + +So, what settings can we perform with /etc/nsswitch.conf? +To explain, lets have a look into an /etc/nsswitch.conf +file set up to all default values: + + + + # /etc/nsswitch.conf + passwd: files db + group: files db + + db_prefix: auto + db_separator: + + db_enum: cache builtin + + + +The first line, starting with a hash # is a comment. +The hash character starts a comment, just as in shell scripts. Everything +up to the end of the line is ignored. So this: + + + + foo: bar # baz + + + +means, set "foo" to value "bar", ignore everything after the hash. + + + +The other lines define the available settings. The first word up to a +colon is a keyword. Note that the colon must follow +immediately after the keyword. This is a valid line: + + + + foo: bar + + + +This is not valid: + + + + foo : bar + + + +Apart from this restriction, the reminder of the line can have as +many spaces and TABs as you like. + + + +Now let's have a look at the available keywords and settings. + + + +The two lines starting with the keywords passwd: and +group: define where Cygwin gets its passwd and group +information from. files means, fetch the information +from the corresponding file in the /etc directory. db +means, fetch the information from the Windows account databases, the SAM +for local accounts, Active Directory for domain account. Examples: + + + + passwd: files + + + +Read passwd entries only from /etc/passwd. + + + + group: db + + + +Read group entries only from SAM/AD. + + + + group: files # db + + + +Read group entries only from /etc/group +(db is only a comment). + + + + passwd: files db + + + +Read passwd entries from /etc/passwd. If a user account +isn't found, try to find it in SAM or AD. This is the default for both, +passwd and group information. + + + + group: db files + + + +This is a valid entry, but the order will be ignored by Cygwin. If both, +files and db are specified, Cygwin will +always try the files first, then the db. + + + +The remaining entries define certain aspects of the Windows account +database search. + + + + + + +db_prefix: determines how the Cygwin user or group name +is created. The recognized values are: + + + + + auto + + + This is the default. If your account is from the primary domain of your + machine, or if your machine is a standalone machine (not a domain member), + your Cygwin account name is just the Windows account name. + + + + If your account is from another domain, or if you're logged in as + local user on a domain machine, the Cygwin username will be the + combination of Windows domainname and username, with the separator + char in between: + + + + + MY_DOM+username + (foreign domain) + + + MACHINE+username + (local account) + + + + + Builtin accounts have just the separator char prepended: + + + + + +LOCAL + + + +Users + + + + + Unknown accounts on NFS or Samba shares (that is, accounts which cannot be + mapped to Windows user accounts via + RFC 2307) get a + Cygwin account name consisting of the artificial domains + Unix_User or Unix_Group and the + uid/gid value, for instance: + + + + + Unix_User+0 + (root) + + + Unix_Group+10 + (wheel) + + + + + + + primary + + + Like auto, but primary domain accounts will be + prepended by the domainname as well. + + + + + + always + + + All accounts, even the builtin accounts, will have the domain name + prepended: + + + + + BUILTIN+Users + + + + + + + + + + +db_separator: defines the spearator char used to prepend the +domain name to the user or group name. The default is the plus character ++. + + + + MY_DOM+username + + + +With db_separator:, you can define any ASCII char except +space, tab, carriage return, line feed, and the colon, as separator char. +Example: + + + + db_separator: \ + + + +This results in usernames with the backslash as separator: + + + + MY_DOM\username + + + + + + +db_enum: defines the depth of a database search, if an +application calls one of the enumeration functions +getpwent +or getgrent. +The problem with these functions is, they neither allow to define how many +entries will be enumerated when calling them in a loop, nor do they +allow to add some filter criteria. They were designed back in the days, +when only /etc/passwd and /etc/group +files existed and the number of user accounts on a typical UNIX system was +seldomly a three-digit number. + + + +These days, with user and group databases sometimes going in the +six-digit range, they are a potential burden. For that reason, Cygwin +does not enumerate all user or group accounts by default, but rather +just a very small list, consisting only of the accounts cached in memory +by the current process, as well as a handful of predefined builtin +accounts. + + + +db_enum: allows to specify the accounts to enumerate in a +fine-grained manner. It takes a list of sources as argument: + + + + db_enum: source1 source2 ... + + + +The recognized sources are the following: + + + + + none + No output from + getpwent/getgrent + at all. + + + all + The opposite. Enumerates accounts from all known sources, including + all trusted domains. + + + cache + Enumerate all accounts currently cached in memory. + + + builtin + Enumerate the predefined builtin accounts for backward compatibility. + These are five passwd accounts (SYSTEM, LocalService, NetworkService, + Administrators, TrustedInstaller) and two group accounts (SYSTEM and + TrustedInstaller). + + + files + Enumerate the accounts from /etc/passwd or + /etc/group. + + + local + Enumerate all accounts from the local SAM. + + + primary + Enumerate all accounts from the primary domain. + + + alltrusted + Enumerate all accounts from all trusted domains. + + + some.domain + Enumerate all accounts from the trusted domain some.domain. The + trusted domain can be given as Netbios flat name (MY_DOMAIN) or as + dns domain name (my_domain.corp). In contrast to the aforementioned + fixed source keywords, distinct domain names are caseinsensitive. + Only domains which are actually trusted domains are enumerated. + Unknown domains are simply ignored. + + + + +Please note that getpwent/getgrent +do not test if an account was already listed from another +source, so an account can easily show up twice or three times. Such a test +would be rather tricky, nor does the Linux implementation perform such test. +Here are a few examples for /etc/nsswitch.conf: + + + + db_enum: none + + + +No output from getpwent/getgrent +at all. The first call to the function immediately returns a NULL pointer. + + + + db_enum: cache files + + + +Enumerate all accounts cached by the current process, plus all entries +from either the /etc/passwd or /etc/group file. + + + + db_enum: cache local primary + + + +Enumerate all accounts cached by the current process, all accounts from the SAM +of the local machine, and all accounts from the primary domain of the machine. + + + + db_enum: local primary alltrusted + + + +Enumerate the accounts from the machine's SAM, from the primary domain of the +machine, and from all trusted domains. + + + + db_enum: primary domain1.corp sub.domain.corp domain2.net + + + +Enumerate the accounts from the primary domain and from the domains +domain1.corp, sub.domain.corp and domain2.net. + + + + db_enum: all + + + +Enumerate everything and the kitchen sink. + + + + + + + + + +File permissions -The POSIX permission mapping leak +On NTFS and if the noacl mount option is not +specified for a mount point, Cygwin sets file permissions as on POSIX +systems. Basically this is done by defining a Security Descriptor with the +matching owner and group SIDs, and a DACL which contains ACEs for the owner, +the group and for "Everyone", which represents what POSIX calls "others". -As promised earlier, here's the problem when trying to map the -POSIX permission model onto the Windows permission model. +There's just one problem when trying to map the POSIX permission model +onto the Windows permission model. -There's a leak in the definition of a "correct" ACL which -disallows a certain POSIX permission setting. The official -documentation explains in short the following: +There's a leak in the definition of a "correct" ACL which disallows a +certain POSIX permission setting. The official documentation explains in short +the following: The requested permissions are checked against all @@ -501,7 +1649,7 @@ OthersAllow: 110 Again: This works on all existing versions of Windows NT, at the -time of writing from at least Windows XP up to Server 2012. Only +time of writing from at least Windows XP up to Server 2012 R2. Only the GUIs aren't able (or willing) to deal with that order. @@ -534,9 +1682,7 @@ inherits the access token from its parent process. Every thread can get its own access token, which allows, for instance, to define threads with restricted permissions. - - -Switching the user context with password authentication +Switching the user context with password authentication To switch the user context, the process has to request such an access token for the new user. This is typically done by calling the Win32 API @@ -612,9 +1758,9 @@ example: - + -Switching the user context without password, Method 1: Create a token from scratch +Switching the user context without password, Method 1: Create a token from scratch An unfortunate aspect of the implementation of set(e)uid is the fact that the calling process @@ -702,9 +1848,9 @@ path as in bash$ grep foo //server/share/foofile - + -Switching the user context without password, Method 2: LSA authentication package +Switching the user context without password, Method 2: LSA authentication package We're looking for another way to switch the user context without having to provide the password. Another technique is to create an @@ -749,9 +1895,9 @@ inconvenience compared to that... Nevertheless, this is already a lot better than what we get by using NtCreateToken, isn't it? - + -Switching the user context without password, Method 3: With password +Switching the user context without password, Method 3: With password Ok, so we have solved almost any problem, except for the network access problem. Not being able to access network shares without @@ -824,9 +1970,9 @@ safely use this method. In all other cases, don't use this method. You have been warned. - + -Switching the user context, how does it all fit together? +Switching the user context, how does it all fit together? Now we learned about four different ways to switch the user context using the set(e)uid system call, but @@ -884,6 +2030,8 @@ fails and returns -1, setting errno to EPERM. + + diff --git a/winsup/doc/pathnames.xml b/winsup/doc/pathnames.xml index 3647253e2..b694c640a 100644 --- a/winsup/doc/pathnames.xml +++ b/winsup/doc/pathnames.xml @@ -44,7 +44,9 @@ all users. Sometimes there's a requirement to have user specific mount points. The Cygwin DLL supports user specific fstab files. These are stored in the directory /etc/fstab.d and the name of the file is the Cygwin username of the user, as it's -stored in the /etc/passwd file. The structure of the +created from the Windows account database or stored in the +/etc/passwd file (see +). The structure of the user specific file is identical to the system-wide fstab file.