From bee95efa4317eacbde98237f7952d020cdfb5e61 Mon Sep 17 00:00:00 2001 From: Evilham Date: Mon, 9 Dec 2019 19:13:10 +0100 Subject: [PATCH 1/7] [new-type] __openldap_server Originally developed at ungleich and improved for Open Sourcing by Evilham. --- cdist/conf/type/__openldap_server/man.rst | 148 +++++++++++ cdist/conf/type/__openldap_server/manifest | 235 ++++++++++++++++++ .../type/__openldap_server/parameter/boolean | 2 + .../type/__openldap_server/parameter/optional | 4 + .../parameter/optional_multiple | 2 + .../type/__openldap_server/parameter/required | 4 + 6 files changed, 395 insertions(+) create mode 100644 cdist/conf/type/__openldap_server/man.rst create mode 100644 cdist/conf/type/__openldap_server/manifest create mode 100644 cdist/conf/type/__openldap_server/parameter/boolean create mode 100644 cdist/conf/type/__openldap_server/parameter/optional create mode 100644 cdist/conf/type/__openldap_server/parameter/optional_multiple create mode 100644 cdist/conf/type/__openldap_server/parameter/required diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst new file mode 100644 index 00000000..29bbc231 --- /dev/null +++ b/cdist/conf/type/__openldap_server/man.rst @@ -0,0 +1,148 @@ +cdist-type__openldap_server(7) +============================== + +NAME +---- +cdist-type__openldap_server - Setup an openldap(4) server instance + + +DESCRIPTION +----------- +This type can be used to bootstrap an LDAP environment using openldap as slapd. + + +REQUIRED PARAMETERS +------------------- +manager-dn + The rootdn to set up in the directory. + E.g. `cn=manager,dc=ungleich,dc=ch`. See `slapd.conf(5)`. + +manager-password-hash + The password for `manager-dn` in the directory. + This should be valid for `slapd.conf` like `{SSHA}qV+mCs3u8Q2sCmUXT4Ybw7MebHTASMyr`. + Generate e.g. with: `slappasswd -s weneedgoodsecurity`. + See `slappasswd(8C)`, `slapd.conf(5)`. + TODO: implement this: http://blog.adamsbros.org/2015/06/09/openldap-ssha-salted-hashes-by-hand/ + to allow for a manager-password parameter and ensure idempotency (care with salts). + Such manager-password parameter should be mutually exclusive with this one. + +serverid + The server for the directory. + E.g. `dc=ungleich,dc=ch`. See `slapd.conf(5)`. + +suffix + The suffix for the directory. + E.g. `dc=ungleich,dc=ch`. See `slapd.conf(5)`. + + +OPTIONAL PARAMETERS +------------------- +syncrepl-credentials + Only has an effect if `replicate` is set; required in that case. + This secret is shared amongst the hosts that will replicate the directory. + Note that each replication server needs this secret and it is saved in + plain text in the directory. + +syncrepl-searchbase + Only has an effect if `replicate` is set; required in that case. + The searchbase to use for replication. + E.g. `dc=ungleich,dc=ch`. See `slapd.conf(5)`. + +tls-cert + If defined, `__letsencrypt_cert` is not used and this must be the path in + the remote hosts to the PEM-encoded TLS certificate. + Requires: `tls-privkey` and `tls-ca`. + Permissions, existence and renewal of these files are left up to the + type's user. + +tls-privkey + Required if `tls-cert` is defined. + Path in the remote hosts to the PEM-encoded private key file. + +tls-ca + Required if `tls-cert` is defined. + Path in the remote hosts to the PEM-encoded CA certificate file. + + +OPTIONAL MULTIPLE PARAMETERS +---------------------------- +syncrepl-host + Only has an effect if `replicate` is set; required in that case. + Set once per host that will replicate the directory. + +module + LDAP module to load. See `slapd.conf(5)`. + Default value is OS-dependent, see manifest. + + +BOOLEAN PARAMETERS +------------------ +staging + Passed to `cdist-type__letsencrypt_cert`; has otherwise no use. + Obtain a test certificate from a staging server. + +replicate + Whether to setup replication or not. + If present `syncrepl-credentials` and `syncrepl-host` are also required. + +EXAMPLES +-------- + +.. code-block:: sh + + # Modify the ruleset on $__target_host: + __pf_ruleset --state present --source /my/pf/ruleset.conf + require="__pf_ruleset" \ + __pf_apply + + # Remove the ruleset on $__target_host (implies disabling pf(4): + __pf_ruleset --state absent + require="__pf_ruleset" \ + __pf_apply + + root@ldap-for-guacamole:~# cat ldapbase.ldif + dn: dc=guaca-test,dc=ungleich,dc=ch + objectClass: top + objectClass: dcObject + objectClass: organization + o: Some description + dc: guaca-test + + + # Sample usage: + # + # id=1 + # for host in ldap-test1.ungleich.ch ldap-test2.ungleich.ch; do + # echo "__ungleich_ldap ${host} \ + # --manager-dn 'cn=manager,dc=ungleich,dc=ch' \ + # --manager-password '{SSHA}fooo' \ + # --serverid '${id}' \ + # --staging \ + # --suffix 'dc=ungleich,dc=ch' \ + # --searchbase 'dc=ungleich,dc=ch' \ + # --syncrepl-credentials 'fooo' \ + # --syncrepl-host 'ldap-test1.ungleich.ch' \ + # --syncrepl-host 'ldap-test2.ungleich.ch' \ + # --descriptiont 'Ungleich LDAP server'" \ + # | cdist config -i - -v ${host} + # id=$((id + 1)) + # done + + +SEE ALSO +-------- +:strong:`cdist-type__letsencrypt_cert`\ (7) + + +AUTHORS +------- +ungleich +Evilham + + +COPYING +------- +Copyright \(C) 2020 ungleich glarus ag. You can redistribute it +and/or modify it under the terms of the GNU General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest new file mode 100644 index 00000000..2acaaed5 --- /dev/null +++ b/cdist/conf/type/__openldap_server/manifest @@ -0,0 +1,235 @@ +#!/bin/sh + +name="${__target_host}" +manager_dn=$(cat "${__object}/parameter/manager-dn") +manager_password_hash=$(cat "${__object}/parameter/manager-password-hash") +serverid=$(cat "${__object}/parameter/serverid") +suffix=$(cat "${__object}/parameter/suffix") +slapd_modules=$(cat "${__object}/parameter/module" || true) + + +OS="$(cat "${__global}/explorer/os")" + +# Setup OS-dependent vars +# TODO: treat other OS better, defaulting to Debian-like +case "${OS}" in + freebsd) + PKGS="openldap-server" + ETC="/usr/local/etc" + SLAPD_DIR="/usr/local/etc/openldap" + SLAPD_DATA_DIR="/var/db/openldap-data" + SLAPD_RUN_DIR="/var/run/openldap" + SLAPD_MODULE_PATH="/usr/local/libexec/openldap" + if [ -z "${slapd_modules}" ]; then + # It looks like ppolicy and syncprov must be compiled + slapd_modules="back_mdb back_monitor" + fi + ;; + *) + PKGS="slapd ldap-utils" + ETC="/etc" + SLAPD_DIR="/etc/ldap" + SLAPD_DATA_DIR="/var/lib/ldap" + SLAPD_RUN_DIR="/var/run/slapd" + SLAPD_MODULE_PATH="/usr/lib/ldap" + if [ -z "${slapd_modules}" ]; then + slapd_modules="back_mdb ppolicy syncprov back_monitor" + fi + ;; +esac + + + +# Determine if __letsencrypt_cert is to be used and setup vars accordingly +if [ -f "${__object}/parameter/tls-cert" ]; then + tls_cert=$(cat "${__object}/parameter/tls-cert") + + if [ ! -f "${__object}/parameter/tls-privkey" ]; then + echo "When tls-cert is defined, tls-privkey is also required." >&2 + exit 1 + fi + tls_privkey=$(cat "${__object}/parameter/tls-privkey") + + if [ ! -f "${__object}/parameter/tls-ca" ]; then + echo "When tls-cert is defined, tls-ca is also required." >&2 + exit 1 + fi + tls_ca=$(cat "${__object}/parameter/tls-ca") + + _skip_letsencrypt_cert="YES" +else + tls_cert="${SLAPD_DIR}/sasl2/cert.pem" + tls_privkey="${SLAPD_DIR}/sasl2/privkey.pem" + tls_ca="${SLAPD_DIR}/sasl2/chain.pem" +fi + +mkdir "${__object}/files" +ldapconf="${__object}/files/ldapconf" + +replication="" +if [ -f "${__object}/parameter/replicate" ]; then + replication=yes + + if [ ! -f "${__object}/parameter/syncrepl-searchbase" ]; then + echo "Requiring the searchbase for replication" >&2 + exit 1 + fi + syncrepl_searchbase=$(cat "${__object}/parameter/syncrepl-searchbase") + + if [ ! -f "${__object}/parameter/syncrepl-credentials" ]; then + echo "Requiring credentials for replication" >&2 + exit 1 + fi + + syncrepl_credentials=$(cat "${__object}/parameter/syncrepl-credentials") + + if [ ! -f "${__object}/parameter/syncrepl-host" ]; then + echo "Requiring host(s) for replication" >&2 + exit 1 + fi + syncrepl_hosts=$(cat "${__object}/parameter/syncrepl-host") + +fi + +# Install required packages +for pkg in ${PKGS}; do + __package ${pkg} +done + + +# TODO: Implement __start_on_boot for BSD +require="__package/slapd" __start_on_boot slapd + +# TODO: treat other OS better. Defaulting to Debian-like. +if [ "${OS}" != "freebsd" ]; then + require="__package/slapd" __line rm_slapd_conf \ + --file ${ETC}/default/slapd \ + --regex 'SLAPD_CONF=.*' \ + --state absent + + require="__package/slapd" __line rm_slapd_services \ + --file ${ETC}/default/slapd \ + --regex 'SLAPD_SERVICES=.*' \ + --state absent + + require="__line/rm_slapd_conf" __line add_slapd_conf \ + --file ${ETC}/default/slapd \ + --line 'SLAPD_CONF=${SLAPD_DIR}/slapd.conf' \ + --state present + + require="__line/rm_slapd_services" __line add_slapd_services \ + --file ${ETC}/default/slapd \ + --line "SLAPD_SERVICES=\"ldap://localhost/ ldap://${name}/\"" \ + --state present +fi + + +if [ -z "${_skip_letsencrypt_cert}" ]; then + if [ -f "${__object}/parameter/staging" ]; then + staging="--staging" + else + staging="" + fi + + __letsencrypt_cert "${name}" --admin-email technik@ungleich.ch \ + --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R openldap:openldap ${SLAPD_DIR}/sasl2 && service slapd restart" \ + --automatic-renewal ${staging} +fi + +require="__package/slapd" __directory ${SLAPD_DIR}/slapd.d --state absent + +if [ -z "${_skip_letsencrypt_cert}" ]; then + require="__package/slapd __letsencrypt_cert/${name}" \ + __file ${SLAPD_DIR}/slapd.conf --owner root --group root --mode 644 \ + --source "${ldapconf}" +else + require="__package/slapd" \ + __file ${SLAPD_DIR}/slapd.conf --owner root --group root --mode 644 \ + --source "${ldapconf}" +fi + +# Start slapd.conf +cat << EOF > "${ldapconf}" +pidfile ${SLAPD_RUN_DIR}/slapd.pid +argsfile ${SLAPD_RUN_DIR}/slapd.args + +TLSCipherSuite NORMAL +TLSCertificateFile ${tls_cert} +TLSCertificateKeyFile ${tls_privkey} +TLSCACertificateFile ${tls_ca} + +disallow bind_anon +require bind +security tls=1 + +include ${SLAPD_DIR}/schema/corba.schema +include ${SLAPD_DIR}/schema/core.schema +include ${SLAPD_DIR}/schema/cosine.schema +include ${SLAPD_DIR}/schema/duaconf.schema +include ${SLAPD_DIR}/schema/dyngroup.schema +include ${SLAPD_DIR}/schema/inetorgperson.schema +include ${SLAPD_DIR}/schema/java.schema +include ${SLAPD_DIR}/schema/misc.schema +include ${SLAPD_DIR}/schema/nis.schema +include ${SLAPD_DIR}/schema/openldap.schema +include ${SLAPD_DIR}/schema/ppolicy.schema +include ${SLAPD_DIR}/schema/collective.schema + +modulepath ${SLAPD_MODULE_PATH} +EOF + +# Add specified modules +for module in ${slapd_modules}; do + echo "moduleload ${module}.la" >> "${ldapconf}" +done + +# Rest of the config +cat << EOF >> "${ldapconf}" +loglevel 1024 + +database mdb +maxsize 1073741824 + +suffix "${suffix}" +directory ${SLAPD_DATA_DIR} +rootdn "${manager_dn}" +rootpw "${manager_password_hash}" + +index objectClass eq,pres +index ou,cn,mail,surname,givenname eq,pres,sub +index uidNumber,gidNumber,loginShell eq,pres +index uid,memberUid eq,pres,sub +index nisMapName,nisMapEntry eq,pres,sub +index entryCSN,entryUUID eq + +serverid ${serverid} +EOF + +# Setup replication +if [ "${replication}" ]; then + rid=1; + for syncrepl in ${syncrepl_hosts}; do + cat <> "${ldapconf}" +syncrepl rid=${rid} + provider=ldap://${syncrepl} + bindmethod=simple + starttls=yes + binddn="${manager_dn}" + credentials=${syncrepl_credentials} + searchbase="${syncrepl_searchbase}" + type=refreshAndPersist + retry="5 + 5 +" + interval=00:00:00:05 +EOF + rid=$((rid + 1)) + done + cat <> "${ldapconf}" +mirrormode true +overlay syncprov +syncprov-checkpoint 100 5 +syncprov-sessionlog 100 + +database monitor +limits dn.exact="${manager_dn}" time=unlimited size=unlimited +EOF +fi diff --git a/cdist/conf/type/__openldap_server/parameter/boolean b/cdist/conf/type/__openldap_server/parameter/boolean new file mode 100644 index 00000000..45056fe9 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/boolean @@ -0,0 +1,2 @@ +staging +replicate diff --git a/cdist/conf/type/__openldap_server/parameter/optional b/cdist/conf/type/__openldap_server/parameter/optional new file mode 100644 index 00000000..a9a8ab2c --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/optional @@ -0,0 +1,4 @@ +description +syncrepl-credentials +syncrepl-searchbase +tls-cert diff --git a/cdist/conf/type/__openldap_server/parameter/optional_multiple b/cdist/conf/type/__openldap_server/parameter/optional_multiple new file mode 100644 index 00000000..107c03d9 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/optional_multiple @@ -0,0 +1,2 @@ +syncrepl-host +module diff --git a/cdist/conf/type/__openldap_server/parameter/required b/cdist/conf/type/__openldap_server/parameter/required new file mode 100644 index 00000000..1ee6f219 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/required @@ -0,0 +1,4 @@ +manager-dn +manager-password-hash +serverid +suffix From fd430eab622206b9a04780ca5fa9d7c807f16c93 Mon Sep 17 00:00:00 2001 From: Evilham Date: Mon, 9 Dec 2019 19:39:43 +0100 Subject: [PATCH 2/7] [new-type] __openldap_server: Add a "schema" optional parameter. --- cdist/conf/type/__openldap_server/man.rst | 7 +++++ cdist/conf/type/__openldap_server/manifest | 29 +++++++------------ .../parameter/default/schema | 12 ++++++++ .../type/__openldap_server/parameter/optional | 3 +- 4 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 cdist/conf/type/__openldap_server/parameter/default/schema diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index 29bbc231..1fc24eaa 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -74,6 +74,13 @@ module LDAP module to load. See `slapd.conf(5)`. Default value is OS-dependent, see manifest. +schema + Name of LDAP schema to load. Must be the name without extension of a + `.schema` file in slapd's schema directory (usually `/etc/slapd/schema` or + `/usr/local/etc/openldap/schema`). + Example value: `inetorgperson` + The type user must ensure that the schema file is deployed. + This defaults to a sensible subset, for details see the type definition. BOOLEAN PARAMETERS ------------------ diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest index 2acaaed5..518edd86 100644 --- a/cdist/conf/type/__openldap_server/manifest +++ b/cdist/conf/type/__openldap_server/manifest @@ -6,6 +6,7 @@ manager_password_hash=$(cat "${__object}/parameter/manager-password-hash") serverid=$(cat "${__object}/parameter/serverid") suffix=$(cat "${__object}/parameter/suffix") slapd_modules=$(cat "${__object}/parameter/module" || true) +schemas=$(cat "${__object}/parameter/schema") OS="$(cat "${__global}/explorer/os")" @@ -14,8 +15,8 @@ OS="$(cat "${__global}/explorer/os")" # TODO: treat other OS better, defaulting to Debian-like case "${OS}" in freebsd) - PKGS="openldap-server" - ETC="/usr/local/etc" + PKGS="openldap-server" + ETC="/usr/local/etc" SLAPD_DIR="/usr/local/etc/openldap" SLAPD_DATA_DIR="/var/db/openldap-data" SLAPD_RUN_DIR="/var/run/openldap" @@ -27,7 +28,7 @@ case "${OS}" in ;; *) PKGS="slapd ldap-utils" - ETC="/etc" + ETC="/etc" SLAPD_DIR="/etc/ldap" SLAPD_DATA_DIR="/var/lib/ldap" SLAPD_RUN_DIR="/var/run/slapd" @@ -39,7 +40,6 @@ case "${OS}" in esac - # Determine if __letsencrypt_cert is to be used and setup vars accordingly if [ -f "${__object}/parameter/tls-cert" ]; then tls_cert=$(cat "${__object}/parameter/tls-cert") @@ -161,24 +161,15 @@ TLSCACertificateFile ${tls_ca} disallow bind_anon require bind security tls=1 - -include ${SLAPD_DIR}/schema/corba.schema -include ${SLAPD_DIR}/schema/core.schema -include ${SLAPD_DIR}/schema/cosine.schema -include ${SLAPD_DIR}/schema/duaconf.schema -include ${SLAPD_DIR}/schema/dyngroup.schema -include ${SLAPD_DIR}/schema/inetorgperson.schema -include ${SLAPD_DIR}/schema/java.schema -include ${SLAPD_DIR}/schema/misc.schema -include ${SLAPD_DIR}/schema/nis.schema -include ${SLAPD_DIR}/schema/openldap.schema -include ${SLAPD_DIR}/schema/ppolicy.schema -include ${SLAPD_DIR}/schema/collective.schema - -modulepath ${SLAPD_MODULE_PATH} EOF +# Add specified schemas +for schema in ${schemas}; do + echo "include ${SLAPD_DIR}/schema/${schema}.schema" >> "${ldapconf}" +done + # Add specified modules +echo "modulepath ${SLAPD_MODULE_PATH}" >> "${ldapconf}" for module in ${slapd_modules}; do echo "moduleload ${module}.la" >> "${ldapconf}" done diff --git a/cdist/conf/type/__openldap_server/parameter/default/schema b/cdist/conf/type/__openldap_server/parameter/default/schema new file mode 100644 index 00000000..825bdb15 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/default/schema @@ -0,0 +1,12 @@ +corba +core +cosine +duaconf +dyngroup +inetorgperson +java +misc +nis +openldap +ppolicy +collective diff --git a/cdist/conf/type/__openldap_server/parameter/optional b/cdist/conf/type/__openldap_server/parameter/optional index a9a8ab2c..53587c4e 100644 --- a/cdist/conf/type/__openldap_server/parameter/optional +++ b/cdist/conf/type/__openldap_server/parameter/optional @@ -1,4 +1,5 @@ -description syncrepl-credentials syncrepl-searchbase tls-cert +tls-privkey +tls-ca From 1ad605a509cfd534334111c1d6c1ea8682446b10 Mon Sep 17 00:00:00 2001 From: Evilham Date: Mon, 9 Dec 2019 19:49:05 +0100 Subject: [PATCH 3/7] [new-type] __openldap_server: Add admin-email parameter. --- cdist/conf/type/__openldap_server/man.rst | 5 +++++ cdist/conf/type/__openldap_server/manifest | 8 +++++++- cdist/conf/type/__openldap_server/parameter/optional | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index 1fc24eaa..4447971a 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -48,6 +48,11 @@ syncrepl-searchbase The searchbase to use for replication. E.g. `dc=ungleich,dc=ch`. See `slapd.conf(5)`. +admin-email + Passed to `cdist-type__letsencrypt_cert`; has otherwise no use. + Required if using `__letsencrypt_cert`. + Where to send Let's Encrypt emails like "certificate needs renewal". + tls-cert If defined, `__letsencrypt_cert` is not used and this must be the path in the remote hosts to the PEM-encoded TLS certificate. diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest index 518edd86..e10432d6 100644 --- a/cdist/conf/type/__openldap_server/manifest +++ b/cdist/conf/type/__openldap_server/manifest @@ -58,6 +58,12 @@ if [ -f "${__object}/parameter/tls-cert" ]; then _skip_letsencrypt_cert="YES" else + if [ ! -f "${__object}/parameter/admin-email" ]; then + echo "When using __letsencrypt_cert, admin-email is also required." >&2 + exit 1 + fi + admin_email=$(cat "${__object}/parameter/admin-email") + tls_cert="${SLAPD_DIR}/sasl2/cert.pem" tls_privkey="${SLAPD_DIR}/sasl2/privkey.pem" tls_ca="${SLAPD_DIR}/sasl2/chain.pem" @@ -131,7 +137,7 @@ if [ -z "${_skip_letsencrypt_cert}" ]; then staging="" fi - __letsencrypt_cert "${name}" --admin-email technik@ungleich.ch \ + __letsencrypt_cert "${name}" --admin-email "${admin_email}" \ --renew-hook "cp ${ETC}/letsencrypt/live/${name}/*.pem ${SLAPD_DIR}/sasl2 && chown -R openldap:openldap ${SLAPD_DIR}/sasl2 && service slapd restart" \ --automatic-renewal ${staging} fi diff --git a/cdist/conf/type/__openldap_server/parameter/optional b/cdist/conf/type/__openldap_server/parameter/optional index 53587c4e..f4254cb6 100644 --- a/cdist/conf/type/__openldap_server/parameter/optional +++ b/cdist/conf/type/__openldap_server/parameter/optional @@ -1,5 +1,6 @@ syncrepl-credentials syncrepl-searchbase +admin-email tls-cert tls-privkey tls-ca From 42914d26c5addae027cc382ec035a687cd3aaf6d Mon Sep 17 00:00:00 2001 From: Evilham Date: Mon, 9 Dec 2019 19:59:15 +0100 Subject: [PATCH 4/7] [new-type] __openldap_server: sudo make nico.happy. --- cdist/conf/type/__openldap_server/manifest | 53 ++++++++++++---------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest index e10432d6..ffd92626 100644 --- a/cdist/conf/type/__openldap_server/manifest +++ b/cdist/conf/type/__openldap_server/manifest @@ -9,11 +9,10 @@ slapd_modules=$(cat "${__object}/parameter/module" || true) schemas=$(cat "${__object}/parameter/schema") -OS="$(cat "${__global}/explorer/os")" +os="$(cat "${__global}/explorer/os")" # Setup OS-dependent vars -# TODO: treat other OS better, defaulting to Debian-like -case "${OS}" in +case "${os}" in freebsd) PKGS="openldap-server" ETC="/usr/local/etc" @@ -26,7 +25,7 @@ case "${OS}" in slapd_modules="back_mdb back_monitor" fi ;; - *) + debian|ubuntu|devuan) PKGS="slapd ldap-utils" ETC="/etc" SLAPD_DIR="/etc/ldap" @@ -37,6 +36,10 @@ case "${OS}" in slapd_modules="back_mdb ppolicy syncprov back_monitor" fi ;; + *) + echo "Don't know the openldap defaults for: $os" >&2 + exit 1 + ;; esac @@ -106,28 +109,32 @@ done # TODO: Implement __start_on_boot for BSD require="__package/slapd" __start_on_boot slapd -# TODO: treat other OS better. Defaulting to Debian-like. -if [ "${OS}" != "freebsd" ]; then - require="__package/slapd" __line rm_slapd_conf \ - --file ${ETC}/default/slapd \ - --regex 'SLAPD_CONF=.*' \ - --state absent +case "${os}" in + debian|ubuntu|devuan) + require="__package/slapd" __line rm_slapd_conf \ + --file ${ETC}/default/slapd \ + --regex 'SLAPD_CONF=.*' \ + --state absent - require="__package/slapd" __line rm_slapd_services \ - --file ${ETC}/default/slapd \ - --regex 'SLAPD_SERVICES=.*' \ - --state absent + require="__package/slapd" __line rm_slapd_services \ + --file ${ETC}/default/slapd \ + --regex 'SLAPD_SERVICES=.*' \ + --state absent - require="__line/rm_slapd_conf" __line add_slapd_conf \ - --file ${ETC}/default/slapd \ - --line 'SLAPD_CONF=${SLAPD_DIR}/slapd.conf' \ - --state present + require="__line/rm_slapd_conf" __line add_slapd_conf \ + --file ${ETC}/default/slapd \ + --line 'SLAPD_CONF=${SLAPD_DIR}/slapd.conf' \ + --state present - require="__line/rm_slapd_services" __line add_slapd_services \ - --file ${ETC}/default/slapd \ - --line "SLAPD_SERVICES=\"ldap://localhost/ ldap://${name}/\"" \ - --state present -fi + require="__line/rm_slapd_services" __line add_slapd_services \ + --file ${ETC}/default/slapd \ + --line "SLAPD_SERVICES=\"ldap://localhost/ ldap://${name}/\"" \ + --state present + ;; + *) + # Nothing to do here, move on. + ;; +esac if [ -z "${_skip_letsencrypt_cert}" ]; then From 22c5cd550bb1069c2bb8106bbe907f016b9b821a Mon Sep 17 00:00:00 2001 From: Evilham Date: Tue, 10 Dec 2019 12:49:07 +0100 Subject: [PATCH 5/7] [new-type] __openldap_server: first public version. This already takes care of setting up the base DN and managing it as well as allowing for settings for the listener URLS. The type was also made a singleton as it doesn't make much sense to setup multiple LDAP servers on the same machine. --- .../type/__openldap_server/gencode-remote | 44 ++++++ cdist/conf/type/__openldap_server/man.rst | 126 +++++++++++++----- cdist/conf/type/__openldap_server/manifest | 48 +++++-- .../parameter/default/description | 1 + .../type/__openldap_server/parameter/optional | 4 +- .../parameter/optional_multiple | 1 + .../type/__openldap_server/parameter/required | 1 + .../parameter/required_multiple | 1 + cdist/conf/type/__openldap_server/singleton | 0 9 files changed, 176 insertions(+), 50 deletions(-) create mode 100644 cdist/conf/type/__openldap_server/gencode-remote create mode 100644 cdist/conf/type/__openldap_server/parameter/default/description create mode 100644 cdist/conf/type/__openldap_server/parameter/required_multiple create mode 100644 cdist/conf/type/__openldap_server/singleton diff --git a/cdist/conf/type/__openldap_server/gencode-remote b/cdist/conf/type/__openldap_server/gencode-remote new file mode 100644 index 00000000..0ac434af --- /dev/null +++ b/cdist/conf/type/__openldap_server/gencode-remote @@ -0,0 +1,44 @@ +#!/bin/sh + +manager_dn=$(cat "${__object}/parameter/manager-dn") +manager_password=$(cat "${__object}/parameter/manager-password") +description=$(cat "${__object}/parameter/description") +suffix=$(cat "${__object}/parameter/suffix") +suffix_dc=$(echo -n ${suffix} | awk -F',' '{print $1}' | awk -F'=' '{print $2}') + +SLAPD_IPC=$(cat "${__object}/parameter/slapd-url" | tr '\n' ' ' | awk '{ print $1}') + +cat <&1 > /dev/null; then + # Already exists, use ldapmodify + ldapmodify -xZ -D "${manager_dn}" -w "${manager_password}" -H '${SLAPD_IPC}' </dev/null || true) schemas=$(cat "${__object}/parameter/schema") +slapd_urls=$(cat "${__object}/parameter/slapd-url" | tr '\n' ' ') +tls_cipher_suite=$(cat "${__object}/parameter/tls-cipher-suite" 2>/dev/null || true) os="$(cat "${__global}/explorer/os")" # Setup OS-dependent vars +CONF_OWNER="root" +CONF_GROUP="root" case "${os}" in freebsd) PKGS="openldap-server" @@ -24,6 +28,12 @@ case "${os}" in # It looks like ppolicy and syncprov must be compiled slapd_modules="back_mdb back_monitor" fi + CONF_OWNER="ldap" + CONF_GROUP="ldap" + if [ -z "${tls_cipher_suite}" ]; then + # TODO: research default for FreeBSD. 'NORMAL' appears to not work + tls_cipher_suite="HIGH:MEDIUM:+SSLv2" + fi ;; debian|ubuntu|devuan) PKGS="slapd ldap-utils" @@ -35,6 +45,9 @@ case "${os}" in if [ -z "${slapd_modules}" ]; then slapd_modules="back_mdb ppolicy syncprov back_monitor" fi + if [ -z "${tls_cipher_suite}" ]; then + tls_cipher_suite="NORMAL" + fi ;; *) echo "Don't know the openldap defaults for: $os" >&2 @@ -42,6 +55,8 @@ case "${os}" in ;; esac +PKG_MAIN=$(echo ${PKGS} | awk '{print $1;}') + # Determine if __letsencrypt_cert is to be used and setup vars accordingly if [ -f "${__object}/parameter/tls-cert" ]; then @@ -106,17 +121,26 @@ for pkg in ${PKGS}; do done -# TODO: Implement __start_on_boot for BSD -require="__package/slapd" __start_on_boot slapd +require="__package/${PKG_MAIN}" __start_on_boot slapd +# Setup -h flag for the listeners. See man slapd (-h flag). case "${os}" in + freebsd) + require="__package/${PKG_MAIN}" __key_value \ + --file "/etc/rc.conf" \ + --key "slapd_flags" \ + --value "\"-h '${slapd_urls}'\"" \ + --delimiter "=" \ + --comment "# LDAP Listener URLs" \ + "${__target_host}__slapd_flags" + ;; debian|ubuntu|devuan) - require="__package/slapd" __line rm_slapd_conf \ + require="__package/${PKG_MAIN}" __line rm_slapd_conf \ --file ${ETC}/default/slapd \ --regex 'SLAPD_CONF=.*' \ --state absent - require="__package/slapd" __line rm_slapd_services \ + require="__package/${PKG_MAIN}" __line rm_slapd_services \ --file ${ETC}/default/slapd \ --regex 'SLAPD_SERVICES=.*' \ --state absent @@ -128,7 +152,7 @@ case "${os}" in require="__line/rm_slapd_services" __line add_slapd_services \ --file ${ETC}/default/slapd \ - --line "SLAPD_SERVICES=\"ldap://localhost/ ldap://${name}/\"" \ + --line "SLAPD_SERVICES=\"${slapd_urls}\"" \ --state present ;; *) @@ -149,15 +173,15 @@ if [ -z "${_skip_letsencrypt_cert}" ]; then --automatic-renewal ${staging} fi -require="__package/slapd" __directory ${SLAPD_DIR}/slapd.d --state absent +require="__package/${PKG_MAIN}" __directory ${SLAPD_DIR}/slapd.d --state absent if [ -z "${_skip_letsencrypt_cert}" ]; then - require="__package/slapd __letsencrypt_cert/${name}" \ - __file ${SLAPD_DIR}/slapd.conf --owner root --group root --mode 644 \ + require="__package/${PKG_MAIN} __letsencrypt_cert/${name}" \ + __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \ --source "${ldapconf}" else - require="__package/slapd" \ - __file ${SLAPD_DIR}/slapd.conf --owner root --group root --mode 644 \ + require="__package/${PKG_MAIN}" \ + __file ${SLAPD_DIR}/slapd.conf --owner ${CONF_OWNER} --group ${CONF_GROUP} --mode 644 \ --source "${ldapconf}" fi @@ -166,7 +190,7 @@ cat << EOF > "${ldapconf}" pidfile ${SLAPD_RUN_DIR}/slapd.pid argsfile ${SLAPD_RUN_DIR}/slapd.args -TLSCipherSuite NORMAL +TLSCipherSuite ${tls_cipher_suite} TLSCertificateFile ${tls_cert} TLSCertificateKeyFile ${tls_privkey} TLSCACertificateFile ${tls_ca} diff --git a/cdist/conf/type/__openldap_server/parameter/default/description b/cdist/conf/type/__openldap_server/parameter/default/description new file mode 100644 index 00000000..6d8e37e1 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/default/description @@ -0,0 +1 @@ +Managed by cdist, do not edit manually. diff --git a/cdist/conf/type/__openldap_server/parameter/optional b/cdist/conf/type/__openldap_server/parameter/optional index f4254cb6..a92b9c6e 100644 --- a/cdist/conf/type/__openldap_server/parameter/optional +++ b/cdist/conf/type/__openldap_server/parameter/optional @@ -1,6 +1,8 @@ +description syncrepl-credentials syncrepl-searchbase admin-email +tls-cipher-suite tls-cert tls-privkey -tls-ca +tls-ca \ No newline at end of file diff --git a/cdist/conf/type/__openldap_server/parameter/optional_multiple b/cdist/conf/type/__openldap_server/parameter/optional_multiple index 107c03d9..52a83d5c 100644 --- a/cdist/conf/type/__openldap_server/parameter/optional_multiple +++ b/cdist/conf/type/__openldap_server/parameter/optional_multiple @@ -1,2 +1,3 @@ syncrepl-host module +schema diff --git a/cdist/conf/type/__openldap_server/parameter/required b/cdist/conf/type/__openldap_server/parameter/required index 1ee6f219..ff58158d 100644 --- a/cdist/conf/type/__openldap_server/parameter/required +++ b/cdist/conf/type/__openldap_server/parameter/required @@ -1,4 +1,5 @@ manager-dn +manager-password manager-password-hash serverid suffix diff --git a/cdist/conf/type/__openldap_server/parameter/required_multiple b/cdist/conf/type/__openldap_server/parameter/required_multiple new file mode 100644 index 00000000..848b8dc2 --- /dev/null +++ b/cdist/conf/type/__openldap_server/parameter/required_multiple @@ -0,0 +1 @@ +slapd-url \ No newline at end of file diff --git a/cdist/conf/type/__openldap_server/singleton b/cdist/conf/type/__openldap_server/singleton new file mode 100644 index 00000000..e69de29b From 79d58f0813fd08c77d826ac552dfdb9e0f40dbbd Mon Sep 17 00:00:00 2001 From: Evilham Date: Tue, 10 Dec 2019 13:04:24 +0100 Subject: [PATCH 6/7] [new-type] __openldap_server: fix docs / dependency. It's nicer to have slapd_flags after slapd_enable in rc.conf on freebsd. --- cdist/conf/type/__openldap_server/man.rst | 6 +++--- cdist/conf/type/__openldap_server/manifest | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index 84b534bd..1c2c9b70 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -141,9 +141,9 @@ EXAMPLES --serverid 0 \ --suffix 'dc=camilion,dc=cloud' \ --slapd-url 'ldaps://ldap.camilion.cloud' \ - --tls-cert '${pki_prefix}/default.crt' \ - --tls-privkey '${pki_prefix}/default.key' \ - --tls-ca '${pki_prefix}/CA.crt' + --tls-cert "${pki_prefix}/default.crt" \ + --tls-privkey "${pki_prefix}/default.key" \ + --tls-ca "${pki_prefix}/CA.crt" # The created basedn looks as follows: # diff --git a/cdist/conf/type/__openldap_server/manifest b/cdist/conf/type/__openldap_server/manifest index 2d1df32f..070a31d5 100644 --- a/cdist/conf/type/__openldap_server/manifest +++ b/cdist/conf/type/__openldap_server/manifest @@ -126,7 +126,7 @@ require="__package/${PKG_MAIN}" __start_on_boot slapd # Setup -h flag for the listeners. See man slapd (-h flag). case "${os}" in freebsd) - require="__package/${PKG_MAIN}" __key_value \ + require="__start_on_boot/slapd" __key_value \ --file "/etc/rc.conf" \ --key "slapd_flags" \ --value "\"-h '${slapd_urls}'\"" \ From 35f0d4dbfa9307923fa013ff806d30087a8cf291 Mon Sep 17 00:00:00 2001 From: Evilham Date: Tue, 10 Dec 2019 13:10:19 +0100 Subject: [PATCH 7/7] [new-type] __openldap_server: another documentation typo. --- cdist/conf/type/__openldap_server/man.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cdist/conf/type/__openldap_server/man.rst b/cdist/conf/type/__openldap_server/man.rst index 1c2c9b70..d20101d1 100644 --- a/cdist/conf/type/__openldap_server/man.rst +++ b/cdist/conf/type/__openldap_server/man.rst @@ -133,8 +133,8 @@ EXAMPLES .. code-block:: sh # Example of a simple server with manual certificate management. - pki_prefix="/usr/local/etc/pki/realms/ldap.camilion.cloud" \ - __openldap_server \ + pki_prefix="/usr/local/etc/pki/realms/ldap.camilion.cloud" + __openldap_server \ --manager-dn 'cn=manager,dc=camilion,dc=cloud' \ --manager-password "foo" \ --manager-password-hash '{SSHA}foo' \