|
|
adf540 |
#!/bin/bash
|
|
|
adf540 |
# This script serves one purpose, to add a possibly missing attribute
|
|
|
adf540 |
# to a ppolicy schema in a dynamic configuration of OpenLDAP. This
|
|
|
adf540 |
# attribute was introduced in openldap-2.4.43 and slapd will not
|
|
|
adf540 |
# start without it later on.
|
|
|
adf540 |
#
|
|
|
adf540 |
# The script tries to update in a directory given as first parameter,
|
|
|
adf540 |
# or in /etc/openldap/slapd.d implicitly.
|
|
|
adf540 |
#
|
|
|
adf540 |
# Author: Matus Honek <mhonek@redhat.com>
|
|
|
adf540 |
# Bugzilla: #1487857
|
|
|
adf540 |
|
|
|
adf540 |
function log {
|
|
|
adf540 |
echo "Update dynamic configuration: " $@
|
|
|
adf540 |
true
|
|
|
adf540 |
}
|
|
|
adf540 |
|
|
|
adf540 |
function iferr {
|
|
|
adf540 |
if [ $? -ne 0 ]; then
|
|
|
adf540 |
log "ERROR: " $@
|
|
|
adf540 |
true
|
|
|
adf540 |
else
|
|
|
adf540 |
false
|
|
|
adf540 |
fi
|
|
|
adf540 |
}
|
|
|
adf540 |
|
|
|
adf540 |
function update {
|
|
|
adf540 |
set -u
|
|
|
adf540 |
shopt -s extglob
|
|
|
adf540 |
|
|
|
adf540 |
ORIGINAL="${1:-/etc/openldap/slapd.d}"
|
|
|
adf540 |
ORIGINAL="${ORIGINAL%*(/)}"
|
|
|
adf540 |
|
|
|
adf540 |
### check if necessary
|
|
|
adf540 |
grep -r "pwdMaxRecordedFail" "${ORIGINAL}/cn=config/cn=schema" >/dev/null
|
|
|
adf540 |
[ $? -eq 0 ] && log "Schemas look up to date. Ok. Quitting." && return 0
|
|
|
adf540 |
|
|
|
adf540 |
### prep
|
|
|
adf540 |
log "Prepare environment."
|
|
|
adf540 |
|
|
|
adf540 |
TEMPDIR=$(mktemp -d)
|
|
|
adf540 |
iferr "Could not create a temporary directory. Quitting." && return 1
|
|
|
adf540 |
DBDIR="${TEMPDIR}/db"
|
|
|
adf540 |
SUBDBDIR="${DBDIR}/cn=temporary"
|
|
|
adf540 |
|
|
|
adf540 |
mkdir "${DBDIR}"
|
|
|
adf540 |
iferr "Could not create temporary configuration directory. Quitting." && return 1
|
|
|
adf540 |
cp -r --no-target-directory "${ORIGINAL}" "${SUBDBDIR}"
|
|
|
adf540 |
iferr "Could not copy configuration. Quitting." && return 1
|
|
|
adf540 |
|
|
|
adf540 |
pushd "$TEMPDIR" >/dev/null
|
|
|
adf540 |
|
|
|
adf540 |
cat > temp.conf <
|
|
|
adf540 |
database ldif
|
|
|
adf540 |
suffix cn=temporary
|
|
|
adf540 |
directory db
|
|
|
adf540 |
access to * by * manage
|
|
|
adf540 |
EOF
|
|
|
adf540 |
|
|
|
adf540 |
SOCKET="$(pwd)/socket"
|
|
|
adf540 |
LISTENER="ldapi://${SOCKET//\//%2F}"
|
|
|
adf540 |
CONN_PARAMS=("-Y" "EXTERNAL" "-H" "${LISTENER}")
|
|
|
adf540 |
|
|
|
adf540 |
slapd -f temp.conf -h "$LISTENER" -d 0 >/dev/null 2>&1 &
|
|
|
adf540 |
SLAPDPID="$!"
|
|
|
adf540 |
sleep 2
|
|
|
adf540 |
|
|
|
adf540 |
ldapadd ${CONN_PARAMS[@]} -d 0 >/dev/null 2>&1 <
|
|
|
adf540 |
dn: cn=temporary
|
|
|
adf540 |
objectClass: olcGlobal
|
|
|
adf540 |
cn: temporary
|
|
|
adf540 |
EOF
|
|
|
adf540 |
iferr "Could not populate the temporary database. Quitting." && return 1
|
|
|
adf540 |
|
|
|
adf540 |
### update
|
|
|
adf540 |
log "Update with new pwdMaxRecordedFailure attribute."
|
|
|
adf540 |
FILTER="(&"
|
|
|
adf540 |
FILTER+="(olcObjectClasses=*'pwdPolicy'*)"
|
|
|
adf540 |
FILTER+="(!(olcObjectClasses=*'pwdPolicy'*'pwdMaxRecordedFailure'*))"
|
|
|
adf540 |
FILTER+="(!(olcAttributeTypes=*'pwdMaxRecordedFailure'*))"
|
|
|
adf540 |
FILTER+=")"
|
|
|
adf540 |
RES=$(ldapsearch ${CONN_PARAMS[@]} \
|
|
|
adf540 |
-b cn=schema,cn=config,cn=temporary \
|
|
|
adf540 |
-LLL \
|
|
|
adf540 |
-o ldif-wrap=no \
|
|
|
adf540 |
"$FILTER" \
|
|
|
adf540 |
dn olcObjectClasses \
|
|
|
adf540 |
2>/dev/null \
|
|
|
adf540 |
| sed '/^$/d')
|
|
|
adf540 |
DN=$(printf "$RES" | grep '^dn:')
|
|
|
adf540 |
OC=$(printf "$RES" | grep "^olcObjectClasses:.*'pwdPolicy'")
|
|
|
adf540 |
NEWOC="${OC//$ pwdSafeModify /$ pwdSafeModify $ pwdMaxRecordedFailure }"
|
|
|
adf540 |
|
|
|
adf540 |
test $(echo "$DN" | wc -l) = 1
|
|
|
adf540 |
iferr "Received more than one DN. Cannot continue. Quitting." && return 1
|
|
|
adf540 |
test "$NEWOC" != "$OC"
|
|
|
adf540 |
iferr "Updating pwdPolicy objectClass definition failed. Quitting." && return 1
|
|
|
adf540 |
|
|
|
adf540 |
ldapmodify ${CONN_PARAMS[@]} -d 0 >/dev/null 2>&1 <
|
|
|
adf540 |
$DN
|
|
|
adf540 |
changetype: modify
|
|
|
adf540 |
add: olcAttributeTypes
|
|
|
adf540 |
olcAttributeTypes: ( 1.3.6.1.4.1.42.2.27.8.1.30 NAME 'pwdMaxRecordedFailur
|
|
|
adf540 |
e' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.
|
|
|
adf540 |
1466.115.121.1.27 SINGLE-VALUE )
|
|
|
adf540 |
-
|
|
|
adf540 |
delete: olcObjectClasses
|
|
|
adf540 |
$OC
|
|
|
adf540 |
-
|
|
|
adf540 |
add: olcObjectClasses
|
|
|
adf540 |
$NEWOC
|
|
|
adf540 |
EOF
|
|
|
adf540 |
iferr "Updating with new attribute failed. Quitting." && return 1
|
|
|
adf540 |
|
|
|
adf540 |
popd >/dev/null
|
|
|
adf540 |
|
|
|
adf540 |
### apply
|
|
|
adf540 |
log "Apply changes."
|
|
|
adf540 |
cp -r --no-target-directory "$ORIGINAL" "$ORIGINAL~backup"
|
|
|
adf540 |
iferr "Backing up old configuration failed. Quitting." && return 1
|
|
|
adf540 |
cp -r --no-target-directory "$SUBDBDIR" "$ORIGINAL"
|
|
|
adf540 |
iferr "Applying new configuration failed. Quitting." && return 1
|
|
|
adf540 |
|
|
|
adf540 |
### clean up
|
|
|
adf540 |
log "Clean up."
|
|
|
adf540 |
kill "$SLAPDPID"
|
|
|
adf540 |
SLAPDPID=
|
|
|
adf540 |
rm -rf "$TEMPDIR"
|
|
|
adf540 |
TEMPDIR=
|
|
|
adf540 |
}
|
|
|
adf540 |
|
|
|
adf540 |
SLAPDPID=
|
|
|
adf540 |
TEMPDIR=
|
|
|
adf540 |
update "$1"
|
|
|
adf540 |
if [ $? -ne 0 ]; then
|
|
|
adf540 |
log "Clean up."
|
|
|
adf540 |
echo "$SLAPDPID"
|
|
|
adf540 |
echo "$TEMPDIR"
|
|
|
adf540 |
kill "$SLAPDPID"
|
|
|
adf540 |
rm -rf "$TEMPDIR"
|
|
|
adf540 |
fi
|
|
|
adf540 |
log "Finished."
|