Răsfoiți Sursa

Merge branch 'release-1.4.0' into stable

Bertrand Gouny 5 ani în urmă
părinte
comite
7ce084bab1

+ 1 - 0
.gitignore

@@ -1,2 +1,3 @@
+.DS_Store
 !/.git*
 !/.git*
 /VOLUMES
 /VOLUMES

+ 23 - 3
CHANGELOG.md

@@ -4,16 +4,35 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
 
+## [1.4.0] - 2020-06-15
+30M+ docker pulls 🎉🎉🎉 thanks to all contributors 💕
+### Added
+  - Allow setting ports on ldap and ldaps #403. Thanks to @chirauki !
+  - Address firewall issues on RHEL in README #394. Thanks to @BirkhoffLee !
+  - Ensure ca certs are up to date #387. Thanks to @Jyrno42 !
+  - Install slapd-contrib to include pbkdf2 pw support #365. Thanks to @col-panic !
+  - Seeding from internal path. #361. Thanks to @dbck !
+  - Enable openldap uid/gid to be specified at runtime #336. Thanks to @lj020326 !
+
+### Changes
+  - Update openldap 2.4.48 to 2.4.50 
+  - LDAP_TLS_PROTOCOL_MIN is deprecated #432. Thanks to @mettacrawler !
+  - Better handling of environment variables checks #382. Thanks to @obourdon !
+
+### Fixed
+  - Multi-node replication fixes #420. Thanks to @pcolmer !
+  - Grant root manage access to database #416. Thanks to @olia-dev !
+
 ## [1.3.0] - 2019-09-29
 ## [1.3.0] - 2019-09-29
-## Added
+### Added
   - Multiarch support
   - Multiarch support
 
 
-## Changes
+### Changes
   - Update openldap 2.4.47 to 2.4.48 #247
   - Update openldap 2.4.47 to 2.4.48 #247
   - Upgrade baseimage to light-baseimage:1.2.0 (debian buster)
   - Upgrade baseimage to light-baseimage:1.2.0 (debian buster)
 
 
 ## [1.2.5] - 2019-08-16
 ## [1.2.5] - 2019-08-16
-## Added
+### Added
   - Support for docker secrets #325. Thanks to @anagno !
   - Support for docker secrets #325. Thanks to @anagno !
   - Add DISABLE_CHOWN environment variable #240
   - Add DISABLE_CHOWN environment variable #240
   - pqChecker lib to check passwords strength with ppolicy pwdCheckModule
   - pqChecker lib to check passwords strength with ppolicy pwdCheckModule
@@ -252,6 +271,7 @@ Environment variable LDAP_REPLICATION_HDB_SYNCPROV changed to LDAP_REPLICATION_D
 ## [0.10.0] - 2015-03-03
 ## [0.10.0] - 2015-03-03
 New version initial release, no changelog before this sorry.
 New version initial release, no changelog before this sorry.
 
 
+[1.4.0]: https://github.com/osixia/docker-openldap/compare/v1.3.0...v1.4.0
 [1.3.0]: https://github.com/osixia/docker-openldap/compare/v1.2.5...v1.3.0
 [1.3.0]: https://github.com/osixia/docker-openldap/compare/v1.2.5...v1.3.0
 [1.2.5]: https://github.com/osixia/docker-openldap/compare/v1.2.4...v1.2.5
 [1.2.5]: https://github.com/osixia/docker-openldap/compare/v1.2.4...v1.2.5
 [1.2.4]: https://github.com/osixia/docker-openldap/compare/v1.2.3...v1.2.4
 [1.2.4]: https://github.com/osixia/docker-openldap/compare/v1.2.3...v1.2.4

+ 1 - 1
Makefile

@@ -1,5 +1,5 @@
 NAME = osixia/openldap
 NAME = osixia/openldap
-VERSION = 1.3.0
+VERSION = 1.4.0
 
 
 .PHONY: build build-nocache test tag-latest push push-latest release git-tag-version
 .PHONY: build build-nocache test tag-latest push push-latest release git-tag-version
 
 

+ 51 - 22
README.md

@@ -4,7 +4,7 @@
 ![Docker Stars](https://img.shields.io/docker/stars/osixia/openldap.svg)
 ![Docker Stars](https://img.shields.io/docker/stars/osixia/openldap.svg)
 ![](https://images.microbadger.com/badges/image/osixia/openldap.svg)
 ![](https://images.microbadger.com/badges/image/osixia/openldap.svg)
 
 
-Latest release: 1.3.0 - OpenLDAP 2.4.48 -  [Changelog](CHANGELOG.md) | [Docker Hub](https://hub.docker.com/r/osixia/openldap/) 
+Latest release: 1.4.0 - OpenLDAP 2.4.50 -  [Changelog](CHANGELOG.md) | [Docker Hub](https://hub.docker.com/r/osixia/openldap/) 
 
 
 **A docker image to run OpenLDAP.**
 **A docker image to run OpenLDAP.**
 
 
@@ -19,6 +19,7 @@ Latest release: 1.3.0 - OpenLDAP 2.4.48 -  [Changelog](CHANGELOG.md) | [Docker H
 			- [Data persistence](#data-persistence)
 			- [Data persistence](#data-persistence)
 			- [Edit your server configuration](#edit-your-server-configuration)
 			- [Edit your server configuration](#edit-your-server-configuration)
 			- [Seed ldap database with ldif](#seed-ldap-database-with-ldif)
 			- [Seed ldap database with ldif](#seed-ldap-database-with-ldif)
+			- [Seed from internal path](#seed-from-internal-path)
 		- [Use an existing ldap database](#use-an-existing-ldap-database)
 		- [Use an existing ldap database](#use-an-existing-ldap-database)
 		- [Backup](#backup)
 		- [Backup](#backup)
 		- [Administrate your ldap server](#administrate-your-ldap-server)
 		- [Administrate your ldap server](#administrate-your-ldap-server)
@@ -38,7 +39,7 @@ Latest release: 1.3.0 - OpenLDAP 2.4.48 -  [Changelog](CHANGELOG.md) | [Docker H
 			- [Docker Secrets](#docker-secrets)
 			- [Docker Secrets](#docker-secrets)
 			- [Make your own image or extend this image](#make-your-own-image-or-extend-this-image)
 			- [Make your own image or extend this image](#make-your-own-image-or-extend-this-image)
 	- [Advanced User Guide](#advanced-user-guide)
 	- [Advanced User Guide](#advanced-user-guide)
-		- [Extend osixia/openldap:1.3.0 image](#extend-osixiaopenldap130-image)
+		- [Extend osixia/openldap:1.4.0 image](#extend-osixiaopenldap140-image)
 		- [Make your own openldap image](#make-your-own-openldap-image)
 		- [Make your own openldap image](#make-your-own-openldap-image)
 		- [Tests](#tests)
 		- [Tests](#tests)
 		- [Kubernetes](#kubernetes)
 		- [Kubernetes](#kubernetes)
@@ -58,11 +59,11 @@ If you find this image useful here's how you can help:
 ## Quick Start
 ## Quick Start
 Run OpenLDAP docker image:
 Run OpenLDAP docker image:
 
 
-	docker run --name my-openldap-container --detach osixia/openldap:1.3.0
+	docker run --name my-openldap-container --detach osixia/openldap:1.4.0
 
 
 Do not forget to add the port mapping for both port 389 and 636 if you wish to access the ldap server from another machine.
 Do not forget to add the port mapping for both port 389 and 636 if you wish to access the ldap server from another machine.
 
 
-	docker run -p 389:389 -p 636:636 --name my-openldap-container --detach osixia/openldap:1.3.0
+	docker run -p 389:389 -p 636:636 --name my-openldap-container --detach osixia/openldap:1.4.0
 
 
 Either command starts a new container with OpenLDAP running inside. Let's make the first search in our LDAP container:
 Either command starts a new container with OpenLDAP running inside. Let's make the first search in our LDAP container:
 
 
@@ -98,7 +99,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:
 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" \
 	docker run --env LDAP_ORGANISATION="My Company" --env LDAP_DOMAIN="my-company.com" \
-	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.3.0
+	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.4.0
 
 
 #### Data persistence
 #### Data persistence
 
 
@@ -120,6 +121,14 @@ For more information about docker data volume, please refer to:
 
 
 > [https://docs.docker.com/engine/tutorials/dockervolumes/](https://docs.docker.com/engine/tutorials/dockervolumes/)
 > [https://docs.docker.com/engine/tutorials/dockervolumes/](https://docs.docker.com/engine/tutorials/dockervolumes/)
 
 
+#### Firewall issues on RHEL/CentOS
+Docker Engine doesn't work well with firewall-cmd and can cause issues if you're connecting to the LDAP server from another container on the same machine. You can fix this by running:
+```
+$ firewall-cmd --add-port=389/tcp --permanent
+$ firewall-cmd --add-port=636/tcp --permanent
+$ firewall-cmd --reload
+```
+Learn more about this issue at https://github.com/moby/moby/issues/32138
 
 
 #### Edit your server configuration
 #### Edit your server configuration
 
 
@@ -149,12 +158,30 @@ argument to entrypoint if you don't want to overwrite them.
 		# single file example:
 		# single file example:
 		docker run \
 		docker run \
       --volume ./bootstrap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/50-bootstrap.ldif \
       --volume ./bootstrap.ldif:/container/service/slapd/assets/config/bootstrap/ldif/50-bootstrap.ldif \
-      osixia/openldap:1.3.0 --copy-service
+      osixia/openldap:1.4.0 --copy-service
 
 
 		#directory example:
 		#directory example:
 		docker run \
 		docker run \
 	     --volume ./ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom \
 	     --volume ./ldif:/container/service/slapd/assets/config/bootstrap/ldif/custom \
-	     osixia/openldap:1.3.0 --copy-service
+	     osixia/openldap:1.4.0 --copy-service
+
+#### Seed from internal path
+
+This image can load ldif and schema files at startup from an internal path. This is useful if a continuous integration service mounts automatically the working copy (sources) into a docker service, which has a relation to the ci job.
+
+For example: Gitlab is not capable of mounting custom paths into docker services of a ci job, but gitlab automatically mounts the working copy in every service container. So the working copy (sources) are accessible under `/builds` in every services
+of a ci job. The path to the working copy can be obtained via `${CI_PROJECT_DIR}`. See also: https://docs.gitlab.com/runner/executors/docker.html#build-directory-in-service
+
+This may also work with other CI services, if they automatically mount the working directory to the services of a ci job like gitlab ci does.
+
+In order to seed ldif or schema files from internal path you must set the specific environment variable `LDAP_SEED_INTERNAL_LDIF_PATH` and/or `LDAP_SEED_INTERNAL_SCHEMA_PATH`. If set this will copy any *.ldif or *.schema file into the default seeding
+directories of this image.
+
+Example variables defined in gitlab-ci.yml:
+
+	variables:
+		LDAP_SEED_INTERNAL_LDIF_PATH: "${CI_PROJECT_DIR}/docker/openldap/ldif"
+		LDAP_SEED_INTERNAL_SCHEMA_PATH: "${CI_PROJECT_DIR}/docker/openldap/schema"
 
 
 ### Use an existing ldap database
 ### Use an existing ldap database
 
 
@@ -165,7 +192,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 \
 	docker run --volume /data/slapd/database:/var/lib/ldap \
 	--volume /data/slapd/config:/etc/ldap/slapd.d \
 	--volume /data/slapd/config:/etc/ldap/slapd.d \
-	--detach osixia/openldap:1.3.0
+	--detach osixia/openldap:1.4.0
 
 
 You can also use data volume containers. Please refer to:
 You can also use data volume containers. Please refer to:
 > [https://docs.docker.com/engine/tutorials/dockervolumes/](https://docs.docker.com/engine/tutorials/dockervolumes/)
 > [https://docs.docker.com/engine/tutorials/dockervolumes/](https://docs.docker.com/engine/tutorials/dockervolumes/)
@@ -185,7 +212,7 @@ If you are looking for a simple solution to administrate your ldap server you ca
 #### Use auto-generated certificate
 #### 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).
 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.3.0
+	docker run --hostname ldap.my-company.com --detach osixia/openldap:1.4.0
 
 
 #### Use your own certificate
 #### Use your own certificate
 
 
@@ -195,24 +222,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_CRT_FILENAME=my-ldap.crt \
 	--env LDAP_TLS_KEY_FILENAME=my-ldap.key \
 	--env LDAP_TLS_KEY_FILENAME=my-ldap.key \
 	--env LDAP_TLS_CA_CRT_FILENAME=the-ca.crt \
 	--env LDAP_TLS_CA_CRT_FILENAME=the-ca.crt \
-	--detach osixia/openldap:1.3.0
+	--detach osixia/openldap:1.4.0
 
 
 Other solutions are available please refer to the [Advanced User Guide](#advanced-user-guide)
 Other solutions are available please refer to the [Advanced User Guide](#advanced-user-guide)
 
 
 #### Disable TLS
 #### Disable TLS
 Add --env LDAP_TLS=false to the run command:
 Add --env LDAP_TLS=false to the run command:
 
 
-	docker run --env LDAP_TLS=false --detach osixia/openldap:1.3.0
+	docker run --env LDAP_TLS=false --detach osixia/openldap:1.4.0
 
 
 ### Multi master replication
 ### Multi master replication
 Quick example, with the default config.
 Quick example, with the default config.
 
 
 	#Create the first ldap server, save the container id in LDAP_CID and get its IP:
 	#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.3.0)
+	LDAP_CID=$(docker run --hostname ldap.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.4.0)
 	LDAP_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $LDAP_CID)
 	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:
 	#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.3.0)
+	LDAP2_CID=$(docker run --hostname ldap2.example.org --env LDAP_REPLICATION=true --detach osixia/openldap:1.4.0)
 	LDAP2_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $LDAP2_CID)
 	LDAP2_IP=$(docker inspect -f "{{ .NetworkSettings.IPAddress }}" $LDAP2_CID)
 
 
 	#Add the pair "ip hostname" to /etc/hosts on each containers,
 	#Add the pair "ip hostname" to /etc/hosts on each containers,
@@ -248,7 +275,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 :
 To fix that run the container with `--copy-service` argument :
 
 
-		docker run [your options] osixia/openldap:1.3.0 --copy-service
+		docker run [your options] osixia/openldap:1.4.0 --copy-service
 
 
 ### Debug
 ### Debug
 
 
@@ -257,11 +284,11 @@ Available levels are: `none`, `error`, `warning`, `info`, `debug` and `trace`.
 
 
 Example command to run the container in `debug` mode:
 Example command to run the container in `debug` mode:
 
 
-	docker run --detach osixia/openldap:1.3.0 --loglevel debug
+	docker run --detach osixia/openldap:1.4.0 --loglevel debug
 
 
 See all command line options:
 See all command line options:
 
 
-	docker run osixia/openldap:1.3.0 --help
+	docker run osixia/openldap:1.4.0 --help
 
 
 
 
 ## Environment Variables
 ## Environment Variables
@@ -327,7 +354,7 @@ Replication options:
 
 
 	If you want to set this variable at docker run command add the tag `#PYTHON2BASH:` and convert the yaml in python:
 	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.3.0
+		docker run --env LDAP_REPLICATION_HOSTS="#PYTHON2BASH:['ldap://ldap.example.org','ldap://ldap2.example.org']" --detach osixia/openldap:1.4.0
 
 
 	To convert yaml to python online: http://yaml-online-parser.appspot.com/
 	To convert yaml to python online: http://yaml-online-parser.appspot.com/
 
 
@@ -340,6 +367,8 @@ Other environment variables:
 - **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.
 - **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.
 - **HOSTNAME**: set the hostname of the running openldap server. Defaults to whatever docker creates.
 - **HOSTNAME**: set the hostname of the running openldap server. Defaults to whatever docker creates.
 - **DISABLE_CHOWN**: do not perform any chown to fix file ownership. Defaults to `false`
 - **DISABLE_CHOWN**: do not perform any chown to fix file ownership. Defaults to `false`
+- LDAP_OPENLDAP_UID: runtime docker user uid to run container as
+- LDAP_OPENLDAP_GID: runtime docker user gid to run container as
 
 
 
 
 ### Set your own environment variables
 ### Set your own environment variables
@@ -348,7 +377,7 @@ Other environment variables:
 Environment variables can be set by adding the --env argument in the command line, for example:
 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" \
 	docker run --env LDAP_ORGANISATION="My company" --env LDAP_DOMAIN="my-company.com" \
-	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.3.0
+	--env LDAP_ADMIN_PASSWORD="JonSn0w" --detach osixia/openldap:1.4.0
 
 
 Be aware that environment variable added in command line will be available at any time
 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
 in the container. In this example if someone manage to open a terminal in this container
@@ -359,14 +388,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
 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 \
 	docker run --volume /data/ldap/environment:/container/environment/01-custom \
-	--detach osixia/openldap:1.3.0
+	--detach osixia/openldap:1.4.0
 
 
 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).
 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**:
 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 \
 	docker run --volume /data/ldap/environment/my-env.yaml:/container/environment/01-custom/env.yaml \
-	--detach osixia/openldap:1.3.0
+	--detach osixia/openldap:1.4.0
 
 
 #### Docker Secrets
 #### Docker Secrets
 
 
@@ -385,13 +414,13 @@ This is the best solution if you have a private registry. Please refer to the [A
 
 
 ## Advanced User Guide
 ## Advanced User Guide
 
 
-### Extend osixia/openldap:1.3.0 image
+### Extend osixia/openldap:1.4.0 image
 
 
 If you need to add your custom TLS certificate, bootstrap config or environment files the easiest way is to extends this 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:
 Dockerfile example:
 
 
-	FROM osixia/openldap:1.3.0
+	FROM osixia/openldap:1.4.0
 	MAINTAINER Your Name <[email protected]>
 	MAINTAINER Your Name <[email protected]>
 
 
 	ADD bootstrap /container/service/slapd/assets/config/bootstrap
 	ADD bootstrap /container/service/slapd/assets/config/bootstrap

+ 8 - 6
example/docker-compose.yml

@@ -1,7 +1,7 @@
 version: '2'
 version: '2'
 services:
 services:
   openldap:
   openldap:
-    image: osixia/openldap:1.3.0
+    image: osixia/openldap:1.4.0
     container_name: openldap
     container_name: openldap
     environment:
     environment:
       LDAP_LOG_LEVEL: "256"
       LDAP_LOG_LEVEL: "256"
@@ -22,11 +22,10 @@ services:
       LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
       LDAP_TLS_CA_CRT_FILENAME: "ca.crt"
       LDAP_TLS_ENFORCE: "false"
       LDAP_TLS_ENFORCE: "false"
       LDAP_TLS_CIPHER_SUITE: "SECURE256:-VERS-SSL3.0"
       LDAP_TLS_CIPHER_SUITE: "SECURE256:-VERS-SSL3.0"
-      LDAP_TLS_PROTOCOL_MIN: "3.1"
       LDAP_TLS_VERIFY_CLIENT: "demand"
       LDAP_TLS_VERIFY_CLIENT: "demand"
       LDAP_REPLICATION: "false"
       LDAP_REPLICATION: "false"
-      #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_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']"
       #LDAP_REPLICATION_HOSTS: "#PYTHON2BASH:['ldap://ldap.example.org','ldap://ldap2.example.org']"
       KEEP_EXISTING_CONFIG: "false"
       KEEP_EXISTING_CONFIG: "false"
       LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
       LDAP_REMOVE_CONFIG_AFTER_SETUP: "true"
@@ -40,8 +39,11 @@ services:
     ports:
     ports:
       - "389:389"
       - "389:389"
       - "636:636"
       - "636:636"
-    domainname: "example.org" # important: same as hostname
-    hostname: "example.org"
+    # For replication to work correctly, domainname and hostname must be
+    # set correctly so that "hostname"."domainname" equates to the
+    # fully-qualified domain name for the host.
+    domainname: "example.org"
+    hostname: "ldap-server"
   phpldapadmin:
   phpldapadmin:
     image: osixia/phpldapadmin:latest
     image: osixia/phpldapadmin:latest
     container_name: phpldapadmin
     container_name: phpldapadmin

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

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

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

@@ -13,7 +13,7 @@ spec:
     spec:
     spec:
       containers:
       containers:
         - name: ldap
         - name: ldap
-          image: osixia/openldap:1.3.0
+          image: osixia/openldap:1.4.0
           volumeMounts:
           volumeMounts:
             - name: ldap-data
             - name: ldap-data
               mountPath: /var/lib/ldap
               mountPath: /var/lib/ldap

+ 1 - 1
example/kubernetes/using-secrets/gce-statefullset.yaml

@@ -12,7 +12,7 @@ spec:
         spec:
         spec:
             containers:
             containers:
             - name: azaldap
             - name: azaldap
-              image: osixia/openldap:1.3.0
+              image: osixia/openldap:1.4.0
               imagePullPolicy: IfNotPresent
               imagePullPolicy: IfNotPresent
               #command: ["/bin/bash","-c","while [ 1 = 1 ] ; do sleep 1; date; done"]
               #command: ["/bin/bash","-c","while [ 1 = 1 ] ; do sleep 1; date; done"]
               ports:
               ports:

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

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

+ 5 - 3
image/Dockerfile

@@ -1,6 +1,6 @@
 # Use osixia/light-baseimage
 # Use osixia/light-baseimage
 # sources: https://github.com/osixia/docker-light-baseimage
 # sources: https://github.com/osixia/docker-light-baseimage
-FROM osixia/light-baseimage:release-1.2.0-dev
+FROM osixia/light-baseimage:1.2.0
 
 
 ARG LDAP_OPENLDAP_GID
 ARG LDAP_OPENLDAP_GID
 ARG LDAP_OPENLDAP_UID
 ARG LDAP_OPENLDAP_UID
@@ -10,8 +10,8 @@ ARG PQCHECKER_MD5=c005ce596e97d13e39485e711dcbc7e1
 
 
 # Add openldap user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
 # Add openldap user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
 # If explicit uid or gid is given, use it.
 # If explicit uid or gid is given, use it.
-RUN if [ -z "${LDAP_OPENLDAP_GID}" ]; then groupadd -r openldap; else groupadd -r -g ${LDAP_OPENLDAP_GID} openldap; fi \
-    && if [ -z "${LDAP_OPENLDAP_UID}" ]; then useradd -r -g openldap openldap; else useradd -r -g openldap -u ${LDAP_OPENLDAP_UID} openldap; fi
+RUN if [ -z "${LDAP_OPENLDAP_GID}" ]; then groupadd -g 911 -r openldap; else groupadd -r -g ${LDAP_OPENLDAP_GID} openldap; fi \
+    && if [ -z "${LDAP_OPENLDAP_UID}" ]; then useradd -u 911 -r -g openldap openldap; else useradd -r -g openldap -u ${LDAP_OPENLDAP_UID} openldap; fi
 
 
 # Add buster-backports in preparation for downloading newer openldap components, especially sladp
 # Add buster-backports in preparation for downloading newer openldap components, especially sladp
 RUN echo "deb http://ftp.debian.org/debian buster-backports main" >> /etc/apt/sources.list
 RUN echo "deb http://ftp.debian.org/debian buster-backports main" >> /etc/apt/sources.list
@@ -33,11 +33,13 @@ RUN echo "path-include /usr/share/doc/krb5*" >> /etc/dpkg/dpkg.cfg.d/docker && a
     libsasl2-modules-sql \
     libsasl2-modules-sql \
     openssl \
     openssl \
     slapd \
     slapd \
+    slapd-contrib \
     krb5-kdc-ldap \
     krb5-kdc-ldap \
     && curl -o pqchecker.deb -SL http://www.meddeb.net/pub/pqchecker/deb/8/pqchecker_${PQCHECKER_VERSION}_amd64.deb \
     && curl -o pqchecker.deb -SL http://www.meddeb.net/pub/pqchecker/deb/8/pqchecker_${PQCHECKER_VERSION}_amd64.deb \
     && echo "${PQCHECKER_MD5} *pqchecker.deb" | md5sum -c - \
     && echo "${PQCHECKER_MD5} *pqchecker.deb" | md5sum -c - \
     && dpkg -i pqchecker.deb \
     && dpkg -i pqchecker.deb \
     && rm pqchecker.deb \
     && rm pqchecker.deb \
+    && update-ca-certificates \
     && apt-get remove -y --purge --auto-remove curl ca-certificates \
     && apt-get remove -y --purge --auto-remove curl ca-certificates \
     && apt-get clean \
     && apt-get clean \
     && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
     && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

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

@@ -61,3 +61,7 @@ LDAP_REMOVE_CONFIG_AFTER_SETUP: true
 LDAP_SSL_HELPER_PREFIX: ldap # ssl-helper first search config from LDAP_SSL_HELPER_* variables, before SSL_HELPER_* variables.
 LDAP_SSL_HELPER_PREFIX: ldap # ssl-helper first search config from LDAP_SSL_HELPER_* variables, before SSL_HELPER_* variables.
 
 
 SSL_HELPER_AUTO_RENEW_SERVICES_IMPACTED: slapd
 SSL_HELPER_AUTO_RENEW_SERVICES_IMPACTED: slapd
+
+# Internal seeding. For example, for services in Gitlab CI.
+LDAP_SEED_INTERNAL_LDIF_PATH:
+LDAP_SEED_INTERNAL_SCHEMA_PATH:

+ 5 - 1
image/environment/default.yaml

@@ -13,4 +13,8 @@ LDAP_LOG_LEVEL: 256
 LDAP_NOFILE: 1024
 LDAP_NOFILE: 1024
 
 
 # Do not perform any chown to fix file ownership
 # Do not perform any chown to fix file ownership
-DISABLE_CHOWN: false
+DISABLE_CHOWN: false
+
+# Default port to bind slapd
+LDAP_PORT: 389
+LDAPS_PORT: 636

+ 1 - 0
image/service/slapd/assets/config/bootstrap/ldif/02-security.ldif

@@ -3,5 +3,6 @@ changetype: modify
 delete: olcAccess
 delete: olcAccess
 -
 -
 add: olcAccess
 add: olcAccess
+olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
 olcAccess: to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,{{ LDAP_BASE_DN }}" write by anonymous auth by * none
 olcAccess: to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,{{ LDAP_BASE_DN }}" write by anonymous auth by * none
 olcAccess: to * by self read by dn="cn=admin,{{ LDAP_BASE_DN }}" write by * none
 olcAccess: to * by self read by dn="cn=admin,{{ LDAP_BASE_DN }}" write by * none

+ 1 - 0
image/service/slapd/assets/config/bootstrap/ldif/readonly-user/readonly-user-acl.ldif

@@ -3,5 +3,6 @@ changetype: modify
 delete: olcAccess
 delete: olcAccess
 -
 -
 add: olcAccess
 add: olcAccess
+olcAccess: to * by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage by * break
 olcAccess: to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,{{ LDAP_BASE_DN }}" write by anonymous auth by * none
 olcAccess: to attrs=userPassword,shadowLastChange by self write by dn="cn=admin,{{ LDAP_BASE_DN }}" write by anonymous auth by * none
 olcAccess: to * by self read by dn="cn=admin,{{ LDAP_BASE_DN }}" write by dn="cn={{ LDAP_READONLY_USER_USERNAME }},{{ LDAP_BASE_DN }}" read by * none
 olcAccess: to * by self read by dn="cn=admin,{{ LDAP_BASE_DN }}" write by dn="cn={{ LDAP_READONLY_USER_USERNAME }},{{ LDAP_BASE_DN }}" read by * none

+ 5 - 1
image/service/slapd/process.sh

@@ -9,4 +9,8 @@ log-helper level eq trace && set -x
 # see https://github.com/docker/docker/issues/8231
 # see https://github.com/docker/docker/issues/8231
 ulimit -n $LDAP_NOFILE
 ulimit -n $LDAP_NOFILE
 
 
-exec /usr/sbin/slapd -h "ldap://$HOSTNAME ldaps://$HOSTNAME ldapi:///" -u openldap -g openldap -d $LDAP_LOG_LEVEL
+# Call hostname to determine the fully qualified domain name. We want OpenLDAP to listen
+# to the named host for the ldap:// and ldaps:// protocols.
+FQDN="$(/bin/hostname --fqdn)"
+HOST_PARAM="ldap://$FQDN:$LDAP_PORT ldaps://$FQDN:$LDAPS_PORT"
+exec /usr/sbin/slapd -h "$HOST_PARAM ldapi:///" -u openldap -g openldap -d "$LDAP_LOG_LEVEL"

+ 69 - 17
image/service/slapd/startup.sh

@@ -12,25 +12,25 @@ ulimit -n $LDAP_NOFILE
 
 
 
 
 # usage: file_env VAR
 # usage: file_env VAR
-#    ie: file_env 'XYZ_DB_PASSWORD' 
+#    ie: file_env 'XYZ_DB_PASSWORD'
 # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
 # (will allow for "$XYZ_DB_PASSWORD_FILE" to fill in the value of
 #  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
 #  "$XYZ_DB_PASSWORD" from a file, especially for Docker's secrets feature)
 file_env() {
 file_env() {
-	local var="$1"
-	local fileVar="${var}_FILE"
+        local var="$1"
+        local fileVar="${var}_FILE"
 
 
   # The variables are already defined from the docker-light-baseimage
   # The variables are already defined from the docker-light-baseimage
   # So if the _FILE variable is available we ovewrite them
   # So if the _FILE variable is available we ovewrite them
-	if [ "${!fileVar:-}" ]; then
+        if [ "${!fileVar:-}" ]; then
     log-helper trace "${fileVar} was defined"
     log-helper trace "${fileVar} was defined"
 
 
-		val="$(< "${!fileVar}")"
+                val="$(< "${!fileVar}")"
     log-helper debug "${var} was repalced with the contents of ${fileVar} (the value was: ${val})"
     log-helper debug "${var} was repalced with the contents of ${fileVar} (the value was: ${val})"
 
 
     export "$var"="$val"
     export "$var"="$val"
-	fi
-	
-	unset "$fileVar"
+        fi
+
+        unset "$fileVar"
 }
 }
 
 
 
 
@@ -38,12 +38,56 @@ file_env 'LDAP_ADMIN_PASSWORD'
 file_env 'LDAP_CONFIG_PASSWORD'
 file_env 'LDAP_CONFIG_PASSWORD'
 file_env 'LDAP_READONLY_USER_PASSWORD'
 file_env 'LDAP_READONLY_USER_PASSWORD'
 
 
+# Seed ldif from internal path if specified
+file_env 'LDAP_SEED_INTERNAL_LDIF_PATH'
+if [ ! -z "${LDAP_SEED_INTERNAL_LDIF_PATH}" ]; then
+  mkdir -p /container/service/slapd/assets/config/bootstrap/ldif/custom/
+  cp -R ${LDAP_SEED_INTERNAL_LDIF_PATH}/*.ldif /container/service/slapd/assets/config/bootstrap/ldif/custom/
+fi
+
+# Seed schema from internal path if specified
+file_env 'LDAP_SEED_INTERNAL_SCHEMA_PATH'
+if [ ! -z "${LDAP_SEED_INTERNAL_SCHEMA_PATH}" ]; then
+  mkdir -p /container/service/slapd/assets/config/bootstrap/schema/custom/
+  cp -R ${LDAP_SEED_INTERNAL_SCHEMA_PATH}/*.schema /container/service/slapd/assets/config/bootstrap/schema/custom/
+fi
+
 # create dir if they not already exists
 # create dir if they not already exists
 [ -d /var/lib/ldap ] || mkdir -p /var/lib/ldap
 [ -d /var/lib/ldap ] || mkdir -p /var/lib/ldap
 [ -d /etc/ldap/slapd.d ] || mkdir -p /etc/ldap/slapd.d
 [ -d /etc/ldap/slapd.d ] || mkdir -p /etc/ldap/slapd.d
 
 
+log-helper info "openldap user and group adjustments"
+LDAP_OPENLDAP_UID=${LDAP_OPENLDAP_UID:-911}
+LDAP_OPENLDAP_GID=${LDAP_OPENLDAP_GID:-911}
+
+log-helper info "get current openldap uid/gid info inside container"
+CUR_USER_GID=`id -g openldap || true`
+CUR_USER_UID=`id -u openldap || true`
+
+LDAP_UIDGID_CHANGED=false
+if [ "$LDAP_OPENLDAP_UID" != "$CUR_USER_UID" ]; then
+    log-helper info "CUR_USER_UID (${CUR_USER_UID}) does't match LDAP_OPENLDAP_UID (${LDAP_OPENLDAP_UID}), adjusting..."
+    usermod -o -u "$LDAP_OPENLDAP_UID" openldap
+    LDAP_UIDGID_CHANGED=true
+fi
+if [ "$LDAP_OPENLDAP_GID" != "$CUR_USER_GID" ]; then
+    log-helper info "CUR_USER_GID (${CUR_USER_GID}) does't match LDAP_OPENLDAP_GID (${LDAP_OPENLDAP_GID}), adjusting..."
+    groupmod -o -g "$LDAP_OPENLDAP_GID" openldap
+    LDAP_UIDGID_CHANGED=true
+fi
+
+log-helper info '-------------------------------------'
+log-helper info 'openldap GID/UID'
+log-helper info '-------------------------------------'
+log-helper info "User uid:    $(id -u openldap)"
+log-helper info "User gid:    $(id -g openldap)"
+log-helper info "uid/gid changed: ${LDAP_UIDGID_CHANGED}"
+log-helper info "-------------------------------------"
+
 # fix file permissions
 # fix file permissions
 if [ "${DISABLE_CHOWN,,}" == "false" ]; then
 if [ "${DISABLE_CHOWN,,}" == "false" ]; then
+  log-helper info "updating file uid/gid ownership"
+  chown -R openldap:openldap /var/run/slapd
   chown -R openldap:openldap /var/lib/ldap
   chown -R openldap:openldap /var/lib/ldap
   chown -R openldap:openldap /etc/ldap
   chown -R openldap:openldap /etc/ldap
   chown -R openldap:openldap ${CONTAINER_SERVICE_DIR}/slapd
   chown -R openldap:openldap ${CONTAINER_SERVICE_DIR}/slapd
@@ -83,13 +127,12 @@ if [ ! -e "$FIRST_START_DONE" ]; then
     fi
     fi
     # Check that LDAP_BASE_DN and LDAP_DOMAIN are in sync
     # Check that LDAP_BASE_DN and LDAP_DOMAIN are in sync
     domain_from_base_dn=$(echo $LDAP_BASE_DN | tr ',' '\n' | sed -e 's/^.*=//' | tr '\n' '.' | sed -e 's/\.$//')
     domain_from_base_dn=$(echo $LDAP_BASE_DN | tr ',' '\n' | sed -e 's/^.*=//' | tr '\n' '.' | sed -e 's/\.$//')
-    set +e
-    echo "$domain_from_base_dn" | egrep -q ".*$LDAP_DOMAIN\$"
-    if [ $? -ne 0 ]; then
+    if `echo "$domain_from_base_dn" | egrep -q ".*$LDAP_DOMAIN\$" || echo $LDAP_DOMAIN | egrep -q ".*$domain_from_base_dn\$"`; then
+      : # pass
+    else
       log-helper error "Error: domain $domain_from_base_dn derived from LDAP_BASE_DN $LDAP_BASE_DN does not match LDAP_DOMAIN $LDAP_DOMAIN"
       log-helper error "Error: domain $domain_from_base_dn derived from LDAP_BASE_DN $LDAP_BASE_DN does not match LDAP_DOMAIN $LDAP_DOMAIN"
       exit 1
       exit 1
     fi
     fi
-    set -e
   }
   }
 
 
   function is_new_schema() {
   function is_new_schema() {
@@ -254,11 +297,11 @@ EOF
 
 
     # start OpenLDAP
     # start OpenLDAP
     log-helper info "Start OpenLDAP..."
     log-helper info "Start OpenLDAP..."
-
+    # At this stage, we can just listen to ldap:// and ldap:// without naming any names
     if log-helper level ge debug; then
     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 &
+      slapd -h "ldap:/// ldapi:///" -u openldap -g openldap -d "$LDAP_LOG_LEVEL" 2>&1 &
     else
     else
-      slapd -h "ldap://$HOSTNAME $PREVIOUS_HOSTNAME_PARAM ldap://localhost ldapi:///" -u openldap -g openldap
+      slapd -h "ldap:/// ldapi:///" -u openldap -g openldap
     fi
     fi
 
 
 
 
@@ -352,7 +395,7 @@ EOF
 
 
       # create DHParamFile if not found
       # create DHParamFile if not found
       [ -f ${LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
       [ -f ${LDAP_TLS_DH_PARAM_PATH} ] || openssl dhparam -out ${LDAP_TLS_DH_PARAM_PATH} 2048
-      
+
       # fix file permissions
       # fix file permissions
       if [ "${DISABLE_CHOWN,,}" == "false" ]; then
       if [ "${DISABLE_CHOWN,,}" == "false" ]; then
         chmod 600 ${LDAP_TLS_DH_PARAM_PATH}
         chmod 600 ${LDAP_TLS_DH_PARAM_PATH}
@@ -507,8 +550,17 @@ ln -sf ${CONTAINER_SERVICE_DIR}/slapd/assets/.ldaprc $HOME/.ldaprc
 ln -sf ${CONTAINER_SERVICE_DIR}/slapd/assets/ldap.conf /etc/ldap/ldap.conf
 ln -sf ${CONTAINER_SERVICE_DIR}/slapd/assets/ldap.conf /etc/ldap/ldap.conf
 
 
 # force OpenLDAP to listen on all interfaces
 # force OpenLDAP to listen on all interfaces
+# We need to make sure that /etc/hosts continues to include the
+# fully-qualified domain name and not just the specified hostname.
+# Without the FQDN, /bin/hostname --fqdn stops working.
+FQDN="$(/bin/hostname --fqdn)"
+if [ "$FQDN" != "$HOSTNAME" ]; then
+    FQDN_PARAM="$FQDN"
+else
+    FQDN_PARAM=""
+fi
 ETC_HOSTS=$(cat /etc/hosts | sed "/$HOSTNAME/d")
 ETC_HOSTS=$(cat /etc/hosts | sed "/$HOSTNAME/d")
-echo "0.0.0.0 $HOSTNAME" > /etc/hosts
+echo "0.0.0.0 $FQDN_PARAM $HOSTNAME" > /etc/hosts
 echo "$ETC_HOSTS" >> /etc/hosts
 echo "$ETC_HOSTS" >> /etc/hosts
 
 
 exit 0
 exit 0

+ 15 - 2
test/test.bats

@@ -22,7 +22,7 @@ load test_helper
 
 
 }
 }
 
 
-@test "ldap domain with ldap base dn" {
+@test "ldap domain with non-matching ldap base dn" {
 
 
   run_image -h ldap.example.org -e LDAP_TLS=false -e LDAP_DOMAIN=example.com -e LDAP_BASE_DN="dc=example,dc=org"
   run_image -h ldap.example.org -e LDAP_TLS=false -e LDAP_DOMAIN=example.com -e LDAP_BASE_DN="dc=example,dc=org"
 
 
@@ -35,7 +35,7 @@ load test_helper
 
 
 }
 }
 
 
-@test "ldap domain with ldap base dn subdomain" {
+@test "ldap domain with matching ldap base dn subdomain" {
 
 
   run_image -h ldap.example.fr -e LDAP_TLS=false -e LDAP_DOMAIN=example.fr -e LDAP_BASE_DN="ou=myou,o=example,c=fr"
   run_image -h ldap.example.fr -e LDAP_TLS=false -e LDAP_DOMAIN=example.fr -e LDAP_BASE_DN="ou=myou,o=example,c=fr"
 
 
@@ -48,6 +48,19 @@ load test_helper
 
 
 }
 }
 
 
+@test "ldap base dn domain with matching ldap subdomain" {
+
+  run_image -h ldap.example.fr -e LDAP_TLS=false -e LDAP_DOMAIN=mysub.example.fr -e LDAP_BASE_DN="o=example,c=fr"
+
+  sleep 5
+
+  CSTATUS=$(check_container)
+  clear_container
+
+  [ "$CSTATUS" == "running 0" ]
+
+}
+
 @test "ldap domain with ldap base dn subdomain included" {
 @test "ldap domain with ldap base dn subdomain included" {
 
 
   run_image -h ldap.example.com -e LDAP_TLS=false -e LDAP_DOMAIN=example.com -e LDAP_BASE_DN="ou=myou,o=example,dc=com,c=fr"
   run_image -h ldap.example.com -e LDAP_TLS=false -e LDAP_DOMAIN=example.com -e LDAP_BASE_DN="ou=myou,o=example,dc=com,c=fr"