Thursday, February 2, 2012

Prepping Cygwin for a multi-user installation

I was working on installing Cygwin on a base Windows 7 image that will be used by a significant number of developers. As much as I like Cygwin, following the same experience I previously documented in Fixing Cygwin's user groups, sometimes things just don't work as smoothly as one would hope.

First, even though this will be a "install once" situation that will be copied as part of the image, I still needed to select the packages to install. Having previously installed Cygwin on a number of individual desktops and other images, I finally needed a better way to choose the packages and other installation options. Fortunately, Cygwin's setup.exe has very comprehensive command-line support. The following replicates what I've been using for all of my recent installs:

setup.exe -l C:\cygwin\Setup ^
-s ^
-P cygrunsrv,^

(The lines are separated by command-line option, and by installation category used in the package manager.)

After installation, there is an issue to address regarding the permissions of the installed Cygwin files. Following Using Windows security in Cygwin, Cygwin operates with all file permissions using the POSIX security model. This leads to some interesting issues, and Cygwin only uses the user/group/other permissions - where as Windows would allow for more than 3 access control entries (ACE) in the access control list (ACL). This results in many files, including /etc/passwd and /etc/group being editable only to the the user that installed Cygwin. This happens even when the default "Install For - All Users" option during installation is kept, vs. selecting the "Just Me" option. (I could have seen choosing "Just Me" affecting this, as its description includes "Only select this if you lack Administrator privileges..." - but this isn't the case.)

The result of this is that once installed, many files can't be edited by another user. This includes later upgrading Cygwin using setup.exe as another user. This could impact systems installed for planned multi-user access - or even just a system that is pre-installed by an Administrator for hand-off to another user. It doesn't matter if these other users are also members of the "Administrators" group, as resulting file permissions look like the following:

$ icacls C:/cygwin/etc/passwd
C:/cygwin/etc/passwd <COMPUTERNAME>\Administrator:(R,W,D,WDAC,WO)

$ ls -l /etc/passwd
-rw-r--r-- 1 Administrator None 437 Feb  2 21:37 /etc/passwd

This is particularly interesting as once each new user attempts to use Cygwin for the first time, they are greeted with the following (generated from the bottom of /etc/profile):

Your group is currently "mkpasswd".  This indicates that your
gid is not in /etc/group and your uid is not in /etc/passwd.

The /etc/passwd (and possibly /etc/group) files should be rebuilt.
See the man pages for mkpasswd and mkgroup then, for example, run

mkpasswd -l [-d] > /etc/passwd
mkgroup  -l [-d] > /etc/group

Note that the -d switch is necessary for domain users.

Without accounting for these permission issues, the user will have no way of doing this, without resetting the file permissions on these files to allow access.

My current work-around for this involves running the following after installing Cygwin or running any updates using setup.exe:

find /bin /dev /etc /lib /tmp /usr /var -user 1000 -exec chown -h Administrators '{}' +
chown -h Administrators /home

This results in the same /etc/passwd file now looking like the following:

$ icacls C:/cygwin/etc/passwd
C:/cygwin/etc/passwd BUILTIN\Administrators:(R,W,D,WDAC,WO)

$ ls -l /etc/passwd
-rw-r--r-- 1 Administrators None 437 Feb  2 21:37 /etc/passwd

Note that this keeps the ACE entries in the same ordering of user/group/other, which prevents what could be implications as detailed in the same URL linked to above. Cygwin doesn't seem to mind that "Administrators" is actually a group instead of a user, and I've not yet seen any side-effects to doing this.

Now ideally, the Cygwin installation could also be modified to automatically add new users to /etc/passwd to avoid the "Your group is currently "mkpasswd"" prompt when they first use Cygwin. Without editing /etc/profile directly (which would cause it to be skipped in any future updates), the only place I could find to tie into this is in /etc/profile.d/. However, this is interesting in that it is dependent upon the shell being used. I.E., if using bash, only *.sh files will be sourced, and if using ZSH, only *.zsh files will be sourced. Assuming that only bash will be used (at least for each initial login), I added the following as /etc/profile.d/

case "$(id -ng)" in
mkpasswd )
 echo "/etc/profile.d/ Running mkpasswd for new user $(id -un)..."
 mkpasswd -c >> /etc/passwd
 echo "Please press any key to exit.  You will need to manually restart Cygwin."
 read -sn 1

I'm not too crazy about requiring Cygwin to be restarted, and furthermore for requiring the user to assist, but this should do the job and eliminate some support requests.

I reported a summary of this to the Cygwin mailing list.

No comments: