It took me a while, but finally I removed all bugs (hopefully) and it works as a charm.

Since I'm using Ubuntu 16, I'll provide complete manual for others who get
lost. Note that in new versions of LDAP us usually used cn=config format,
so I'll show how to create database in this format.

1) Install dev packages to be able compile sources (maybe you will need to
   install some additional packages)

$ sudo apt install gcc libdb-dev libsasl2-dev make libltdl-dev && echo "OK"


2) Make sure you do not have Ubuntu's LDAP server. If you're not sure sure,
   simply try following command and if it FAIL, it is OK. Otherwise you need
   to uninstall Ubuntu's LDAP, or change port settings in your custom LDAP
   server

$ sudo service slapd stop
slapd: unrecognized service # This is OK, else uninstall slapd package


3) Simply remove (3A) or configure (3B) "apparmor" to avoid strange start
   failure and another "permission denied" errors. Choice is up to you
   (security vs convenience)

3A) Remove apparrmor
$ sudo apt remove apparmor

3B) Configure apparmor

  Create new file and add following lines (without "====" separator):

$ sudo vim /etc/apparmor.d/opt.openldap.libexec.slapd
==============================================================================
# vim:syntax=apparmor
# Last Modified: Fri Jan  4 15:18:13 2008
# Author: Jamie Strandboge <jamie@ubuntu.com>

#include <tunables/global>

/opt/openldap/libexec/slapd {
  #include <abstractions/base>
  #include <abstractions/nameservice>
  #include <abstractions/p11-kit>

  #include <abstractions/ssl_certs>
  /etc/ssl/private/ r,
  /etc/ssl/private/* r,

  /etc/sasldb2 r,

  capability dac_override,
  capability net_bind_service,
  capability setgid,
  capability setuid,

  /etc/gai.conf r,
  /etc/hosts.allow r,
  /etc/hosts.deny r,

  # ldap files
  /opt/openldap/etc/openldap/** kr,
  /opt/openldap/etc/openldap/slapd.d/** rw,

  # kerberos/gssapi
  /dev/tty rw,
  /etc/gss/mech.d/   r,
  /etc/gss/mech.d/* kr,
  /etc/krb5.keytab kr,
  /opt/openldap/var/tmp/ rw,
  /opt/openldap/var/tmp/** rw,

  # the databases and logs
  /opt/openldap/var/openldap-data/ r,
  /opt/openldap/var/openldap-data/** rwk,

  # lock file
  /opt/openldap/lib/alock kw,

  # pid files and sockets
  /opt/openldap/var/run/* w,
  /opt/openldap/var/run/ldapi rw,
  /opt/openldap/var/run/socket rw,

  /opt/openldap/lib/ r,
  /opt/openldap/lib/* mr,

  /opt/openldap/libexec/slapd mr,

  # Site-specific additions and overrides. See local/README for details.
  # #include <local/opt.openldap.libexec.slapd>
}
==============================================================================

  And restart "apparmor" service ($ sudo service apparmor restart)

4) configure - Enable "meta" and "ldap" backend + specific environment
   settings and install it.

sudo mkdir -p /opt/openldap/ && \
./configure --enable-meta --enable-ldap --enable-spasswd \
  --prefix=/opt/openldap/ && \
echo "Configure OK" && \
make -j4 depend && echo "Make depend OK" && make -j4 && echo "Make OK" && \
su root -c 'make install' && echo "Install OK"


5) Create new group "ldap_mod" for example and change rights.

$ sudo useradd -rMU ldap_mod && \
  sudo touch /opt/openldap/var/run/slapd.pid \
             /opt/openldap/var/run/slapd.m.args && \
  sudo mkdir /opt/openldap/etc/openldap/slapd.d && \
  sudo chown -R ldap_mod /opt/openldap/ && \
  ls -l /opt/openldap/ && echo "All OK"


6) Create new service. Simply put following text to "/etc/init.d/ldap_mod"
==============================================================================
#!/bin/sh
### BEGIN INIT INFO
# Provides:          slapd
# Required-Start:    $remote_fs $network $syslog
# Required-Stop:     $remote_fs $network $syslog
# Default-Start:     2 3 4 5
# Default-Stop:      0 1 6
# Short-Description: OpenLDAP standalone server (Lightweight Directory Access Protocol)
### END INIT INFO

# Specify path variable
PATH=/opt/openldap/bin:/opt/openldap/libexec:/opt/openldap/sbin:/bin/:/usr/bin/:/sbin/

. /lib/lsb/init-functions

# Kill me on all errors
set -e

# Set the paths to slapd as a variable so that someone who really
# wants to can override the path in /etc/default/slapd.
SLAPD=/opt/openldap/libexec/slapd

# Stop processing if slapd is not there
[ -x $SLAPD ] || exit 0

# debconf may have this file descriptor open and it makes things work a bit
# more reliably if we redirect it as a matter of course.  db_stop will take
# care of this, but this won't hurt.
exec 3>/dev/null

# Source the init script configuration
#if [ -f "/etc/default/slapd" ]; then
#       . /etc/default/slapd
#fi
# Instead of file, define it here.
#SLAPD_CONF="/opt/openldap/etc/openldap/slapd.conf"
SLAPD_CONF="/opt/openldap/etc/openldap/slapd.d"
SLAPD_USER="ldap_mod"
SLAPD_GROUP="ldap_mod"
SLAPD_PIDFILE="/opt/openldap/var/run/slapd.pid" # Check ldap.conf
SLAPD_SERVICES="ldap:/// ldapi:///"

# Additional options to pass to slapd
#SLAPD_OPTIONS=" -d 0xFFFFFFFF -s 7"
SLAPD_OPTIONS=" "



# Load the default location of the slapd config file
if [ -z "$SLAPD_CONF" ]; then
        if [ -e /opt/openldap/etc/openldap/slapd.d ]; then
                SLAPD_CONF=/opt/openldap/etc/openldap/slapd.d
        else
                SLAPD_CONF=/opt/openldap/etc/openldap/slapd.conf
        fi
fi

# Stop processing if the config file is not there
if [ ! -r "$SLAPD_CONF" ]; then
  log_warning_msg "No configuration file was found for slapd at $SLAPD_CONF."
  # if there is no config at all, we should assume slapd is not running
  # and exit 0 on stop so that unconfigured packages can be removed.
  [ "x$1" = xstop ] && exit 0 || exit 1
fi

# extend options depending on config type
if [ -f "$SLAPD_CONF" ]; then
        SLAPD_OPTIONS="-f $SLAPD_CONF $SLAPD_OPTIONS"
elif [ -d "$SLAPD_CONF" ] ; then
        SLAPD_OPTIONS="-F $SLAPD_CONF $SLAPD_OPTIONS"
fi

# Find out the name of slapd's pid file
if [ -z "$SLAPD_PIDFILE" ]; then
        # If using old one-file configuration scheme
        if [ -f "$SLAPD_CONF" ] ; then
                SLAPD_PIDFILE=`sed -ne 's/^pidfile[[:space:]]\+\(.\+\)/\1/p' \
                        "$SLAPD_CONF"`
        # Else, if using new directory configuration scheme
        elif [ -d "$SLAPD_CONF" ] ; then
                SLAPD_PIDFILE=`sed -ne \
                        's/^olcPidFile:[[:space:]]\+\(.\+\)[[:space:]]*/\1/p' \
                        "$SLAPD_CONF"/'cn=config.ldif'`
        fi
fi

# XXX: Breaks upgrading if there is no pidfile (invoke-rc.d stop will fail)
# -- Torsten
if [ -z "$SLAPD_PIDFILE" ]; then
        log_failure_msg "The pidfile for slapd has not been specified"
        exit 1
fi

# Make sure the pidfile directory exists with correct permissions
piddir=`dirname "$SLAPD_PIDFILE"`
if [ ! -d "$piddir" ]; then
        mkdir -p "$piddir"
        [ -z "$SLAPD_USER" ] || chown -R "$SLAPD_USER" "$piddir"
        [ -z "$SLAPD_GROUP" ] || chgrp -R "$SLAPD_GROUP" "$piddir"
fi

# Pass the user and group to run under to slapd
if [ "$SLAPD_USER" ]; then
        SLAPD_OPTIONS="-u $SLAPD_USER $SLAPD_OPTIONS"
fi

if [ "$SLAPD_GROUP" ]; then
        SLAPD_OPTIONS="-g $SLAPD_GROUP $SLAPD_OPTIONS"
fi

# Check whether we were configured to not start the services.
check_for_no_start() {
        if [ -n "$SLAPD_NO_START" ]; then
                echo 'Not starting slapd: SLAPD_NO_START set in /etc/default/slapd' >&2
                exit 0
        fi
        if [ -n "$SLAPD_SENTINEL_FILE" ] && [ -e "$SLAPD_SENTINEL_FILE" ]; then
                echo "Not starting slapd: $SLAPD_SENTINEL_FILE exists" >&2
                exit 0
        fi
}

# Tell the user that something went wrong and give some hints for
# resolving the problem.
report_failure() {
        log_end_msg 1
        if [ -n "$reason" ]; then
                log_failure_msg "$reason"
        else
                log_failure_msg "The operation failed but no output was produced."

                if [ -n "$SLAPD_OPTIONS" -o \
                     -n "$SLAPD_SERVICES" ]; then
                        if [ -z "$SLAPD_SERVICES" ]; then
                                if [ -n "$SLAPD_OPTIONS" ]; then
                                        log_failure_msg "Command line used: slapd $SLAPD_OPTIONS"
                                fi
                        else
                                log_failure_msg "Command line used: slapd -h '$SLAPD_SERVICES' $SLAPD_OPTIONS"
                        fi
                fi
        fi
}

# Start the slapd daemon and capture the error message if any to
# $reason.
start_slapd() {
        if [ -z "$SLAPD_SERVICES" ]; then
                echo "Running command: "$SLAPD" "$SLAPD_OPTIONS""
                reason="`start-stop-daemon --start --verbose --oknodo \
                        --pidfile "$SLAPD_PIDFILE" \
                        --exec $SLAPD -- $SLAPD_OPTIONS 2>&1`"
        else
                echo "Running command: "$SLAPD" -h '"$SLAPD_SERVICES"' "$SLAPD_OPTIONS""
                reason="`start-stop-daemon --start --verbose --oknodo \
                        --pidfile "$SLAPD_PIDFILE" \
                        --exec $SLAPD -- -h "$SLAPD_SERVICES" $SLAPD_OPTIONS 2>&1`"
        fi

        echo "$reason"

        # Backward compatibility with OpenLDAP 2.1 client libraries.
        #if [ ! -h /var/run/ldapi ] && [ ! -e /var/run/ldapi ] ; then
        #       ln -s slapd/ldapi /var/run/ldapi
        #fi
}

# Stop the slapd daemon and capture the error message (if any) to
# $reason.
stop_slapd() {
        reason="`start-stop-daemon --stop --quiet --oknodo --retry TERM/10 \
                --pidfile "$SLAPD_PIDFILE" \
                --exec $SLAPD 2>&1`"
}

# Start the OpenLDAP daemons
start_ldap() {
        trap 'report_failure' 0
        log_daemon_msg "Starting OpenLDAP (custom)" "slapd"
        start_slapd
        trap "-" 0
        log_end_msg 0
}

# Stop the OpenLDAP daemons
stop_ldap() {
        trap 'report_failure' 0
        log_daemon_msg "Stopping OpenLDAP (custom)" "slapd"
        stop_slapd
        trap "-" 0
        log_end_msg 0
}

case "$1" in
  start)
        check_for_no_start
        start_ldap ;;
  stop)
        stop_ldap ;;
  restart|force-reload)
        check_for_no_start
        stop_ldap
        start_ldap
        ;;
  status)
        status_of_proc -p $SLAPD_PIDFILE $SLAPD slapd
        ;;
  *)
        echo "Usage: $0 {start|stop|restart|force-reload|status}"
        exit 1
        ;;
esac
==============================================================================


9) Create old-style slapd-meta_test.conf for example at your home directory.
   At sources is slapd-meta.conf, which can be your reference. Replace
   variables @SOMETHING@ with real data. There is my example which I save to
   my home directory:
==============================================================================
# master slapd config -- for testing
# $OpenLDAP$
## This work is part of OpenLDAP Software <http://www.openldap.org/>.
##
## Copyright 1998-2016 The OpenLDAP Foundation.
## 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 the file LICENSE in the
## top-level directory of the distribution or, alternatively, at
## <http://www.OpenLDAP.org/license.html>.

include        ./servers/slapd/schema/core.schema
include        ./servers/slapd/schema//cosine.schema
include        ./servers/slapd/schema/inetorgperson.schema
include        ./servers/slapd/schema/openldap.schema
include        ./servers/slapd/schema/nis.schema
include        ./servers/slapd/schema/ppolicy.schema
pidfile         /opt/openldap/var/run/slapd.pid
argsfile        /opt/openldap/var/run/slapd.m.args

#ldapmod#modulepath ../servers/slapd/back-ldap/
#ldapmod#moduleload back_ldap.la
#metamod#modulepath ../servers/slapd/back-meta/
#metamod#moduleload back_meta.la
#monitormod#modulepath ../servers/slapd/back-monitor/
#monitormod#moduleload back_monitor.la

# seems to improve behavior under very heavy load
# (i.e. it alleviates load on target systems)
threads        8

#######################################################################
# database definitions
#######################################################################

database    meta
suffix        "dc=company,dc=com"
rootdn        "cn=binder,dc=company,dc=com"
rootpw        bind
chase-referrals    yes
#nretries    forever
nretries    100
# 1 sec timeout for binds
bind-timeout    1000000
#norefs        true

# remote1
uri        "ldap://somewhere.eu:389/ou=cz,dc=company,dc=com"
#  ubtree-exclude "ou=Excluded,ou=Meta,o=Example,c=US"
suffixmassage    "ou=cz,dc=company,dc=com" "dc=cz,dc=company,dc=eu"
###pseudorootdn    "cn=manager,ou=meta,dc=example,dc=com"
###pseudorootpw    secret
idassert-bind    bindmethod=simple
        binddn="cn=binder for CZ,dc=cz,dc=company,dc=eu"
        credentials="binders's secret password"
        mode=none
        flags=non-prescriptive
#idassert-authzFrom    "dn.exact:cn=Manager,o=Local"

# remote2
uri        "ldap://somewhere.else.eu:389/ou=de,dc=company,dc=com"
#subtree-include "dn.subtree:o=Example,c=US"
suffixmassage    "ou=de,dc=company,dc=com" "dc=company,dc=eu"
###pseudorootdn    "cn=manager,dc=example,dc=com"
###pseudorootpw    secret
idassert-bind    bindmethod=simple
                binddn="cn=binder for DE,dc=de,dc=company,dc=eu"
                credentials="binders's secret password2"
        mode=none
        flags=non-prescriptive
#idassert-authzFrom    "dn.exact:cn=Manager,o=Local"

#limits        dn.exact="cn=Bjorn Jensen,ou=Information Technology Division,ou=People,o=Example,c=US" time=1 size=8

# This is only for binding as the rootdn
#database    meta
#suffix        "o=Local"
#rootdn        "cn=Manager,o=Local"
#rootpw        secret
#uri        "ldap://127.3.3.3:389/o=Local"

#monitor#database    monitor

==============================================================================


7) Create new (void) directory:
   $ mkdir -p /tmp/slapd.d
   
8) Move/stay in directory with LDAP sources (so your modified paths will
   work) and convert old style-syntax to new one:

$ rm -rf /tmp/slapd.d/* && \
  sudo touch /opt/openldap/var/run/slapd.pid \
             /opt/openldap/var/run/slapd.m.args && \
  ./servers/slapd/slaptest -f ~/slapd-meta_test.conf -F /tmp/slapd.d/ && \
  echo "Conversion OK"
   
9) If conversion is OK, copy database to slapd.d
 
$ sudo rm -rf /opt/openldap/etc/openldap/slapd.d/* && \
  sudo cp -r /tmp/slapd.d/* /opt/openldap/etc/openldap/slapd.d/ && \
  sudo chmod 700 /opt/openldap/etc/openldap/slapd.d/ && \
  sudo chown -R ldap_mod:ldap_mod /opt/openldap/ && \
  echo "All right"
 
7) Update rc.d. This should be problem-less. Run it only once. It is enough.

$ sudo update-rc.d ldap_mod defaults && \
  sudo update-rc.d ldap_mod enable && echo "All OK"

 
8) Try to run service. If it fails, you need to find out reason. Good start
   might be /var/log/syslog.

$ sudo service ldap_mod restart && echo OK


##############################################################################

I know that configuration files could be more flexible thanks to variables,
but I wanted to keep it simple. Hopefully it will help someone and save some
time.

Thanks again for great support!

Best regards
  Martin Stejskal


From: openldap-technical <openldap-technical-bounces@openldap.org> on behalf of Martin Stejskal <mstejskal@alps.cz>
Sent: 13 January 2017 10:24:42
To: Michael Ströder; openldap-technical@openldap.org
Subject: Re: slapd-meta with olc
 
This sender failed our fraud detection checks and may not be who they appear to be. Learn about spoofing Feedback


Hi Michael, Quannah and Howard,

 thanks for great support.

 I've some progress, but I did not solved/tested problem yet (working on it). So I'll summarize my progress:


First of all, at Ubuntu 16 (and probably others as well) LDAP binary is compiled without "meta" support -> that caused some strange errors when I was trying for conversion -> need to build LDAP server from sources and install it on target system.

As reference I used "slapd-meta.conf" from sources. But there was some variables, which I had to change. For example I changed "@BACKEND@" to "./servers/slapd/schema/", "@URI@" to "ldap://127.0.0.1:389/" and so on.

Then convert command was successful:

$ slaptest -f ~/slapd-meta_test.conf -F /tmp/slapd.d/


If there will be some problem, I'll let you know. Also in case I'll run it successfully. I'll post manual as well.


Best regards

  Martin Stejskal





From: Michael Ströder <michael@stroeder.com>
Sent: 13 January 2017 10:03:49
To: Martin Stejskal; openldap-technical@openldap.org
Subject: Re: slapd-meta with olc
 
Martin Stejskal wrote:
> I know there is slapd.conf to cn=config converter, but unfortunately I was not
> able to make it work (errors during conversion).

Could you please elaborate on that ideally with a slapd.conf for which the
conversion fails?

CIao, Michael.