Compare commits
19 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
016fedfacf | ||
![]() |
5068c903fe | ||
![]() |
10d496a8f4 | ||
![]() |
86923be42e | ||
![]() |
68e238875b | ||
![]() |
d1995499b0 | ||
![]() |
9cef6de7af | ||
![]() |
fcee0594d4 | ||
![]() |
cc267252f6 | ||
![]() |
92a5316886 | ||
![]() |
4576ecd885 | ||
![]() |
656382d46b | ||
![]() |
3b877a763f | ||
![]() |
aa2b9b5dca | ||
![]() |
c6569b162c | ||
![]() |
5f0f8223f7 | ||
![]() |
471fcb3d9d | ||
![]() |
d0d022ef0f | ||
![]() |
093586313d |
30
.drone.yml
30
.drone.yml
@ -1,30 +0,0 @@
|
|||||||
---
|
|
||||||
kind: pipeline
|
|
||||||
name: default
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: build image only
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
repo: eumau/openldap
|
|
||||||
auto_tag: true
|
|
||||||
dry_run: true
|
|
||||||
when:
|
|
||||||
ref:
|
|
||||||
- refs/pull/**
|
|
||||||
# event no anda (?)
|
|
||||||
# event:
|
|
||||||
# - pull_request
|
|
||||||
|
|
||||||
- name: build and publish image
|
|
||||||
image: plugins/docker
|
|
||||||
settings:
|
|
||||||
repo: eumau/openldap
|
|
||||||
auto_tag: true
|
|
||||||
username:
|
|
||||||
from_secret: dockerhub_username
|
|
||||||
password:
|
|
||||||
from_secret: dockerhub_password
|
|
||||||
when:
|
|
||||||
branch:
|
|
||||||
- master
|
|
39
.gitea/workflows/build.yml
Normal file
39
.gitea/workflows/build.yml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
name: Build Docker images
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: true
|
||||||
|
matrix:
|
||||||
|
repo:
|
||||||
|
- "eumau/openldap"
|
||||||
|
tag:
|
||||||
|
- "1"
|
||||||
|
- latest
|
||||||
|
steps:
|
||||||
|
-
|
||||||
|
name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
-
|
||||||
|
name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
-
|
||||||
|
name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
-
|
||||||
|
name: Build and push image
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
push: true
|
||||||
|
tags: ${{ matrix.repo }}:${{ matrix.tag }}
|
||||||
|
platforms: linux/amd64,linux/arm64
|
13
Dockerfile
13
Dockerfile
@ -1,4 +1,4 @@
|
|||||||
FROM eumau/debian:buster-slim
|
FROM eumau/debian:bookworm-slim
|
||||||
|
|
||||||
# admin CN => dn: cn=%%ADMIN_CN%%,%%DOMAIN_DN%%
|
# admin CN => dn: cn=%%ADMIN_CN%%,%%DOMAIN_DN%%
|
||||||
ENV LDAP_ADMIN_CN="admin"
|
ENV LDAP_ADMIN_CN="admin"
|
||||||
@ -18,12 +18,6 @@ ENV LDAP_DOMAIN_INDEX="cn,uid eq\nmember,memberUid eq\nobjectClass eq\nuidNumber
|
|||||||
ENV LDAP_DOMAIN_OUS="People Alias Group"
|
ENV LDAP_DOMAIN_OUS="People Alias Group"
|
||||||
# enable memberOf module
|
# enable memberOf module
|
||||||
ENV LDAP_MEMBEROF="true"
|
ENV LDAP_MEMBEROF="true"
|
||||||
# enable replication provider
|
|
||||||
ENV LDAP_PROVIDER="false"
|
|
||||||
# replicator CN => dn: cn=%%REPLICATOR_CN%%,%%DOMAIN_DN%%
|
|
||||||
ENV LDAP_REPLICATOR_CN="replicator"
|
|
||||||
# replicator password
|
|
||||||
ENV LDAP_REPLICATOR_PASSWORD="${LDAP_ADMIN_PASSWORD}"
|
|
||||||
# space-separated list of schemas to load
|
# space-separated list of schemas to load
|
||||||
ENV LDAP_SCHEMAS="core cosine inetorgperson misc nis"
|
ENV LDAP_SCHEMAS="core cosine inetorgperson misc nis"
|
||||||
|
|
||||||
@ -34,13 +28,14 @@ RUN apt-get update \
|
|||||||
apt-get clean && \
|
apt-get clean && \
|
||||||
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||||
|
|
||||||
|
ADD setup /start.d
|
||||||
|
ADD confd /etc/confd/
|
||||||
ADD entrypoint.sh /
|
ADD entrypoint.sh /
|
||||||
|
ADD ldap_backup ldap_restore /usr/local/sbin/
|
||||||
|
|
||||||
EXPOSE 389
|
EXPOSE 389
|
||||||
|
|
||||||
VOLUME ["/etc/ldap/schema", "/etc/ldap/slapd.d", "/var/lib/ldap", "/var/backups/ldap"]
|
VOLUME ["/etc/ldap/schema", "/etc/ldap/slapd.d", "/var/lib/ldap", "/var/backups/ldap"]
|
||||||
|
|
||||||
ENTRYPOINT ["/entrypoint.sh"]
|
|
||||||
|
|
||||||
# log level info:
|
# log level info:
|
||||||
CMD ["slapd", "-d", "32768", "-u", "openldap", "-g", "openldap"]
|
CMD ["slapd", "-d", "32768", "-u", "openldap", "-g", "openldap"]
|
||||||
|
11
confd/conf.d/add_ldap_group.toml
Normal file
11
confd/conf.d/add_ldap_group.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[template]
|
||||||
|
src = "add_ldap_group.tmpl"
|
||||||
|
prefix = "/ldap"
|
||||||
|
dest = "/usr/local/bin/add_ldap_group"
|
||||||
|
mode = "0755"
|
||||||
|
keys = [
|
||||||
|
"/admin/cn",
|
||||||
|
"/admin/password",
|
||||||
|
"/domain",
|
||||||
|
"/domain/dn",
|
||||||
|
]
|
11
confd/conf.d/add_ldap_user.toml
Normal file
11
confd/conf.d/add_ldap_user.toml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
[template]
|
||||||
|
src = "add_ldap_user.tmpl"
|
||||||
|
prefix = "/ldap"
|
||||||
|
dest = "/usr/local/bin/add_ldap_user"
|
||||||
|
mode = "0755"
|
||||||
|
keys = [
|
||||||
|
"/admin/cn",
|
||||||
|
"/admin/password",
|
||||||
|
"/domain",
|
||||||
|
"/domain/dn",
|
||||||
|
]
|
100
confd/templates/add_ldap_group.tmpl
Normal file
100
confd/templates/add_ldap_group.tmpl
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
usage: docker exec [...] add_ldap_group [-c COMMON_NAME] [-u UID] [-p PASSWORD] [-e EMAIL]
|
||||||
|
Unset options will be prompted interactively.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMON_NAME=
|
||||||
|
USER_UID=
|
||||||
|
USER_EMAIL=
|
||||||
|
USER_PASS=
|
||||||
|
SURNAME=
|
||||||
|
while getopts "c: u: e: p:" OPCION
|
||||||
|
do
|
||||||
|
case ${OPCION} in
|
||||||
|
"c")
|
||||||
|
COMMON_NAME=${OPTARG}
|
||||||
|
;;
|
||||||
|
"s")
|
||||||
|
SURNAME=${OPTARG}
|
||||||
|
;;
|
||||||
|
"u")
|
||||||
|
USER_UID=${OPTARG}
|
||||||
|
;;
|
||||||
|
"e")
|
||||||
|
USER_EMAIL=${OPTARG}
|
||||||
|
;;
|
||||||
|
"p")
|
||||||
|
USER_PASS=${OPTARG}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
LDAP_ADMIN_CN="{{ getv "/admin/cn" }}"
|
||||||
|
LDAP_ADMIN_PASSWORD="{{ getv "/admin/password" }}"
|
||||||
|
LDAP_DOMAIN="{{ getv "/domain" }}"
|
||||||
|
LDAP_DOMAIN_DN="{{ getv "/domain/dn" }}"
|
||||||
|
|
||||||
|
DN0="dc=${LDAP_DOMAIN//./,dc=}"
|
||||||
|
LDAP_DOMAIN_DN=${LDAP_DOMAIN_DN:=${DN0}}
|
||||||
|
|
||||||
|
[[ -n ${USER_UID} ]] || {
|
||||||
|
echo -n "Enter user UID (e.g. jdoe) > "
|
||||||
|
read USER_UID
|
||||||
|
}
|
||||||
|
|
||||||
|
# echo "Check if uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN} exists"
|
||||||
|
RES_DN=$(ldapsearch -LLL -H ldap:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" -s base \
|
||||||
|
-b "uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}" \
|
||||||
|
"(objectClass=*)" 2>/dev/null \
|
||||||
|
| egrep '^dn: ' | sed -e 's/^dn: //g' )
|
||||||
|
[[ -z ${RES_DN} ]]
|
||||||
|
assert "User already present. Please choose a different UID."
|
||||||
|
|
||||||
|
[[ -n ${COMMON_NAME} ]] || {
|
||||||
|
echo -n "Enter user CN (e.g. John Doe) > "
|
||||||
|
read COMMON_NAME
|
||||||
|
}
|
||||||
|
[[ -n ${SURNAME} ]] || {
|
||||||
|
echo -n "Enter user SN (e.g. Doe) > "
|
||||||
|
read SURNAME
|
||||||
|
}
|
||||||
|
[[ -n ${USER_PASS} ]] || {
|
||||||
|
echo -n "Enter user password (will not be echoed) > "
|
||||||
|
read -s USER_PASS
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
[[ -n ${USER_EMAIL} ]] || {
|
||||||
|
echo -n "Enter user email (leave blank for ${USER_UID}@${LDAP_DOMAIN}) > "
|
||||||
|
read USER_EMAIL
|
||||||
|
}
|
||||||
|
USER_EMAIL="${USER_EMAIL:=${USER_UID}@${LDAP_DOMAIN}}"
|
||||||
|
|
||||||
|
|
||||||
|
PWHASH=$(slappasswd -h "{SSHA}" -s "${USER_PASS}")
|
||||||
|
|
||||||
|
echo "Creating user uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldap:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
||||||
|
dn: uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: inetOrgPerson
|
||||||
|
objectClass: organizationalPerson
|
||||||
|
objectClass: person
|
||||||
|
objectClass: top
|
||||||
|
cn: ${COMMON_NAME}
|
||||||
|
sn: ${SURNAME}
|
||||||
|
uid: ${USER_UID}
|
||||||
|
userPassword: ${PWHASH}
|
||||||
|
mail: ${USER_EMAIL}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
assert "Error adding user!"
|
100
confd/templates/add_ldap_user.tmpl
Normal file
100
confd/templates/add_ldap_user.tmpl
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
|
usage() {
|
||||||
|
cat <<EOF
|
||||||
|
usage: docker exec [...] add_ldap_user [-c COMMON_NAME] [-s SURNAME] [-u UID] [-p PASSWORD] [-e EMAIL]
|
||||||
|
Unset options will be prompted interactively.
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
COMMON_NAME=
|
||||||
|
USER_UID=
|
||||||
|
USER_EMAIL=
|
||||||
|
USER_PASS=
|
||||||
|
SURNAME=
|
||||||
|
while getopts "c: u: e: p:" OPCION
|
||||||
|
do
|
||||||
|
case ${OPCION} in
|
||||||
|
"c")
|
||||||
|
COMMON_NAME=${OPTARG}
|
||||||
|
;;
|
||||||
|
"s")
|
||||||
|
SURNAME=${OPTARG}
|
||||||
|
;;
|
||||||
|
"u")
|
||||||
|
USER_UID=${OPTARG}
|
||||||
|
;;
|
||||||
|
"e")
|
||||||
|
USER_EMAIL=${OPTARG}
|
||||||
|
;;
|
||||||
|
"p")
|
||||||
|
USER_PASS=${OPTARG}
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
exit 2
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
LDAP_ADMIN_CN="{{ getv "/admin/cn" }}"
|
||||||
|
LDAP_ADMIN_PASSWORD="{{ getv "/admin/password" }}"
|
||||||
|
LDAP_DOMAIN="{{ getv "/domain" }}"
|
||||||
|
LDAP_DOMAIN_DN="{{ getv "/domain/dn" }}"
|
||||||
|
|
||||||
|
DN0="dc=${LDAP_DOMAIN//./,dc=}"
|
||||||
|
LDAP_DOMAIN_DN=${LDAP_DOMAIN_DN:=${DN0}}
|
||||||
|
|
||||||
|
[[ -n ${USER_UID} ]] || {
|
||||||
|
echo -n "Enter user UID (e.g. jdoe) > "
|
||||||
|
read USER_UID
|
||||||
|
}
|
||||||
|
|
||||||
|
# echo "Check if uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN} exists"
|
||||||
|
RES_DN=$(ldapsearch -LLL -H ldap:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" -s base \
|
||||||
|
-b "uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}" \
|
||||||
|
"(objectClass=*)" 2>/dev/null \
|
||||||
|
| egrep '^dn: ' | sed -e 's/^dn: //g' )
|
||||||
|
[[ -z ${RES_DN} ]]
|
||||||
|
assert "User already present. Please choose a different UID."
|
||||||
|
|
||||||
|
[[ -n ${COMMON_NAME} ]] || {
|
||||||
|
echo -n "Enter user CN (e.g. John Doe) > "
|
||||||
|
read COMMON_NAME
|
||||||
|
}
|
||||||
|
[[ -n ${SURNAME} ]] || {
|
||||||
|
echo -n "Enter user SN (e.g. Doe) > "
|
||||||
|
read SURNAME
|
||||||
|
}
|
||||||
|
[[ -n ${USER_PASS} ]] || {
|
||||||
|
echo -n "Enter user password (will not be echoed) > "
|
||||||
|
read -s USER_PASS
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
[[ -n ${USER_EMAIL} ]] || {
|
||||||
|
echo -n "Enter user email (leave blank for ${USER_UID}@${LDAP_DOMAIN}) > "
|
||||||
|
read USER_EMAIL
|
||||||
|
}
|
||||||
|
USER_EMAIL="${USER_EMAIL:=${USER_UID}@${LDAP_DOMAIN}}"
|
||||||
|
|
||||||
|
|
||||||
|
PWHASH=$(slappasswd -h "{SSHA}" -s "${USER_PASS}")
|
||||||
|
|
||||||
|
echo "Creating user uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldap:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
||||||
|
dn: uid=${USER_UID},ou=People,${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: inetOrgPerson
|
||||||
|
objectClass: organizationalPerson
|
||||||
|
objectClass: person
|
||||||
|
objectClass: top
|
||||||
|
cn: ${COMMON_NAME}
|
||||||
|
sn: ${SURNAME}
|
||||||
|
uid: ${USER_UID}
|
||||||
|
userPassword: ${PWHASH}
|
||||||
|
mail: ${USER_EMAIL}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
assert "Error adding user!"
|
358
entrypoint.sh
358
entrypoint.sh
@ -1,356 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
|
||||||
|
|
||||||
# from https://github.com/dinkel/docker-openldap/blob/master/entrypoint.sh:
|
|
||||||
# When not limiting the open file descritors limit, the memory consumption of
|
|
||||||
# slapd is absurdly high. See https://github.com/docker/docker/issues/8231
|
|
||||||
ulimit -n 8192
|
|
||||||
|
|
||||||
slapd -u openldap -g openldap -h ldapi:///
|
|
||||||
assert "FATAL: sldapd died unexpectedly!"
|
|
||||||
|
|
||||||
PIDFILE=$(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// -b "cn=config" -s base \
|
|
||||||
"" olcPidFile | grep olcPidFile | awk "{print $2}")
|
|
||||||
echo "slapd running. pidfile = ${PIDFILE}"
|
|
||||||
|
|
||||||
[[ -n "${LDAP_DOMAIN}" ]]
|
|
||||||
assert "FATAL: Please set LDAP_DOMAIN and retry."
|
|
||||||
DN0="dc=${LDAP_DOMAIN//./,dc=}"
|
|
||||||
LDAP_DOMAIN_DN=${LDAP_DOMAIN_DN:=${DN0}}
|
|
||||||
|
|
||||||
echo "setting up domain = ${LDAP_DOMAIN}, dn = ${LDAP_DOMAIN_DN}"
|
|
||||||
|
|
||||||
[[ -n "${LDAP_CONFIG_PASSWORD}" ]]
|
|
||||||
assert "FATAL: Please set LDAP_CONFIG_PASSWORD and retry."
|
|
||||||
LDAP_CONFIG_PWHASH=$(slappasswd -h "{SSHA}" -s "${LDAP_CONFIG_PASSWORD}")
|
|
||||||
|
|
||||||
[[ -n "${LDAP_ADMIN_PASSWORD}" ]]
|
|
||||||
assert "FATAL: Please set LDAP_ADMIN_PASSWORD and retry."
|
|
||||||
LDAP_ADMIN_PWHASH=$(slappasswd -h "{SSHA}" -s "${LDAP_ADMIN_PASSWORD}")
|
|
||||||
|
|
||||||
# TODO: verify password before updating =======================================
|
|
||||||
|
|
||||||
echo "Setting cn=admin,cn=config password"
|
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
|
||||||
dn: olcDatabase={0}config,cn=config
|
|
||||||
changetype: modify
|
|
||||||
replace: olcRootPW
|
|
||||||
olcRootPW: ${LDAP_CONFIG_PWHASH}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
assert "FATAL: error setting cn=admin,cn=config password"
|
|
||||||
|
|
||||||
# SCHEMAS ---------------------------------------------------------------------
|
|
||||||
eval "declare -A LOADED_SCHEMAS=( $(ldapsearch -LLL -Y EXTERNAL -H ldapi:/// \
|
|
||||||
-b "cn=schema,cn=config" -s one cn \
|
|
||||||
| sed -n 's/^cn:.*[{].*[}]\(.*\)$/[\1]=loaded/p') )"
|
|
||||||
echo "Loaded schemas: ${!LOADED_SCHEMAS[@]}"
|
|
||||||
|
|
||||||
# load schemas
|
|
||||||
# built-in: core, cosine, nis, inetorgperson
|
|
||||||
# available: collective, corba, duaconf, dyngroup, java, misc, nis, openldap, pmi, ppolicy
|
|
||||||
for schema in ${LDAP_SCHEMAS}
|
|
||||||
do
|
|
||||||
[[ -z "${LOADED_SCHEMAS[$schema]}" ]] || continue;
|
|
||||||
|
|
||||||
echo "Loading ${schema} schema"
|
|
||||||
|
|
||||||
[[ -f /etc/ldap/schema/${schema}.ldif ]]
|
|
||||||
assert "FATAL: schema file /etc/ldap/schema/${schema}.ldif not found!"
|
|
||||||
|
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/ldap/schema/${schema}.ldif
|
|
||||||
assert "FATAL: error loading schema ${schema}!"
|
|
||||||
done
|
|
||||||
# END SCHEMAS -----------------------------------------------------------------
|
|
||||||
|
|
||||||
# MEMBEROF MODULE -------------------------------------------------------------
|
|
||||||
if ${LDAP_MEMBEROF}
|
|
||||||
then
|
|
||||||
echo "Enabling memberof module"
|
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: cn=module{0},cn=config
|
|
||||||
changetype: modify
|
|
||||||
add: olcModuleLoad
|
|
||||||
olcModuleLoad: memberof
|
|
||||||
|
|
||||||
EOF
|
|
||||||
RES=$?
|
|
||||||
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
|
||||||
assert "FATAL: error loading memberof module (return status ${RES})"
|
|
||||||
unset RES
|
|
||||||
fi
|
|
||||||
# END MEMBEROF MODULE ---------------------------------------------------------
|
|
||||||
|
|
||||||
# REPLICATION PROVIDER --------------------------------------------------------
|
|
||||||
if ${LDAP_PROVIDER}
|
|
||||||
then
|
|
||||||
echo "Enabling syncprov module"
|
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: cn=module{0},cn=config
|
|
||||||
changetype: modify
|
|
||||||
add: olcModuleLoad
|
|
||||||
olcModuleLoad: syncprov
|
|
||||||
|
|
||||||
EOF
|
|
||||||
RES=$?
|
|
||||||
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
|
||||||
assert "FATAL: error loading syncprov module (return status ${RES})"
|
|
||||||
|
|
||||||
echo "Enabling accesslog module"
|
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: cn=module{0},cn=config
|
|
||||||
changetype: modify
|
|
||||||
add: olcModuleLoad
|
|
||||||
olcModuleLoad: accesslog
|
|
||||||
|
|
||||||
EOF
|
|
||||||
RES=$?
|
|
||||||
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
|
||||||
assert "FATAL: error loading accesslog module (return status ${RES})"
|
|
||||||
unset RES
|
|
||||||
|
|
||||||
if ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "cn=config" \
|
|
||||||
"(&(olcSuffix=\"cn=accesslog\")(olcDatabase=mdb))" | \
|
|
||||||
egrep -q '^dn: '
|
|
||||||
then
|
|
||||||
echo "Found cn=config entry for cn=accesslog"
|
|
||||||
else
|
|
||||||
echo "No cn=config entry for cn=accesslog."
|
|
||||||
|
|
||||||
echo "Creating directory /var/lib/ldap/cn=accesslog"
|
|
||||||
mkdir "/var/lib/ldap/cn=accesslog"
|
|
||||||
chown -R openldap:openldap "/var/lib/ldap/cn=accesslog"
|
|
||||||
|
|
||||||
echo "Creating cn=config entry for cn=accesslog"
|
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: olcDatabase=mdb,cn=config
|
|
||||||
objectClass: olcDatabaseConfig
|
|
||||||
objectClass: olcMdbConfig
|
|
||||||
olcRootDN: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
|
||||||
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
|
||||||
olcDbMaxSize: 8589934592
|
|
||||||
olcSuffix: cn=accesslog
|
|
||||||
olcDbDirectory: /var/lib/ldap/cn=accesslog
|
|
||||||
olcAccess: {0}to * by dn="cn=${LDAP_REPLICATOR_CN},${LDAP_DOMAIN_DN}" read
|
|
||||||
olcLimits: {0}to dn.exact="cn=${LDAP_REPLICATOR_CN},${LDAP_DOMAIN_DN}" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
|
|
||||||
olcLimits: {1}to dn.exact="cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
if ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "cn=config" \
|
|
||||||
"(&(olcSuffix=\"cn=accesslog\")(olcDatabase=mdb))" | \
|
|
||||||
egrep -q '^dn: '
|
|
||||||
then
|
|
||||||
echo "Found cn=config entry for cn=accesslog"
|
|
||||||
else
|
|
||||||
echo "No cn=config entry for cn=accesslog."
|
|
||||||
|
|
||||||
echo "Creating directory /var/lib/ldap/cn=accesslog"
|
|
||||||
mkdir "/var/lib/ldap/cn=accesslog"
|
|
||||||
chown -R openldap:openldap "/var/lib/ldap/cn=accesslog"
|
|
||||||
|
|
||||||
echo "Creating cn=config entry for cn=accesslog"
|
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: olcDatabase=mdb,cn=config
|
|
||||||
objectClass: olcDatabaseConfig
|
|
||||||
objectClass: olcMdbConfig
|
|
||||||
olcRootDN: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
|
||||||
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
|
||||||
olcDbMaxSize: 8589934592
|
|
||||||
olcSuffix: cn=accesslog
|
|
||||||
olcDbDirectory: /var/lib/ldap/cn=accesslog
|
|
||||||
olcAccess: {0}to * by dn="cn=${LDAP_REPLICATOR_CN},${LDAP_DOMAIN_DN}" read
|
|
||||||
olcLimits: {0}to dn.exact="cn=${LDAP_REPLICATOR_CN},${LDAP_DOMAIN_DN}" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
|
|
||||||
olcLimits: {1}to dn.exact="cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}" time.soft=unlimited time.hard=unlimited size.soft=unlimited size.hard=unlimited
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Get DN of cn=config entry for cn=accesslog"
|
|
||||||
CN_CONFIG_DN=$(ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b cn=config \
|
|
||||||
"(&(olcSuffix=cn=accesslog)(olcDatabase=mdb))" \
|
|
||||||
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${CN_CONFIG_DN} ]]
|
|
||||||
then echo "Found DN = ${CN_CONFIG_DN}"
|
|
||||||
else
|
|
||||||
echo "FATAL: could not find cn=config entry for cn=accesslog"
|
|
||||||
echo "PLEASE NOTE: only MDB database format is supported (PR welcome :)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TODO: olcOverlay=syncprov ===============================================
|
|
||||||
|
|
||||||
# TODO: replication users (on domain setup?) ==============================
|
|
||||||
|
|
||||||
fi
|
|
||||||
# END REPLICATION PROVIDER ----------------------------------------------------
|
|
||||||
|
|
||||||
# DOMAIN SETUP ----------------------------------------------------------------
|
|
||||||
if ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "cn=config" \
|
|
||||||
"(&(olcSuffix=\"${LDAP_DOMAIN_DN}\")(olcDatabase=mdb))" | \
|
|
||||||
egrep -q '^dn: '
|
|
||||||
then
|
|
||||||
echo "Found cn=config entry for ${LDAP_DOMAIN_DN}"
|
|
||||||
else
|
|
||||||
echo "No cn=config entry for ${LDAP_DOMAIN_DN}."
|
|
||||||
echo "Creating directory /var/lib/ldap/${LDAP_DOMAIN_DN}"
|
|
||||||
mkdir "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
|
||||||
chown -R openldap:openldap "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
|
||||||
|
|
||||||
echo "Creating cn=config entry for ${LDAP_DOMAIN_DN}"
|
|
||||||
|
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: olcDatabase=mdb,cn=config
|
|
||||||
objectClass: olcDatabaseConfig
|
|
||||||
objectClass: olcMdbConfig
|
|
||||||
olcDbMaxSize: 1073741824
|
|
||||||
olcSuffix: ${LDAP_DOMAIN_DN}
|
|
||||||
olcDbDirectory: /var/lib/ldap/${LDAP_DOMAIN_DN}
|
|
||||||
olcRootDN: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
|
||||||
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
|
||||||
$(echo -ne "${LDAP_DOMAIN_ACCESS}" | sed -e 's/^/olcAccess: /g')
|
|
||||||
olcDbCheckpoint: 512 30
|
|
||||||
olcLastMod: TRUE
|
|
||||||
$(echo -ne "${LDAP_DOMAIN_INDEX}" | sed -e 's/^/olcDbIndex: /g')
|
|
||||||
$(echo -ne "${LDAP_DOMAIN_LIMITS}" | sed -e 's/^/olcLimits: /g')
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Get cn=config entry for ${LDAP_DOMAIN_DN}"
|
|
||||||
CN_CONFIG_DN=$(ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b "cn=config" \
|
|
||||||
"(&(olcSuffix=${LDAP_DOMAIN_DN})(olcDatabase=mdb))" \
|
|
||||||
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${CN_CONFIG_DN} ]]
|
|
||||||
then echo "Found DN = ${CN_CONFIG_DN}"
|
|
||||||
else
|
|
||||||
echo "FATAL: could not find cn=config entry for ${LDAP_DOMAIN_DN}"
|
|
||||||
echo "PLEASE NOTE: only MDB database format is supported (PR welcome :)"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TODO: verify admin password before updating =================================
|
|
||||||
|
|
||||||
echo "Setting domain administrator password"
|
|
||||||
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF
|
|
||||||
dn: ${CN_CONFIG_DN}
|
|
||||||
changetype: modify
|
|
||||||
replace: olcRootPW
|
|
||||||
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
assert "FATAL: could not set administrator password!"
|
|
||||||
# END DOMAIN SETUP ------------------------------------------------------------
|
|
||||||
|
|
||||||
# MEMBEROF OVERLAY ------------------------------------------------------------
|
|
||||||
if [[ ${LDAP_MEMBEROF} ]]
|
|
||||||
then
|
|
||||||
echo "Check if memberOf overlay is enabled"
|
|
||||||
MEMBEROF_DN=$(ldapsearch -LLL -H ldapi:/// -Y EXTERNAL -s one -b \
|
|
||||||
"${CN_CONFIG_DN}" "(olcOverlay=memberOf)" | \
|
|
||||||
egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${MEMBEROF_DN} ]]
|
|
||||||
then echo "memberOf overlay already enabled for ${CN_CONFIG_DN}"
|
|
||||||
else
|
|
||||||
echo "Enabling memberOf overlay"
|
|
||||||
ldapadd -Y EXTERNAL -H ldapi:/// <<-EOF
|
|
||||||
dn: olcOverlay=memberof,${CN_CONFIG_DN}
|
|
||||||
objectClass: olcOverlayConfig
|
|
||||||
objectClass: olcConfig
|
|
||||||
objectClass: olcMemberOf
|
|
||||||
olcMemberOfDangling: ignore
|
|
||||||
olcMemberOfRefInt: FALSE
|
|
||||||
olcMemberOfGroupOC: groupOfNames
|
|
||||||
olcMemberOfMemberAD: member
|
|
||||||
olcMemberOfMemberOfAD: memberOf
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
# END MEMBEROF OVERLAY --------------------------------------------------------
|
|
||||||
|
|
||||||
# DIT ENTRIES -----------------------------------------------------------------
|
|
||||||
echo "Check if ${LDAP_DOMAIN_DN} exists"
|
|
||||||
DOM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" -s base -b "${LDAP_DOMAIN_DN}" \
|
|
||||||
"(objectClass=*)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${DOM_DN} ]]
|
|
||||||
then echo "${LDAP_DOMAIN_DN} already present"
|
|
||||||
else
|
|
||||||
echo "Creating ${LDAP_DOMAIN_DN}"
|
|
||||||
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
|
||||||
dn: ${LDAP_DOMAIN_DN}
|
|
||||||
objectClass: dcObject
|
|
||||||
objectClass: organization
|
|
||||||
objectClass: top
|
|
||||||
dc: $(echo -n "${LDAP_DOMAIN_DN#dc=}" | sed 's/,.*$//g')
|
|
||||||
o: ${LDAP_DOMAIN}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Admin user
|
|
||||||
echo "Check if cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} exists"
|
|
||||||
ADM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" -s base -b \
|
|
||||||
"cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}" "(objectClass=*)" \
|
|
||||||
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${ADM_DN} ]]
|
|
||||||
then echo "cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} already present"
|
|
||||||
else
|
|
||||||
echo "Creating cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}"
|
|
||||||
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
|
||||||
dn: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
|
||||||
objectClass: organizationalRole
|
|
||||||
objectClass: simpleSecurityObject
|
|
||||||
cn: ${LDAP_ADMIN_CN}
|
|
||||||
description: LDAP Administrator role for domain ${LDAP_DOMAIN}
|
|
||||||
userPassword: ${ADMIN_PW_HASH}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
|
|
||||||
# TODO: update admin password =================================================
|
|
||||||
|
|
||||||
# create OUs
|
|
||||||
for OU in ${LDAP_DOMAIN_OUS}
|
|
||||||
do
|
|
||||||
echo "Check if ou=${OU},${LDAP_DOMAIN_DN} exists"
|
|
||||||
OU_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" -s base \
|
|
||||||
-b "ou=${OU},${LDAP_DOMAIN_DN}" "(objectClass=*)" \
|
|
||||||
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
|
||||||
|
|
||||||
if [[ -n ${OU_DN} ]]
|
|
||||||
then echo "ou=${OU} already present in ${LDAP_DOMAIN_DN}"
|
|
||||||
else
|
|
||||||
echo "Creating ou=${OU},${LDAP_DOMAIN_DN}"
|
|
||||||
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
|
||||||
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
|
||||||
dn: ou=${OU},${LDAP_DOMAIN_DN}
|
|
||||||
objectClass: organizationalUnit
|
|
||||||
objectClass: top
|
|
||||||
ou: ${OU}
|
|
||||||
|
|
||||||
EOF
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# -------------------------------------------
|
|
||||||
|
|
||||||
# kill slapd after initial setup
|
|
||||||
echo "Killing initial server"
|
|
||||||
kill -INT $(cat ${PIDFILE})
|
|
||||||
|
|
||||||
# unset sensitive variables
|
|
||||||
unset LDAP_ADMIN_PASSWORD LDAP_CONFIG_PASSWORD LDAP_ADMIN_PWHASH \
|
|
||||||
LDAP_CONFIG_PWHASH LOADED_SCHEMAS PIDFILE
|
|
||||||
|
|
||||||
# run Dockerfile CMD
|
|
||||||
echo "Running CMD $@"
|
|
||||||
set -e
|
set -e
|
||||||
exec "$@"
|
/usr/local/bin/confd -onetime -backend env
|
||||||
|
run-parts -v /start.d
|
||||||
|
ulimit -n 1024
|
||||||
|
exec ${@}
|
||||||
|
15
ldap_backup
Executable file
15
ldap_backup
Executable file
@ -0,0 +1,15 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
|
|
||||||
|
[[ -n "${LDAP_CONFIG_PASSWORD}" ]]
|
||||||
|
assert "FATAL: Please set LDAP_CONFIG_PASSWORD and retry."
|
||||||
|
|
||||||
|
# Count databases
|
||||||
|
DB_COUNT=$(ldapsearch -D cn=admin,cn=config -w "${LDAP_CONFIG_PASSWORD}" -b cn=config -LLL "(olcDatabase=mdb)" dn | tr -s '\n' | wc -l)
|
||||||
|
|
||||||
|
# Perform backup
|
||||||
|
for i in $(seq 0 ${DB_COUNT})
|
||||||
|
do slapcat -n ${i} -l /var/backups/ldap/${i}.ldif
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "Backed up ${DB_COUNT} databases in /var/backups/ldap."
|
53
ldap_restore
Executable file
53
ldap_restore
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
|
|
||||||
|
[[ -f /var/backups/ldap/0.ldif ]]
|
||||||
|
assert "Unable to restore backup. Missing /var/backups/ldap/0.ldif backup of cn=config."
|
||||||
|
|
||||||
|
[[ -f /var/backups/ldap/1.ldif ]]
|
||||||
|
assert "Unable to restore backup. Missing /var/backups/ldap/1.ldif backup of first database."
|
||||||
|
|
||||||
|
[[ -n "${LDAP_DOMAIN}" ]]
|
||||||
|
assert "FATAL: Please set LDAP_DOMAIN and retry."
|
||||||
|
DN0="dc=${LDAP_DOMAIN//./,dc=}"
|
||||||
|
LDAP_DOMAIN_DN=${LDAP_DOMAIN_DN:=${DN0}}
|
||||||
|
|
||||||
|
# Backup and clean existing config directory
|
||||||
|
tar czf /var/backups/ldap/etc_ldap_slapd_d-$(date '+%Y-%m-%d').tar.gz /etc/ldap/slapd.d
|
||||||
|
assert "FATAL: could not backup /etc/ldap/slapd.d before restoring."
|
||||||
|
find /etc/ldap/slapd.d -mindepth 1 -delete
|
||||||
|
assert "FATAL: could not clean /etc/ldap/slapd.d before restoring."
|
||||||
|
|
||||||
|
# Backup and clean existing data directory
|
||||||
|
tar czf /var/backups/ldap/var_lib_ldap-$(date '+%Y-%m-%d').tar.gz /var/lib/ldap
|
||||||
|
assert "FATAL: could not backup /var/lib/ldap before restoring."
|
||||||
|
find /var/lib/ldap -mindepth 1 -delete
|
||||||
|
assert "FATAL: could not clean /var/lib/ldap before restoring."
|
||||||
|
mkdir "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
assert "FATAL: could not create /var/lib/ldap/${LDAP_DOMAIN_DN}."
|
||||||
|
|
||||||
|
# Restore cn=config
|
||||||
|
echo "Restoring cn=config..."
|
||||||
|
slapadd -n 0 -F /etc/ldap/slapd.d -l /var/backups/ldap/0.ldif
|
||||||
|
assert "FATAL: error restoring cn=config using slapadd."
|
||||||
|
chown -R openldap:openldap /etc/ldap/slapd.d
|
||||||
|
assert "FATAL: could not fix /etc/ldap/slapd.d permissions."
|
||||||
|
|
||||||
|
for LDIF in /var/backups/ldap/*.ldif
|
||||||
|
do
|
||||||
|
# Check if it's cn=config backup
|
||||||
|
if [[ "${LDIF}" == "/var/backups/ldap/0.ldif" ]]
|
||||||
|
then continue
|
||||||
|
else
|
||||||
|
INDEX=$(basename "${LDIF}" | sed 's/.ldif$//g')
|
||||||
|
[[ "${INDEX}" =~ ^[0-9]+$ ]]
|
||||||
|
assert "FATAL: could not determine the DB index for ${LDIF}."
|
||||||
|
|
||||||
|
echo "Restoring database ${INDEX}..."
|
||||||
|
slapadd -n ${INDEX} -F /etc/ldap/slapd.d -l "${LDIF}"
|
||||||
|
assert "FATAL: error restoring database ${INDEX} using slapadd."
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
chown -R openldap:openldap /var/lib/ldap
|
||||||
|
assert "FATAL: could not fix /var/lib/ldap permissions."
|
250
setup
Executable file
250
setup
Executable file
@ -0,0 +1,250 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
assert(){ [[ $? -eq 0 ]] || { [[ -n ${1} ]] && echo ${@} ; exit 1 ; } }
|
||||||
|
|
||||||
|
# from https://github.com/dinkel/docker-openldap/blob/master/entrypoint.sh:
|
||||||
|
# When not limiting the open file descritors limit, the memory consumption of
|
||||||
|
# slapd is absurdly high. See https://github.com/docker/docker/issues/8231
|
||||||
|
ulimit -n 1024
|
||||||
|
|
||||||
|
chown -R openldap:openldap /var/lib/ldap
|
||||||
|
assert "FATAL: could not set required directory permissions"
|
||||||
|
|
||||||
|
slapd -u openldap -g openldap -h ldapi:///
|
||||||
|
assert "FATAL: sldapd died unexpectedly!"
|
||||||
|
|
||||||
|
PIDFILE=$(ldapsearch -LLL -QY EXTERNAL -H ldapi:/// -b "cn=config" -s base \
|
||||||
|
olcPidFile | grep olcPidFile | awk '{print $2}')
|
||||||
|
echo "slapd running. pidfile = ${PIDFILE}"
|
||||||
|
|
||||||
|
[[ -n "${LDAP_DOMAIN}" ]]
|
||||||
|
assert "FATAL: Please set LDAP_DOMAIN and retry."
|
||||||
|
DN0="dc=${LDAP_DOMAIN//./,dc=}"
|
||||||
|
LDAP_DOMAIN_DN=${LDAP_DOMAIN_DN:=${DN0}}
|
||||||
|
|
||||||
|
echo "setting up domain = ${LDAP_DOMAIN}, dn = ${LDAP_DOMAIN_DN}"
|
||||||
|
|
||||||
|
[[ -n "${LDAP_CONFIG_PASSWORD}" ]]
|
||||||
|
assert "FATAL: Please set LDAP_CONFIG_PASSWORD and retry."
|
||||||
|
LDAP_CONFIG_PWHASH=$(slappasswd -h "{SSHA}" -s "${LDAP_CONFIG_PASSWORD}")
|
||||||
|
|
||||||
|
[[ -n "${LDAP_ADMIN_PASSWORD}" ]]
|
||||||
|
assert "FATAL: Please set LDAP_ADMIN_PASSWORD and retry."
|
||||||
|
LDAP_ADMIN_PWHASH=$(slappasswd -h "{SSHA}" -s "${LDAP_ADMIN_PASSWORD}")
|
||||||
|
|
||||||
|
# TODO: verify password before updating =======================================
|
||||||
|
|
||||||
|
echo "Setting cn=admin,cn=config password"
|
||||||
|
ldapmodify -QY EXTERNAL -H ldapi:/// <<EOF
|
||||||
|
dn: olcDatabase={0}config,cn=config
|
||||||
|
changetype: modify
|
||||||
|
replace: olcRootPW
|
||||||
|
olcRootPW: ${LDAP_CONFIG_PWHASH}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
assert "FATAL: error setting cn=admin,cn=config password"
|
||||||
|
|
||||||
|
# SCHEMAS ---------------------------------------------------------------------
|
||||||
|
eval "declare -A LOADED_SCHEMAS=( $(ldapsearch -QLLL -Y EXTERNAL -H ldapi:/// \
|
||||||
|
-b "cn=schema,cn=config" -s one cn \
|
||||||
|
| sed -n 's/^cn:.*[{].*[}]\(.*\)$/[\1]=loaded/p') )"
|
||||||
|
echo "Loaded schemas: ${!LOADED_SCHEMAS[@]}"
|
||||||
|
|
||||||
|
# load schemas
|
||||||
|
# built-in: core, cosine, nis, inetorgperson
|
||||||
|
# available: collective, corba, duaconf, dyngroup, java, misc, nis, openldap, pmi, ppolicy
|
||||||
|
for schema in ${LDAP_SCHEMAS}
|
||||||
|
do
|
||||||
|
[[ -z "${LOADED_SCHEMAS[$schema]}" ]] || continue;
|
||||||
|
|
||||||
|
echo "Loading ${schema} schema"
|
||||||
|
|
||||||
|
[[ -f /etc/ldap/schema/${schema}.ldif ]]
|
||||||
|
assert "FATAL: schema file /etc/ldap/schema/${schema}.ldif not found!"
|
||||||
|
|
||||||
|
ldapadd -QY EXTERNAL -H ldapi:/// -f /etc/ldap/schema/${schema}.ldif
|
||||||
|
assert "FATAL: error loading schema ${schema}!"
|
||||||
|
done
|
||||||
|
# END SCHEMAS -----------------------------------------------------------------
|
||||||
|
|
||||||
|
# MEMBEROF MODULE -------------------------------------------------------------
|
||||||
|
if ${LDAP_MEMBEROF}
|
||||||
|
then
|
||||||
|
echo "Enabling memberof module"
|
||||||
|
ldapmodify -QY EXTERNAL -H ldapi:/// <<-EOF
|
||||||
|
dn: cn=module{0},cn=config
|
||||||
|
changetype: modify
|
||||||
|
add: olcModuleLoad
|
||||||
|
olcModuleLoad: memberof
|
||||||
|
|
||||||
|
EOF
|
||||||
|
RES=$?
|
||||||
|
[[ $RES -eq 0 ]] || [[ $RES -eq 20 ]]
|
||||||
|
assert "FATAL: error loading memberof module (return status ${RES})"
|
||||||
|
unset RES
|
||||||
|
fi
|
||||||
|
# END MEMBEROF MODULE ---------------------------------------------------------
|
||||||
|
|
||||||
|
# DOMAIN SETUP ----------------------------------------------------------------
|
||||||
|
if ldapsearch -LLL -H ldapi:/// -QY EXTERNAL -s one -b "cn=config" \
|
||||||
|
"(&(olcSuffix=\"${LDAP_DOMAIN_DN}\")(olcDatabase=mdb))" | \
|
||||||
|
egrep -q '^dn: '
|
||||||
|
then
|
||||||
|
echo "Found cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
else
|
||||||
|
echo "No cn=config entry for ${LDAP_DOMAIN_DN}."
|
||||||
|
echo "Creating directory /var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
mkdir "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
chown -R openldap:openldap "/var/lib/ldap/${LDAP_DOMAIN_DN}"
|
||||||
|
|
||||||
|
echo "Creating cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
|
||||||
|
ldapadd -QY EXTERNAL -H ldapi:/// <<-EOF
|
||||||
|
dn: olcDatabase=mdb,cn=config
|
||||||
|
objectClass: olcDatabaseConfig
|
||||||
|
objectClass: olcMdbConfig
|
||||||
|
olcDbMaxSize: 1073741824
|
||||||
|
olcSuffix: ${LDAP_DOMAIN_DN}
|
||||||
|
olcDbDirectory: /var/lib/ldap/${LDAP_DOMAIN_DN}
|
||||||
|
olcRootDN: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
||||||
|
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_ACCESS}" | sed -e 's/^/olcAccess: /g')
|
||||||
|
olcDbCheckpoint: 512 30
|
||||||
|
olcLastMod: TRUE
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_INDEX}" | sed -e 's/^/olcDbIndex: /g')
|
||||||
|
$(echo -ne "${LDAP_DOMAIN_LIMITS}" | sed -e 's/^/olcLimits: /g')
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Get cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
CN_CONFIG_DN=$(ldapsearch -LLL -H ldapi:/// -QY EXTERNAL -s one -b "cn=config" \
|
||||||
|
"(&(olcSuffix=${LDAP_DOMAIN_DN})(olcDatabase=mdb))" \
|
||||||
|
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${CN_CONFIG_DN} ]]
|
||||||
|
then echo "Found DN = ${CN_CONFIG_DN}"
|
||||||
|
else
|
||||||
|
echo "FATAL: could not find cn=config entry for ${LDAP_DOMAIN_DN}"
|
||||||
|
echo "PLEASE NOTE: only MDB database format is supported (PR welcome :)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: verify admin password before updating =================================
|
||||||
|
|
||||||
|
echo "Setting domain administrator password"
|
||||||
|
ldapmodify -QY EXTERNAL -H ldapi:/// <<EOF
|
||||||
|
dn: ${CN_CONFIG_DN}
|
||||||
|
changetype: modify
|
||||||
|
replace: olcRootPW
|
||||||
|
olcRootPW: ${LDAP_ADMIN_PWHASH}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
assert "FATAL: could not set administrator password!"
|
||||||
|
# END DOMAIN SETUP ------------------------------------------------------------
|
||||||
|
|
||||||
|
# MEMBEROF OVERLAY ------------------------------------------------------------
|
||||||
|
if [[ ${LDAP_MEMBEROF} ]]
|
||||||
|
then
|
||||||
|
echo "Check if memberOf overlay is enabled"
|
||||||
|
MEMBEROF_DN=$(ldapsearch -LLL -H ldapi:/// -QY EXTERNAL -s one -b \
|
||||||
|
"${CN_CONFIG_DN}" "(olcOverlay=memberOf)" | \
|
||||||
|
egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${MEMBEROF_DN} ]]
|
||||||
|
then echo "memberOf overlay already enabled for ${CN_CONFIG_DN}"
|
||||||
|
else
|
||||||
|
echo "Enabling memberOf overlay"
|
||||||
|
ldapadd -QY EXTERNAL -H ldapi:/// <<-EOF
|
||||||
|
dn: olcOverlay=memberof,${CN_CONFIG_DN}
|
||||||
|
objectClass: olcOverlayConfig
|
||||||
|
objectClass: olcConfig
|
||||||
|
objectClass: olcMemberOf
|
||||||
|
olcMemberOfDangling: ignore
|
||||||
|
olcMemberOfRefInt: FALSE
|
||||||
|
olcMemberOfGroupOC: groupOfNames
|
||||||
|
olcMemberOfMemberAD: member
|
||||||
|
olcMemberOfMemberOfAD: memberOf
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
# END MEMBEROF OVERLAY --------------------------------------------------------
|
||||||
|
|
||||||
|
# DIT ENTRIES -----------------------------------------------------------------
|
||||||
|
echo "Check if ${LDAP_DOMAIN_DN} exists"
|
||||||
|
DOM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" -s base -b "${LDAP_DOMAIN_DN}" \
|
||||||
|
"(objectClass=*)" | egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${DOM_DN} ]]
|
||||||
|
then echo "${LDAP_DOMAIN_DN} already present"
|
||||||
|
else
|
||||||
|
echo "Creating ${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
||||||
|
dn: ${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: dcObject
|
||||||
|
objectClass: organization
|
||||||
|
objectClass: top
|
||||||
|
dc: $(echo -n "${LDAP_DOMAIN_DN#dc=}" | sed 's/,.*$//g')
|
||||||
|
o: ${LDAP_DOMAIN}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Admin user
|
||||||
|
echo "Check if cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} exists"
|
||||||
|
ADM_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" -s base -b \
|
||||||
|
"cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}" "(objectClass=*)" \
|
||||||
|
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${ADM_DN} ]]
|
||||||
|
then echo "cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} already present"
|
||||||
|
else
|
||||||
|
echo "Creating cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
||||||
|
dn: cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: organizationalRole
|
||||||
|
objectClass: simpleSecurityObject
|
||||||
|
cn: ${LDAP_ADMIN_CN}
|
||||||
|
description: LDAP Administrator role for domain ${LDAP_DOMAIN}
|
||||||
|
userPassword: ${ADMIN_PW_HASH}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
|
||||||
|
# TODO: update admin password =================================================
|
||||||
|
|
||||||
|
# create OUs
|
||||||
|
for OU in ${LDAP_DOMAIN_OUS}
|
||||||
|
do
|
||||||
|
echo "Check if ou=${OU},${LDAP_DOMAIN_DN} exists"
|
||||||
|
OU_DN=$(ldapsearch -LLL -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" -s base \
|
||||||
|
-b "ou=${OU},${LDAP_DOMAIN_DN}" "(objectClass=*)" \
|
||||||
|
| egrep '^dn: ' | sed -e 's/^dn: //g')
|
||||||
|
|
||||||
|
if [[ -n ${OU_DN} ]]
|
||||||
|
then echo "ou=${OU} already present in ${LDAP_DOMAIN_DN}"
|
||||||
|
else
|
||||||
|
echo "Creating ou=${OU},${LDAP_DOMAIN_DN}"
|
||||||
|
ldapadd -H ldapi:/// -D cn=${LDAP_ADMIN_CN},${LDAP_DOMAIN_DN} \
|
||||||
|
-w "${LDAP_ADMIN_PASSWORD}" <<-EOF
|
||||||
|
dn: ou=${OU},${LDAP_DOMAIN_DN}
|
||||||
|
objectClass: organizationalUnit
|
||||||
|
objectClass: top
|
||||||
|
ou: ${OU}
|
||||||
|
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
# kill slapd after initial setup
|
||||||
|
echo "Killing initial server"
|
||||||
|
kill -INT $(cat ${PIDFILE})
|
||||||
|
|
||||||
|
# unset sensitive variables
|
||||||
|
unset LDAP_ADMIN_PASSWORD LDAP_CONFIG_PASSWORD LDAP_ADMIN_PWHASH \
|
||||||
|
LDAP_CONFIG_PWHASH LOADED_SCHEMAS PIDFILE
|
Loading…
x
Reference in New Issue
Block a user