-
Notifications
You must be signed in to change notification settings - Fork 1
/
prepare_theory_native_environment
169 lines (133 loc) · 5.48 KB
/
prepare_theory_native_environment
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
#!/bin/bash
function fail {
if [[ ! $? == 0 ]]; then
echo "Error running $0"
exit 1
fi
}
function is_uint {
# test if $1 is unsigned integer
case $1 in
'' | *[!0-9]*)
return 1
;;
esac
}
function version_is_lower {
# expects the classical version pattern major.minor.release[.subrelease...]
# with major, minor, release being unsigned integers
# $1: version to be tested
# $2: pattern to be tested against
# $3: controls the #sections to be compared (from left to right)
# returns
# 0: in case of $1 is lower than $2
# 1: in case of $1 is equal or higher than $2
# 2: in case of an error
is_uint "$3" || return 2
sections=$3
IFS=. read -a ver_arr <<<"$1" || return 2
IFS=. read -a pat_arr <<<"$2" || return 2
(( ${#ver_arr[@]} < $sections )) || (( ${#pat_arr[@]} < $sections )) && return 2
for (( i=0; i<$sections; i++ )); do
is_uint "${ver_arr[$i]}" || return 2
is_uint "${pat_arr[$i]}" || return 2
done
for (( i=0; i<$sections; i++ )); do
(( ${ver_arr[$i]} < ${pat_arr[$i]} )) && return 0
(( ${ver_arr[$i]} > ${pat_arr[$i]} )) && return 1
done
((sections--))
(( ${ver_arr[$sections]} == ${pat_arr[$sections]} )) && return 1
return 2
}
function check_whoami {
eff_user="$(whoami)"
eff_user_id=$(id -u $eff_user)
if [[ $eff_user_id != 0 ]]; then
echo "You are '${eff_user}, userid '$eff_user_id'."
echo "To run this command you must be userid '0'."
echo "Try again with 'sudo $0'."
return 1
fi
}
function prepare_sudoers {
sudo_min_version="1.9.10"
sudo_version="$(grep -Piom1 'version[^0-9]+\K.*' <(sudo -V 2>/dev/null) 2>/dev/null)"
echo "Found Sudo-Version $sudo_version."
version_is_lower "${sudo_version%%[^0-9\.]*}" "$sudo_min_version" 3 >/dev/null 2>&1
case $? in
0)
echo "This sudo version is lower than $sudo_min_version."
echo "It does not support regular expressions."
echo "Hence, sudoers will not be modified."
return 1
;;
1)
# continue
;;
*)
echo "Can't compare sudo version number."
return 1
;;
esac
sudoers_includedir="/etc/sudoers.d"
sudoers_conf="/etc/sudoers"
# according to 'man sudoers':
# "... skipping file names that end in ‘~’ or contain a ‘.’ character to avoid causing
# problems with package manager or editor temporary/backup files."
# Hence, avoid those characters here but it is save to rename backup files '*.backup-*'.
sudoers_addons="50-lhcathome_boinc_theory_native"
if [[ ! -e "$sudoers_conf" ]]; then
echo "File '$sudoers_conf' not found."
return 1
fi
if ! grep -Eqm1 "^\s*[@#]{1}(include|includedir)\s*${sudoers_includedir}" <(tac $sudoers_conf); then
echo "includedir $sudoers_includedir is not enabled in $sudoers_conf."
sudoers_confirm="no"
read -p "Type 'yes' to enable it ... " sudoers_confirm
if [[ "${sudoers_confirm,,}" != "yes" ]]; then
echo "Missing confirmation."
return 1
fi
echo "@includedir ${sudoers_includedir}" >>$sudoers_conf
fi
if [[ ! -d "$sudoers_includedir" ]]; then
echo "Missing directory $sudoers_includedir."
sudoers_confirm="no"
read -p "Type 'yes' to create it ... " sudoers_confirm
if [[ "${sudoers_confirm,,}" != "yes" ]]; then
echo "Missing confirmation."
return 1
fi
install -o root -g root -m 750 -d "$sudoers_includedir" || return 1
fi
if [[ -e "$sudoers_includedir/$sudoers_addons" ]]; then
while :; do
sudoers_backup="$(mktemp -uqp $sudoers_includedir -t $sudoers_addons.backup-XXXXXXXX)"
[[ ! -e "$sudoers_backup" ]] && break 2
done
echo "$sudoers_includedir/$sudoers_addons already exists."
echo "Will save it as $sudoers_backup."
cp $sudoers_includedir/$sudoers_addons $sudoers_backup || return 1
fi
# Do not indent the heredoc EOF!
cat << EOF_SUDOERS_FILE >"$sudoers_includedir/$sudoers_addons"
# save this file as '$sudoers_includedir/$sudoers_addons'
# ownership must be 'root:root' and access rights must be '-r--r-----'
# '@includedir $sudoers_includedir' must be enabled in $sudoers_conf
# regular expressions are enclosed between '^' and '$'
# this is supported since sudo version 1.9.10
# for more information read 'man sudoers'
# the regex patterns given here must match the command arguments in the calling script
# missing/additional arguments or an argument order not in sync causes a command to be rejected
# the commands are permitted for the local group 'boinc'
# ensure the calling user is a member of that group
Cmnd_Alias LHCATHOMEBOINC_01 = /usr/bin/cat ^$sudoers_includedir/$sudoers_addons$
Cmnd_Alias LHCATHOMEBOINC_02 = /usr/bin/systemctl ^(freeze|thaw) Theory_[-a-zA-Z0-9_]+\.scope$
Cmnd_Alias LHCATHOMEBOINC_03 = /usr/bin/systemd-run ^--scope -u [a-zA-Z0-9_-]+ -p BindsTo=[a-zA-Z0-9_\.@-]+ -p After=[a-zA-Z0-9_\.@-]+ --slice-inherit --uid=[a-zA-Z0-9_-]+ --gid=boinc --same-dir -q -G /[a-zA-Z0-9_\./-]+/(runc|runc\.new|runc\.old) --root state run -b cernvm [a-zA-Z0-9_-]+$
%boinc ALL = (ALL) NOPASSWD: LHCATHOMEBOINC_01, LHCATHOMEBOINC_02, LHCATHOMEBOINC_03
EOF_SUDOERS_FILE
chmod 440 "$sudoers_includedir/$sudoers_addons"
}
check_whoami || fail
prepare_sudoers || fail