summaryrefslogtreecommitdiff
blob: 1e0c2ff0392eb7bcd9df069b01fd7451d091cf12 (plain)
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
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
# Copyright 1999-2015 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2

# @ECLASS: pam.eclass
# @MAINTAINER:
# pam-bugs@gentoo.org
# @AUTHOR:
# Diego Pettenò <flameeyes@gentoo.org>
# @BLURB: Handles pam related tasks
# @DESCRIPTION:
# This eclass contains functions to install pamd configuration files and
# pam modules.

if [[ -z ${_PAM_ECLASS} ]]; then
_PAM_ECLASS=1

inherit flag-o-matic multilib

# @FUNCTION: dopamd
# @USAGE: <file> [more files]
# @DESCRIPTION:
# Install pam auth config file in /etc/pam.d
dopamd() {
	[[ -z $1 ]] && die "dopamd requires at least one argument"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	( # dont want to pollute calling env
		insinto /etc/pam.d
		insopts -m 0644
		doins "$@"
	) || die "failed to install $@"
	cleanpamd "$@"
}

# @FUNCTION: newpamd
# @USAGE: <old name> <new name>
# @DESCRIPTION:
# Install pam file <old name> as <new name> in /etc/pam.d
newpamd() {
	[[ $# -ne 2 ]] && die "newpamd requires two arguments"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	( # dont want to pollute calling env
		insinto /etc/pam.d
		insopts -m 0644
		newins "$1" "$2"
	) || die "failed to install $1 as $2"
	cleanpamd $2
}

# @FUNCTION: dopamsecurity
# @USAGE: <section> <file> [more files]
# @DESCRIPTION:
# Installs the config files in /etc/security/<section>/
dopamsecurity() {
	[[ $# -lt 2 ]] && die "dopamsecurity requires at least two arguments"

	if has pam ${IUSE} && ! use pam; then
		return 0
	fi

	( # dont want to pollute calling env
		insinto /etc/security/$1
		insopts -m 0644
		doins "${@:2}"
	) || die "failed to install ${@:2}"
}

# @FUNCTION: newpamsecurity
# @USAGE: <section> <old name> <new name>
# @DESCRIPTION:
# Installs the config file <old name> as <new name> in /etc/security/<section>/
newpamsecurity() {
	[[ $# -ne 3 ]] && die "newpamsecurity requires three arguments"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	( # dont want to pollute calling env
		insinto /etc/security/$1
		insopts -m 0644
		newins "$2" "$3"
	) || die "failed to install $2 as $3"
}

# @FUNCTION: getpam_mod_dir
# @DESCRIPTION:
# Returns the pam modules' directory for current implementation
getpam_mod_dir() {
	if has_version sys-libs/pam || has_version sys-libs/openpam; then
		PAM_MOD_DIR=/$(get_libdir)/security
	else
		# Unable to find PAM implementation... defaulting
		PAM_MOD_DIR=/$(get_libdir)/security
	fi

	echo ${PAM_MOD_DIR}
}

# @FUNCTION: pammod_hide_symbols
# @DESCRIPTION:
# Hide all non-PAM-used symbols from the module; this function creates a
# simple ld version script that hides all the symbols that are not
# necessary for PAM to load the module, then uses append-flags to make
# sure that it gets used.
pammod_hide_symbols() {
	cat - > "${T}"/pam-eclass-pam_symbols.ver <<EOF
{
	global: pam_sm_*;
	local: *;
};
EOF

	append-ldflags -Wl,--version-script="${T}"/pam-eclass-pam_symbols.ver
}

# @FUNCTION: dopammod
# @USAGE: <file> [more files]
# @DESCRIPTION:
# Install pam module file in the pam modules' dir for current implementation
dopammod() {
	[[ -z $1 ]] && die "dopammod requires at least one argument"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	exeinto $(getpam_mod_dir)
	doexe "$@" || die "failed to install $@"
}

# @FUNCTION: newpammod
# @USAGE: <old name> <new name>
# @DESCRIPTION:
# Install pam module file <old name> as <new name> in the pam
# modules' dir for current implementation
newpammod() {
	[[ $# -ne 2 ]] && die "newpammod requires two arguements"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	exeinto $(getpam_mod_dir)
	newexe "$1" "$2" || die "failed to install $1 as $2"
}

# @FUNCTION: pamd_mimic_system
# @USAGE: <pamd file> [auth levels]
# @DESCRIPTION:
# This function creates a pamd file which mimics system-auth file
# for the given levels in the /etc/pam.d directory.
pamd_mimic_system() {
	[[ $# -lt 2 ]] && die "pamd_mimic_system requires at least two argments"
	pamd_mimic system-auth "$@"
}

# @FUNCTION: pamd_mimic
# @USAGE: <stack> <pamd file> [auth levels]
# @DESCRIPTION:
# This function creates a pamd file which mimics the given stack
# for the given levels in the /etc/pam.d directory.
pamd_mimic() {
	[[ $# -lt 3 ]] && die "pamd_mimic requires at least three argments"

	if has pam ${IUSE} && ! use pam; then
		return 0;
	fi

	dodir /etc/pam.d
	pamdfile=${D}/etc/pam.d/$2
	echo -e "# File autogenerated by pamd_mimic in pam eclass\n\n" >> \
		$pamdfile

	originalstack=$1
	authlevels="auth account password session"

	if has_version '<sys-libs/pam-0.78'; then
		mimic="\trequired\t\tpam_stack.so service=${originalstack}"
	else
		mimic="\tinclude\t\t${originalstack}"
	fi

	shift; shift

	while [[ -n $1 ]]; do
		has $1 ${authlevels} || die "unknown level type"

		echo -e "$1${mimic}" >> ${pamdfile}

		shift
	done
}

# @FUNCTION: cleanpamd
# @USAGE: <pamd file>
# @DESCRIPTION:
# Cleans a pam.d file from modules that might not be present on the system
# where it's going to be installed
cleanpamd() {
	while [[ -n $1 ]]; do
		if ! has_version sys-libs/pam; then
			sed -i -e '/pam_shells\|pam_console/s:^:#:' "${D}/etc/pam.d/$1"
		fi

		shift
	done
}

# @FUNCTION: pam_epam_expand
# @USAGE: <pamd file>
# @DESCRIPTION:
# Steer clear, deprecated, don't use, bad experiment
pam_epam_expand() {
	sed -n -e 's|#%EPAM-\([[:alpha:]-]\+\):\([-+<>=/.![:alnum:]]\+\)%#.*|\1 \2|p' \
	"$@" | sort -u | while read condition parameter; do

	disable="yes"

	case "$condition" in
		If-Has)
		message="This can be used only if you have ${parameter} installed"
		has_version "$parameter" && disable="no"
		;;
		Use-Flag)
		message="This can be used only if you enabled the ${parameter} USE flag"
		use "$parameter" && disable="no"
		;;
		*)
		eerror "Unknown EPAM condition '${condition}' ('${parameter}')"
		die "Unknown EPAM condition '${condition}' ('${parameter}')"
		;;
	esac

	if [ "${disable}" = "yes" ]; then
		sed -i -e "/#%EPAM-${condition}:${parameter/\//\\/}%#/d" "$@"
	else
		sed -i -e "s|#%EPAM-${condition}:${parameter}%#||" "$@"
	fi

	done
}

# Think about it before uncommenting this one, for now run it by hand
# pam_pkg_preinst() {
# 	eshopts_push -o noglob # so that bash doen't expand "*"
#
# 	pam_epam_expand "${D}"/etc/pam.d/*
#
# 	eshopts_pop # reset old shell opts
# }

fi