-
Notifications
You must be signed in to change notification settings - Fork 1
/
inst
executable file
·257 lines (214 loc) · 9.84 KB
/
inst
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
#!/bin/bash
#
# App join script
#
# Copyright 2021-2024 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.
## joinscript api: bindpwdfile
VERSION="7"
. /usr/share/univention-join/joinscripthelper.lib
. /usr/share/univention-lib/all.sh
. /usr/share/univention-ssl/make-certificates.sh
joinscript_init
app_id="keycloak"
domainname="$(ucr get domainname)"
hostname="$(ucr get hostname)"
ldap_base="$(ucr get ldap/base)"
sso_url="$(ucr get keycloak/server/sso/fqdn)"
COMPONENT_ID=$(univention-app get $app_id component_id | cut -f 2 -d ':' | tr -d '[:space:]')
ucr set \
ucs/web/overview/entries/admin/$app_id/description/de="Keycloak" \
ucs/web/overview/entries/admin/$app_id/description="Keycloak" \
ucs/web/overview/entries/admin/$app_id/label="Keycloak" \
ucs/web/overview/entries/admin/$app_id/link="https://$sso_url/admin/" \
ucs/web/overview/entries/admin/$app_id/icon="/univention/js/dijit/themes/umc/icons/scalable/apps-$COMPONENT_ID.svg" \
ucs/web/overview/entries/admin/$app_id/link-target='newwindow'
## Only make the portal tile for the Keycloak App visible once a Domain Admin is logged in on the portal
domain_admins_dn=$(univention-ldapsearch -LLL "(&(cn=Domain Admins)(objectClass=univentionGroup))" 1.1 | ldapsearch-decode64 | sed -n 's/^dn: //p')
udm portals/entry modify "$@" \
--dn "cn=keycloak,cn=entry,cn=portals,cn=univention,$ldap_base" \
--append allowedGroups="$domain_admins_dn" || die
# register LDAP acl to hide settings/data attribute. Contains database password
ucs_registerLDAPExtension "$@" \
--ucsversionstart "4.4-0" --ucsversionend "5.99-0" \
--packagename "$app_id" \
--packageversion "1" \
--acl "/var/lib/univention-appcenter/apps/$app_id/conf/67keycloak.acl" || die
## as variables were changed we need the new ones
psql_pwd_path="/etc/postgresql-keycloak.secret"
machine_secret="/etc/machine.secret"
eval "$(ucr shell)"
ucs_parseCredentials "$@"
primary="$ldap_master"
# check if we need to create a new certificate
if [ "$server_role" = "domaincontroller_backup" ] && [ -z "$keycloak_apache2_ssl_certificate" ]; then
univention-scp "$machine_secret" "-r $hostname\$@$primary:/etc/univention/ssl/${keycloak_server_sso_fqdn}/ /etc/univention/ssl/" || die
chgrp -R "DC Backup Hosts" "/etc/univention/ssl/$keycloak_server_sso_fqdn/"
default_sso_fqdn="ucs-sso-ng.$(ucr get domainname)"
[[ "$default_sso_fqdn" != ${default_sso_fqdn,,} ]] && ln -s "/etc/univention/ssl/$default_sso_fqdn" "/etc/univention/ssl/${default_sso_fqdn,,}" || true
fi
keycloak_db_host_dn=$(univention-ldapsearch -LLL univentionService="$app_id DB" 1.1 | sed -ne "s/^dn: //p")
if [ -z "$keycloak_db_host_dn" ]; then
ucs_addServiceToLocalhost "$app_id DB" "$@"
else
keycloak_db_host=$(ucs_getAttrOfDN "cn" "$keycloak_db_host_dn")
univention-scp $machine_secret "-r $hostname\$@$keycloak_db_host:/etc/keycloak.secret /etc/keycloak.secret" || die
fi
# Re-create Apache configuration after the certificate generation
[ -x /usr/sbin/univention-config-registry ] && univention-config-registry register univention-keycloak || true
ucr commit /etc/apache2/sites-available/univention-keycloak.conf
a2ensite univention-keycloak
systemctl restart apache2
# Make keycloak DB available for other systems
[ -x /usr/sbin/univention-config-registry ] && univention-config-registry register 50-keycloak || true
ucr commit /etc/postgresql/11/main/pg_hba.conf
ucr commit /etc/postgresql/15/main/pg_hba.conf
service postgresql reload # don't restart here to not interrupt the keycloak init process
sso_hostname="$(echo "$keycloak_server_sso_fqdn" | cut -d '.' -f 1)"
sso_domainname="$(echo "$keycloak_server_sso_fqdn" | cut -d '.' -f 2-)"
if [ -z "$keycloak_server_sso_autoregistration" ] || is_ucr_true keycloak/server/sso/autoregistration; then
/usr/share/univention-directory-manager-tools/univention-dnsedit "$@" --ignore-exists \
"$sso_domainname" add a "$sso_hostname" "$(get_default_ip_address)" || die
if is_localhost_in_admember_mode; then
ucs_parseCredentials "$@"
if { [ -z "$binddn" ] || [ -z "$bindpwdfile" ]; } && is_ucr_true ad/member; then
binddn="uid=$connector_ad_ldap_binddn"
bindpwdfile="$connector_ad_ldap_bindpw"
fi
if [ -n "$binddn" ] && [ -n "$bindpwdfile" ]; then
add_host_record_in_ad "$binddn" "" "$bindpwdfile" \
"$keycloak_server_sso_fqdn" "$(get_default_ip_address)" || die
fi
fi
fi
# wait for the keycloak_server_sso_fqdn dns record
wait_for_dns () {
local server="${1:?missing server param}" i out
for ((i=0; i<300; i++))
do
out="$(nslookup -timeout=1 -retry=0 "$server")" && return 0
echo "waiting for $server ..."
sleep 1
done
echo "failed to lookup $server"
echo "$out"
return 1
}
wait_for_dns "$keycloak_server_sso_fqdn" || die
wait_for_keycloak () {
local i=0
for ((i=0; i<400; i++)); do
test "$(docker inspect -f "{{.State.Health.Status}}" "keycloak")" = "healthy" && univention-keycloak --binduser "${keycloak_admin_user:-admin}" realms get && return 0
sleep 3;
done
echo "ERROR: Container did not come up healthy"
return 1
}
wait_for_keycloak || die
univention-app restart keycloak
wait_for_keycloak || die
# if init is necessary (ucs realm does not exist),
# this also sets domain_config_version
# and domain_config_init to the current keycloak version
univention-keycloak --binduser "${keycloak_admin_user:-admin}" init || die
# for upgrades, upgrade-config runs all upgrade
# steps between "domain_config_version" and
# the current keycloak version and saves the
# current version in "domain_config_version"
if ! is_ucr_false keycloak/auto-migration; then
univention-keycloak "$@" --binduser "${keycloak_admin_user:-admin}" upgrade-config || die
fi
for umc in $(univention-ldapsearch -LLL univentionService="Univention Management Console" displayName | sed -n 's/displayName: //p' | tr ";" "\n")
do
univention-keycloak "$@" --binduser "${keycloak_admin_user:-admin}" saml/sp create --metadata-url="https://$umc.$domainname/univention/saml/metadata" --umc-uid-mapper
if [ "$?" != "0" ]; then
echo "Error creating a saml serviceprovider for the umc of $umc.$domainname"
fi
done
# create kerberos user
echo "creating keycloak kerberos user"
spn_account_name="krbkeycloak"
servicePrincipalName="HTTP/$keycloak_server_sso_fqdn"
servicePrincipal="$servicePrincipalName"'@'"$kerberos_realm"
keytab_path="/var/lib/univention-appcenter/apps/keycloak/conf/keycloak.keytab"
user_exists=$(univention-ldapsearch -LLL uid="$spn_account_name" 1.1)
if [ -n "$user_exists" ]; then
echo "Kerberos Service Principal already exists: $user_exists.\nSkipping user creation"
else
krb_password="$(makepasswd --chars 20)"
udm users/user create "$@" --ignore_exists \
--position "cn=users,$ldap_base" \
--set username="$spn_account_name" \
--set lastname="keycloak" \
--set password="$krb_password" \
--append objectFlag=hidden || die
fi
ldapmodify -x -H "ldap://$ldap_master:${ldap_master_port:-7389}" -D "cn=admin,$ldap_base" -y "/etc/ldap.secret" <<%EOF
dn: uid=$spn_account_name,cn=users,$ldap_base
changetype: modify
replace: krb5PrincipalName
krb5PrincipalName: $servicePrincipal
%EOF
if dpkg -s univention-samba4 &> /dev/null; then
samba_private_dir="/var/lib/samba/private"
timeout=${keycloak_kerberos_timeout:-1200}
for i in $(seq 1 10 $timeout); do
echo "looking for spn account \"$spn_account_name\" in local samba"
service_account_dn=$(ldbsearch -H $samba_private_dir/sam.ldb samAccountName="$spn_account_name" dn | sed -n 's/^dn: \(.*\)/\1/p')
[ -n "$service_account_dn" ] && break
sleep 10
done
samba-tool spn add "$servicePrincipalName" "$spn_account_name"
fi
rm "$keytab_path"
kadmin -l ext --keytab="$keytab_path" "$servicePrincipal" || die
chown "1000":"DC Backup Hosts" "$keytab_path" || die
chmod 660 "$keytab_path" || die
univention-keycloak kerberos-config set --server-principal "$servicePrincipal"
# TODO, test if that is necessary, if not remove
## another restart for the cache initialization
#univention-app restart keycloak
#wait_for_keycloak || die
ucs_addServiceToLocalhost "$app_id" "$@"
configure_umc_keycloak () {
univention-keycloak "$@" --binduser "${keycloak_admin_user:-admin}" saml/sp update "https://$hostname.$domainname/univention/saml/metadata" \
'{"attributes": {"saml.assertion.lifespan": "'"$umc_saml_assertion_lifetime"'"}}'
if is_ucr_true 'umc/web/sso/enabled' && [ -z "$umc_saml_idp_server" ]; then
rm /usr/share/univention-management-console/saml/idp/*.xml
ucr --debug set umc/saml/idp-server="$(univention-keycloak get-keycloak-base-url)/realms/ucs/protocol/saml/descriptor" || return 1
[ "$(ls -A /usr/share/univention-management-console/saml/idp/*.xml)" ] || return 1
service slapd restart
fi
}
if [ "$version_version" == "5.2" ]; then
configure_umc_keycloak "$@" || {
echo "UMC keycloak configuration failed. Consider attempting manual setup using the Univention Keycloak app manual."
ucr unset umc/saml/idp-server
}
fi
joinscript_save_current_version
exit 0