[K12OSN] create Samba homedirs automagically

Chuck Kollars chuck at ckollars.org
Sat Mar 25 22:50:45 UTC 2006


I (apparently like lots of others:-) had problems creating homedirs before they were needed by Samba in our combined middle/high school. Scripts that used to work in a simpler environment (only one Samba fileserver which was also the sole Domain Controller) didn't always work in more complex environments (more than one Samba fileserver, BDCs as well as PDC). And seemingly cleverer techniques (ex: the PHP exec(...) function) didn't work either.

The reason? In a multi-server environment the computer I'm working on (for example the LDAP master) isn't necessarily the computer where the homedir needs to exist. I could have made it work by turning off most security and invoking something like `rsh/rlogin` all over the place, but doing that seemed way too reckless and risky for even a mildly security-conscious network.

I solved my problem by configuring Samba to "create" any homedirs it finds it needs when the first logon to that share occurs (sort of a "just in time" solution). Although this is neither rocket science nor new, I couldn't find any code to "borrow" and so had to roll my own. To save some effort for the next person who faces the same problem I faced, here's the code that works for me:


========== relevant line in smb.conf ==================

     ...
     [homes]
     ...
      root preexec = /usr/local/sbin/folderhomeuser-initial.sh %u
     ...

========== new script folderhomeuser-initial.sh ==========

     #!/bin/bash

     ## Input arguments
     ##  username (required)

     ## other assumed inputs:
     ##  directory and contents /sambahome/sambahomeskel set up exactly the way
     ##  it's wanted, including permissions/acls

     ## OUTPUT STATUS VALUES
     ##  0 - no error
     ##  1 - help (probably because invalid arguments)
     ##  2 - invalid username
     ##  3 - user's home directory already exists

     if [[ $# -ne 1 || "$1" =~ '^[-\.?"/\/]' ]]; then
      echo "usage: `basename $0` username"
      echo " Create new/empty home directory."
      echo " Can be run meaningfully only by root."
      exit 1
     fi

     function firstword ()
     {
      echo $1
     }

     function thirdword ()
     {
      echo $3
     }

     function sixthword ()
     {
      echo $6
     }

     function gethomedir ()
     {
      HOMEDIR=`eval echo ~$1`
      if [ `expr "$HOMEDIR" : '\(.\)'` = '~' ]; then
       echo "username  $1  is not valid"
       return 2
      fi
      # strip trailing slash if it exists
      HOMEDIR=${HOMEDIR%/}
      echo $HOMEDIR
     }

     function makeparentdirs () {
      ONE=${1%/} # strip any trailing slash that might mess up follow RE
      PARENT=`expr "$ONE" : '\(.*\)/'`
      mkdir -p $PARENT
     }

     PRIMARYGROUP=`id -g $1`

     HOMEDIR=`gethomedir $1`
     RETCODE=$?
     if [ $RETCODE -ne 0 ]; then echo $HOMEDIR; exit $RETCODE; fi

     if [ -e $HOMEDIR ]; then
      echo "$HOMEDIR (home for $1) already exists"
      exit 2
     fi

     makeparentdirs $HOMEDIR

     cp -r -p /sambahome/sambahomeskel $HOMEDIR
     # although we know this won't work right if there's a trailing slash on
     # HOMEDIR, we can confidently assume it's not the case since gethomedir
     # never returns such a result

     chown -R $1:$PRIMARYGROUP $HOMEDIR
     # we assume permissions/acls were already correct on the skeleton, because
     # although we could set permissions/acls here we don't because it's too slow

     logger -p daemon.info "successfully created and populated $HOMEDIR for $1"
     echo "$HOMEDIR (home for $1) created and populated"
     exit 0

(The coding style of the script isn't all that great; improvements are clearly possible. The upside is it does work.)

(Note this creates new homedirs with whatever initial content you desire by copying a template [similar to /etc/skel which is used for local logins], specifically in this case /sambahome/sambahomeskel].)

(Note this setup assumes that scripts can find a user's Samba home directory path from the *nix side without any help from Samba, even if the user is defined in LDAP and even if the user isn't able to directly logon to the *nix system. This will be true so long as you've used `authconfig --enableldap` so your /etc/nsswitch.conf specifies both "files" and "ldap" on its "passwd" line. Provided this is true, you can just use the `bash` tilde shortand [~username] to find a user's homedir. It should also be possible [although arguably less flexible:-] to eliminate this assumption and instead have Samba pass the home directory path to the script as a calling argument.)

I hope this helps somebody. Enjoy!
--
Chuck Kollars

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://listman.redhat.com/archives/k12osn/attachments/20060325/deddb0ee/attachment.htm>


More information about the K12OSN mailing list