Friday, 3 July 2015

Cygwin, access control, default groups and just getting it playing nice

correcting current and default permissions

If you've been messing with your permissions on copying data across from another NTFS system, some of the owners/groups may be off and the even after correcting the owners and their permissions, any new files don't have the right defaults. This simple script replaces the ACL records for each file and directory, giving the default permissions specified.
find $1 -type f -exec setfacl -f facl {} \;
find $1 -type d -exec setfacl -f dacl {} \;
dacl - directory permissions
user::rwx
group::rwx
other:r-x
default:user::rwx
default:group::rwx
default:other:r-x
facl - File Permissions
user::rw-
group::rw-
other:r--
default:user::rw-
default:group::rw-
default:other:r--

Specifying the default groups for users

The documentation for cygwin is in depth but doesn't simply answer the question: How do I set the default group for a user? (in the out of the box configuration).
The starting point is the mkpasswd utility. These are the following steps, assuming non-special accounts - the SYSTEM ("Local System") account can't be changed.
  1. > mkpasswd -l -u MyUser >> /etc/passwd
    This creates a mapping record in the passwd file with the default group.
  2. > id MyGroup
    uid=197613(mygroup) gid=197613(mygroup) groups=11(Authenticated Users),197613(mygroup)
    The gid is the group id we need, i.e. 197613
  3. > vi /etc/passwd
  4. Change the 4th field to the gid above i.e.
    MyUser:*:197608:197121:U-MY-PC\MyUser,S-1-5-21-818915124-687840057-3584311183-1000:/home/MyUser:/bin/bash
    becomes
    MyUser:*:197608:197613:U-MY-PC\MyUser,S-1-5-21-818915124-687840057-3584311183-1000:/home/MyUser:/bin/bash

sudo - run command as Administrator

This isn't a full implementation but it elevates the current user to admin rights.
Getting the escaping to work properly is tricky, see this article for how the rules are applied with bash.
# TODO the hardcoded path is a bit hacky
if [ "$1" == "-" ]; then
 #echo "interactive shell"
 cygstart --action=runas "C:\\cygwin64\\bin\\mintty.exe" -h always
else
 #echo "evelavated command"
 CMD="cd $(pwd); $@"
 #note the order of the quotes below, we want to send the cmd as a single arg but surrounded by double quotes
 #use cygstart -v to debug
 cygstart --action=runas "C:\\cygwin64\\bin\\mintty.exe" -l sudo.log -h error -e /usr/bin/bash -l -c "\" $CMD \""
fi

#to use:
./runas-admin.sh somescript.sh param1
# or to open a shell
./runas-admin.sh -
The latest version is kept here: runas-admin.sh

su - switch user

This is a near drop-in replacement, not all options are supported and it differs from the standard linux in that in opens up a new window instead of using the same terminal.
if [ $DO_LOGIN == 1 ]; then
 TTYCMD="- $COMMAND"
else
 TTYCMD="$COMMAND"
fi

if [ $USER != 'root' ]; then
 cygstart --hide cmd.exe /c "\"\"%WINDIR%\\system32\\runas.exe\" /savecred /user:$USER \"$(cygpath -w /usr/bin/mintty.exe) $TTYCMD \"\""
else
        cygstart --action=runas "C:\\cygwin64\\bin\\mintty.exe" -h error -e $TTYCMD
fi

# to use, loging into a new shell with MyUser:
./runas-admin.sh - MyUser
Download the full script here: switch-user.sh

Alternate method: cyglsa

Reading through the security documentation, it gives different instructions on how to get login tokens (at a programatic level). From what I can tell its for sshd and/or services only, there is no mention of support for su/sudo commands.
/usr/bin/cyglsa-config