summaryrefslogtreecommitdiffstats
path: root/remote/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share
blob: 5416842f3d5c77601590067b661efcbffa2c94dc (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
###################################################################
#
#       This script is a part of the pam_script_auth script
#       and is not stand-alone!
#
#       It will try to mount the common shares specified in the
#       variables of the global slx config '/opt/openslx/config'.
#       A primary and a secondary share may be given. Every share
#       require following bundle of variables:
#
#
#       SLX_SHARE_[0-9]_AUTH_TYPE		[guest|user|pam]
#       SLX_SHARE_[0-9]_AUTH_USER		<username>
#       SLX_SHARE_[0-9]_AUTH_PASS		<password>
#       SLX_SHARE_[0-9]_PERM				[ro|rw]
#       SLX_SHARE_[0-9]_PATH				<path_to_share>
#
#       Example:
#                 SLX_SHARE_0_PATH='//windows.server/sharename'
#                 SLX_SHARE_0_AUTH_TYPE='user'
#                 SLX_SHARE_0_AUTH_USER='shareuser'
#                 SLX_SHARE_0_AUTH_PASS='sharepass'
#                 SLX_SHARE_0_PERM='rw'
#
#       Note: When AUTH_TYPE is set to 'pam' or 'guest',
#             no need to specify AUTH_USER or AUTH_PASS.
#
#
# usage: mount_share <auth_type> <auth_user> <auth_password> <permissions> <path> <share>
mount_share() {
	# only want two arguments
	[ $# -ne 6 ] && { slxlog "pam-share-args" "Wrong number of arguments given! Need 6, $# given."; return; }
	
	# lets check if we have our variables
	local SHARE_AUTH_TYPE="$1"
	local SHARE_AUTH_USER="$2"
	local SHARE_AUTH_PASS="$3"
	local SHARE_PERM="$4"
	local SHARE_PATH="$5"
	local SHARE_NUM="$6"

	# unless specified otherwise, mount the share read-only
	[ "x${SHARE_PERM}" != "xrw" ] && SHARE_PERM='ro'

	# all good: now we can mount depending on the type
	# supports: cifs?/nfs? 
	if [ "${SHARE_PATH:0:2}" = "//" ]; then
		# '//' prefixed, assume windows share
		# prepare common mount options for either authentication type
		MOUNT_OPTS="-t cifs -o nounix,uid=${USER_UID},gid=${USER_GID},forceuid,forcegid,nobrl,noacl,$SHARE_PERM"

		# flag for failure
		SIGNAL=$(mktemp)
		rm -f -- "${SIGNAL}"
		# output of command
		MOUNT_OUTPUT=$(mktemp)
		# now construct the mount options depending on the type of the share.
		if [ "${SHARE_AUTH_TYPE}" = "guest" ]; then
			MOUNT_OPTS="${MOUNT_OPTS},guest,file_mode=0777,dir_mode=0777"
		elif [ "${SHARE_AUTH_TYPE}" = "pam" ]; then
			export USER="{PAM_USER}"
			export PASSWD="{PAM_AUTHTOK}"
			MOUNT_OPTS="${MOUNT_OPTS},sec=ntlm,file_mode=0700,dir_mode=0700"
		elif [ "${SHARE_AUTH_TYPE}" = "user" ]; then
			# check if credentials are set
			[ ! -z "${SHARE_AUTH_USER}" ] || \
				{ slxlog "pam-share-noauthuser" "Share${SHARE_NUM}: No variable 'SLX_SHARE_${SHARE_NUM}_AUTH_USER' found in config!"; return; }
			# now export them to the env
			export USER="${SHARE_AUTH_USER}"
			export PASSWD="${SHARE_AUTH_PASS}"
			MOUNT_OPTS="${MOUNT_OPTS},sec=ntlm,file_mode=0700,dir_mode=0700"
		else
			slxlog "pam-share-auth" "Share${SHARE_NUM}: Auth type '${SHARE_AUTH_TYPE}' not supported."
			return;
		fi

		# we just mount it to the directory with the same name as the
		# last directory in the path name of the share
		# e.g. //windows.net/lehrpool -> ${COMMON_SHARE_MOUNT_POINT}/lehrpool
		local TARGET_DIR="${COMMON_SHARE_MOUNT_POINT}/$(basename ${SHARE_PATH})"
		# it exists, so let's create ${COMMON_SHARE_MOUNT_POINT}/lehrpool_${SHARE_NUM}
		[ -d "${TARGET_DIR}" ] && TARGET_DIR="${TARGET_DIR}_${SHARE_NUM}"

		# at this point is TARGET_DIR pointing to the right directory.
		mkdir -p "${TARGET_DIR}" || \
			{ slxlog "pam-share-mkdirfail" "Share${SHARE_NUM}: Could not create directory '${TARGET_DIR}'. Skipping share."; return; }
		# now try to mount it
		( mount ${MOUNT_OPTS} "${SHARE_PATH}" "${TARGET_DIR}" > "${MOUNT_OUTPUT}" 2>&1 || touch "${SIGNAL}" ) &
		MOUNT_PID=$!
		for COUNTER in 1 1 2 4; do
			kill -0 "${MOUNT_PID}" 2>/dev/null || break
			sleep "${COUNTER}"
		done

		# check for failures
		if [ -e "${SIGNAL}" ]; then
			slxlog "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' failed. (Args: ${MOUNT_OPTS}" "${MOUNT_OUTPUT}"
			rm -f -- "${SIGNAL}"
		elif kill -9 "${MOUNT_PID}" 2>/dev/null; then
			slxlog "pam-share-mount" "Mount of '${SHARE_PATH}' to '${TARGET_DIR}' timed out. (Args: ${MOUNT_OPTS}" "${MOUNT_OUTPUT}"
		fi
		( sleep 2; rm -f -- "${MOUNT_OUTPUT}" ) &

		# always unset credentials
		unset USER
		unset PASSWD
	fi
}

# at this point we need the slx config to do anything
[ -e "/opt/openslx/config" ] || \
	{ slxlog "pam-share-noconfig" "File '/opt/openslx/config' not found."; return; }

# we have it as we should, source it
. /opt/openslx/config || \
	{ slxlog "pam-share-sourceconfig" "Could not source '/opt/openslx/config'."; return; }

# Since many shares can be specified, we need to identify how many we have first.
# We just go over all SLX_SHARE_* variables and check for those ending in _PATH
# For each of those, a share was specified and we will try to mount it.
for SHARE in ${!SLX_SHARE_*}; do
	# skip if the variable doesn't end in _PATH
	[[ "$SHARE" =~ .*_PATH$ ]] || continue
	# first let's check if we have already mounted it, since we don't have to
	# do anything is it already is.
	if mount | grep -q "${SHARE}"; then
		# already mounted, just skip.
		continue
	fi
	# ok so we have a path in $SHARE, let's extract the number of the share
	# i.e. SLX_SHARE_0_PATH -> share number 0
	# first strip the leading SLX_SHARE_
	SHARE=${SHARE#SLX_SHARE_}
	# now remove the trailing _PATH
	SHARE=${SHARE%_PATH}
	# now it should be a number, TODO accept more than numbers? Doesn't really matter...
	# this check is mostly to be sure that the variable splitting worked as it should
	[[ "$SHARE" =~ ^[0-9]+$ ]] || continue
	eval mount_share \""\$SLX_SHARE_${SHARE}_AUTH_TYPE"\" \""\$SLX_SHARE_${SHARE}_AUTH_USER"\" \""\$SLX_SHARE_${SHARE}_AUTH_PASS"\" \""\$SLX_SHARE_${SHARE}_PERM"\" \""\$SLX_SHARE_${SHARE}_PATH"\" \""$SHARE"\"
done