فهرست منبع

Merge branch 'hotfix-1.1.9' into stable

Bertrand Gouny 8 سال پیش
والد
کامیت
aee872140c

+ 7 - 0
CHANGELOG.md

@@ -1,5 +1,12 @@
 # Changelog
 
+## 1.1.9
+Add :
+  - LDAP_RFC2307BIS_SCHEMA option to use rfc2307bis schema instead of nis default schema
+  - KEEP_EXISTING_CONFIG option to not change the ldap config
+
+Update to light-baseimage:1.1.0 (debian stretch)
+
 ## 1.1.8
 Fix :
   - LDAP_ENFORCE_TLS is not working correctly #107

+ 14 - 9
Makefile

@@ -1,9 +1,7 @@
 NAME = osixia/openldap
-VERSION = 1.1.8
+VERSION = 1.1.9
 
-.PHONY: all build build-nocache test tag_latest release
-
-all: build
+.PHONY: build build-nocache test tag-latest push push-latest release git-tag-version
 
 build:
 	docker build -t $(NAME):$(VERSION) --rm image
@@ -14,10 +12,17 @@ build-nocache:
 test:
 	env NAME=$(NAME) VERSION=$(VERSION) bats test/test.bats
 
-tag_latest:
+tag-latest:
 	docker tag $(NAME):$(VERSION) $(NAME):latest
 
-release: build test tag_latest
-	@if ! docker images $(NAME) | awk '{ print $$2 }' | grep -q -F $(VERSION); then echo "$(NAME) version $(VERSION) is not yet built. Please run 'make build'"; false; fi
-	docker push $(NAME)
-	@echo "*** Don't forget to run 'twgit release/hotfix finish' :)"
+push:
+	docker push $(NAME):$(VERSION)
+
+push-latest:
+	docker push $(NAME):latest
+
+release: build test tag-latest push push-latest
+
+git-tag-version: release
+	git tag -a v$(VERSION) -m "v$(VERSION)"
+	git push origin v$(VERSION)

+ 51 - 24
README.md

@@ -4,14 +4,10 @@
 ![Docker Stars](https://img.shields.io/docker/stars/osixia/openldap.svg)
 ![](https://images.microbadger.com/badges/image/osixia/openldap.svg)
 
-Latest release: 1.1.8 - OpenLDAP 2.4.40 -  [Changelog](CHANGELOG.md) | [Docker Hub](https://hub.docker.com/r/osixia/openldap/) 
+Latest release: 1.1.9 - OpenLDAP 2.4.44 -  [Changelog](CHANGELOG.md) | [Docker Hub](https://hub.docker.com/r/osixia/openldap/) 
 
 **A docker image to run OpenLDAP.**
 
-Note:
- - In the release 1.1.6 files `*.yaml.startup` have been renamed to `*.startup.yaml`
- - Due to issues #44 and #73 versions before 1.1.6 are not considered as stable and tags will be removed from docker hub.
-
 > OpenLDAP website : [www.openldap.org](http://www.openldap.org/)
 
 - [Contributing](#contributing)
@@ -38,7 +34,7 @@ Note:
 		- [Link environment file](#link-environment-file)
 		- [Make your own image or extend this image](#make-your-own-image-or-extend-this-image)
 - [Advanced User Guide](#advanced-user-guide)
-	- [Extend osixia/openldap:1.1.8 image](#extend-osixiaopenldap118-image)
+	- [Extend osixia/openldap:1.1.9 image](#extend-osixiaopenldap119-image)
 	- [Make your own openldap image](#make-your-own-openldap-image)
 	- [Tests](#tests)
 	- [Kubernetes](#kubernetes)
@@ -56,7 +52,7 @@ If you find this image useful here's how you can help:
 ## Quick Start
 Run OpenLDAP docker image:
 
-	docker run --name my-openldap-container --detach osixia/openldap:1.1.8
+	docker run --name my-openldap-container --detach osixia/openldap:1.1.9
 
 This start a new container with OpenLDAP running inside. Let's make the first search in our LDAP container:
 
@@ -92,7 +88,7 @@ It will create an empty ldap for the company **Example Inc.** and the domain **e
 By default the admin has the password **admin**. All those default settings can be changed at the docker command line, for example:
 
 	docker run --env LDAP_ORGANISATION="My Company" --env LDAP_DOMAIN="my-company.com" \
-	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.1.8
+	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.1.9
 
 #### Data persistence
 
@@ -108,6 +104,31 @@ For more information about docker data volume, please refer to:
 
 Do not edit slapd.conf it's not used. To modify your server configuration use ldap utils: **ldapmodify / ldapadd / ldapdelete**
 
+#### Seed ldap database with ldif
+
+This image can load ldif files at startup with either `ldapadd` or `ldapmodify`.
+Mount `.ldif` in `/container/service/slapd/assets/config/bootstrap/ldif` directory if you want to overwrite image default boostrap ldif files or in `/container/service/slapd/assets/config/bootstrap/ldif/custom` (recommended) to extend image config.
+
+Files containing `changeType:` attributes will be loaded with `ldapmodify`.
+
+The startup script provide some substitution in bootstrap ldif files:
+`{{LDAP_BASE_DN }}` and `{{ LDAP_BACKEND }}` values are supported. Other `{{ * }}`
+substitution are left as is.
+
+Since startup script modifies `ldif` files, you **must** add `--copy-service`
+argument to entrypoint if you don't want to overwrite them.
+
+
+		# single file example:
+		docker run \
+      --volume ./bootstrap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/50-bootstrap.ldif \
+      osixia/openldap:1.1.9 --copy-service
+
+		#directory example:
+		docker run \
+	     --volume ./lidf:/container/service/slapd/assets/config/bootstrap/ldif/custom \
+	     osixia/openldap:1.1.9 --copy-service
+
 ### Use an existing ldap database
 
 This can be achieved by mounting host directories as volume.
@@ -117,7 +138,7 @@ simply mount this directories as a volume to `/var/lib/ldap` and `/etc/ldap/slap
 
 	docker run --volume /data/slapd/database:/var/lib/ldap \
 	--volume /data/slapd/config:/etc/ldap/slapd.d
-	--detach osixia/openldap:1.1.8
+	--detach osixia/openldap:1.1.9
 
 You can also use data volume containers. Please refer to:
 > [https://docs.docker.com/engine/tutorials/dockervolumes/](https://docs.docker.com/engine/tutorials/dockervolumes/)
@@ -137,7 +158,7 @@ If you are looking for a simple solution to administrate your ldap server you ca
 #### Use auto-generated certificate
 By default, TLS is already configured and enabled, certificate is created using container hostname (it can be set by docker run --hostname option eg: ldap.example.org).
 
-	docker run --hostname ldap.my-company.com --detach osixia/openldap:1.1.8
+	docker run --hostname ldap.my-company.com --detach osixia/openldap:1.1.9
 
 #### Use your own certificate
 
@@ -147,24 +168,24 @@ You can set your custom certificate at run time, by mounting a directory contain
 	--env LDAP_TLS_CRT_FILENAME=my-ldap.crt \
 	--env LDAP_TLS_KEY_FILENAME=my-ldap.key \
 	--env LDAP_TLS_CA_CRT_FILENAME=the-ca.crt \
-	--detach osixia/openldap:1.1.8
+	--detach osixia/openldap:1.1.9
 
 Other solutions are available please refer to the [Advanced User Guide](#advanced-user-guide)
 
 #### Disable TLS
 Add --env LDAP_TLS=false to the run command:
 
-	docker run --env LDAP_TLS=false --detach osixia/openldap:1.1.8
+	docker run --env LDAP_TLS=false --detach osixia/openldap:1.1.9
 
 ### Multi master replication
 Quick example, with the default config.
 
 	#Create the first ldap server, save the container id in LDAP_CID and get its IP:
-	LDAP_CID=$(docker run --hostname ldap.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.1.8)
+	LDAP_CID=$(docker run --hostname ldap.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.1.9)
 	LDAP_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $LDAP_CID)
 
 	#Create the second ldap server, save the container id in LDAP2_CID and get its IP:
-	LDAP2_CID=$(docker run --hostname ldap2.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.1.8)
+	LDAP2_CID=$(docker run --hostname ldap2.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.1.9)
 	LDAP2_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $LDAP2_CID)
 
 	#Add the pair "ip hostname" to /etc/hosts on each containers,
@@ -200,7 +221,7 @@ You may have some problems with mounted files on some systems. The startup scrip
 
 To fix that run the container with `--copy-service` argument :
 
-		docker run [your options] osixia/openldap:1.1.8 --copy-service
+		docker run [your options] osixia/openldap:1.1.9 --copy-service
 
 ### Debug
 
@@ -209,11 +230,11 @@ Available levels are: `none`, `error`, `warning`, `info`, `debug` and `trace`.
 
 Example command to run the container in `debug` mode:
 
-	docker run --detach osixia/openldap:1.1.8 --loglevel debug
+	docker run --detach osixia/openldap:1.1.9 --loglevel debug
 
 See all command line options:
 
-	docker run osixia/openldap:1.1.8 --help
+	docker run osixia/openldap:1.1.9 --help
 
 
 ## Environment Variables
@@ -245,6 +266,8 @@ Required and used for new ldap server only:
 - **LDAP_READONLY_USER_USERNAME** Read only user username. Defaults to `readonly`
 - **LDAP_READONLY_USER_PASSWORD** Read only user password. Defaults to `readonly`
 
+- **LDAP_RFC2307BIS_SCHEMA** Use rfc2307bis schema instead of nis schema. Defaults to `false`
+
 Backend:
 - **LDAP_BACKEND**: Ldap backend. Defaults to `hdb` (In comming versions v1.2.x default will be mdb)
 
@@ -276,11 +299,15 @@ Replication options:
 
 	If you want to set this variable at docker run command add the tag `#PYTHON2BASH:` and convert the yaml in python:
 
-		docker run --env LDAP_REPLICATION_HOSTS="#PYTHON2BASH:['ldap://ldap.example.org','ldap://ldap2.example.org']" --detach osixia/openldap:1.1.8
+		docker run --env LDAP_REPLICATION_HOSTS="#PYTHON2BASH:['ldap://ldap.example.org','ldap://ldap2.example.org']" --detach osixia/openldap:1.1.9
 
 	To convert yaml to python online: http://yaml-online-parser.appspot.com/
 
 Other environment variables:
+- **KEEP_EXISTING_CONFIG**: Do not change the ldap config. Defaults to `false`
+	- if set to *true* with an existing database, config will remain unchanged. Image tls and replication config will not be run. The container can be started with LDAP_ADMIN_PASSWORD and LDAP_CONFIG_PASSWORD empty or filled with fake data.
+	- if set to *true* when bootstrapping a new database, bootstap ldif and schema will not be added and tls and replication config will not be run.
+
 - **LDAP_REMOVE_CONFIG_AFTER_SETUP**: delete config folder after setup. Defaults to `true`
 - **LDAP_SSL_HELPER_PREFIX**: ssl-helper environment variables prefix. Defaults to `ldap`, ssl-helper first search config from LDAP_SSL_HELPER_* variables, before SSL_HELPER_* variables.
 
@@ -291,7 +318,7 @@ Other environment variables:
 Environment variables can be set by adding the --env argument in the command line, for example:
 
 	docker run --env LDAP_ORGANISATION="My company" --env LDAP_DOMAIN="my-company.com" \
-	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.1.8
+	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.1.9
 
 Be aware that environment variable added in command line will be available at any time
 in the container. In this example if someone manage to open a terminal in this container
@@ -302,14 +329,14 @@ he will be able to read the admin password in clear text from environment variab
 For example if your environment files **my-env.yaml** and **my-env.startup.yaml** are in /data/ldap/environment
 
 	docker run --volume /data/ldap/environment:/container/environment/01-custom \
-	--detach osixia/openldap:1.1.8
+	--detach osixia/openldap:1.1.9
 
 Take care to link your environment files folder to `/container/environment/XX-somedir` (with XX < 99 so they will be processed before default environment files) and not  directly to `/container/environment` because this directory contains predefined baseimage environment files to fix container environment (INITRD, LANG, LANGUAGE and LC_CTYPE).
 
 Note: the container will try to delete the **\*.startup.yaml** file after the end of startup files so the file will also be deleted on the docker host. To prevent that : use --volume /data/ldap/environment:/container/environment/01-custom**:ro** or set all variables in **\*.yaml** file and don't use **\*.startup.yaml**:
 
 	docker run --volume /data/ldap/environment/my-env.yaml:/container/environment/01-custom/env.yaml \
-	--detach osixia/openldap:1.1.8
+	--detach osixia/openldap:1.1.9
 
 #### Make your own image or extend this image
 
@@ -317,13 +344,13 @@ This is the best solution if you have a private registry. Please refer to the [A
 
 ## Advanced User Guide
 
-### Extend osixia/openldap:1.1.8 image
+### Extend osixia/openldap:1.1.9 image
 
 If you need to add your custom TLS certificate, bootstrap config or environment files the easiest way is to extends this image.
 
 Dockerfile example:
 
-	FROM osixia/openldap:1.1.8
+	FROM osixia/openldap:1.1.9
 	MAINTAINER Your Name <[email protected]>
 
 	ADD bootstrap /container/service/slapd/assets/config/bootstrap
@@ -345,7 +372,7 @@ Clone this project:
 Adapt Makefile, set your image NAME and VERSION, for example:
 
 	NAME = osixia/openldap
-	VERSION = 1.1.8
+	VERSION = 1.1.9
 
 	become:
 	NAME = cool-guy/openldap

+ 4 - 1
example/docker-compose.yml

@@ -1,7 +1,7 @@
 version: '2'
 services:
   openldap:
-    image: osixia/openldap:1.1.8
+    image: osixia/openldap:1.1.9
     container_name: openldap
     environment:
       LDAP_LOG_LEVEL: "256"
@@ -13,6 +13,7 @@ services:
       LDAP_READONLY_USER: "false"
       #LDAP_READONLY_USER_USERNAME: "readonly"
       #LDAP_READONLY_USER_PASSWORD: "readonly"
+      LDAP_RFC2307BIS_SCHEMA: "false"
       LDAP_BACKEND: "hdb"
       LDAP_TLS: "true"
       LDAP_TLS_CRT_FILENAME: "ldap.crt"
@@ -26,6 +27,7 @@ services:
       #LDAP_REPLICATION_CONFIG_SYNCPROV: "binddn="cn=admin,cn=config" bindmethod=simple credentials=$LDAP_CONFIG_PASSWORD searchbase="cn=config" type=refreshAndPersist retry="60 +" timeout=1 starttls=critical"
       #LDAP_REPLICATION_DB_SYNCPROV: "binddn="cn=admin,$LDAP_BASE_DN" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase="$LDAP_BASE_DN" type=refreshAndPersist interval=00:00:00:10 retry="60 +" timeout=1 starttls=critical"
       #LDAP_REPLICATION_HOSTS: "#PYTHON2BASH:['ldap://ldap.example.org','ldap://ldap2.example.org']"
+      KEEP_EXISTING_CONFIG: "false"
       LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
       LDAP_SSL_HELPER_PREFIX: "ldap"
     tty: true
@@ -37,6 +39,7 @@ services:
     ports:
       - "389:389"
       - "636:636"
+    domainname: "example.org" # important: same as hostname
     hostname: "example.org"
   phpldapadmin:
     image: osixia/phpldapadmin:latest

+ 1 - 1
example/extend-osixia-openldap/Dockerfile

@@ -1,4 +1,4 @@
-FROM osixia/openldap:1.1.8
+FROM osixia/openldap:1.1.9
 MAINTAINER Your Name <[email protected]>
 
 ADD bootstrap /container/service/slapd/assets/config/bootstrap

+ 5 - 1
example/kubernetes/simple/ldap-deployment.yaml

@@ -13,7 +13,7 @@ spec:
     spec:
       containers:
         - name: ldap
-          image: osixia/openldap:1.1.8
+          image: osixia/openldap:1.1.9
           volumeMounts:
             - name: ldap-data
               mountPath: /var/lib/ldap
@@ -41,6 +41,8 @@ spec:
               value: "readonly"
             - name: LDAP_READONLY_USER_PASSWORD
               value: "readonly"
+            - name: LDAP_RFC2307BIS_SCHEMA
+              value: "false"
             - name: LDAP_BACKEND
               value: "hdb"
             - name: LDAP_TLS
@@ -65,6 +67,8 @@ spec:
               value: "binddn=\"cn=admin,$LDAP_BASE_DN\" bindmethod=simple credentials=$LDAP_ADMIN_PASSWORD searchbase=\"$LDAP_BASE_DN\" type=refreshAndPersist interval=00:00:00:10 retry=\"60 +\" timeout=1 starttls=critical"
             - name: LDAP_REPLICATION_HOSTS
               value: "#PYTHON2BASH:['ldap://ldap-one-service', 'ldap://ldap-two-service']"
+            - name: KEEP_EXISTING_CONFIG
+              value: "false"
             - name: LDAP_REMOVE_CONFIG_AFTER_SETUP
               value: "true"
             - name: LDAP_SSL_HELPER_PREFIX

+ 8 - 0
example/kubernetes/using-secrets/environment/my-env.startup.yaml

@@ -18,6 +18,8 @@ LDAP_READONLY_USER: false
 LDAP_READONLY_USER_USERNAME: readonly
 LDAP_READONLY_USER_PASSWORD: readonly
 
+LDAP_RFC2307BIS_SCHEMA: false
+
 # Backend
 LDAP_BACKEND: hdb
 
@@ -46,6 +48,12 @@ LDAP_REPLICATION_HOSTS:
   - ldap://ldap2.example.org
 
 
+# Do not change the ldap config
+# - If set to true with an existing database, config will remain unchanged. Image tls and replication config will not be run.
+#   The container can be started with LDAP_ADMIN_PASSWORD and LDAP_CONFIG_PASSWORD empty or filled with fake data.
+# - If set to true when bootstrapping a new database, bootstap ldif and schema will not be added and tls and replication config will not be run.
+KEEP_EXISTING_CONFIG: false
+
 # Remove config after setup
 LDAP_REMOVE_CONFIG_AFTER_SETUP: true
 

+ 1 - 1
example/kubernetes/using-secrets/ldap-deployment.yaml

@@ -13,7 +13,7 @@ spec:
     spec:
       containers:
         - name: ldap
-          image: osixia/openldap:1.1.8
+          image: osixia/openldap:1.1.9
           args: ["--copy-service"]
           volumeMounts:
             - name: ldap-data

+ 8 - 2
image/Dockerfile

@@ -1,6 +1,6 @@
 # Use osixia/light-baseimage
 # sources: https://github.com/osixia/docker-light-baseimage
-FROM osixia/light-baseimage:0.2.6
+FROM osixia/light-baseimage:1.1.0
 MAINTAINER Bertrand Gouny <[email protected]>
 
 # Add openldap user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
@@ -11,8 +11,14 @@ RUN groupadd -r openldap && useradd -r -g openldap openldap
 #          https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/download.sh
 RUN apt-get -y update \
     && /container/tool/add-service-available :ssl-tools \
-	  && LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes --no-install-recommends \
+	  && LC_ALL=C DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
        ldap-utils \
+       libsasl2-modules \
+       libsasl2-modules-db \
+       libsasl2-modules-gssapi-mit \
+       libsasl2-modules-ldap \
+       libsasl2-modules-otp \
+       libsasl2-modules-sql \
        openssl \
        slapd \
     && apt-get clean \

+ 7 - 0
image/environment/default.startup.yaml

@@ -18,6 +18,8 @@ LDAP_READONLY_USER: false
 LDAP_READONLY_USER_USERNAME: readonly
 LDAP_READONLY_USER_PASSWORD: readonly
 
+LDAP_RFC2307BIS_SCHEMA: false
+
 # Backend
 LDAP_BACKEND: hdb
 
@@ -45,6 +47,11 @@ LDAP_REPLICATION_HOSTS:
   - ldap://ldap.example.org # The order must be the same on all ldap servers
   - ldap://ldap2.example.org
 
+# Do not change the ldap config
+# - If set to true with an existing database, config will remain unchanged. Image tls and replication config will not be run.
+#   The container can be started with LDAP_ADMIN_PASSWORD and LDAP_CONFIG_PASSWORD empty or filled with fake data.
+# - If set to true when bootstrapping a new database, bootstap ldif and schema will not be added and tls and replication config will not be run.
+KEEP_EXISTING_CONFIG: false
 
 # Remove config after setup
 LDAP_REMOVE_CONFIG_AFTER_SETUP: true

+ 9 - 0
image/service/slapd/assets/config/bootstrap/ldif/custom/README.md

@@ -0,0 +1,9 @@
+Add your custom ldif files here if you don't want to overwrite image default boostrap ldif.
+at run time you can also mount a data volume with your ldif files to /container/service/slapd/assets/config/bootstrap/ldif/custom
+
+The startup script provide some substitution in bootstrap ldif files:
+`{{LDAP_BASE_DN }}` and `{{ LDAP_BACKEND }}` values are supported.
+Other `{{ * }}` substitution are left as is.
+
+Since startup script modifies `ldif` files,
+you **must** add `--copy-service` argument to entrypoint if you don't want to overwrite them.

+ 4 - 0
image/service/slapd/assets/config/bootstrap/schema/rfc2307bis.conf

@@ -0,0 +1,4 @@
+include         /etc/ldap/schema/core.schema
+include         /etc/ldap/schema/cosine.schema
+include         /etc/ldap/schema/inetorgperson.schema
+include         /etc/ldap/schema/rfc2307bis.schema

+ 158 - 0
image/service/slapd/assets/config/bootstrap/schema/rfc2307bis.ldif

@@ -0,0 +1,158 @@
+# AUTO-GENERATED FILE - DO NOT EDIT!! Use ldapmodify.
+# CRC32 6b6ad917
+dn: cn=rfc2307bis,cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: rfc2307bis
+olcAttributeTypes: {0}( 1.3.6.1.1.1.1.2 NAME 'gecos' DESC 'The GECOS field;
+ the common name' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE )
+olcAttributeTypes: {1}( 1.3.6.1.1.1.1.3 NAME 'homeDirectory' DESC 'The absol
+ ute path to the home directory' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4
+ .1.1466.115.121.1.26 SINGLE-VALUE )
+olcAttributeTypes: {2}( 1.3.6.1.1.1.1.4 NAME 'loginShell' DESC 'The path to
+ the login shell' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121
+ .1.26 SINGLE-VALUE )
+olcAttributeTypes: {3}( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange' EQUALITY int
+ egerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.2
+ 7 SINGLE-VALUE )
+olcAttributeTypes: {4}( 1.3.6.1.1.1.1.6 NAME 'shadowMin' EQUALITY integerMat
+ ch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGL
+ E-VALUE )
+olcAttributeTypes: {5}( 1.3.6.1.1.1.1.7 NAME 'shadowMax' EQUALITY integerMat
+ ch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGL
+ E-VALUE )
+olcAttributeTypes: {6}( 1.3.6.1.1.1.1.8 NAME 'shadowWarning' EQUALITY intege
+ rMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 S
+ INGLE-VALUE )
+olcAttributeTypes: {7}( 1.3.6.1.1.1.1.9 NAME 'shadowInactive' EQUALITY integ
+ erMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+ SINGLE-VALUE )
+olcAttributeTypes: {8}( 1.3.6.1.1.1.1.10 NAME 'shadowExpire' EQUALITY intege
+ rMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 S
+ INGLE-VALUE )
+olcAttributeTypes: {9}( 1.3.6.1.1.1.1.11 NAME 'shadowFlag' EQUALITY integerM
+ atch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SIN
+ GLE-VALUE )
+olcAttributeTypes: {10}( 1.3.6.1.1.1.1.12 NAME 'memberUid' EQUALITY caseExac
+ tMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+olcAttributeTypes: {11}( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup' EQUALITY
+ caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+olcAttributeTypes: {12}( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple' DESC 'Net
+ group triple' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYN
+ TAX 1.3.6.1.4.1.1466.115.121.1.15 )
+olcAttributeTypes: {13}( 1.3.6.1.1.1.1.15 NAME 'ipServicePort' DESC 'Service
+  port number' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.
+ 3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+olcAttributeTypes: {14}( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol' DESC 'Ser
+ vice protocol name' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.12
+ 1.1.15 )
+olcAttributeTypes: {15}( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber' DESC 'IP p
+ rotocol number' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX
+ 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE )
+olcAttributeTypes: {16}( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber' DESC 'ONC RPC
+ number' EQUALITY integerMatch ORDERING integerOrderingMatch SYNTAX 1.3.6.1.
+ 4.1.1466.115.121.1.27 SINGLE-VALUE )
+olcAttributeTypes: {17}( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber' DESC 'IPv4 add
+ resses as a dotted decimal omitting leading               zeros or IPv6 add
+ resses as defined in RFC2373' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.
+ 1.1466.115.121.1.26 )
+olcAttributeTypes: {18}( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber' DESC 'IP ne
+ twork omitting leading zeros, eg. 192.168' EQUALITY caseIgnoreIA5Match SYNT
+ AX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+olcAttributeTypes: {19}( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber' DESC 'IP ne
+ tmask omitting leading zeros, eg. 255.255.255.0' EQUALITY caseIgnoreIA5Matc
+ h SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE )
+olcAttributeTypes: {20}( 1.3.6.1.1.1.1.22 NAME 'macAddress' DESC 'MAC addres
+ s in maximal, colon separated hex               notation, eg. 00:00:92:90:e
+ e:e2' EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+olcAttributeTypes: {21}( 1.3.6.1.1.1.1.23 NAME 'bootParameter' DESC 'rpc.boo
+ tparamd parameter' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.1
+ 21.1.26 )
+olcAttributeTypes: {22}( 1.3.6.1.1.1.1.24 NAME 'bootFile' DESC 'Boot image n
+ ame' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+olcAttributeTypes: {23}( 1.3.6.1.1.1.1.26 NAME 'nisMapName' DESC 'Name of a
+ generic NIS map' EQUALITY caseIgnoreMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1
+ .15{64} )
+olcAttributeTypes: {24}( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry' DESC 'A generic
+  NIS entry' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{10
+ 24} SINGLE-VALUE )
+olcAttributeTypes: {25}( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey' DESC 'NIS publ
+ ic key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SING
+ LE-VALUE )
+olcAttributeTypes: {26}( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey' DESC 'NIS secr
+ et key' EQUALITY octetStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.40 SING
+ LE-VALUE )
+olcAttributeTypes: {27}( 1.3.6.1.1.1.1.30 NAME 'nisDomain' DESC 'NIS domain'
+  EQUALITY caseIgnoreIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+olcAttributeTypes: {28}( 1.3.6.1.1.1.1.31 NAME 'automountMapName' DESC 'auto
+ mount Map Name' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.1
+ 5 SINGLE-VALUE )
+olcAttributeTypes: {29}( 1.3.6.1.1.1.1.32 NAME 'automountKey' DESC 'Automoun
+ t Key value' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 S
+ INGLE-VALUE )
+olcAttributeTypes: {30}( 1.3.6.1.1.1.1.33 NAME 'automountInformation' DESC '
+ Automount information' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.
+ 121.1.15 SINGLE-VALUE )
+olcObjectClasses: {0}( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction
+  of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ u
+ idNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ ge
+ cos $ description ) )
+olcObjectClasses: {1}( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' DESC 'Additional
+  attributes for shadow passwords' SUP top AUXILIARY MUST uid MAY ( userPass
+ word $ description $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarni
+ ng $ shadowInactive $ shadowExpire $ shadowFlag ) )
+olcObjectClasses: {2}( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction o
+ f a group of accounts' SUP top AUXILIARY MUST gidNumber MAY ( userPassword
+ $ memberUid $ description ) )
+olcObjectClasses: {3}( 1.3.6.1.1.1.2.3 NAME 'ipService' DESC 'Abstraction an
+  Internet Protocol service.               Maps an IP port and protocol (suc
+ h as tcp or udp)               to one or more names; the distinguished valu
+ e of               the cn attribute denotes the services canonical
+       name' SUP top STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtoco
+ l ) MAY description )
+olcObjectClasses: {4}( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' DESC 'Abstraction o
+ f an IP protocol. Maps a protocol number               to one or more names
+ . The distinguished value of the cn               attribute denotes the pro
+ tocol canonical name' SUP top STRUCTURAL MUST ( cn $ ipProtocolNumber ) MAY
+  description )
+olcObjectClasses: {5}( 1.3.6.1.1.1.2.5 NAME 'oncRpc' DESC 'Abstraction of an
+  Open Network Computing (ONC)              [RFC1057] Remote Procedure Call
+ (RPC) binding.              This class maps an ONC RPC number to a name.
+            The distinguished value of the cn attribute denotes
+  the RPC service canonical name' SUP top STRUCTURAL MUST ( cn $ oncRpcNumbe
+ r ) MAY description )
+olcObjectClasses: {6}( 1.3.6.1.1.1.2.6 NAME 'ipHost' DESC 'Abstraction of a
+ host, an IP device. The distinguished               value of the cn attribu
+ te denotes the hosts canonical            name. Device SHOULD be used as a
+ structural class' SUP top AUXILIARY MUST ( cn $ ipHostNumber ) MAY ( userPa
+ ssword $ l $ description $ manager ) )
+olcObjectClasses: {7}( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Abstraction of
+  a network. The distinguished value of               the cn attribute denot
+ es the network canonical name' SUP top STRUCTURAL MUST ipNetworkNumber MAY
+ ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
+olcObjectClasses: {8}( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' DESC 'Abstraction
+ of a netgroup. May refer to other               netgroups' SUP top STRUCTUR
+ AL MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
+olcObjectClasses: {9}( 1.3.6.1.1.1.2.9 NAME 'nisMap' DESC 'A generic abstrac
+ tion of a NIS map' SUP top STRUCTURAL MUST nisMapName MAY description )
+olcObjectClasses: {10}( 1.3.6.1.1.1.2.10 NAME 'nisObject' DESC 'An entry in
+ a NIS map' SUP top STRUCTURAL MUST ( cn $ nisMapEntry $ nisMapName ) )
+olcObjectClasses: {11}( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' DESC 'A device
+  with a MAC address; device SHOULD be               used as a structural cl
+ ass' SUP top AUXILIARY MAY macAddress )
+olcObjectClasses: {12}( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' DESC 'A devic
+ e with boot parameters; device SHOULD be               used as a structural
+  class' SUP top AUXILIARY MAY ( bootFile $ bootParameter ) )
+olcObjectClasses: {13}( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' DESC 'An object
+  with a public and secret key' SUP top AUXILIARY MUST ( cn $ nisPublicKey $
+  nisSecretKey ) MAY ( uidNumber $ description ) )
+olcObjectClasses: {14}( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' DESC 'Associ
+ ates a NIS domain with a naming context' SUP top AUXILIARY MUST nisDomain )
+olcObjectClasses: {15}( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTU
+ RAL MUST automountMapName MAY description )
+olcObjectClasses: {16}( 1.3.6.1.1.1.2.17 NAME 'automount' DESC 'Automount in
+ formation' SUP top STRUCTURAL MUST ( automountKey $ automountInformation )
+ MAY description )
+olcObjectClasses: {17}( 1.3.6.1.1.1.2.18 NAME 'groupOfMembers' DESC 'A group
+  with members (DNs)' SUP top STRUCTURAL MUST cn MAY ( businessCategory $ se
+ eAlso $ owner $ ou $ o $ description $ member ) )

+ 385 - 0
image/service/slapd/assets/config/bootstrap/schema/rfc2307bis.schema

@@ -0,0 +1,385 @@
+#
+# rfc2307bis.schema
+#
+# Extracted from http://tools.ietf.org/id/draft-howard-rfc2307bis-02.txt
+# as of 2012/05/25, by Robin H. Johnson <[email protected]>
+# Found at http://dev.gentoo.org/~robbat2/distfiles/rfc2307bis.schema-20120525
+#
+# Changed so that OpenLDAP 2.4.39 is able to import the schema
+# on 2014/11/28 by Stijn Hoop <[email protected]>
+#
+#attributetype     ( 1.3.6.1.1.1.1.0 NAME 'uidNumber'
+#         DESC 'An integer uniquely identifying a user in an
+#               administrative domain'
+#         EQUALITY integerMatch
+#         ORDERING integerOrderingMatch
+#         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#         SINGLE-VALUE )
+#
+#
+#attributetype     ( 1.3.6.1.1.1.1.1 NAME 'gidNumber'
+#         DESC 'An integer uniquely identifying a group in an
+#               administrative domain'
+#         EQUALITY integerMatch
+#         ORDERING integerOrderingMatch
+#         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+#         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.2 NAME 'gecos'
+         DESC 'The GECOS field; the common name'
+         EQUALITY caseIgnoreMatch
+         SUBSTR caseIgnoreSubstringsMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.3 NAME 'homeDirectory'
+         DESC 'The absolute path to the home directory'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.4 NAME 'loginShell'
+         DESC 'The path to the login shell'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+         SINGLE-VALUE )
+
+attributetype     ( 1.3.6.1.1.1.1.5 NAME 'shadowLastChange'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.6 NAME 'shadowMin'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.7 NAME 'shadowMax'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.8 NAME 'shadowWarning'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.9 NAME 'shadowInactive'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.10 NAME 'shadowExpire'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.11 NAME 'shadowFlag'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+
+
+attributetype     ( 1.3.6.1.1.1.1.12 NAME 'memberUid'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.13 NAME 'memberNisNetgroup'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.14 NAME 'nisNetgroupTriple'
+         DESC 'Netgroup triple'
+         EQUALITY caseIgnoreMatch
+         SUBSTR caseIgnoreSubstringsMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.15 NAME 'ipServicePort'
+         DESC 'Service port number'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.16 NAME 'ipServiceProtocol'
+         DESC 'Service protocol name'
+         EQUALITY caseIgnoreMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.17 NAME 'ipProtocolNumber'
+         DESC 'IP protocol number'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.18 NAME 'oncRpcNumber'
+         DESC 'ONC RPC number'
+         EQUALITY integerMatch
+         ORDERING integerOrderingMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
+         SINGLE-VALUE )
+
+
+
+
+
+
+
+
+attributetype     ( 1.3.6.1.1.1.1.19 NAME 'ipHostNumber'
+         DESC 'IPv4 addresses as a dotted decimal omitting leading
+               zeros or IPv6 addresses as defined in RFC2373'
+         EQUALITY caseIgnoreIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.20 NAME 'ipNetworkNumber'
+         DESC 'IP network omitting leading zeros, eg. 192.168'
+         EQUALITY caseIgnoreIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.21 NAME 'ipNetmaskNumber'
+         DESC 'IP netmask omitting leading zeros, eg. 255.255.255.0'
+         EQUALITY caseIgnoreIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.22 NAME 'macAddress'
+         DESC 'MAC address in maximal, colon separated hex
+               notation, eg. 00:00:92:90:ee:e2'
+         EQUALITY caseIgnoreIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.23 NAME 'bootParameter'
+         DESC 'rpc.bootparamd parameter'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.24 NAME 'bootFile'
+         DESC 'Boot image name'
+         EQUALITY caseExactIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
+
+
+attributetype     ( 1.3.6.1.1.1.1.26 NAME 'nisMapName'
+         DESC 'Name of a generic NIS map'
+         EQUALITY caseIgnoreMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} )
+
+
+
+
+
+
+
+
+
+attributetype     ( 1.3.6.1.1.1.1.27 NAME 'nisMapEntry'
+         DESC 'A generic NIS entry'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.28 NAME 'nisPublicKey'
+         DESC 'NIS public key'
+         EQUALITY octetStringMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.29 NAME 'nisSecretKey'
+         DESC 'NIS secret key'
+         EQUALITY octetStringMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.30 NAME 'nisDomain'
+         DESC 'NIS domain'
+         EQUALITY caseIgnoreIA5Match
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+
+
+attributetype     ( 1.3.6.1.1.1.1.31 NAME 'automountMapName'
+         DESC 'automount Map Name'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.32 NAME 'automountKey'
+         DESC 'Automount Key value'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE )
+
+
+attributetype     ( 1.3.6.1.1.1.1.33 NAME 'automountInformation'
+         DESC 'Automount information'
+         EQUALITY caseExactMatch
+         SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+         SINGLE-VALUE )
+
+
+
+objectclass     ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
+         DESC 'Abstraction of an account with POSIX attributes'
+         MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory )
+         MAY ( userPassword $ loginShell $ gecos $
+               description ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' SUP top AUXILIARY
+         DESC 'Additional attributes for shadow passwords'
+         MUST uid
+         MAY ( userPassword $ description $
+               shadowLastChange $ shadowMin $ shadowMax $
+               shadowWarning $ shadowInactive $
+               shadowExpire $ shadowFlag ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' SUP top AUXILIARY
+         DESC 'Abstraction of a group of accounts'
+         MUST gidNumber
+         MAY ( userPassword $ memberUid $
+               description ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.3 NAME 'ipService' SUP top STRUCTURAL
+         DESC 'Abstraction an Internet Protocol service.
+               Maps an IP port and protocol (such as tcp or udp)
+               to one or more names; the distinguished value of
+               the cn attribute denotes the services canonical
+               name'
+         MUST ( cn $ ipServicePort $ ipServiceProtocol )
+         MAY description )
+
+
+objectclass     ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' SUP top STRUCTURAL
+         DESC 'Abstraction of an IP protocol. Maps a protocol number
+               to one or more names. The distinguished value of the cn
+               attribute denotes the protocol canonical name'
+         MUST ( cn $ ipProtocolNumber )
+         MAY description )
+
+
+
+
+
+objectclass     ( 1.3.6.1.1.1.2.5 NAME 'oncRpc' SUP top STRUCTURAL
+         DESC 'Abstraction of an Open Network Computing (ONC)
+              [RFC1057] Remote Procedure Call (RPC) binding.
+              This class maps an ONC RPC number to a name.
+              The distinguished value of the cn attribute denotes
+              the RPC service canonical name'
+         MUST ( cn $ oncRpcNumber )
+         MAY description )
+
+
+objectclass     ( 1.3.6.1.1.1.2.6 NAME 'ipHost' SUP top AUXILIARY
+         DESC 'Abstraction of a host, an IP device. The distinguished
+               value of the cn attribute denotes the hosts canonical
+            name. Device SHOULD be used as a structural class'
+         MUST ( cn $ ipHostNumber )
+         MAY ( userPassword $ l $ description $
+               manager ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' SUP top STRUCTURAL
+         DESC 'Abstraction of a network. The distinguished value of
+               the cn attribute denotes the network canonical name'
+         MUST ipNetworkNumber
+         MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' SUP top STRUCTURAL
+         DESC 'Abstraction of a netgroup. May refer to other
+               netgroups'
+         MUST cn
+         MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.9 NAME 'nisMap' SUP top STRUCTURAL
+         DESC 'A generic abstraction of a NIS map'
+         MUST nisMapName
+         MAY description )
+
+
+objectclass     ( 1.3.6.1.1.1.2.10 NAME 'nisObject' SUP top STRUCTURAL
+         DESC 'An entry in a NIS map'
+         MUST ( cn $ nisMapEntry $ nisMapName ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' SUP top AUXILIARY
+         DESC 'A device with a MAC address; device SHOULD be
+               used as a structural class'
+         MAY macAddress )
+
+
+
+
+
+objectclass     ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' SUP top AUXILIARY
+         DESC 'A device with boot parameters; device SHOULD be
+               used as a structural class'
+         MAY ( bootFile $ bootParameter ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY
+         DESC 'An object with a public and secret key'
+         MUST ( cn $ nisPublicKey $ nisSecretKey )
+         MAY ( uidNumber $ description ) )
+
+
+objectclass     ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY
+         DESC 'Associates a NIS domain with a naming context'
+         MUST nisDomain )
+
+
+objectclass     ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
+         MUST ( automountMapName )
+         MAY description )
+
+
+objectclass     ( 1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
+         DESC 'Automount information'
+         MUST ( automountKey $ automountInformation )
+         MAY description )
+
+
+objectclass     ( 1.3.6.1.1.1.2.18 NAME 'groupOfMembers' SUP top STRUCTURAL
+         DESC 'A group with members (DNs)'
+         MUST cn
+         MAY ( businessCategory $ seeAlso $ owner $ ou $ o $
+               description $ member ) )

+ 12 - 1
image/service/slapd/assets/schema-to-ldif.sh

@@ -11,9 +11,15 @@ pushd ${tmpd} >>/dev/null
 
 echo "include /etc/ldap/schema/core.schema" >> convert.dat
 echo "include /etc/ldap/schema/cosine.schema" >> convert.dat
-echo "include /etc/ldap/schema/nis.schema" >> convert.dat
 echo "include /etc/ldap/schema/inetorgperson.schema" >> convert.dat
 
+if [ -e "/etc/ldap/schema/rfc2307bis.schema" ]; then
+  echo "include /etc/ldap/schema/rfc2307bis.schema" >> convert.dat
+else
+  echo "include /etc/ldap/schema/nis.schema" >> convert.dat
+fi
+
+
 for schema in ${SCHEMAS} ; do
     echo "include ${schema}" >> convert.dat
 done
@@ -31,6 +37,11 @@ for schema in ${SCHEMAS} ; do
     schema_dir=`dirname ${fullpath}`
     ldif_file=${schema_name}.ldif
 
+    if [ -e "${schema_dir}/${ldif_file}" ]; then
+      log-helper warning "${schema} ldif file ${schema_dir}/${ldif_file} already exists skipping conversion"
+      continue
+    fi
+
     find . -name *\}${schema_name}.ldif -exec mv '{}' ./${ldif_file} \;
 
     # TODO: these sed invocations could all be combined

+ 246 - 205
image/service/slapd/startup.sh

@@ -24,6 +24,12 @@ WAS_STARTED_WITH_TLS="/etc/ldap/slapd.d/docker-openldap-was-started-with-tls"
 WAS_STARTED_WITH_TLS_ENFORCE="/etc/ldap/slapd.d/docker-openldap-was-started-with-tls-enforce"
 WAS_STARTED_WITH_REPLICATION="/etc/ldap/slapd.d/docker-openldap-was-started-with-replication"
 
+LDAP_TLS_CA_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CA_CRT_FILENAME"
+LDAP_TLS_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CRT_FILENAME"
+LDAP_TLS_KEY_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_KEY_FILENAME"
+LDAP_TLS_DH_PARAM_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/dhparam.pem"
+
+
 # CONTAINER_SERVICE_DIR and CONTAINER_STATE_DIR variables are set by
 # the baseimage run tool more info : https://github.com/osixia/docker-light-baseimage
 
@@ -56,6 +62,17 @@ if [ ! -e "$FIRST_START_DONE" ]; then
     fi
   }
 
+  function ldap_add_or_modify (){
+    local LDIF_FILE=$1
+    sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" $LDIF_FILE
+    sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" $LDIF_FILE
+    if grep -iq changetype $LDIF_FILE ; then
+        ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f $LDIF_FILE 2>&1 | log-helper debug || ldapmodify -h localhost -p 389 -D cn=admin,$LDAP_BASE_DN -w $LDAP_ADMIN_PASSWORD -f $LDIF_FILE 2>&1 | log-helper debug
+    else
+        ldapadd -Y EXTERNAL -Q -H ldapi:/// -f $LDIF_FILE |& log-helper debug
+    fi
+  }
+
   #
   # Global variables
   #
@@ -71,7 +88,6 @@ if [ ! -e "$FIRST_START_DONE" ]; then
     log-helper info "Database and config directory are empty..."
     log-helper info "Init new ldap server..."
 
-
     cat <<EOF | debconf-set-selections
 slapd slapd/internal/generated_adminpw password ${LDAP_ADMIN_PASSWORD}
 slapd slapd/internal/adminpw password ${LDAP_ADMIN_PASSWORD}
@@ -90,6 +106,24 @@ EOF
 
     dpkg-reconfigure -f noninteractive slapd
 
+    # RFC2307bis schema
+    if [ "${LDAP_RFC2307BIS_SCHEMA,,}" == "true" ]; then
+
+      log-helper info "Switching schema to RFC2307bis..."
+      cp ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema/rfc2307bis.* /etc/ldap/schema/
+
+      rm -f /etc/ldap/slapd.d/cn=config/cn=schema/*
+
+      mkdir -p /tmp/schema
+      slaptest -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema/rfc2307bis.conf -F /tmp/schema
+      mv /tmp/schema/cn=config/cn=schema/* /etc/ldap/slapd.d/cn=config/cn=schema
+      rm -r /tmp/schema
+
+      chown -R openldap:openldap /etc/ldap/slapd.d/cn=config/cn=schema
+    fi
+
+    rm ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema/rfc2307bis.*
+
   #
   # Error: the database directory (/var/lib/ldap) is empty but not the config directory (/etc/ldap/slapd.d)
   #
@@ -105,275 +139,282 @@ EOF
     exit 1
   fi
 
-  #
-  # start OpenLDAP
-  #
-
-  # get previous hostname if OpenLDAP was started with replication
-  # to avoid configuration pbs
-  PREVIOUS_HOSTNAME_PARAM=""
-  if [ -e "$WAS_STARTED_WITH_REPLICATION" ]; then
+  if [ "${KEEP_EXISTING_CONFIG,,}" == "true" ]; then
+    log-helper info "/!\ KEEP_EXISTING_CONFIG = true configration will not be updated"
+  else
+    #
+    # start OpenLDAP
+    #
+
+    # get previous hostname if OpenLDAP was started with replication
+    # to avoid configuration pbs
+    PREVIOUS_HOSTNAME_PARAM=""
+    if [ -e "$WAS_STARTED_WITH_REPLICATION" ]; then
+
+      source $WAS_STARTED_WITH_REPLICATION
+
+      # if previous hostname != current hostname
+      # set previous hostname to a loopback ip in /etc/hosts
+      if [ "$PREVIOUS_HOSTNAME" != "$HOSTNAME" ]; then
+        echo "127.0.0.2 $PREVIOUS_HOSTNAME" >> /etc/hosts
+        PREVIOUS_HOSTNAME_PARAM="ldap://$PREVIOUS_HOSTNAME"
+      fi
+    fi
 
-    source $WAS_STARTED_WITH_REPLICATION
+    # if the config was bootstraped with TLS
+    # to avoid error (#6) (#36) and (#44)
+    # we create fake temporary certificates if they do not exists
+    if [ -e "$WAS_STARTED_WITH_TLS" ]; then
+      source $WAS_STARTED_WITH_TLS
 
-    # if previous hostname != current hostname
-    # set previous hostname to a loopback ip in /etc/hosts
-    if [ "$PREVIOUS_HOSTNAME" != "$HOSTNAME" ]; then
-      echo "127.0.0.2 $PREVIOUS_HOSTNAME" >> /etc/hosts
-      PREVIOUS_HOSTNAME_PARAM="ldap://$PREVIOUS_HOSTNAME"
-    fi
-  fi
+      log-helper debug "Check previous TLS certificates..."
 
-  # if the config was bootstraped with TLS
-  # to avoid error (#6) (#36) and (#44)
-  # we create fake temporary certificates if they do not exists
-  if [ -e "$WAS_STARTED_WITH_TLS" ]; then
-    source $WAS_STARTED_WITH_TLS
+      # fix for #73
+      # image started with an existing database/config created before 1.1.5
+      [[ -z "$PREVIOUS_LDAP_TLS_CA_CRT_PATH" ]] && PREVIOUS_LDAP_TLS_CA_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CA_CRT_FILENAME"
+      [[ -z "$PREVIOUS_LDAP_TLS_CRT_PATH" ]] && PREVIOUS_LDAP_TLS_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CRT_FILENAME"
+      [[ -z "$PREVIOUS_LDAP_TLS_KEY_PATH" ]] && PREVIOUS_LDAP_TLS_KEY_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_KEY_FILENAME"
+      [[ -z "$PREVIOUS_LDAP_TLS_DH_PARAM_PATH" ]] && PREVIOUS_LDAP_TLS_DH_PARAM_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/dhparam.pem"
 
-    log-helper debug "Check previous TLS certificates..."
+      ssl-helper $LDAP_SSL_HELPER_PREFIX $PREVIOUS_LDAP_TLS_CRT_PATH $PREVIOUS_LDAP_TLS_KEY_PATH $PREVIOUS_LDAP_TLS_CA_CRT_PATH
+      [ -f ${PREVIOUS_LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
 
-    # fix for #73
-    # image started with an existing database/config created before 1.1.5
-    [[ -z "$PREVIOUS_LDAP_TLS_CA_CRT_PATH" ]] && PREVIOUS_LDAP_TLS_CA_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CA_CRT_FILENAME"
-    [[ -z "$PREVIOUS_LDAP_TLS_CRT_PATH" ]] && PREVIOUS_LDAP_TLS_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CRT_FILENAME"
-    [[ -z "$PREVIOUS_LDAP_TLS_KEY_PATH" ]] && PREVIOUS_LDAP_TLS_KEY_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_KEY_FILENAME"
-    [[ -z "$PREVIOUS_LDAP_TLS_DH_PARAM_PATH" ]] && PREVIOUS_LDAP_TLS_DH_PARAM_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/dhparam.pem"
+      chmod 600 ${PREVIOUS_LDAP_TLS_DH_PARAM_PATH}
+      chown openldap:openldap $PREVIOUS_LDAP_TLS_CRT_PATH $PREVIOUS_LDAP_TLS_KEY_PATH $PREVIOUS_LDAP_TLS_CA_CRT_PATH $PREVIOUS_LDAP_TLS_DH_PARAM_PATH
+    fi
 
-    ssl-helper $LDAP_SSL_HELPER_PREFIX $PREVIOUS_LDAP_TLS_CRT_PATH $PREVIOUS_LDAP_TLS_KEY_PATH $PREVIOUS_LDAP_TLS_CA_CRT_PATH
-    [ -f ${PREVIOUS_LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
+    # start OpenLDAP
+    log-helper info "Start OpenLDAP..."
 
-    chmod 600 ${PREVIOUS_LDAP_TLS_DH_PARAM_PATH}
-    chown openldap:openldap $PREVIOUS_LDAP_TLS_CRT_PATH $PREVIOUS_LDAP_TLS_KEY_PATH $PREVIOUS_LDAP_TLS_CA_CRT_PATH $PREVIOUS_LDAP_TLS_DH_PARAM_PATH
-  fi
+    if log-helper level ge debug; then
+      slapd -h "ldap://$HOSTNAME $PREVIOUS_HOSTNAME_PARAM ldap://localhost ldapi:///" -u openldap -g openldap -d $LDAP_LOG_LEVEL 2>&1 &
+    else
+      slapd -h "ldap://$HOSTNAME $PREVIOUS_HOSTNAME_PARAM ldap://localhost ldapi:///" -u openldap -g openldap
+    fi
 
-  # start OpenLDAP
-  log-helper info "Start OpenLDAP..."
 
-  if log-helper level eq debug; then
-    # debug
-    slapd -h "ldap://$HOSTNAME $PREVIOUS_HOSTNAME_PARAM ldap://localhost ldapi:///" -u openldap -g openldap -d $LDAP_LOG_LEVEL 2>&1 &
-  else
-    slapd -h "ldap://$HOSTNAME $PREVIOUS_HOSTNAME_PARAM ldap://localhost ldapi:///" -u openldap -g openldap
-  fi
+    log-helper info "Waiting for OpenLDAP to start..."
+    while [ ! -e /run/slapd/slapd.pid ]; do sleep 0.1; done
 
+    #
+    # setup bootstrap config - Part 2
+    #
+    if $BOOTSTRAP; then
 
-  log-helper info "Waiting for OpenLDAP to start..."
-  while [ ! -e /run/slapd/slapd.pid ]; do sleep 0.1; done
+      log-helper info "Add bootstrap schemas..."
 
-  #
-  # setup bootstrap config - Part 2
-  #
-  if $BOOTSTRAP; then
-
-    log-helper info "Add bootstrap schemas..."
-
-    # add ppolicy schema
-    ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif 2>&1 | log-helper debug
-
-    # convert schemas to ldif
-    SCHEMAS=""
-    for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema -name \*.schema -type f); do
-      SCHEMAS="$SCHEMAS ${f}"
-    done
-    ${CONTAINER_SERVICE_DIR}/slapd/assets/schema-to-ldif.sh "$SCHEMAS"
-
-    # add converted schemas
-    for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema -name \*.ldif -type f); do
-      log-helper debug "Processing file ${f}"
-      # add schema if not already exists
-      SCHEMA=$(basename "${f}" .ldif)
-      ADD_SCHEMA=$(is_new_schema $SCHEMA)
-      if [ "$ADD_SCHEMA" -eq 1 ]; then
-        ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f $f 2>&1 | log-helper debug
-      else
-        log-helper info "schema ${f} already exists"
-      fi
-    done
+      # add ppolicy schema
+      ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f /etc/ldap/schema/ppolicy.ldif 2>&1 | log-helper debug
 
-    # set config password
-    LDAP_CONFIG_PASSWORD_ENCRYPTED=$(slappasswd -s $LDAP_CONFIG_PASSWORD)
-    sed -i "s|{{ LDAP_CONFIG_PASSWORD_ENCRYPTED }}|${LDAP_CONFIG_PASSWORD_ENCRYPTED}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/01-config-password.ldif
+      # convert schemas to ldif
+      SCHEMAS=""
+      for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema -name \*.schema -type f); do
+        SCHEMAS="$SCHEMAS ${f}"
+      done
+      ${CONTAINER_SERVICE_DIR}/slapd/assets/schema-to-ldif.sh "$SCHEMAS"
+
+      # add converted schemas
+      for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/schema -name \*.ldif -type f); do
+        log-helper debug "Processing file ${f}"
+        # add schema if not already exists
+        SCHEMA=$(basename "${f}" .ldif)
+        ADD_SCHEMA=$(is_new_schema $SCHEMA)
+        if [ "$ADD_SCHEMA" -eq 1 ]; then
+          ldapadd -c -Y EXTERNAL -Q -H ldapi:/// -f $f 2>&1 | log-helper debug
+        else
+          log-helper info "schema ${f} already exists"
+        fi
+      done
 
-    # adapt security config file
-    get_ldap_base_dn
-    sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/02-security.ldif
+      # set config password
+      LDAP_CONFIG_PASSWORD_ENCRYPTED=$(slappasswd -s $LDAP_CONFIG_PASSWORD)
+      sed -i "s|{{ LDAP_CONFIG_PASSWORD_ENCRYPTED }}|${LDAP_CONFIG_PASSWORD_ENCRYPTED}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/01-config-password.ldif
 
-    # process config files (*.ldif) in bootstrap directory (do no process files in subdirectories)
-    log-helper info "Add bootstrap ldif..."
-    for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif -mindepth 1 -maxdepth 1 -type f -name \*.ldif  | sort); do
-      log-helper debug "Processing file ${f}"
-      sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" $f
-      sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" $f
-      ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f $f 2>&1 | log-helper debug || ldapmodify -h localhost -p 389 -D cn=admin,$LDAP_BASE_DN -w $LDAP_ADMIN_PASSWORD -f $f 2>&1 | log-helper debug
-    done
+      # adapt security config file
+      get_ldap_base_dn
+      sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/02-security.ldif
 
-    # read only user
-    if [ "${LDAP_READONLY_USER,,}" == "true" ]; then
+      # process config files (*.ldif) in bootstrap directory (do no process files in subdirectories)
+      log-helper info "Add image bootstrap ldif..."
+      for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif -mindepth 1 -maxdepth 1 -type f -name \*.ldif  | sort); do
+        log-helper debug "Processing file ${f}"
+        ldap_add_or_modify "$f"
+      done
 
-      log-helper info "Add read only user..."
+      log-helper info "Add custom bootstrap ldif..."
+      for f in $(find ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/custom -type f -name \*.ldif  | sort); do
+        log-helper debug "Processing file ${f}"
+        ldap_add_or_modify "$f"
+      done
 
-      LDAP_READONLY_USER_PASSWORD_ENCRYPTED=$(slappasswd -s $LDAP_READONLY_USER_PASSWORD)
-      sed -i "s|{{ LDAP_READONLY_USER_USERNAME }}|${LDAP_READONLY_USER_USERNAME}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
-      sed -i "s|{{ LDAP_READONLY_USER_PASSWORD_ENCRYPTED }}|${LDAP_READONLY_USER_PASSWORD_ENCRYPTED}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
-      sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
+      # read only user
+      if [ "${LDAP_READONLY_USER,,}" == "true" ]; then
 
-      sed -i "s|{{ LDAP_READONLY_USER_USERNAME }}|${LDAP_READONLY_USER_USERNAME}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
-      sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
+        log-helper info "Add read only user..."
 
-      sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
+        LDAP_READONLY_USER_PASSWORD_ENCRYPTED=$(slappasswd -s $LDAP_READONLY_USER_PASSWORD)
+        sed -i "s|{{ LDAP_READONLY_USER_USERNAME }}|${LDAP_READONLY_USER_USERNAME}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
+        sed -i "s|{{ LDAP_READONLY_USER_PASSWORD_ENCRYPTED }}|${LDAP_READONLY_USER_PASSWORD_ENCRYPTED}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
+        sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif
 
-      log-helper debug "Processing file ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif"
-      ldapmodify -h localhost -p 389 -D cn=admin,$LDAP_BASE_DN -w $LDAP_ADMIN_PASSWORD -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif 2>&1 | log-helper debug
+        sed -i "s|{{ LDAP_READONLY_USER_USERNAME }}|${LDAP_READONLY_USER_USERNAME}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
+        sed -i "s|{{ LDAP_BASE_DN }}|${LDAP_BASE_DN}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
 
-      log-helper debug "Processing file ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif"
-      ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif 2>&1 | log-helper debug
+        sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif
 
-    fi
-  fi
+        log-helper debug "Processing file ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif"
+        ldapmodify -h localhost -p 389 -D cn=admin,$LDAP_BASE_DN -w $LDAP_ADMIN_PASSWORD -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user.ldif 2>&1 | log-helper debug
 
-  #
-  # TLS config
-  #
-  if [ -e "$WAS_STARTED_WITH_TLS" ] && [ "${LDAP_TLS,,}" != "true" ]; then
-    log-helper error "/!\ WARNING: LDAP_TLS=false but the container was previously started with LDAP_TLS=true"
-    log-helper error "TLS can't be disabled once added. Ignoring LDAP_TLS=false."
-    LDAP_TLS=true
-  fi
+        log-helper debug "Processing file ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif"
+        ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif 2>&1 | log-helper debug
 
-  if [ -e "$WAS_STARTED_WITH_TLS_ENFORCE" ] && [ "${LDAP_TLS_ENFORCE,,}" != "true" ]; then
-    log-helper error "/!\ WARNING: LDAP_TLS_ENFORCE=false but the container was previously started with LDAP_TLS_ENFORCE=true"
-    log-helper error "TLS enforcing can't be disabled once added. Ignoring LDAP_TLS_ENFORCE=false."
-    LDAP_TLS_ENFORCE=true
-  fi
+      fi
+    fi
 
-  if [ "${LDAP_TLS,,}" == "true" ]; then
+    #
+    # TLS config
+    #
+    if [ -e "$WAS_STARTED_WITH_TLS" ] && [ "${LDAP_TLS,,}" != "true" ]; then
+      log-helper error "/!\ WARNING: LDAP_TLS=false but the container was previously started with LDAP_TLS=true"
+      log-helper error "TLS can't be disabled once added. Ignoring LDAP_TLS=false."
+      LDAP_TLS=true
+    fi
 
-    log-helper info "Add TLS config..."
+    if [ -e "$WAS_STARTED_WITH_TLS_ENFORCE" ] && [ "${LDAP_TLS_ENFORCE,,}" != "true" ]; then
+      log-helper error "/!\ WARNING: LDAP_TLS_ENFORCE=false but the container was previously started with LDAP_TLS_ENFORCE=true"
+      log-helper error "TLS enforcing can't be disabled once added. Ignoring LDAP_TLS_ENFORCE=false."
+      LDAP_TLS_ENFORCE=true
+    fi
 
-    LDAP_TLS_CA_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CA_CRT_FILENAME"
-    LDAP_TLS_CRT_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_CRT_FILENAME"
-    LDAP_TLS_KEY_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/$LDAP_TLS_KEY_FILENAME"
-    LDAP_TLS_DH_PARAM_PATH="${CONTAINER_SERVICE_DIR}/slapd/assets/certs/dhparam.pem"
+    if [ "${LDAP_TLS,,}" == "true" ]; then
 
-    # generate a certificate and key with ssl-helper tool if LDAP_CRT and LDAP_KEY files don't exists
-    # https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/assets/tool/ssl-helper
-    ssl-helper $LDAP_SSL_HELPER_PREFIX $LDAP_TLS_CRT_PATH $LDAP_TLS_KEY_PATH $LDAP_TLS_CA_CRT_PATH
+      log-helper info "Add TLS config..."
 
-    # create DHParamFile if not found
-    [ -f ${LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
-    chmod 600 ${LDAP_TLS_DH_PARAM_PATH}
+      # generate a certificate and key with ssl-helper tool if LDAP_CRT and LDAP_KEY files don't exists
+      # https://github.com/osixia/docker-light-baseimage/blob/stable/image/service-available/:ssl-tools/assets/tool/ssl-helper
+      ssl-helper $LDAP_SSL_HELPER_PREFIX $LDAP_TLS_CRT_PATH $LDAP_TLS_KEY_PATH $LDAP_TLS_CA_CRT_PATH
 
-    # fix file permissions
-    chown -R openldap:openldap ${CONTAINER_SERVICE_DIR}/slapd
+      # create DHParamFile if not found
+      [ -f ${LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
+      chmod 600 ${LDAP_TLS_DH_PARAM_PATH}
 
-    # adapt tls ldif
-    sed -i "s|{{ LDAP_TLS_CA_CRT_PATH }}|${LDAP_TLS_CA_CRT_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
-    sed -i "s|{{ LDAP_TLS_CRT_PATH }}|${LDAP_TLS_CRT_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
-    sed -i "s|{{ LDAP_TLS_KEY_PATH }}|${LDAP_TLS_KEY_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
-    sed -i "s|{{ LDAP_TLS_DH_PARAM_PATH }}|${LDAP_TLS_DH_PARAM_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      # fix file permissions
+      chown -R openldap:openldap ${CONTAINER_SERVICE_DIR}/slapd
 
-    sed -i "s|{{ LDAP_TLS_CIPHER_SUITE }}|${LDAP_TLS_CIPHER_SUITE}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
-    sed -i "s|{{ LDAP_TLS_VERIFY_CLIENT }}|${LDAP_TLS_VERIFY_CLIENT}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      # adapt tls ldif
+      sed -i "s|{{ LDAP_TLS_CA_CRT_PATH }}|${LDAP_TLS_CA_CRT_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      sed -i "s|{{ LDAP_TLS_CRT_PATH }}|${LDAP_TLS_CRT_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      sed -i "s|{{ LDAP_TLS_KEY_PATH }}|${LDAP_TLS_KEY_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      sed -i "s|{{ LDAP_TLS_DH_PARAM_PATH }}|${LDAP_TLS_DH_PARAM_PATH}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
 
-    ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif 2>&1 | log-helper debug
+      sed -i "s|{{ LDAP_TLS_CIPHER_SUITE }}|${LDAP_TLS_CIPHER_SUITE}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
+      sed -i "s|{{ LDAP_TLS_VERIFY_CLIENT }}|${LDAP_TLS_VERIFY_CLIENT}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif
 
-    [[ -f "$WAS_STARTED_WITH_TLS" ]] && rm -f "$WAS_STARTED_WITH_TLS"
-    echo "export PREVIOUS_LDAP_TLS_CA_CRT_PATH=${LDAP_TLS_CA_CRT_PATH}" > $WAS_STARTED_WITH_TLS
-    echo "export PREVIOUS_LDAP_TLS_CRT_PATH=${LDAP_TLS_CRT_PATH}" >> $WAS_STARTED_WITH_TLS
-    echo "export PREVIOUS_LDAP_TLS_KEY_PATH=${LDAP_TLS_KEY_PATH}" >> $WAS_STARTED_WITH_TLS
-    echo "export PREVIOUS_LDAP_TLS_DH_PARAM_PATH=${LDAP_TLS_DH_PARAM_PATH}" >> $WAS_STARTED_WITH_TLS
+      ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enable.ldif 2>&1 | log-helper debug
 
-    # ldap client config
-    sed -i --follow-symlinks "s,TLS_CACERT.*,TLS_CACERT ${LDAP_TLS_CA_CRT_PATH},g" /etc/ldap/ldap.conf
-    echo "TLS_REQCERT ${LDAP_TLS_VERIFY_CLIENT}" >> /etc/ldap/ldap.conf
-    cp -f /etc/ldap/ldap.conf ${CONTAINER_SERVICE_DIR}/slapd/assets/ldap.conf
+      [[ -f "$WAS_STARTED_WITH_TLS" ]] && rm -f "$WAS_STARTED_WITH_TLS"
+      echo "export PREVIOUS_LDAP_TLS_CA_CRT_PATH=${LDAP_TLS_CA_CRT_PATH}" > $WAS_STARTED_WITH_TLS
+      echo "export PREVIOUS_LDAP_TLS_CRT_PATH=${LDAP_TLS_CRT_PATH}" >> $WAS_STARTED_WITH_TLS
+      echo "export PREVIOUS_LDAP_TLS_KEY_PATH=${LDAP_TLS_KEY_PATH}" >> $WAS_STARTED_WITH_TLS
+      echo "export PREVIOUS_LDAP_TLS_DH_PARAM_PATH=${LDAP_TLS_DH_PARAM_PATH}" >> $WAS_STARTED_WITH_TLS
 
-    [[ -f "$HOME/.ldaprc" ]] && rm -f $HOME/.ldaprc
-    echo "TLS_CERT ${LDAP_TLS_CRT_PATH}" > $HOME/.ldaprc
-    echo "TLS_KEY ${LDAP_TLS_KEY_PATH}" >> $HOME/.ldaprc
-    cp -f $HOME/.ldaprc ${CONTAINER_SERVICE_DIR}/slapd/assets/.ldaprc
+      # enforce TLS
+      if [ "${LDAP_TLS_ENFORCE,,}" == "true" ]; then
+        log-helper info "Add enforce TLS..."
+        ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enforce-enable.ldif 2>&1 | log-helper debug
+        touch $WAS_STARTED_WITH_TLS_ENFORCE
 
-    # enforce TLS
-    if [ "${LDAP_TLS_ENFORCE,,}" == "true" ]; then
-      log-helper info "Add enforce TLS..."
-      ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enforce-enable.ldif 2>&1 | log-helper debug
-      touch $WAS_STARTED_WITH_TLS_ENFORCE
+      # disable tls enforcing (not possible for now)
+      #else
+        #log-helper info "Disable enforce TLS..."
+        #ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enforce-disable.ldif 2>&1 | log-helper debug || true
+        #[[ -f "$WAS_STARTED_WITH_TLS_ENFORCE" ]] && rm -f "$WAS_STARTED_WITH_TLS_ENFORCE"
+      fi
 
-    # disable tls enforcing (not possible for now)
+    # disable tls (not possible for now)
     #else
-      #log-helper info "Disable enforce TLS..."
-      #ldapmodify -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-enforce-disable.ldif 2>&1 | log-helper debug || true
-      #[[ -f "$WAS_STARTED_WITH_TLS_ENFORCE" ]] && rm -f "$WAS_STARTED_WITH_TLS_ENFORCE"
+      #log-helper info "Disable TLS config..."
+      #ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-disable.ldif 2>&1 | log-helper debug || true
+      #[[ -f "$WAS_STARTED_WITH_TLS" ]] && rm -f "$WAS_STARTED_WITH_TLS"
     fi
 
-  # disable tls (not possible for now)
-  #else
-    #log-helper info "Disable TLS config..."
-    #ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/tls/tls-disable.ldif 2>&1 | log-helper debug || true
-    #[[ -f "$WAS_STARTED_WITH_TLS" ]] && rm -f "$WAS_STARTED_WITH_TLS"
-  fi
 
 
+    #
+    # Replication config
+    #
 
-  #
-  # Replication config
-  #
+    function disableReplication() {
+      sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-disable.ldif
+      ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-disable.ldif 2>&1 | log-helper debug || true
+      [[ -f "$WAS_STARTED_WITH_REPLICATION" ]] && rm -f "$WAS_STARTED_WITH_REPLICATION"
+    }
 
-  function disableReplication() {
-    sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-disable.ldif
-    ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-disable.ldif 2>&1 | log-helper debug || true
-    [[ -f "$WAS_STARTED_WITH_REPLICATION" ]] && rm -f "$WAS_STARTED_WITH_REPLICATION"
-  }
+    if [ "${LDAP_REPLICATION,,}" == "true" ]; then
 
-  if [ "${LDAP_REPLICATION,,}" == "true" ]; then
+      log-helper info "Add replication config..."
+      disableReplication || true
 
-    log-helper info "Add replication config..."
-    disableReplication || true
+      i=1
+      for host in $(complex-bash-env iterate LDAP_REPLICATION_HOSTS)
+      do
+        sed -i "s|{{ LDAP_REPLICATION_HOSTS }}|olcServerID: $i ${!host}\n{{ LDAP_REPLICATION_HOSTS }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+        sed -i "s|{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}|olcSyncRepl: rid=00$i provider=${!host} ${LDAP_REPLICATION_CONFIG_SYNCPROV}\n{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+        sed -i "s|{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}|olcSyncRepl: rid=10$i provider=${!host} ${LDAP_REPLICATION_DB_SYNCPROV}\n{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
 
-    i=1
-    for host in $(complex-bash-env iterate LDAP_REPLICATION_HOSTS)
-    do
-      sed -i "s|{{ LDAP_REPLICATION_HOSTS }}|olcServerID: $i ${!host}\n{{ LDAP_REPLICATION_HOSTS }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-      sed -i "s|{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}|olcSyncRepl: rid=00$i provider=${!host} ${LDAP_REPLICATION_CONFIG_SYNCPROV}\n{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-      sed -i "s|{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}|olcSyncRepl: rid=10$i provider=${!host} ${LDAP_REPLICATION_DB_SYNCPROV}\n{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+        ((i++))
+      done
 
-      ((i++))
-    done
+      get_ldap_base_dn
+      sed -i "s|\$LDAP_BASE_DN|$LDAP_BASE_DN|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "s|\$LDAP_ADMIN_PASSWORD|$LDAP_ADMIN_PASSWORD|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "s|\$LDAP_CONFIG_PASSWORD|$LDAP_CONFIG_PASSWORD|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
 
-    get_ldap_base_dn
-    sed -i "s|\$LDAP_BASE_DN|$LDAP_BASE_DN|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-    sed -i "s|\$LDAP_ADMIN_PASSWORD|$LDAP_ADMIN_PASSWORD|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-    sed -i "s|\$LDAP_CONFIG_PASSWORD|$LDAP_CONFIG_PASSWORD|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "/{{ LDAP_REPLICATION_HOSTS }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "/{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "/{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
 
-    sed -i "/{{ LDAP_REPLICATION_HOSTS }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-    sed -i "/{{ LDAP_REPLICATION_HOSTS_CONFIG_SYNC_REPL }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
-    sed -i "/{{ LDAP_REPLICATION_HOSTS_DB_SYNC_REPL }}/d" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
 
-    sed -i "s|{{ LDAP_BACKEND }}|${LDAP_BACKEND}|g" ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif
+      ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif 2>&1 | log-helper debug || true
 
-    ldapmodify -c -Y EXTERNAL -Q -H ldapi:/// -f ${CONTAINER_SERVICE_DIR}/slapd/assets/config/replication/replication-enable.ldif 2>&1 | log-helper debug || true
+      [[ -f "$WAS_STARTED_WITH_REPLICATION" ]] && rm -f "$WAS_STARTED_WITH_REPLICATION"
+      echo "export PREVIOUS_HOSTNAME=${HOSTNAME}" > $WAS_STARTED_WITH_REPLICATION
 
-    [[ -f "$WAS_STARTED_WITH_REPLICATION" ]] && rm -f "$WAS_STARTED_WITH_REPLICATION"
-    echo "export PREVIOUS_HOSTNAME=${HOSTNAME}" > $WAS_STARTED_WITH_REPLICATION
+    else
 
-  else
+      log-helper info "Disable replication config..."
+      disableReplication || true
+
+    fi
 
-    log-helper info "Disable replication config..."
-    disableReplication || true
+    #
+    # stop OpenLDAP
+    #
+    log-helper info "Stop OpenLDAP..."
 
+    SLAPD_PID=$(cat /run/slapd/slapd.pid)
+    kill -15 $SLAPD_PID
+    while [ -e /proc/$SLAPD_PID ]; do sleep 0.1; done # wait until slapd is terminated
   fi
 
   #
-  # stop OpenLDAP
+  # ldap client config
   #
-  log-helper info "Stop OpenLDAP..."
+  if [ "${LDAP_TLS,,}" == "true" ]; then
+    log-helper info "Configure ldap client TLS configuration..."
+    sed -i --follow-symlinks "s,TLS_CACERT.*,TLS_CACERT ${LDAP_TLS_CA_CRT_PATH},g" /etc/ldap/ldap.conf
+    echo "TLS_REQCERT ${LDAP_TLS_VERIFY_CLIENT}" >> /etc/ldap/ldap.conf
+    cp -f /etc/ldap/ldap.conf ${CONTAINER_SERVICE_DIR}/slapd/assets/ldap.conf
 
-  SLAPD_PID=$(cat /run/slapd/slapd.pid)
-  kill -15 $SLAPD_PID
-  while [ -e /proc/$SLAPD_PID ]; do sleep 0.1; done # wait until slapd is terminated
+    [[ -f "$HOME/.ldaprc" ]] && rm -f $HOME/.ldaprc
+    echo "TLS_CERT ${LDAP_TLS_CRT_PATH}" > $HOME/.ldaprc
+    echo "TLS_KEY ${LDAP_TLS_KEY_PATH}" >> $HOME/.ldaprc
+    cp -f $HOME/.ldaprc ${CONTAINER_SERVICE_DIR}/slapd/assets/.ldaprc
+  fi
 
   #
-  # remove config files
+  # remove container config files
   #
   if [ "${LDAP_REMOVE_CONFIG_AFTER_SETUP,,}" == "true" ]; then
     log-helper info "Remove config files..."

+ 7 - 0
image/service/slapd/test.sh

@@ -0,0 +1,7 @@
+#!/bin/bash -e
+
+# Copy testing data to their respective directories on an as-needed basis
+mkdir -p /var/lib/ldap
+mkdir -p /etc/ldap/slapd.d
+cp -rf /container/test/database/* /var/lib/ldap/ || true
+cp -rf /container/test/config/* /etc/ldap/slapd.d/ || true

+ 1 - 5
test/test.bats

@@ -37,21 +37,17 @@ load test_helper
   run docker exec $CONTAINER_ID ldapsearch -x -h ldap.osixia.net -b dc=example,dc=org -ZZ -D "cn=admin,dc=example,dc=org" -w admin
   clear_container
 
-  chmod 777 -R test/config/ test/database/ test/ssl/
-
   [ "$status" -eq 0 ]
 
 }
 
 @test "ldapsearch existing database and config" {
 
-  run_image -h ldap.example.org -e LDAP_TLS=false -v $BATS_TEST_DIRNAME/database:/var/lib/ldap -v $BATS_TEST_DIRNAME/config:/etc/ldap/slapd.d
+  run_image -h ldap.example.org -e LDAP_TLS=false -v $BATS_TEST_DIRNAME/database:/container/test/database -v $BATS_TEST_DIRNAME/config:/container/test/config
   wait_process slapd
   run docker exec $CONTAINER_ID ldapsearch -x -h ldap.example.org -b dc=osixia,dc=net -D "cn=admin,dc=osixia,dc=net" -w admin
   clear_container
 
-  chmod 777 -R test/config/ test/database/ test/ssl/
-
   [ "$status" -eq 0 ]
 
 }

+ 1 - 1
test/test_helper.bash

@@ -9,7 +9,7 @@ build_image() {
 }
 
 run_image() {
-  CONTAINER_ID=$(docker run $@ -d $IMAGE_NAME)
+  CONTAINER_ID=$(docker run $@ -d $IMAGE_NAME --copy-service -c "/container/service/slapd/test.sh")
   CONTAINER_IP=$(get_container_ip_by_cid $CONTAINER_ID)
 }