#!/bin/sh
#
# A simple script to allow mixing domain/local groups for domain users for 
# Samba shares with Samba 3 / Samba 4 when using security = ads option.
#
# To use domain groups this script must not print anything to prevent 
# mapping. To use local groups this script must print the plain username 
# (without the domain part) which is also the format which must be used 
# for local group memberships - beware in multi-domain environments!
#
# Written by Marko Myllynen <myllynen@redhat.com>
#

user="$1"
domain=${user%\\*}
ldom=$(hostname -s | tr '[a-z]' '[A-Z]')

# Ignore non-domain, built-in, and local domain users
case $user in
  ${user#*\\}) exit 0 ;;
  BUILTIN\\*) exit 0 ;;
  $ldom\\*) exit 0 ;;
esac

# Since there is currently no way to determine the share name $PPID is serving 
# we need to go through all the local groups.
valid_users=$(sed -n -e 's/#.*//' -e 's/,/ /g' -e 's/.*valid users[ ]*=\(.*\)/\1/p' /etc/samba/smb.conf)

# Ignore plain usernames and domain groups
for g in $valid_users; do
  if [ "$g" = "${g#\@}" -o "@$domain" = "${g%\\*}" ]; then
    continue
  fi
  groups="$groups ${g#\@}"
done

# Map user if part of any local group in use by calling getent to avoid 
# talking to winbind and thus going over possibly massive domain groups
srvs=$(sed -n -e '/^group:/s/winbind//' -e 's/^group://p' /etc/nsswitch.conf)
for s in $srvs; do
  for g in $groups; do
    found=$(getent -s $s group $g | sed -n -e s'/$/,/g' -e 's/.*,\('${user#*\\}'\),.*/\1/p')
    if [ -n "$found" ]; then
      echo ${user#*\\}
      exit 0
    fi
  done
done
