summaryrefslogblamecommitdiffstats
path: root/core/modules/pam-slx-plug/data/opt/openslx/pam/exec_auth
blob: 9de6170855227b794e4fc60ed6b6b6332ee023c8 (plain) (tree)
1
2
3
4
5
6
7
8
9
10









                                                              
                 
 
                                           








                                                                                                                    


                                                                             
 


                                                           
                                                                
                                                          

                                                                  
                                                                               
  



















                                                     
                
                       





                                                     





                               
                                                  






                                                                        
 













                                                                                                            


                                                                                              



























                                                                                        
                            



















                                                                                            
                                                                                                                    

                                                                                                       



                                                                                            

                                 

                                                                    
  



                                                                














                                                                                             
                                                                







                                                        
    
                           
  
 








                                                                                      

















                                                              







                                                               
 
                                                     
 

                              
                                                          





                                                                              
#!/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