summaryrefslogtreecommitdiffstats
path: root/remote/modules/pam-common-share/data/opt/openslx/scripts/pam_script_mount_common_share
blob: 5c034824c77968e0dc0717fdd5d236b43278d31e (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
###################################################################
#
#       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

		# now create the subdir within $COMMON_SHARE_MOUNT_POINT
		mkdir -p "${COMMON_SHARE_MOUNT_POINT}/${SHARE_NUM}" || \
			{ slxlog "pam-share-mkdirfail" "Share${SHARE_NUM}: Could not create directory '${COMMON_SHARE_MOUNT_POINT}/${SHARE_NUM}'."; return; }
		# now try to mount it
		( mount ${MOUNT_OPTS} "${SHARE_PATH}" "${COMMON_SHARE_MOUNT_POINT}/${SHARE_NUM}" > "${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 '${COMMON_SHARE_MOUNT_POINT}/${SHARE_NUM}' 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 '${COMMON_SHARE_MOUNT_POINT}/${SHARE_NUM}' 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
	# ok so we have a path in S, 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