diff options
Diffstat (limited to 'user/openldap')
-rw-r--r-- | user/openldap/APKBUILD | 212 | ||||
-rw-r--r-- | user/openldap/CVE-2017-9287.patch | 28 | ||||
-rw-r--r-- | user/openldap/configs.patch | 117 | ||||
-rw-r--r-- | user/openldap/fix-manpages.patch | 75 | ||||
-rw-r--r-- | user/openldap/libressl.patch | 65 | ||||
-rw-r--r-- | user/openldap/openldap-2.4-ppolicy.patch | 13 | ||||
-rw-r--r-- | user/openldap/openldap-2.4.11-libldap_r.patch | 11 | ||||
-rw-r--r-- | user/openldap/openldap-mqtt-overlay.patch | 447 | ||||
-rw-r--r-- | user/openldap/openldap.post-install | 11 | ||||
-rw-r--r-- | user/openldap/openldap.post-upgrade | 31 | ||||
-rw-r--r-- | user/openldap/openldap.pre-install | 7 | ||||
-rw-r--r-- | user/openldap/slapd.confd | 12 | ||||
-rw-r--r-- | user/openldap/slapd.initd | 34 |
13 files changed, 1063 insertions, 0 deletions
diff --git a/user/openldap/APKBUILD b/user/openldap/APKBUILD new file mode 100644 index 000000000..84cbc1471 --- /dev/null +++ b/user/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/user/openldap/CVE-2017-9287.patch b/user/openldap/CVE-2017-9287.patch new file mode 100644 index 000000000..1599c1331 --- /dev/null +++ b/user/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/user/openldap/configs.patch b/user/openldap/configs.patch new file mode 100644 index 000000000..e7ec65c4b --- /dev/null +++ b/user/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/user/openldap/fix-manpages.patch b/user/openldap/fix-manpages.patch new file mode 100644 index 000000000..179569494 --- /dev/null +++ b/user/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/user/openldap/libressl.patch b/user/openldap/libressl.patch new file mode 100644 index 000000000..ac0106418 --- /dev/null +++ b/user/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/user/openldap/openldap-2.4-ppolicy.patch b/user/openldap/openldap-2.4-ppolicy.patch new file mode 100644 index 000000000..c05790e3e --- /dev/null +++ b/user/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/user/openldap/openldap-2.4.11-libldap_r.patch b/user/openldap/openldap-2.4.11-libldap_r.patch new file mode 100644 index 000000000..448249a3b --- /dev/null +++ b/user/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/user/openldap/openldap-mqtt-overlay.patch b/user/openldap/openldap-mqtt-overlay.patch new file mode 100644 index 000000000..795480f1e --- /dev/null +++ b/user/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/user/openldap/openldap.post-install b/user/openldap/openldap.post-install new file mode 100644 index 000000000..e90d25760 --- /dev/null +++ b/user/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/user/openldap/openldap.post-upgrade b/user/openldap/openldap.post-upgrade new file mode 100644 index 000000000..7be8906a9 --- /dev/null +++ b/user/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/user/openldap/openldap.pre-install b/user/openldap/openldap.pre-install new file mode 100644 index 000000000..eb6b10fa4 --- /dev/null +++ b/user/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/user/openldap/slapd.confd b/user/openldap/slapd.confd new file mode 100644 index 000000000..f69f92b4a --- /dev/null +++ b/user/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/user/openldap/slapd.initd b/user/openldap/slapd.initd new file mode 100644 index 000000000..350cc0d50 --- /dev/null +++ b/user/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 $? +} |