Skip to content

Instantly share code, notes, and snippets.

@sjorge
Last active January 11, 2020 16:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sjorge/fce4d62a90831199137e8381cd9c903e to your computer and use it in GitHub Desktop.
Save sjorge/fce4d62a90831199137e8381cd9c903e to your computer and use it in GitHub Desktop.
#!/bin/bash
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# Copyright 2019 Joyent, Inc.
# Inspired by
# http://znogger.blogspot.com/2010/05/solaris-automatic-creation-of-home-dirs.html
# To use this script to automatically create home directories, either import
# autofs_local.ldif into your LDAP DIT or add the following to
# `/etc/auto_master`:
#
# /home /etc/auto_homedir
if [[ -n "$TRACE" ]]; then
export PS4='[\D{%FT%TZ}] ${BASH_SOURCE}:${LINENO}: ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
set -o xtrace
fi
# Configurable variables
# Ideally, this should be in a config file.
homebase="home" # Required
exportbase="export/${homebase}" # Required
zpool="auto" # Delete this if not using
delegated_base="" # Delete this if not using
# Set some reasonable restrictions on user zfs datasets
zfs_options=( -o devices=off -o setuid=off -o snapshot_limit=16 )
zfs_local_allow="diff,mount,rollback,snapshot"
zfs_descendent_allow="clone,create,destroy,rename"
# Non-configurable variables
user="$1"
homedir="/${homebase:?}/${user:?}"
exportdir="/${exportbase:?}/${user:?}"
##
## Exit early if possible
##
if ! [[ -d "/$homebase" ]]; then
: $homebase does not exist
exit 0
fi
# Get user details from passwd database
IFS=: read -r -a ent <<< $(getent passwd "$user")
if [[ -z "${ent[0]}" ]]; then
: User "$user" does not exist
exit 0
fi
if ! [[ "${ent[5]}" == "$homedir" ]]; then
: "${ent[5]}" is not a child of "/$homebase"
exit 0
fi
# Check if homedir exists
if [[ -d "$exportdir" ]]; then
: $exportdir already exists
echo "localhost:$exportdir"
exit 0
fi
##
## Create homedir
##
if [[ -n "$zpool" ]]; then
if [[ "$zpool" == "auto" ]]; then
zfshome="$(zfs list -H -o mountpoint,name | awk '$1~mount { print $2 }' mount="^/${exportbase:?}$")"
else
zonename="$(zonename)"
case "$zonename" in
global)
zfsbase="${zpool:?}"
;;
*)
zfsbase="${zpool:?}/${zonename}/${delegated_base}"
;;
esac
zfshome="${zfsbase}/${homebase}"
fi
fi
# If $zfshome exists create a child dataset, otherwise just make a directory.
if [[ -n "$zfshome" ]]; then
if ! zfs list $zfshome 2> /dev/null > /dev/null; then
zfs create -o mountpoint="/$exportbase" "${zfshome}"
fi
if zfs create "${zfs_options[@]}" "${zfshome}/${user}"; then
zfs allow "$user" "$zfs_local_allow" "${zfshome}/${user}"
zfs allow -d "$user" "$zfs_descendent_allow" "${zfshome}/${user}"
fi
fi
[[ -d "$exportdir" ]] || mkdir -p "$exportdir"
# Populate initial contents of home directory
rsync -a "/etc/skel/" "${exportdir}/"
chown -Rh "${ent[2]}:${ent[3]}" "$exportdir"
echo "localhost:$exportdir"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment