summaryrefslogtreecommitdiff
path: root/system/openldap
diff options
context:
space:
mode:
Diffstat (limited to 'system/openldap')
-rw-r--r--system/openldap/APKBUILD212
-rw-r--r--system/openldap/CVE-2017-9287.patch28
-rw-r--r--system/openldap/configs.patch117
-rw-r--r--system/openldap/fix-manpages.patch75
-rw-r--r--system/openldap/libressl.patch65
-rw-r--r--system/openldap/openldap-2.4-ppolicy.patch13
-rw-r--r--system/openldap/openldap-2.4.11-libldap_r.patch11
-rw-r--r--system/openldap/openldap-mqtt-overlay.patch447
-rw-r--r--system/openldap/openldap.post-install11
-rw-r--r--system/openldap/openldap.post-upgrade31
-rw-r--r--system/openldap/openldap.pre-install7
-rw-r--r--system/openldap/slapd.confd12
-rw-r--r--system/openldap/slapd.initd34
13 files changed, 1063 insertions, 0 deletions
diff --git a/system/openldap/APKBUILD b/system/openldap/APKBUILD
new file mode 100644
index 000000000..84cbc1471
--- /dev/null
+++ b/system/openldap/APKBUILD
@@ -0,0 +1,212 @@
+# Maintainer: Natanael Copa <ncopa@alpinelinux.org>
+# Contributor: Jakub Jirutka <jakub@jirutka.cz>
+#
+# secfixes:
+# 2.4.46:
+# - CVE-2017-14159
+# - CVE-2017-17740
+# 2.4.44-r5:
+# - CVE-2017-9287
+#
+pkgname=openldap
+pkgver=2.4.46
+pkgrel=0
+pkgdesc="LDAP Server"
+url="http://www.openldap.org/"
+arch="all"
+options="!check" # Test suite takes > 2 hours to complete on each builder.
+license="custom"
+depends=""
+pkgusers="ldap"
+pkggroups="ldap"
+depends_dev="openssl-dev cyrus-sasl-dev util-linux-dev"
+makedepends="$depends_dev db-dev groff unixodbc-dev libtool
+ autoconf automake libtool"
+subpackages="$pkgname-dev $pkgname-doc libldap $pkgname-openrc
+ $pkgname-clients $pkgname-passwd-pbkdf2:passwd_pbkdf2
+ $pkgname-backend-all:_backend_all:noarch
+ $pkgname-overlay-all:_overlay_all:noarch"
+install="$pkgname.pre-install $pkgname.post-install $pkgname.post-upgrade"
+source="ftp://ftp.$pkgname.org/pub/OpenLDAP/$pkgname-release/$pkgname-$pkgver.tgz
+ openldap-2.4-ppolicy.patch
+ openldap-2.4.11-libldap_r.patch
+ fix-manpages.patch
+ configs.patch
+
+ slapd.initd
+ slapd.confd
+ "
+builddir="$srcdir/$pkgname-$pkgver"
+
+# SLAPD backends
+_backends=""
+for _name in bdb dnssrv hdb ldap mdb meta monitor null passwd \
+ relay shell sql sock
+do
+ subpackages="$subpackages $pkgname-back-$_name:_backend"
+ _backends="$_backends $pkgname-back-$_name"
+done
+
+# SLAPD overlays
+_overlays=""
+for _name in accesslog auditlog collect constraint dds deref dyngroup \
+ dynlist memberof ppolicy proxycache refint retcode rwm seqmod \
+ sssvlv syncprov translucent unique valsort
+do
+ subpackages="$subpackages $pkgname-overlay-$_name:_overlay"
+ _overlays="$_overlays $pkgname-overlay-$_name"
+done
+
+prepare() {
+ cd "$builddir"
+ update_config_sub
+
+ sed -i '/^STRIP/s,-s,,g' build/top.mk
+ libtoolize --force && aclocal && autoconf
+}
+
+build () {
+ cd "$builddir"
+
+ ./configure \
+ --build=$CBUILD \
+ --host=$CHOST \
+ --prefix=/usr \
+ --libexecdir=/usr/lib \
+ --sysconfdir=/etc \
+ --mandir=/usr/share/man \
+ --localstatedir=/var/lib/openldap \
+ --enable-slapd \
+ --enable-crypt \
+ --enable-modules \
+ --enable-dynamic \
+ --enable-bdb=mod \
+ --enable-dnssrv=mod \
+ --enable-hdb=mod \
+ --enable-ldap=mod \
+ --enable-mdb=mod \
+ --enable-meta=mod \
+ --enable-monitor=mod \
+ --enable-null=mod \
+ --enable-passwd=mod \
+ --enable-relay=mod \
+ --enable-shell=mod \
+ --enable-sock=mod \
+ --enable-sql=mod \
+ --enable-overlays=mod \
+ --with-tls=openssl \
+ --with-cyrus-sasl
+ make
+
+ # Build passwd pbkdf2.
+ make prefix=/usr libexecdir=/usr/lib \
+ -C contrib/slapd-modules/passwd/pbkdf2
+}
+
+check() {
+ cd "$builddir"
+ make check
+}
+
+package() {
+ cd "$builddir"
+
+ make DESTDIR="$pkgdir" install
+
+ # Install passwd pbkdf2.
+ make DESTDIR="$pkgdir" prefix=/usr libexecdir=/usr/lib \
+ -C contrib/slapd-modules/passwd/pbkdf2 install
+
+ cd "$pkgdir"
+
+ rmdir var/lib/openldap/run
+
+ # Fix tools symlinks to slapd.
+ local path; for path in $(find usr/sbin/ -type l); do
+ ln -sf slapd $path
+ done
+
+ # Move executable from lib to sbin.
+ mv usr/lib/slapd usr/sbin/
+
+ # Move *.default configs to docs.
+ mkdir -p usr/share/doc/$pkgname
+ mv etc/openldap/*.default usr/share/doc/$pkgname/
+
+ chgrp ldap etc/openldap/slapd.*
+ chmod g+r etc/openldap/slapd.*
+
+ install -d -m 700 -o ldap -g ldap \
+ var/lib/openldap \
+ var/lib/openldap/openldap-data
+
+ install -D -m 755 "$srcdir"/slapd.initd etc/init.d/slapd
+ install -D -m 644 "$srcdir"/slapd.confd etc/conf.d/slapd
+}
+
+libldap() {
+ pkgdesc="OpenLDAP libraries"
+ depends=""
+ install=""
+
+ _submv "usr/lib/*.so*" etc/openldap/ldap.conf
+}
+
+clients() {
+ pkgdesc="LDAP client utilities"
+
+ _submv usr/bin
+}
+
+passwd_pbkdf2() {
+ pkgdesc="PBKDF2 OpenLDAP support"
+ depends="$pkgname"
+
+ _submv "usr/lib/openldap/pw-pbkdf2.*"
+}
+
+_backend_all() {
+ pkgdesc="Virtual package that installs all OpenLDAP backends"
+ depends="$_backends"
+
+ mkdir -p "$subpkgdir"
+}
+
+_overlay_all() {
+ pkgdesc="Virtual package that installs all OpenLDAP overlays"
+ depends="$_overlays"
+
+ mkdir -p "$subpkgdir"
+}
+
+_backend() {
+ backend_name="${subpkgname#openldap-back-}"
+ pkgdesc="OpenLDAP $backend_name backend"
+
+ _submv "usr/lib/openldap/back_$backend_name*"
+}
+
+_overlay() {
+ overlay_name="${subpkgname#openldap-overlay-}"
+ pkgdesc="OpenLDAP $backend_name overlay"
+
+ case "$overlay_name" in
+ proxycache) overlay_name=pcache;;
+ esac
+ _submv "usr/lib/openldap/$overlay_name*"
+}
+
+_submv() {
+ local path; for path in "$@"; do
+ mkdir -p "$subpkgdir"/${path%/*}
+ mv "$pkgdir"/$path "$subpkgdir"/${path%/*}/
+ done
+}
+
+sha512sums="eef39d43f04aa09c657a1422cefef060fe00368559ae40d0d97536c08ebeaaa1ab06207b3f121ba6afcde54abdc550027c3505e5217e5fd47ae6f8c001260186 openldap-2.4.46.tgz
+5d34d49eabe7cb66cf8284cc3bd9730fa23df4932df68549e242d250ee50d40c434ae074ebc720d5fbcd9d16587c9333c5598d30a5f1177caa61461ab7771f38 openldap-2.4-ppolicy.patch
+44d97efb25d4f39ab10cd5571db43f3bfa7c617a5bb087085ae16c0298aca899b55c8742a502121ba743a73e6d77cd2056bc96cee63d6d0862dabc8fb5574357 openldap-2.4.11-libldap_r.patch
+8c4244d316a05870dd1147b2ab7ddbcfd7626b5dce2f5a0e72f066dc635c2edb4f1ea3be88c6fec2d5ab016001be16bedef70f2ce0695c3cd96f69e1614ff177 fix-manpages.patch
+0d2e570ddcb7ace1221abad9fc1d3dd0d00d6948340df69879b449959a68feee6a0ad8e17ef9971b35986293e16fc9d8e88de81815fedd5ea6a952eb085406ca configs.patch
+0c3606e4dad1b32f1c4b62f2bc1990a4c9f7ccd10c7b50e623309ba9df98064e68fc42a7242450f32fb6e5fa2203609d3d069871b5ae994cd4b227a078c93532 slapd.initd
+64dc4c0aa0abe3d9f7d2aef25fe4c8e23c53df2421067947ac4d096c9e942b26356cb8577ebc41b52d88d0b0a03b2a3e435fe86242671f9b36555a5f82ee0e3a slapd.confd"
diff --git a/system/openldap/CVE-2017-9287.patch b/system/openldap/CVE-2017-9287.patch
new file mode 100644
index 000000000..1599c1331
--- /dev/null
+++ b/system/openldap/CVE-2017-9287.patch
@@ -0,0 +1,28 @@
+From 0cee1ffb6021b1aae3fcc9581699da1c85a6dd6e Mon Sep 17 00:00:00 2001
+From: Ryan Tandy <ryan@nardis.ca>
+Date: Wed, 17 May 2017 20:07:39 -0700
+Subject: [PATCH] ITS#8655 fix double free on paged search with pagesize 0
+
+Fixes a double free when a search includes the Paged Results control
+with a page size of 0 and the search base matches the filter.
+---
+ servers/slapd/back-mdb/search.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/servers/slapd/back-mdb/search.c b/servers/slapd/back-mdb/search.c
+index 301d1a4..43442aa 100644
+--- a/servers/slapd/back-mdb/search.c
++++ b/servers/slapd/back-mdb/search.c
+@@ -1066,7 +1066,8 @@ notfound:
+ /* check size limit */
+ if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
+ if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
+- mdb_entry_return( op, e );
++ if (e != base)
++ mdb_entry_return( op, e );
+ e = NULL;
+ send_paged_response( op, rs, &lastid, tentries );
+ goto done;
+--
+1.7.10.4
+
diff --git a/system/openldap/configs.patch b/system/openldap/configs.patch
new file mode 100644
index 000000000..e7ec65c4b
--- /dev/null
+++ b/system/openldap/configs.patch
@@ -0,0 +1,117 @@
+--- a/servers/slapd/slapd.conf
++++ b/servers/slapd/slapd.conf
+@@ -2,7 +2,7 @@
+ # See slapd.conf(5) for details on configuration options.
+ # This file should NOT be world readable.
+ #
+-include %SYSCONFDIR%/schema/core.schema
++include /etc/openldap/schema/core.schema
+
+ # Define global ACLs to disable default read access.
+
+@@ -10,13 +10,16 @@
+ # service AND an understanding of referrals.
+ #referral ldap://root.openldap.org
+
+-pidfile %LOCALSTATEDIR%/run/slapd.pid
+-argsfile %LOCALSTATEDIR%/run/slapd.args
++# If you change this, adjust pidfile path also in runscript!
++pidfile /run/openldap/slapd.pid
++argsfile /run/openldap/slapd.args
+
+ # Load dynamic backend modules:
+-# modulepath %MODULEDIR%
+-# moduleload back_mdb.la
+-# moduleload back_ldap.la
++modulepath /usr/lib/openldap
++moduleload back_mdb.so
++# moduleload back_hdb.so
++# moduleload back_bbd.so
++# moduleload back_ldap.so
+
+ # Sample security restrictions
+ # Require integrity protection (prevent hijacking)
+@@ -53,13 +56,16 @@
+ maxsize 1073741824
+ suffix "dc=my-domain,dc=com"
+ rootdn "cn=Manager,dc=my-domain,dc=com"
++
+ # Cleartext passwords, especially for the rootdn, should
+ # be avoid. See slappasswd(8) and slapd.conf(5) for details.
+ # Use of strong authentication encouraged.
+ rootpw secret
++
+ # The database directory MUST exist prior to running slapd AND
+ # should only be accessible by the slapd and slap tools.
+ # Mode 700 recommended.
+-directory %LOCALSTATEDIR%/openldap-data
++directory /var/lib/openldap/openldap-data
++
+ # Indices to maintain
+ index objectClass eq
+--- a/servers/slapd/slapd.ldif
++++ b/servers/slapd/slapd.ldif
+@@ -9,8 +9,9 @@
+ #
+ # Define global ACLs to disable default read access.
+ #
+-olcArgsFile: %LOCALSTATEDIR%/run/slapd.args
+-olcPidFile: %LOCALSTATEDIR%/run/slapd.pid
++# If you change this, set pidfile variable in /etc/conf.d/slapd!
++olcPidFile: /run/openldap/slapd.pid
++olcArgsFile: /run/openldap/slapd.args
+ #
+ # Do not enable referrals until AFTER you have a working directory
+ # service AND an understanding of referrals.
+@@ -26,22 +27,23 @@
+ #
+ # Load dynamic backend modules:
+ #
+-#dn: cn=module,cn=config
+-#objectClass: olcModuleList
+-#cn: module
+-#olcModulepath: %MODULEDIR%
+-#olcModuleload: back_bdb.la
+-#olcModuleload: back_hdb.la
+-#olcModuleload: back_ldap.la
+-#olcModuleload: back_passwd.la
+-#olcModuleload: back_shell.la
++dn: cn=module,cn=config
++objectClass: olcModuleList
++cn: module
++olcModulepath: /usr/lib/openldap
++#olcModuleload: back_bdb.so
++#olcModuleload: back_hdb.so
++#olcModuleload: back_ldap.so
++olcModuleload: back_mdb.so
++#olcModuleload: back_passwd.so
++#olcModuleload: back_shell.so
+
+
+ dn: cn=schema,cn=config
+ objectClass: olcSchemaConfig
+ cn: schema
+
+-include: file://%SYSCONFDIR%/schema/core.ldif
++include: file:///etc/openldap/schema/core.ldif
+
+ # Frontend settings
+ #
+@@ -83,13 +85,16 @@
+ olcDatabase: mdb
+ olcSuffix: dc=my-domain,dc=com
+ olcRootDN: cn=Manager,dc=my-domain,dc=com
++
+ # Cleartext passwords, especially for the rootdn, should
+ # be avoided. See slappasswd(8) and slapd-config(5) for details.
+ # Use of strong authentication encouraged.
+ olcRootPW: secret
++
+ # The database directory MUST exist prior to running slapd AND
+ # should only be accessible by the slapd and slap tools.
+ # Mode 700 recommended.
+-olcDbDirectory: %LOCALSTATEDIR%/openldap-data
++olcDbDirectory: /var/lib/openldap/openldap-data
++
+ # Indices to maintain
+ olcDbIndex: objectClass eq
diff --git a/system/openldap/fix-manpages.patch b/system/openldap/fix-manpages.patch
new file mode 100644
index 000000000..179569494
--- /dev/null
+++ b/system/openldap/fix-manpages.patch
@@ -0,0 +1,75 @@
+Various manual pages changes:
+* removes LIBEXECDIR from slapd.8
+* removes references to non-existing manpages (bz 624616)
+
+Patch-Source: https://src.fedoraproject.org/rpms/openldap/blob/f27/f/openldap-manpages.patch
+
+diff --git a/doc/man/man1/ldapmodify.1 b/doc/man/man1/ldapmodify.1
+index 3def6da..466c772 100644
+--- a/doc/man/man1/ldapmodify.1
++++ b/doc/man/man1/ldapmodify.1
+@@ -397,8 +397,7 @@ exit status and a diagnostic message being written to standard error.
+ .BR ldap_add_ext (3),
+ .BR ldap_delete_ext (3),
+ .BR ldap_modify_ext (3),
+-.BR ldap_modrdn_ext (3),
+-.BR ldif (5).
++.BR ldif (5)
+ .SH AUTHOR
+ The OpenLDAP Project <http://www.openldap.org/>
+ .SH ACKNOWLEDGEMENTS
+diff --git a/doc/man/man5/ldap.conf.5 b/doc/man/man5/ldap.conf.5
+index cfde143..63592cb 100644
+--- a/doc/man/man5/ldap.conf.5
++++ b/doc/man/man5/ldap.conf.5
+@@ -317,6 +317,7 @@ certificates in separate individual files. The
+ .B TLS_CACERT
+ is always used before
+ .B TLS_CACERTDIR.
++The specified directory must be managed with the LibreSSL c_rehash utility.
+ This parameter is ignored with GnuTLS.
+
+ When using Mozilla NSS, <path> may contain a Mozilla NSS cert/key
+diff --git a/doc/man/man8/slapd.8 b/doc/man/man8/slapd.8
+index b739f4d..e2a1a00 100644
+--- a/doc/man/man8/slapd.8
++++ b/doc/man/man8/slapd.8
+@@ -5,7 +5,7 @@
+ .SH NAME
+ slapd \- Stand-alone LDAP Daemon
+ .SH SYNOPSIS
+-.B LIBEXECDIR/slapd
++.B slapd
+ [\c
+ .BR \-4 | \-6 ]
+ [\c
+@@ -317,7 +317,7 @@ the LDAP databases defined in the default config file, just type:
+ .LP
+ .nf
+ .ft tt
+- LIBEXECDIR/slapd
++ slapd
+ .ft
+ .fi
+ .LP
+@@ -328,7 +328,7 @@ on voluminous debugging which will be printed on standard error, type:
+ .LP
+ .nf
+ .ft tt
+- LIBEXECDIR/slapd \-f /var/tmp/slapd.conf \-d 255
++ slapd -f /var/tmp/slapd.conf -d 255
+ .ft
+ .fi
+ .LP
+@@ -336,7 +336,7 @@ To test whether the configuration file is correct or not, type:
+ .LP
+ .nf
+ .ft tt
+- LIBEXECDIR/slapd \-Tt
++ slapd -Tt
+ .ft
+ .fi
+ .LP
+--
+1.8.1.4
+
diff --git a/system/openldap/libressl.patch b/system/openldap/libressl.patch
new file mode 100644
index 000000000..ac0106418
--- /dev/null
+++ b/system/openldap/libressl.patch
@@ -0,0 +1,65 @@
+--- a/libraries/libldap/tls_o.c.orig 2017-06-04 16:31:28 UTC
++++ b/libraries/libldap/tls_o.c
+@@ -47,7 +47,7 @@
+ #include <ssl.h>
+ #endif
+
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000
++#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+ #define ASN1_STRING_data(x) ASN1_STRING_get0_data(x)
+ #endif
+
+@@ -157,7 +157,7 @@ tlso_init( void )
+ (void) tlso_seed_PRNG( lo->ldo_tls_randfile );
+ #endif
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
+ SSL_load_error_strings();
+ SSL_library_init();
+ OpenSSL_add_all_digests();
+@@ -205,7 +205,7 @@ static void
+ tlso_ctx_ref( tls_ctx *ctx )
+ {
+ tlso_ctx *c = (tlso_ctx *)ctx;
+-#if OPENSSL_VERSION_NUMBER < 0x10100000
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
+ #define SSL_CTX_up_ref(ctx) CRYPTO_add( &(ctx->references), 1, CRYPTO_LOCK_SSL_CTX )
+ #endif
+ SSL_CTX_up_ref( c );
+@@ -464,7 +464,7 @@ tlso_session_my_dn( tls_session *sess, struct berval *
+ if (!x) return LDAP_INVALID_CREDENTIALS;
+
+ xn = X509_get_subject_name(x);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
+ der_dn->bv_len = i2d_X509_NAME( xn, NULL );
+ der_dn->bv_val = xn->bytes->data;
+ #else
+@@ -500,7 +500,7 @@ tlso_session_peer_dn( tls_session *sess, struct berval
+ return LDAP_INVALID_CREDENTIALS;
+
+ xn = X509_get_subject_name(x);
+-#if OPENSSL_VERSION_NUMBER < 0x10100000
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
+ der_dn->bv_len = i2d_X509_NAME( xn, NULL );
+ der_dn->bv_val = xn->bytes->data;
+ #else
+@@ -721,7 +721,7 @@ struct tls_data {
+ Sockbuf_IO_Desc *sbiod;
+ };
+
+-#if OPENSSL_VERSION_NUMBER < 0x10100000
++#if OPENSSL_VERSION_NUMBER < 0x10100000 || defined(LIBRESSL_VERSION_NUMBER)
+ #define BIO_set_init(b, x) b->init = x
+ #define BIO_set_data(b, x) b->ptr = x
+ #define BIO_clear_flags(b, x) b->flags &= ~(x)
+@@ -822,7 +822,7 @@ tlso_bio_puts( BIO *b, const char *str )
+ return tlso_bio_write( b, str, strlen( str ) );
+ }
+
+-#if OPENSSL_VERSION_NUMBER >= 0x10100000
++#if OPENSSL_VERSION_NUMBER >= 0x10100000 && !defined(LIBRESSL_VERSION_NUMBER)
+ struct bio_method_st {
+ int type;
+ const char *name;
diff --git a/system/openldap/openldap-2.4-ppolicy.patch b/system/openldap/openldap-2.4-ppolicy.patch
new file mode 100644
index 000000000..c05790e3e
--- /dev/null
+++ b/system/openldap/openldap-2.4-ppolicy.patch
@@ -0,0 +1,13 @@
+diff -urN ./clients.orig/tools/common.c ./clients/tools/common.c
+--- ./clients.orig/tools/common.c 2007-09-01 01:13:50.000000000 +0200
++++ ./clients/tools/common.c 2008-01-13 21:50:06.000000000 +0100
+@@ -1262,8 +1262,8 @@
+ int nsctrls = 0;
+
+ #ifdef LDAP_CONTROL_PASSWORDPOLICYREQUEST
++ LDAPControl c;
+ if ( ppolicy ) {
+- LDAPControl c;
+ c.ldctl_oid = LDAP_CONTROL_PASSWORDPOLICYREQUEST;
+ c.ldctl_value.bv_val = NULL;
+ c.ldctl_value.bv_len = 0;
diff --git a/system/openldap/openldap-2.4.11-libldap_r.patch b/system/openldap/openldap-2.4.11-libldap_r.patch
new file mode 100644
index 000000000..448249a3b
--- /dev/null
+++ b/system/openldap/openldap-2.4.11-libldap_r.patch
@@ -0,0 +1,11 @@
+diff -Nuar openldap-2.4.11.orig/servers/slapd/slapi/Makefile.in openldap-2.4.11/servers/slapd/slapi/Makefile.in
+--- openldap-2.4.11.orig/servers/slapd/slapi/Makefile.in 2008-02-11 15:26:49.000000000 -0800
++++ openldap-2.4.11/servers/slapd/slapi/Makefile.in 2008-10-14 02:10:18.402799262 -0700
+@@ -37,6 +37,7 @@
+ XLIBS = $(LIBRARY)
+ XXLIBS =
+ NT_LINK_LIBS = $(AC_LIBS)
++UNIX_LINK_LIBS = ../../../libraries/libldap_r/libldap_r.la $(LTHREAD_LIBS)
+
+ XINCPATH = -I$(srcdir)/.. -I$(srcdir)
+ XDEFS = $(MODULES_CPPFLAGS)
diff --git a/system/openldap/openldap-mqtt-overlay.patch b/system/openldap/openldap-mqtt-overlay.patch
new file mode 100644
index 000000000..795480f1e
--- /dev/null
+++ b/system/openldap/openldap-mqtt-overlay.patch
@@ -0,0 +1,447 @@
+diff --git a/contrib/slapd-modules/mqtt/Makefile b/contrib/slapd-modules/mqtt/Makefile
+new file mode 100644
+index 0000000..2cb4db7
+--- /dev/null
++++ b/contrib/slapd-modules/mqtt/Makefile
+@@ -0,0 +1,45 @@
++# $OpenLDAP$
++
++LDAP_SRC = ../../..
++LDAP_BUILD = ../../..
++LDAP_INC = -I$(LDAP_BUILD)/include -I$(LDAP_SRC)/include -I$(LDAP_SRC)/servers/slapd
++LDAP_LIB = $(LDAP_BUILD)/libraries/libldap_r/libldap_r.la \
++ $(LDAP_BUILD)/libraries/liblber/liblber.la
++
++LIBTOOL = $(LDAP_BUILD)/libtool
++CC = gcc
++OPT = -g -O2 -Wall
++DEFS =
++INCS = $(LDAP_INC)
++LIBS = $(LDAP_LIB) -lmosquitto
++
++PROGRAMS = mqtt.la
++LTVER = 0:0:0
++
++prefix=/usr/local
++exec_prefix=$(prefix)
++ldap_subdir=/openldap
++
++libdir=$(exec_prefix)/lib
++libexecdir=$(exec_prefix)/libexec
++moduledir = $(libdir)$(ldap_subdir)
++
++.SUFFIXES: .c .o .lo
++
++.c.lo:
++ $(LIBTOOL) --mode=compile $(CC) $(OPT) $(DEFS) $(INCS) -c $<
++
++all: $(PROGRAMS)
++
++mqtt.la: mqtt.lo
++ $(LIBTOOL) --mode=link $(CC) $(OPT) -version-info $(LTVER) \
++ -rpath $(moduledir) -module -o $@ $? $(LIBS)
++
++clean:
++ rm -rf *.o *.lo *.la .libs
++
++install: $(PROGRAMS)
++ mkdir -p $(DESTDIR)$(moduledir)
++ for p in $(PROGRAMS) ; do \
++ $(LIBTOOL) --mode=install cp $$p $(DESTDIR)$(moduledir) ; \
++ done
+diff --git a/contrib/slapd-modules/mqtt/mqtt.c b/contrib/slapd-modules/mqtt/mqtt.c
+new file mode 100644
+index 0000000..b3a0a31
+--- /dev/null
++++ b/contrib/slapd-modules/mqtt/mqtt.c
+@@ -0,0 +1,389 @@
++/* $OpenLDAP$ */
++/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
++ *
++ * Copyright 2014 Timo Teräs <timo.teras@iki.fi>.
++ * All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted only as authorized by the OpenLDAP
++ * Public License.
++ *
++ * A copy of this license is available in file LICENSE in the
++ * top-level directory of the distribution or, alternatively, at
++ * http://www.OpenLDAP.org/license.html.
++ */
++/* mqtt-overlay
++ *
++ * This is an OpenLDAP overlay that... */
++
++#include <mosquitto.h>
++#include <unistd.h>
++
++#include "portable.h"
++#include "slap.h"
++#include "config.h"
++
++typedef struct mqtt_notify_t {
++ struct mqtt_notify_t *next;
++ char *topic;
++ char *dn_group_str;
++ char *oc_group_str;
++ char *str_member;
++
++ struct berval ndn_group;
++ ObjectClass *oc_group;
++ AttributeDescription *ad_member;
++ int notify_pending;
++} mqtt_notify_t;
++
++typedef struct mqtt_t {
++ struct mosquitto *mq;
++ int port;
++ char *hostname, *username, *password;
++ mqtt_notify_t *notify_map;
++} mqtt_t;
++
++static ConfigDriver mqtt_config_notify;
++
++static ConfigTable mqttcfg[] = {
++ { "mqtt-hostname", "hostname", 2, 2, 0,
++ ARG_STRING|ARG_OFFSET, (void *)offsetof(mqtt_t, hostname),
++ "( OLcfgCtAt:5.1 NAME 'olcMqttHostname' "
++ "DESC 'Hostname of MQTT broker' "
++ "SYNTAX OMsDirectoryString SINGLE-VALUE )",
++ NULL, NULL },
++ { "mqtt-port", "port", 2, 2, 0,
++ ARG_INT|ARG_OFFSET, (void *)offsetof(mqtt_t, port),
++ "( OLcfgCtAt:5.2 NAME 'olcMqttPort' "
++ "DESC 'Port of MQTT broker' "
++ "SYNTAX OMsInteger SINGLE-VALUE )",
++ NULL, NULL },
++ { "mqtt-username", "username", 2, 2, 0,
++ ARG_STRING|ARG_OFFSET, (void *)offsetof(mqtt_t, username),
++ "( OLcfgCtAt:5.3 NAME 'olcMqttUsername' "
++ "DESC 'Username for MQTT broker' "
++ "SYNTAX OMsDirectoryString SINGLE-VALUE )",
++ NULL, NULL },
++ { "mqtt-password", "password", 2, 2, 0,
++ ARG_STRING|ARG_OFFSET, (void *)offsetof(mqtt_t, password),
++ "( OLcfgCtAt:5.4 NAME 'olcMqttPassword' "
++ "DESC 'Password for MQTT broker' "
++ "SYNTAX OMsDirectoryString SINGLE-VALUE )",
++ NULL, NULL },
++ { "mqtt-notify-password", "topic> <group-dn> <group-oc> <member-ad", 2, 5, 0,
++ ARG_MAGIC, mqtt_config_notify,
++ "( OLcfgCtAt:5.5 NAME 'olcMqttNotifyPassword' "
++ "DESC 'Notify password change on <topic>, optionally checking that the object is in the specified group.'"
++ "SYNTAX OMsDirectoryString X-ORDERED 'VALUES' )",
++ NULL, NULL },
++ { NULL, NULL, 0, 0, 0, ARG_IGNORED }
++};
++
++static ConfigOCs mqttocs[] = {
++ { "( OLcfgCtOc:5.1 "
++ "NAME 'olcMqttConfig' "
++ "DESC 'MQTT configuration' "
++ "SUP olcOverlayConfig "
++ "MAY ( "
++ "olcMqttHostname "
++ "$ olcMqttPort"
++ "$ olcMqttUsername"
++ "$ olcMqttPassword"
++ "$ olcMqttNotifyPassword"
++ " ) )",
++ Cft_Overlay, mqttcfg },
++
++ { NULL, 0, NULL }
++};
++
++static int mqtt_init(BackendInfo *bi)
++{
++ return mosquitto_lib_init();
++}
++
++static int mqtt_destroy(BackendInfo *bi)
++{
++ return mosquitto_lib_cleanup();
++}
++
++static const char *ca_arg(ConfigArgs *c, int n)
++{
++ return (c->argc <= n) ? NULL : c->argv[n];
++}
++
++static void free_notify(mqtt_notify_t *n)
++{
++ ch_free(n->topic);
++ ch_free(n->oc_group_str);
++ ch_free(n->str_member);
++ ch_free(n->dn_group_str);
++ if (!BER_BVISNULL(&n->ndn_group))
++ ber_memfree(n->ndn_group.bv_val);
++ ch_free(n);
++}
++
++static void free_all_notifies(mqtt_t *mqtt)
++{
++ mqtt_notify_t *n, *next;
++
++ for (n = mqtt->notify_map; n; n = next) {
++ next = n->next;
++ free_notify(n);
++ }
++ mqtt->notify_map = NULL;
++}
++
++static int mqtt_config_notify(ConfigArgs *c)
++{
++ slap_overinst *on = (slap_overinst *)c->bi;
++ mqtt_t *mqtt = (mqtt_t *) on->on_bi.bi_private;
++ mqtt_notify_t *n, **pprev;
++ const char *text = NULL;
++ struct berval bv = BER_BVNULL, ndn = BER_BVNULL;
++ int rc, i;
++
++ switch (c->op) {
++ case SLAP_CONFIG_EMIT:
++ for (i = 0, n = mqtt->notify_map; n; n = n->next, i++) {
++ char *ptr = c->cr_msg, *end = &c->cr_msg[sizeof(c->cr_msg)-1];
++
++ ptr += snprintf(ptr, end-ptr, SLAP_X_ORDERED_FMT "%s", i, n->topic);
++ if (n->dn_group_str)
++ ptr += snprintf(ptr, end-ptr, " \"%s\"", n->dn_group_str);
++ if (n->oc_group_str)
++ ptr += snprintf(ptr, end-ptr, " \"%s\"", n->oc_group_str);
++ if (n->str_member)
++ ptr += snprintf(ptr, end-ptr, " \"%s\"", n->str_member);
++
++ bv.bv_val = c->cr_msg;
++ bv.bv_len = ptr - bv.bv_val;
++ value_add_one(&c->rvalue_vals, &bv);
++ }
++ return 0;
++ case LDAP_MOD_DELETE:
++ if (c->valx < 0) {
++ free_all_notifies(mqtt);
++ } else {
++ pprev = &mqtt->notify_map;
++ n = mqtt->notify_map;
++ for (i = 0; i < c->valx; i++) {
++ pprev = &n->next;
++ n = n->next;
++ }
++ *pprev = n->next;
++ free_notify(n);
++ }
++ return 0;
++ }
++
++ const char *groupdn = ca_arg(c, 2);
++ const char *oc_name = ca_arg(c, 3);
++ const char *ad_name = ca_arg(c, 4);
++ ObjectClass *oc = NULL;
++ AttributeDescription *ad = NULL;
++
++ if (groupdn) {
++ oc = oc_find(oc_name ?: SLAPD_GROUP_CLASS);
++ if (oc == NULL) {
++ Debug(LDAP_DEBUG_ANY, "mqtt_db_open: unable to find objectClass=\"%s\"\n",
++ oc_name, 0, 0);
++ return 1;
++ }
++
++ rc = slap_str2ad(ad_name ?: SLAPD_GROUP_ATTR, &ad, &text);
++ if (rc != LDAP_SUCCESS) {
++ Debug(LDAP_DEBUG_ANY, "mqtt_db_config_notify: unable to find attribute=\"%s\": %s (%d)\n",
++ ad_name, text, rc);
++ return rc;
++ }
++
++ ber_str2bv(groupdn, 0, 0, &bv);
++ rc = dnNormalize(0, NULL, NULL, &bv, &ndn, NULL);
++ if (rc != LDAP_SUCCESS) {
++ Debug(LDAP_DEBUG_ANY, "mqtt_db_config_notify: DN normalization failed for \"%s\": %d\n",
++ groupdn, rc, 0);
++ return rc;
++ }
++ }
++
++ n = ch_calloc(1, sizeof(*n));
++ n->topic = ch_strdup(c->argv[1]);
++ n->dn_group_str = groupdn ? ch_strdup(groupdn) : NULL;
++ n->oc_group_str = oc_name ? ch_strdup(oc_name) : NULL;
++ n->str_member = ad_name ? ch_strdup(ad_name) : NULL;
++ n->ndn_group = ndn;
++ n->oc_group = oc;
++ n->ad_member = ad;
++
++ for (pprev = &mqtt->notify_map; *pprev; pprev = &(*pprev)->next);
++ *pprev = n;
++
++ return 0;
++}
++
++static void mqtt_send_notify(mqtt_t *mqtt, mqtt_notify_t *n)
++{
++ Debug(LDAP_DEBUG_TRACE, "mqtt_send_notify: pub on topic '%s'\n", n->topic, 0, 0);
++ n->notify_pending = mosquitto_publish(mqtt->mq, NULL, n->topic, 0, NULL, 1, true) == MOSQ_ERR_NO_CONN;
++}
++
++static void mqtt_on_connect(struct mosquitto *mq, void *obj, int rc)
++{
++ slap_overinst *on = (slap_overinst *) obj;
++ mqtt_t *mqtt = (mqtt_t *) on->on_bi.bi_private;
++ mqtt_notify_t *n;
++
++ Debug(LDAP_DEBUG_TRACE, "mqtt_on_connect: connected with status %d\n", rc, 0, 0);
++ if (rc != 0)
++ return;
++
++ for (n = mqtt->notify_map; n; n = n->next)
++ if (n->notify_pending)
++ mqtt_send_notify(mqtt, n);
++}
++
++static int mqtt_db_init(BackendDB *be, ConfigReply *cr)
++{
++ slap_overinst *on = (slap_overinst *) be->bd_info;
++
++ Debug(LDAP_DEBUG_TRACE, "mqtt_db_init: initialize overlay\n", 0, 0, 0);
++ on->on_bi.bi_private = ch_calloc(1, sizeof(mqtt_t));
++
++ return 0;
++}
++
++static int mqtt_db_destroy(BackendDB *be, ConfigReply *cr)
++{
++ slap_overinst *on = (slap_overinst *) be->bd_info;
++ mqtt_t *mqtt = on->on_bi.bi_private;
++
++ Debug(LDAP_DEBUG_TRACE, "mqtt_db_destroy: destroy overlay\n", 0, 0, 0);
++ free_all_notifies(mqtt);
++ ch_free(mqtt);
++
++ return 0;
++}
++
++static int mqtt_db_open(BackendDB *be, ConfigReply *cr)
++{
++ slap_overinst *on = (slap_overinst *) be->bd_info;
++ mqtt_t *mqtt = (mqtt_t *) on->on_bi.bi_private;
++ struct mosquitto *mq;
++ char id[256];
++ int n;
++
++ n = snprintf(id, sizeof(id), "openldap-mqtt/%d/", getpid());
++ gethostname(&id[n], sizeof(id) - n);
++
++ Debug(LDAP_DEBUG_TRACE, "mqtt_db_open, id='%s'\n", id, 0, 0);
++ mqtt->mq = mq = mosquitto_new(id, true, on);
++ if (!mq) return 1;
++
++ if (mqtt->username && mqtt->password)
++ mosquitto_username_pw_set(mq, mqtt->username, mqtt->password);
++
++ mosquitto_connect_callback_set(mq, mqtt_on_connect);
++ mosquitto_connect_async(mq, mqtt->hostname ?: "127.0.0.1", mqtt->port ?: 1883, 60);
++ mosquitto_loop_start(mq);
++
++ return 0;
++}
++
++static int mqtt_db_close(BackendDB *be, ConfigReply *cr)
++{
++ slap_overinst *on = (slap_overinst *) be->bd_info;
++ mqtt_t *mqtt = (mqtt_t *) on->on_bi.bi_private;
++
++ Debug(LDAP_DEBUG_TRACE, "mqtt_db_close\n", 0, 0, 0);
++ mosquitto_disconnect(mqtt->mq);
++ mosquitto_loop_stop(mqtt->mq, false);
++ mosquitto_destroy(mqtt->mq);
++
++ free(mqtt->hostname); mqtt->hostname = NULL;
++ free(mqtt->username); mqtt->username = NULL;
++ free(mqtt->password); mqtt->password = NULL;
++
++ return 0;
++}
++
++static int mqtt_response(Operation *op, SlapReply *rs)
++{
++ slap_overinst *on = (slap_overinst *) op->o_bd->bd_info;
++ mqtt_t *mqtt = (mqtt_t *) on->on_bi.bi_private;
++ Attribute *a;
++ Modifications *m;
++ bool change = false;
++
++ switch (op->o_tag) {
++ case LDAP_REQ_ADD:
++ for (a = op->ora_e->e_attrs; a; a = a->a_next) {
++ if (a->a_desc == slap_schema.si_ad_userPassword) {
++ change = true;
++ break;
++ }
++ }
++ break;
++ case LDAP_REQ_MODIFY:
++ for (m = op->orm_modlist; m; m = m->sml_next) {
++ if (m->sml_desc == slap_schema.si_ad_userPassword) {
++ change = true;
++ break;
++ }
++ }
++ break;
++ case LDAP_REQ_EXTENDED:
++ if (ber_bvcmp(&slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid) == 0)
++ change = true;
++ break;
++ }
++
++ if (change) {
++ mqtt_notify_t *n;
++ int r, cache;
++
++ for (n = mqtt->notify_map; n; n = n->next) {
++ if (n->oc_group) {
++ cache = op->o_do_not_cache;
++ op->o_do_not_cache = 1;
++ r = backend_group(op, NULL, &n->ndn_group, &op->o_req_ndn, n->oc_group, n->ad_member);
++ op->o_do_not_cache = cache;
++ } else {
++ r = 0;
++ }
++
++ Debug(LDAP_DEBUG_TRACE, "tested o_req_ndn='%s' in ndn_group='%s' r=%d\n",
++ op->o_req_ndn.bv_val, n->ndn_group.bv_val, r);
++
++ if (r == 0)
++ mqtt_send_notify(mqtt, n);
++ }
++ }
++
++ return SLAP_CB_CONTINUE;
++}
++
++static int mqtt_init_overlay()
++{
++ static slap_overinst ov;
++ int rc;
++
++ ov.on_bi.bi_type = "mqtt";
++ ov.on_bi.bi_init = mqtt_init;
++ ov.on_bi.bi_destroy = mqtt_destroy;
++ ov.on_bi.bi_db_init = mqtt_db_init;
++ ov.on_bi.bi_db_destroy = mqtt_db_destroy;
++ ov.on_bi.bi_db_open = mqtt_db_open;
++ ov.on_bi.bi_db_close = mqtt_db_close;
++ ov.on_bi.bi_cf_ocs = mqttocs;
++ ov.on_response = mqtt_response;
++
++ rc = config_register_schema(mqttcfg, mqttocs);
++ if (rc) return rc;
++
++ return overlay_register(&ov);
++}
++
++int init_module(int argc, char *argv[])
++{
++ return mqtt_init_overlay();
++}
+
diff --git a/system/openldap/openldap.post-install b/system/openldap/openldap.post-install
new file mode 100644
index 000000000..e90d25760
--- /dev/null
+++ b/system/openldap/openldap.post-install
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+cat >&2 <<-EOF
+*
+* To use LDAP server, you have to install some backend. Most users would need MDB
+* backend which you can install with: apk add openldap-back-mdb.
+*
+* If you use overlays, you have to install them separately too:
+* apk add openldap-overlay-<name>, or openldap-overlay-all to install them all.
+*
+EOF
diff --git a/system/openldap/openldap.post-upgrade b/system/openldap/openldap.post-upgrade
new file mode 100644
index 000000000..7be8906a9
--- /dev/null
+++ b/system/openldap/openldap.post-upgrade
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+new_ver="$1"
+old_ver="$2"
+
+if [ "$(apk version -t "$old_ver" "2.4.45-r2")" = "<" ]; then
+ cat >&2 <<-EOF
+ *
+ * All SLAPD backends and overlays have been moved to subpackages.
+ * You can install specific backend or overlay with apk:
+ *
+ * apk add openldap-back-<name>
+ * apk add openldap-overlay-<name>
+ *
+ * Or you can install all of them using metapackages openldap-back-all
+ * and openldap-overlay-all.
+ EOF
+ if [ -e /var/lib/openldap/openldap-data/data.mdb ]; then
+ cat >&2 <<-EOF
+ *
+ * Found existing MDB database. You have to install MDB backend:
+ * apk add openldap-back-mdb
+ *
+ * and add "moduleload back_mdb.so" to /etc/openldap/slapd.conf,
+ * or "olcModuleload back_mdb.so" to slapd.ldif.
+ *
+ EOF
+ else
+ echo "*" >&2
+ fi
+fi
diff --git a/system/openldap/openldap.pre-install b/system/openldap/openldap.pre-install
new file mode 100644
index 000000000..eb6b10fa4
--- /dev/null
+++ b/system/openldap/openldap.pre-install
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+addgroup -S ldap 2>/dev/null
+adduser -S -D -H -h /usr/lib/openldap -s /sbin/nologin -G ldap \
+ -g "OpenLdap User" ldap 2>/dev/null
+
+exit 0
diff --git a/system/openldap/slapd.confd b/system/openldap/slapd.confd
new file mode 100644
index 000000000..f69f92b4a
--- /dev/null
+++ b/system/openldap/slapd.confd
@@ -0,0 +1,12 @@
+# Configuration for /etc/init.d/slapd
+
+# Location of the configuration file.
+cfgfile="/etc/openldap/slapd.conf"
+
+# Location of the configuration directory (OpenLDAP 2.3+).
+#cfgdir=""
+
+# To enable both the standard unciphered server and the ssl encrypted
+# one uncomment this line or set any other server starting options
+# you may desire.
+#command_args="-h 'ldaps:// ldap:// ldapi://%2fvar%2frun%2fopenldap%2fslapd.sock'"
diff --git a/system/openldap/slapd.initd b/system/openldap/slapd.initd
new file mode 100644
index 000000000..350cc0d50
--- /dev/null
+++ b/system/openldap/slapd.initd
@@ -0,0 +1,34 @@
+#!/sbin/openrc-run
+
+: ${pidfile:="/run/openldap/slapd.pid"}
+
+name="LDAP server"
+extra_commands="checkconfig"
+description_checkconfig="Check slapd.conf for errors"
+
+command="/usr/sbin/slapd"
+# OPTS is for backward compatibility
+cfg_opt="${cfgdir:+"-F $cfgdir"} ${cfgfile:+"-f $cfgfile"}"
+command_args="-u ldap -g ldap $cfg_opt ${command_args:-${OPTS:-}}"
+
+stopsig=2
+start_stop_daemon_args="
+ ${KRB5_KTNAME:+"--env KRB5_KTNAME=$KRB5_KTNAME"}"
+
+depend() {
+ need net
+ after firewall
+ before dbus hald avahi-daemon
+ provide ldap
+}
+
+start_pre() {
+ checkpath --directory --owner ldap:ldap "${pidfile%/*}"
+ /usr/sbin/slaptest -u -Q $cfg_opt || /usr/sbin/slaptest -u $cfg_opt
+}
+
+checkconfig() {
+ ebegin "Checking $name configuration..."
+ /usr/sbin/slaptest -u $cfg_opt
+ eend $?
+}