blob: 9de6170855227b794e4fc60ed6b6b6332ee023c8 (
plain) (
tree)
|
|
#!/bin/ash
# grab the password from stdin asap
[ "$PAM_TYPE" = "auth" ] || exit 1
unset USER_PASSWORD
read -r USER_PASSWORD > /dev/null 2>&1
readonly USER_PASSWORD
[ -z "$USER_PASSWORD" ] && echo "No password given." && exit 1
USER_NAME="$PAM_USER"
readonly PAM_USER
# Needed as pam_script/pam_exec clears PATH
export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin"
# check for invalid char ':'
if echo "$PAM_USER" | grep -Fq ':'; then
slxlog --echo "pam-format-username" "Username '$PAM_USER' contains disallowed character ':', denying access"
exit 1
fi
# check if the script runs as root
SCRIPT_USER=$(whoami)
readonly SCRIPT_USER
[ "x$SCRIPT_USER" = "xroot" ] || [ "x$SCRIPT_USER" = "x$PAM_USER" ] || exit 1
grepname=$( echo "$PAM_USER" | sed 's/\./\\./g;s/*/\\*/g' )
if [ "$SCRIPT_USER" = "root" ]; then
# See if we have a shadow entry - skip user in that case
grep -q -i "^${grepname}:" "/etc/shadow" && exit 1
else
# Running in user context - user must be known from before
grep -q "^${grepname}:x:.*:.*:${grepname}@SLX:" "/etc/passwd" || exit 1
fi
# ppam -- pluggable pluggable authentication module
# Source all scripts in the auth-source.d directory
# until one succeeds.
# A succeeding script should set USER_UID to the
# uidNumber of the user authenticating, additionally
# it must set USER_GID or USER_GROUP (or both).
# Additional variables that can be set are
# NETWORK_HOME (network path to home directory)
# HOME_MOUNT_OPTS (mount options to use)
# REAL_ACCOUNT (real account name in case any
# mapping took place)
for auth_file in /opt/openslx/pam/auth-source.d/*; do
NETWORK_HOME=
HOME_MOUNT_OPTS=
REAL_ACCOUNT=
USER_UID=
USER_GID=
USER_GROUP=
USER_HOME=
USER_DN=
USER_INFO_FILE=
[ -f "$auth_file" ] || continue
. "$auth_file"
[ -n "$USER_UID" ] || continue
[ -n "${USER_GID}${USER_GROUP}" ] || continue
break
done
# No success - access denied
[ -z "$USER_UID" ] && exit 1
# No root
[ "$USER_UID" = "0" ] && exit 1
[ -z "$REAL_ACCOUNT" ] && REAL_ACCOUNT="$PAM_USER"
readonly USER_UID REAL_ACCOUNT USER_NAME
# Confirm caps matches!
if [ "$USER_NAME" != "$PAM_USER" ]; then
echo "Capitalization mismatch: '$PAM_USER' vs. '$USER_NAME'" >&2
exit 1
fi
# Validate
if ! echo "$USER_UID" | grep -Exq '[0-9]+'; then
slxlog --echo "pam-format-uid" "'$PAM_USER' has invalid userid '$USER_UID'"
exit 1
fi
if [ -n "$USER_GID" ] && ! echo "$USER_GID" | grep -Exq '[0-9]+'; then
slxlog --echo "pam-format-gid" "'$PAM_USER' has invalid groupid '$USER_GID'"
exit 1
fi
if [ "$(echo "${USER_UID}${USER_GID}${USER_GROUP}${USER_HOME}" | wc -l)" != "1" ]; then
slxlog --echo "pam-format-any" "A ppam module returned multilined attributes for uid/gid/group/home"
exit 1
fi
# If not run as root, we're done here as the directory mount stuff etc. doesn't make any sense
[ "$SCRIPT_USER" = "root" ] || exit 0
# Make sure group exists locally
GROUPENT=
if [ -n "$USER_GID" ]; then
GROUPENT=$(getent group "$USER_GID" 2>/dev/null)
fi
if [ -z "$GROUPENT" ] && [ -n "$USER_GROUP" ]; then
GROUPENT=$(getent group "$USER_GROUP" 2>/dev/null)
fi
# Force -- neither group nor gid exist yet
if [ -z "$GROUPENT" ]; then
if [ -z "$USER_GROUP" ]; then
USER_GROUP=generic
fi
if [ -n "$USER_GID" ]; then
addgroup -g "$USER_GID" "$USER_GROUP" >/dev/null 2>&1
else
addgroup "$USER_GROUP" >/dev/null 2>&1
fi
GROUPENT=$(getent group "$USER_GROUP")
fi
if [ -n "$GROUPENT" ]; then
[ -z "$USER_GID" ] && USER_GID=$(echo "$GROUPENT" | awk -F ':' '{print $3}')
[ -z "$USER_GROUP" ] && USER_GROUP=$(echo "$GROUPENT" | awk -F ':' '{print $1}')
if ! grep -q "^${USER_GROUP}:" '/etc/group'; then
echo "$GROUPENT" >> '/etc/group'
fi
fi
readonly USER_GID USER_GROUP
. /opt/openslx/pam/common/homedir-passwd
# The user's non-persistent home directory mount point, which should be their linux home
TEMP_HOME_DIR="$USER_HOME"
# The user's persistent home directory mount point
PERSISTENT_HOME_DIR="${TEMP_HOME_DIR}/PERSISTENT"
readonly TEMP_HOME_DIR PERSISTENT_HOME_DIR
###############################################################################
#
# Preparations for volatile /home/<user>
#
#
# check if we already mounted the home directory
if ! awk '{print $2}' /proc/mounts | grep -Fxq -- "${TEMP_HOME_DIR}"; then
# no home, lets create it
if ! mkdir -p "${TEMP_HOME_DIR}"; then
slxlog --echo "pam-global-mktemphome" "Could not create '${TEMP_HOME_DIR}'."
fi
if ! mount -t tmpfs -o "uid=${USER_UID},gid=${USER_GID},mode=0700,size=1024m" tmpfs "${TEMP_HOME_DIR}"; then
slxlog --echo "pam-global-tmpfstemphome" "Could not make a tmpfs on '${TEMP_HOME_DIR}'"
fi
# mount another tmpfs into subdir so we can create files that the user cannot modify
# but still read, while at the same time preventing any other user from reading it
mkdir -p "${TEMP_HOME_DIR}/.openslx"
mount -t tmpfs -o size=1m,uid=0,gid=0,mode=0755 tmpfs "${TEMP_HOME_DIR}/.openslx"
fi
if [ -n "${REAL_ACCOUNT}" ]; then
echo "${REAL_ACCOUNT}" > "${TEMP_HOME_DIR}/.openslx/account"
chmod 0644 "${TEMP_HOME_DIR}/.openslx/account"
fi
if [ -n "$USER_INFO_FILE" ] && [ -s "$USER_INFO_FILE" ]; then
mv -- "$USER_INFO_FILE" "${TEMP_HOME_DIR}/.openslx/ldap"
chmod 0644 "${TEMP_HOME_DIR}/.openslx/ldap"
fi
###############################################################################
#
# Preparations for /home/<user>/PERSISTENT
#
#
isHomeMounted() {
grep -Fuq " ${PERSISTENT_HOME_DIR} " /proc/mounts
}
PERSISTENT_OK=
if ! isHomeMounted; then
if ! mkdir -p "${PERSISTENT_HOME_DIR}"; then
slxlog "pam-global-mkpersistent" "Could not create '${PERSISTENT_HOME_DIR}'."
else
for mount_file in /opt/openslx/pam/mount.d/*; do
[ -f "$mount_file" ] || continue
. "$mount_file"
if isHomeMounted; then
PERSISTENT_OK="yes"
break
fi
done
fi
else
PERSISTENT_OK="yes"
fi
# Just try to delete the persistent dir. If the mount was successful, it will not work
# If it was not successful, it will be removed so the user doesn't think he can store
# anything in there
rmdir -- "${PERSISTENT_HOME_DIR}" 2> /dev/null
# Write warning message to tmpfs home
if [ -n "${PERSISTENT_OK}" ]; then
# home directory mount SUCCESS
# create a WARNING.txt for the user with hint to PERSISTENT
cat > "${TEMP_HOME_DIR}/WARNING.txt" <<EOF
ATTENTION: This is the non-persistent home directory!
Files saved here will be lost on shutdown.
Your real home is under ${PERSISTENT_HOME_DIR}
Please save your files there.
EOF
else
# home directory mount FAILED
# create a WARNING.txt for the user, no PERSISTENT :-(
cat > "${TEMP_HOME_DIR}/WARNING.txt" <<EOF
ATTENTION: This is a non-persistent home directory!
Files saved here will be lost on shutdown.
Please save your files on a USB drive or upload them
to some web service.
EOF
fi
chown "${USER_UID}" "${TEMP_HOME_DIR}/WARNING.txt"
# Remember for hooks in auth-slx-source.d
if [ "${NETWORK_HOME:0:2}" = '//' ]; then
PERSISTENT_NETPATH=$(echo "$NETWORK_HOME" | tr '/' '\')
else
PERSISTENT_NETPATH="$NETWORK_HOME"
fi
export PERSISTENT_NETPATH
#
# source the stuff in auth-slx-source.d, if it exists
#
PAM_AUTHTOK="${USER_PASSWORD}"
readonly PAM_AUTHTOK
for file in /opt/openslx/pam/hooks/auth-slx-source.d/*; do
[ -f "$file" ] || continue
( . "$file" ) || slxlog "pam-source-hooks" "Could not source '$file'."
done
exit 0
|