mirror of
https://github.com/vegardit/docker-openldap.git
synced 2026-04-10 06:31:56 +02:00
Initial import
This commit is contained in:
parent
b3fc7301be
commit
985bca6429
43
.gitattributes
vendored
Normal file
43
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
# from https://github.com/alexkaratarakis/gitattributes/blob/master/Java.gitattributes
|
||||
|
||||
# Handle line endings automatically for files detected as text
|
||||
# and leave all files detected as binary untouched.
|
||||
* text=auto
|
||||
|
||||
#
|
||||
# The above will handle all files NOT found below
|
||||
#
|
||||
# These files are text and should be normalized (Convert crlf => lf)
|
||||
*.css text
|
||||
*.df text
|
||||
*.htm text
|
||||
*.html text
|
||||
*.java text
|
||||
*.js text
|
||||
*.json text
|
||||
*.jsp text
|
||||
*.jspf text
|
||||
*.jspx text
|
||||
*.properties text
|
||||
*.sh text
|
||||
*.tld text
|
||||
*.txt text
|
||||
*.tag text
|
||||
*.tagx text
|
||||
*.xml text
|
||||
*.yml text
|
||||
|
||||
# These files are binary and should be left untouched
|
||||
# (binary is a macro for -text -diff)
|
||||
*.class binary
|
||||
*.dll binary
|
||||
*.ear binary
|
||||
*.gif binary
|
||||
*.ico binary
|
||||
*.jar binary
|
||||
*.jpg binary
|
||||
*.jpeg binary
|
||||
*.png binary
|
||||
*.so binary
|
||||
*.war binary
|
||||
|
||||
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
/.project
|
||||
/.settings
|
||||
/.svn
|
||||
**/.*.md.html
|
||||
39
.travis.yml
Normal file
39
.travis.yml
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
# https://github.com/travis-ci/travis-yml/blob/master/schema.json
|
||||
language: bash # using 'bash' instead of 'minimal' to prevent https://travis-ci.community/t/job-stuck-booting/4976
|
||||
|
||||
sudo: true
|
||||
|
||||
services:
|
||||
- docker
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.trivy/cache
|
||||
|
||||
env:
|
||||
global:
|
||||
DOCKER_REGISTRY=docker.io
|
||||
DOCKER_REPO=vegardit/openldap
|
||||
TRIVY_CACHE_DIR=$HOME/.trivy/cache
|
||||
|
||||
|
||||
before_script:
|
||||
# workaround for
|
||||
# - https://stackoverflow.com/questions/34130613/how-to-make-travis-ci-work-with-a-local-git-branch-instead-of-a-specific-commit
|
||||
# - https://unhashable.com/getting-the-current-branch-name-during-a-pull-request-in-travis-ci/
|
||||
- if [ "$TRAVIS_PULL_REQUEST" == "false" ]; then
|
||||
export GIT_BRANCH="$TRAVIS_BRANCH";
|
||||
else
|
||||
export GIT_BRANCH="$TRAVIS_PULL_REQUEST_BRANCH";
|
||||
fi
|
||||
#- printenv | sort
|
||||
- mkdir -p "$TRIVY_CACHE_DIR"
|
||||
|
||||
script:
|
||||
- echo "$DOCKER_PASSWORD" | docker login -u="$DOCKER_USERNAME" "$DOCKER_REGISTRY" --password-stdin &&
|
||||
if [[ "$TRAVIS_BRANCH" == "master" ]]; then
|
||||
DOCKER_PUSH=1 bash ./build-image.sh;
|
||||
else
|
||||
bash ./build-image.sh;
|
||||
fi
|
||||
- ls -l $TRIVY_CACHE_DIR/trivy
|
||||
7
CONTRIBUTING.md
Normal file
7
CONTRIBUTING.md
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
# Contributing to docker-openldap
|
||||
|
||||
Thanks for contributing to docker-openldap!
|
||||
|
||||
## License
|
||||
|
||||
By contributing your code, you agree to license your contribution under the [Apache License 2.0](LICENSE.txt).
|
||||
201
LICENSE
201
LICENSE
|
|
@ -1,201 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
201
LICENSE.txt
Normal file
201
LICENSE.txt
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
201
README.md
201
README.md
|
|
@ -1,2 +1,199 @@
|
|||
# docker-openldap
|
||||
Opinionated docker image based on minideb (Debian 10 "buster") to run an OpenLDAP 2.4 server.
|
||||
# vegardit/openldap <a href="https://github.com/vegardit/docker-openldap/" title="GitHub Repo"><img height="30" src="https://raw.githubusercontent.com/simple-icons/simple-icons/develop/icons/github.svg?sanitize=true"></a>
|
||||
|
||||
[](https://travis-ci.com/vegardit/docker-openldap)
|
||||
[](#license)
|
||||
[](https://hub.docker.com/r/vegardit/openldap)
|
||||
[](https://hub.docker.com/r/vegardit/openldap)
|
||||
[](https://hub.docker.com/r/vegardit/openldap)
|
||||
|
||||
1. [What is it?](#what-is-it)
|
||||
1. [Configuration](#config)
|
||||
1. [Initial configuration](#initial-config)
|
||||
1. [Customizing the Password Policy](#ppolicy)
|
||||
1. [Changing UID/GID of OpenLDAP service user](#uidgid)
|
||||
1. [Periodic LDAP Backup](#backup)
|
||||
1. [Synchronizing timezone/time with docker host](#timesync)
|
||||
1. [Performance tuning](#performance-tuning)
|
||||
1. [Troubleshooting](#troubleshooting)
|
||||
1. [References](#references)
|
||||
1. [License](#license)
|
||||
|
||||
|
||||
## <a name="what-is-it"></a>What is it?
|
||||
|
||||
Opinionated docker image based on [minideb](https://github.com/bitnami/minideb) (Debian 10 "buster") to run an [OpenLDAP 2.4](https://www.openldap.org/doc/admin24/) server.
|
||||
|
||||
To keep the image light and simple, it does not configure TLS. Instead we recommend configuring a [Traefik 2.x](https://traefik.io) [TCP service](https://docs.traefik.io/routing/services/#configuring-tcp-services) with e.g. an auto-renewing [Let's Encrypt configuration](https://docs.traefik.io/https/acme/) in front of the OpenLDAP service.
|
||||
|
||||
|
||||
## <a name="config"></a>Configuration
|
||||
|
||||
### <a name="initial-config"></a>Initial configuration
|
||||
|
||||
Various parts of the LDAP server can be configured via environment variables. All environment variables starting with `LDAP_INIT_`
|
||||
are only evaluated on the **first** container launch. Changing their values later has no effect when restarting or updating the container.
|
||||
|
||||
To customize the initial configuration you can set the following environment variables:
|
||||
|
||||
```sh
|
||||
LDAP_INIT_ORG_DN='dc=example,dc=com'
|
||||
LDAP_INIT_ORG_NAME='Example Corporation'
|
||||
LDAP_INIT_ADMIN_GROUP_DN='cn=ldapadmins,ou=Groups,${LDAP_INIT_ORG_DN}'
|
||||
LDAP_INIT_ROOT_USER_DN='uid=admin,${LDAP_INIT_ORG_DN}'
|
||||
LDAP_INIT_ROOT_USER_PW='changeit'
|
||||
LDAP_INIT_RFC2307BIS_SCHEMA=0 # 0=use NIS (RFC2307) schema, 1=use RFC2307bis schema
|
||||
```
|
||||
|
||||
Environment variables can for example be set using `docker run` with `-e`, e.g.
|
||||
|
||||
```sh
|
||||
docker run -itd \
|
||||
-e LDAP_INIT_ORG_DN='o=yourorg' \
|
||||
-e LDAP_INIT_ROOT_USER_PW='newpassword' \
|
||||
-e LDAP_INIT_ORG_NAME='Company Inc' \
|
||||
-e LDAP_INIT_PPOLICY_PW_MIN_LENGTH='12' \
|
||||
vegardit/openldap
|
||||
```
|
||||
|
||||
Alternatively you can use an [env-file](https://docs.docker.com/compose/env-file/) to store all changed variables and use the option `--env-file` with `docker run`, e.g.:
|
||||
|
||||
```sh
|
||||
docker run -itd --env-file environment vegardit/openldap
|
||||
```
|
||||
|
||||
In environment file values must not be enclosed using quotes (`'` or `"`), please remove them. See this example file: [example/docker/example.env].
|
||||
|
||||
The initial LDAP tree structure is imported from [/opt/ldifs/init_org_tree.ldif](ldifs/init_org_tree.ldif).
|
||||
You can mount a custom file at `/opt/ldifs/init_org_tree.ldif` if you require changes.
|
||||
|
||||
LDAP entries (users, groups) are imported from [/opt/ldifs/init_org_entries.ldif](ldifs/init_org_entries.ldif).
|
||||
You can mount a custom file at `/opt/ldifs/init_org_entries.ldif` if you require changes.
|
||||
|
||||
### <a name="ppolicy"></a>Customizing the Password Policy
|
||||
|
||||
On **initial** container launch, the [password policy](https://www.openldap.org/doc/admin24/overlays.html#Password%20Policies) is imported from [/opt/ldifs/init_org_ppolicy.ldif](ldifs/init_org_ppolicy.ldif)
|
||||
|
||||
The following parameters can be modified via environment variables **before** initial container launch:
|
||||
|
||||
```sh
|
||||
LDAP_INIT_PPOLICY_DEFAULT_DN='cn=DefaultPasswordPolicy,ou=Policies,${LDAP_INIT_ORG_DN}'
|
||||
LDAP_INIT_PPOLICY_PW_MIN_LENGTH=8
|
||||
LDAP_INIT_PPOLICY_MAX_FAILURES=3
|
||||
LDAP_INIT_PPOLICY_LOCKOUT_DURATION=300
|
||||
```
|
||||
|
||||
If more customizations are required, simply mount a custom policy file at `/opt/ldifs/init_org_ppolicy.ldif` **before** initial container launch.
|
||||
|
||||
**Password Quality Checker:**
|
||||
|
||||
[pqChecker](https://www.meddeb.net/pqchecker/) is configured as default password quality checker using the rule `0|01010101` with
|
||||
the following meaning:
|
||||
|
||||
|Pos. |Value |Effective Rule
|
||||
|----:|:-----:|:----------
|
||||
|0-1 | `0\|`|Don't broadcast passwords.
|
||||
|2-4 | `01` |Minimum 1 uppercase character.
|
||||
|5-6 | `01` |Minimum 1 lowercase character.
|
||||
|7-8 | `01` |Minimum 1 digit.
|
||||
|9-10 | `01` |Minimum 1 special character.
|
||||
|11-..| empty | No characters are disallowed in passwords.
|
||||
|
||||
The pqChecker rule syntax is explained here in more detail: https://www.meddeb.net/pqchecker/?Idx=2
|
||||
|
||||
A custom rule can be provided via an environment variable, e.g.:
|
||||
|
||||
```sh
|
||||
LDAP_PPOLICY_PQCHECKER_RULE='0|01020101@!+-#'
|
||||
```
|
||||
|
||||
### <a name="uidgid"></a>Changing UID/GID of OpenLDAP service user
|
||||
|
||||
The UID/GID of the user running the OpenLDAP service can be aligned with the docker host, using the environment variables
|
||||
`LDAP_OPENLDAP_UID` and `LDAP_OPENLDAP_GID`.
|
||||
|
||||
During each container start it is verified that the given UID/GID matches the currently effective UID/GID. If not, the UID/GID
|
||||
of the `openldap` user are changed accordingly and `chown` on `/etc/ldap` and `/var/lib/slapd` is executed before the OpenLDAP service is started.
|
||||
|
||||
### <a name="backup"></a>Periodic LDAP Backup
|
||||
|
||||
This image automatically generates a daily LDIF export at `2 a.m.` to `/var/lib/ldap/data.ldif`.
|
||||
|
||||
The following environment variables can be used to configure the automatic LDAP backup:
|
||||
```bash
|
||||
LDAP_BACKUP_TIME='02:00' # Format is "HH:MM", i.e. 24-hour format with minute precision
|
||||
LDAP_BACKUP_FILE='/var/lib/ldap/data.ldif'
|
||||
```
|
||||
|
||||
To disable automatic backup set an empty value for the environment variable `LDAP_BACKUP_TIME`.
|
||||
|
||||
### <a name="timesync"></a>Synchronizing timezone/time with docker host
|
||||
|
||||
To use the same timezone and/or time of the docker host you can run the docker image with `--volume /etc/localtime:/etc/localtime:ro --volume /etc/timezone:/etc/timezone:ro`
|
||||
|
||||
Docker compose file example:
|
||||
```yaml
|
||||
version: '3.7'
|
||||
services:
|
||||
openldap:
|
||||
image: vegardit/openldap:latest
|
||||
volumes:
|
||||
- /etc/localtime:/etc/localtime:ro
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
```
|
||||
|
||||
### <a name="performance-tuning"></a>Performance tuning
|
||||
|
||||
#### DB Indexes
|
||||
|
||||
The database indexes that are configured during initial container launch are imported from [/opt/ldifs/init_backend_indexes.ldif](ldifs/init_mdb_indexes.ldif)
|
||||
|
||||
To use other indexes, simply mount a custom file at `/opt/ldifs/init_backend_indexes.ldif` **before** initial container launch.
|
||||
|
||||
#### Memory usage
|
||||
|
||||
The maximum number of open files is set to `1024` by default to prevent excessive RAM consumption as reported [here](https://github.com/docker/docker/issues/8231).
|
||||
|
||||
The following environment variable can be used to increase this limit:
|
||||
|
||||
```sh
|
||||
LDAP_NOFILE_LIMIT=2048
|
||||
```
|
||||
|
||||
### <a name="troubleshooting"></a>Troubleshooting
|
||||
|
||||
The slapd service logs to stdout. You can change the active log levels by setting this environment variable:
|
||||
|
||||
```sh
|
||||
LDAP_LOG_LEVELS='Config Stats'
|
||||
```
|
||||
|
||||
The following [log levels](https://www.openldap.org/doc/admin24/slapdconfig.html#loglevel%20%3Clevel%3E) are available:
|
||||
```
|
||||
Any (-1) enable all debugging
|
||||
Trace (1) trace function calls
|
||||
Packets (2) debug packet handling
|
||||
Args (4) heavy trace debugging
|
||||
Conns (8) connection management
|
||||
BER (16) print out packets sent and received
|
||||
Filter (32) search filter processing
|
||||
Config (64) configuration processing
|
||||
ACL (128) access control list processing
|
||||
Stats (256) stats log connections/operations/results
|
||||
Stats2 (512) stats log entries sent
|
||||
Shell (1024) print communication with shell backends
|
||||
Parse (2048) print entry parsing debugging
|
||||
Sync (16384) syncrepl consumer processing
|
||||
None (32768) only messages that get logged whatever log level is set
|
||||
```
|
||||
|
||||
|
||||
## <a name="references"></a>References
|
||||
|
||||
- OpenLDAP Software 2.4 Administrator's Guide https://www.openldap.org/doc/admin24/guide.html
|
||||
- OpenLDAP Online Configuration Reference https://tylersguides.com/guides/openldap-online-configuration-reference/
|
||||
- slapd-config(5) - Linux man page https://linux.die.net/man/5/slapd-config
|
||||
|
||||
|
||||
## <a name="license"></a>License
|
||||
|
||||
All files in this repository are released under the [Apache License 2.0](LICENSE.txt).
|
||||
|
|
|
|||
11
build-debug-image.sh
Normal file
11
build-debug-image.sh
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright 2019-2020 by Vegard IT GmbH, Germany, https://vegardit.com
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# @author Sebastian Thomschke, Vegard IT GmbH
|
||||
#
|
||||
# https://github.com/vegardit/docker-openldap
|
||||
#
|
||||
|
||||
bash "$(dirname "$0")/build-image.sh" --build-arg DEBUG_BUILD=1
|
||||
77
build-image.sh
Normal file
77
build-image.sh
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright 2019-2020 by Vegard IT GmbH, Germany, https://vegardit.com
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# @author Sebastian Thomschke, Vegard IT GmbH
|
||||
#
|
||||
# https://github.com/vegardit/docker-openldap
|
||||
#
|
||||
|
||||
set -e -x
|
||||
if [ ! -n "$BASH" ]; then /usr/bin/env bash "$0" "$@"; exit; fi
|
||||
|
||||
DOCKER_REGISTRY=${DOCKER_REGISTRY:-docker.io}
|
||||
DOCKER_REPO=${DOCKER_REPO:-vegardit/openldap}
|
||||
|
||||
last_commit_date=$(date -d @$(git log -1 --format="%at") --utc +"%Y%m%d_%H%M%S")
|
||||
|
||||
docker build $(dirname $0)/image \
|
||||
--compress \
|
||||
--build-arg GIT_BRANCH="${GIT_BRANCH:-$(git rev-parse --abbrev-ref HEAD)}" \
|
||||
--build-arg GIT_COMMIT_DATE="$(date -d @$(git log -1 --format='%at') --utc +'%Y-%m-%d %H:%M:%S UTC')" \
|
||||
--build-arg GIT_COMMIT_HASH="$(git rev-parse --short HEAD)" \
|
||||
--build-arg GIT_REPO_URL="$(git config --get remote.origin.url)" \
|
||||
`# using the current date as value for BASE_LAYER_CACHE_KEY, i.e. the base layer cache (that holds system packages with security updates) will be invalidate once per day` \
|
||||
--build-arg BASE_LAYER_CACHE_KEY=$(date +%Y%m%d) \
|
||||
-t $DOCKER_REPO:latest \
|
||||
-t $DOCKER_REPO:latest-buster \
|
||||
-t $DOCKER_REPO:${last_commit_date} \
|
||||
-t $DOCKER_REPO:${last_commit_date}-buster \
|
||||
"$@"
|
||||
|
||||
#
|
||||
# perform security audit using https://github.com/aquasecurity/trivy
|
||||
#
|
||||
mkdir -p ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache}
|
||||
docker run --rm \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache}:/root/.cache/ \
|
||||
aquasec/trivy --no-progress --exit-code 0 --severity HIGH,CRITICAL $DOCKER_REPO:${last_commit_date}
|
||||
docker run --rm \
|
||||
-v /var/run/docker.sock:/var/run/docker.sock \
|
||||
-v ${TRIVY_CACHE_DIR:-$HOME/.trivy/cache}:/root/.cache/ \
|
||||
aquasec/trivy --no-progress --ignore-unfixed --exit-code 1 --severity HIGH,CRITICAL $DOCKER_REPO:${last_commit_date}
|
||||
sudo chown -R $USER:$(id -gn) $TRIVY_CACHE_DIR || true
|
||||
|
||||
#
|
||||
# determine effective LDAP version and apply tags
|
||||
#
|
||||
ldap_version=$(docker run $DOCKER_REPO:${last_commit_date} "dpkg -s slapd | grep 'Version:' | grep -oP 'Version: \K\d+\.\d+\.\d+'")
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%.*}.x #2.4.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%%.*}.x #2.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x
|
||||
|
||||
#
|
||||
# push image with tags to remote docker registry
|
||||
#
|
||||
if [[ "${DOCKER_PUSH:-0}" == "1" ]]; then
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:latest
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:latest-buster
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version} #2.4.47
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version}-buster #2.4.47
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x #2.4.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x #2.x
|
||||
docker image tag $DOCKER_REPO:${last_commit_date} $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x
|
||||
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:latest
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:latest-buster
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version} #2.4.47
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version}-buster #2.4.47
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x #2.4.x
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%.*}.x-buster #2.4.x
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x #2.x
|
||||
docker push $DOCKER_REGISTRY/$DOCKER_REPO:${ldap_version%%.*}.x-buster #2.x
|
||||
fi
|
||||
66
example/docker-compose/docker-compose.yml
Normal file
66
example/docker-compose/docker-compose.yml
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#############################
|
||||
# @author Sebastian Thomschke, Vegard IT GmbH
|
||||
#############################
|
||||
|
||||
version: '3.7'
|
||||
|
||||
# https://docs.docker.com/compose/compose-file/
|
||||
|
||||
services:
|
||||
|
||||
ldap_service:
|
||||
# https://github.com/vegardit/docker-openldap
|
||||
image: vegardit/openldap:latest # https://hub.docker.com/r/vegardit/openldap
|
||||
environment:
|
||||
#DEBUG_RUN_SH: 1
|
||||
LDAP_INIT_ORG_DN: o=example.com
|
||||
LDAP_INIT_ORG_NAME: Example Inc.
|
||||
LDAP_INIT_ROOT_USER_DN: uid=admin,o=example.com
|
||||
LDAP_INIT_ROOT_USER_PW: CHANGE@it
|
||||
LDAP_BACKUP_TIME: # disable backup by setting to empty string
|
||||
ports:
|
||||
- 389:389
|
||||
volumes:
|
||||
- ./ldifs/init_org_entries.ldif:/opt/ldifs/init_org_entries.ldif:ro
|
||||
- ./ldifs/init_org_tree.ldif:/opt/ldifs/init_org_tree.ldif:ro
|
||||
|
||||
ldap_ui:
|
||||
# https://github.com/alekseydemidov/pla-ssp
|
||||
image: netflyer/openldap-ui:latest # https://hub.docker.com/r/netflyer/openldap-ui
|
||||
ports:
|
||||
- 8080:8080
|
||||
- 8081:8081
|
||||
environment:
|
||||
###############################
|
||||
# PHP LDAP Admin (Port 8080)
|
||||
###############################
|
||||
PHPLDAPADMIN_LDAP_BASE: o=example.com
|
||||
PHPLDAPADMIN_LDAP_CLIENT_TLS: 'false'
|
||||
PHPLDAPADMIN_LDAP_HOSTS: ldap_service
|
||||
###############################
|
||||
# SelfService Password (Port 8081) https://github.com/ltb-project/self-service-password
|
||||
###############################
|
||||
DEBUG_MODE: 'false'
|
||||
#LDAP connection https://ltb-project.org/documentation/self-service-password/1.3/config_ldap
|
||||
LDAP_URL: ldap://ldap_service
|
||||
LDAP_BASE_DN: ou=Users,o=example.com
|
||||
LDAP_USER_DN: uid=ldapbind,ou=TechnicalAccounts,ou=Users,o=example.com
|
||||
LDAP_USER_PASSWORD: CHANGE@it
|
||||
LDAP_FILTER: '(\&(objectClass=inetOrgPerson)(uid={login}))' # backslash is mandatory!
|
||||
LDAP_LOGIN_ATTRIBUTE: 'uid'
|
||||
LDAP_FULLNAME_ATTRIBUTE: 'cn'
|
||||
CHANGE_SSHKEY: 'true'
|
||||
MAIL_ADDRESS_USE_LDAP: 'true'
|
||||
USE_TOKENS: 'false' # don't use "forgot my password" links
|
||||
USE_QUESTIONS: 'false' # https://ltb-project.org/documentation/self-service-password/latest/config_questions
|
||||
# Password policy https://ltb-project.org/documentation/self-service-password/1.3/config_ppolicy
|
||||
PWD_MIN_LENGTH: 8
|
||||
PWD_MAX_LENGTH: 32
|
||||
PWD_MIN_LOWER: 1
|
||||
PWD_MIN_UPPER: 1
|
||||
PWD_MIN_DIGIT: 1
|
||||
PWD_MIN_SPECIAL: 1
|
||||
PWD_NO_REUSE: 'false'
|
||||
PWD_SHOW_POLICY: 'always'
|
||||
PWD_SHOW_POLICY_POS: 'below'
|
||||
USE_PWNEDPASSWORD: 'false'
|
||||
68
example/docker-compose/ldifs/init_org_entries.ldif
Normal file
68
example/docker-compose/ldifs/init_org_entries.ldif
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
version: 1
|
||||
|
||||
##############################
|
||||
# Employees
|
||||
# slappasswd -h {SHA} -s changeit
|
||||
##############################
|
||||
dn: uid=alice,ou=Employees,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Employees
|
||||
ou: Users
|
||||
description: Alice Young
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
objectClass: ldapPublicKey
|
||||
uid: alice
|
||||
cn: Alice Young
|
||||
sn: Young
|
||||
givenName: Alice
|
||||
mail: alice@example.com
|
||||
userPassword: CHANGE@it
|
||||
sshPublicKey:
|
||||
|
||||
dn: uid=bob,ou=Employees,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Employees
|
||||
ou: Users
|
||||
description: Bob Old
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
objectClass: ldapPublicKey
|
||||
uid: bob
|
||||
cn: Bob Old
|
||||
sn: Old
|
||||
givenName: Bob
|
||||
mail: bob@example.com
|
||||
userPassword: CHANGE@it
|
||||
sshPublicKey:
|
||||
|
||||
|
||||
##############################
|
||||
# Technical Accounts
|
||||
##############################
|
||||
dn: uid=ldapbind,ou=TechnicalAccounts,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: TechnicalAccounts
|
||||
ou: Users
|
||||
description: ldapbind user
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
uid: ldapbind
|
||||
cn: ldapbind
|
||||
sn: ldapbind
|
||||
userPassword: CHANGE@it
|
||||
|
||||
##############################
|
||||
# Groups
|
||||
##############################
|
||||
dn: cn=ldapadmins,ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
description: LDAP Administrators Group
|
||||
objectClass: top
|
||||
objectClass: groupOfUniqueNames
|
||||
cn: ldapadmins
|
||||
uniqueMember: uid=alice,ou=Employees,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
uniqueMember: uid=bob,ou=Employees,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
43
example/docker-compose/ldifs/init_org_tree.ldif
Normal file
43
example/docker-compose/ldifs/init_org_tree.ldif
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
version: 1
|
||||
|
||||
##############################
|
||||
# LDAP tree definition
|
||||
##############################
|
||||
dn: ${LDAP_INIT_ORG_DN}
|
||||
description: ${LDAP_INIT_ORG_NAME}
|
||||
objectClass: top
|
||||
objectClass: organization
|
||||
${LDAP_INIT_ORG_DN_ATTR}
|
||||
|
||||
dn: ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
description: Groups
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Users
|
||||
description: Users Accounts
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=Employees,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Employees
|
||||
ou: Users
|
||||
description: Internal Users (Employees)
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: External
|
||||
ou: Users
|
||||
description: External Users (Contractors, Customers)
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=TechnicalAccounts,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: TechnicalAccounts
|
||||
ou: Users
|
||||
description: Technical Accounts
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
24
example/docker/example.env
Normal file
24
example/docker/example.env
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#See https://docs.docker.com/compose/env-file/
|
||||
|
||||
#DEBUG_RUN_SH=0
|
||||
#INIT_SH_FILE=
|
||||
|
||||
LDAP_INIT_ORG_DN=o=yourorg
|
||||
LDAP_INIT_ORG_NAME=Example Inc
|
||||
#LDAP_INIT_ADMIN_GROUP_DN=cn=ldapadmins,ou=Groups,o=yourorg
|
||||
#LDAP_INIT_ROOT_USER_DN=uid=admin,o=yourorg
|
||||
LDAP_INIT_ROOT_USER_PW=password
|
||||
|
||||
#LDAP_INIT_PPOLICY_DEFAULT_DN=cn=DefaultPasswordPolicy,ou=Policies,o=yourorg
|
||||
LDAP_INIT_PPOLICY_PW_MIN_LENGTH=8
|
||||
#LDAP_INIT_PPOLICY_MAX_FAILURES=3
|
||||
#LDAP_INIT_PPOLICY_LOCKOUT_DURATION=300
|
||||
#LDAP_INIT_RFC2307BIS_SCHEMA=0
|
||||
#LDAP_PPOLICY_PQCHECKER_RULE=0|01010101
|
||||
|
||||
#LDAP_NOFILE_LIMIT=1024
|
||||
#LDAP_LOG_LEVELS=Config Stats
|
||||
|
||||
# Format is "HH:MM", i.e. 24-hour format with minute precision
|
||||
#LDAP_BACKUP_TIME=02:00
|
||||
#LDAP_BACKUP_FILE=/var/lib/ldap/data.ldif
|
||||
131
image/Dockerfile
Normal file
131
image/Dockerfile
Normal file
|
|
@ -0,0 +1,131 @@
|
|||
# Copyright 2019-2020 by Vegard IT GmbH, Germany, https://vegardit.com
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# @author Sebastian Thomschke, Vegard IT GmbH
|
||||
#
|
||||
# https://github.com/vegardit/docker-openldap
|
||||
#
|
||||
|
||||
# built daily:
|
||||
# https://hub.docker.com/r/bitnami/minideb/tags?page=1&name=buster
|
||||
FROM bitnami/minideb:buster
|
||||
|
||||
# built monthly:
|
||||
# https://hub.docker.com/_/debian?tab=tags&page=1&name=buster-slim
|
||||
# FROM debian:buster-slim
|
||||
|
||||
LABEL maintainer="Vegard IT GmbH (vegardit.com)"
|
||||
|
||||
# if set to 1 debug tools are added to the image (htop,less,mc,vim)
|
||||
ARG DEBUG_BUILD=0
|
||||
|
||||
ARG PQCHECKER_URL=https://www.meddeb.net/pub/pqchecker/deb/8/pqchecker_2.0.0_amd64.deb
|
||||
ARG PQCHECKER_MD5=c005ce596e97d13e39485e711dcbc7e1
|
||||
|
||||
ARG DEBIAN_FRONTEND=noninteractive
|
||||
ARG LC_ALL=C
|
||||
|
||||
ARG BASE_LAYER_CACHE_KEY
|
||||
|
||||
SHELL ["/bin/bash", "-c"]
|
||||
|
||||
RUN \
|
||||
apt-get update -y && \
|
||||
# https://github.com/phusion/baseimage-docker/issues/319
|
||||
apt-get install -y apt-utils 2> >( grep -v 'debconf: delaying package configuration, since apt-utils is not installed' >&2 ) && \
|
||||
############################################################
|
||||
if [ "${DEBUG_BUILD}" = "1" ]; then \
|
||||
echo "Installing debugging tools..." && \
|
||||
apt-get update -y && \
|
||||
apt-get install --no-install-recommends -y libcomerr2 mc && \
|
||||
apt-get install --no-install-recommends -y htop less procps vim && \
|
||||
echo 'set ignorecase\n\
|
||||
set showmatch\n\
|
||||
set novisualbell\n\
|
||||
set noerrorbells\n\
|
||||
syntax enable\n\
|
||||
set mouse-=a' > ~/.vimrc; \
|
||||
fi && \
|
||||
############################################################
|
||||
echo "Installing slapd..." && \
|
||||
echo 'slapd slapd/root_password password whatever' | debconf-set-selections && \
|
||||
echo 'slapd slapd/root_password_again password whatever' | debconf-set-selections && \
|
||||
apt-get install --no-install-recommends -y slapd ldap-utils && \
|
||||
echo "OpenLDAP $(apt-cache show slapd | grep Version)" >> /opt/build_info && \
|
||||
# workaround for 'service slapd stop' not working, see https://stackoverflow.com/a/58792698/5116073
|
||||
sed -i 's/--exec $SLAPD 2/--name slapd 2/' /etc/init.d/slapd && \
|
||||
############################################################
|
||||
echo "Installing pqChecker password quality checker module..." && \
|
||||
# https://www.meddeb.net/pqchecker/
|
||||
apt-get install --no-install-recommends -y curl && \
|
||||
curl -k -o /tmp/pqchecker.deb -SL "${PQCHECKER_URL}" && \
|
||||
echo "${PQCHECKER_MD5} /tmp/pqchecker.deb" | md5sum -c - && \
|
||||
dpkg -i /tmp/pqchecker.deb && \
|
||||
rm /tmp/pqchecker.deb && \
|
||||
apt-get remove --auto-remove -y curl && \
|
||||
############################################################
|
||||
echo "Moving config and data directories..." && \
|
||||
mv /etc/ldap/slapd.d /etc/ldap/slapd.d_orig && \
|
||||
mkdir /etc/ldap/slapd.d && \
|
||||
mv /var/lib/ldap /var/lib/ldap_orig && \
|
||||
mkdir /var/lib/ldap && \
|
||||
############################################################
|
||||
echo "apt-get clean up..." && \
|
||||
apt-get clean autoclean && \
|
||||
apt-get autoremove --purge -y && \
|
||||
############################################################
|
||||
echo "Removing logs, caches and temp files..." && \
|
||||
rm -rf /var/cache/{apt,debconf} \
|
||||
/var/lib/apt/lists/* \
|
||||
/var/log/{apt,alternatives.log,bootstrap.log,dpkg.log} \
|
||||
/tmp/* /var/tmp/*
|
||||
|
||||
VOLUME ["/etc/ldap/slapd.d", "/var/lib/ldap"]
|
||||
|
||||
ARG GIT_REPO_URL
|
||||
ARG GIT_BRANCH
|
||||
ARG GIT_COMMIT_HASH
|
||||
ARG GIT_COMMIT_DATE
|
||||
|
||||
LABEL \
|
||||
org.label-schema.vcs-ref=$GIT_COMMIT_HASH \
|
||||
org.label-schema.vcs-url="https://github.com/vegardit/docker-openldap"
|
||||
|
||||
RUN \
|
||||
echo "GIT_REPO: $GIT_REPO_URL" > /opt/build_info && \
|
||||
echo "GIT_BRANCH: $GIT_BRANCH" >> /opt/build_info && \
|
||||
echo "GIT_COMMIT: $GIT_COMMIT_HASH @ $GIT_COMMIT_DATE" >> /opt/build_info && \
|
||||
cat /opt/build_info
|
||||
|
||||
COPY ldifs /opt/ldifs
|
||||
COPY run.sh /opt/run.sh
|
||||
|
||||
# Default configuration: can be overridden at the docker command line
|
||||
ENV \
|
||||
DEBUG_RUN_SH=0 \
|
||||
INIT_SH_FILE='' \
|
||||
LDAP_INIT_ORG_DN='o=example.com' \
|
||||
LDAP_INIT_ORG_NAME='Example Corporation' \
|
||||
LDAP_INIT_ADMIN_GROUP_DN='cn=ldapadmins,ou=Groups,${LDAP_INIT_ORG_DN}' \
|
||||
LDAP_INIT_ROOT_USER_DN='uid=admin,${LDAP_INIT_ORG_DN}' \
|
||||
LDAP_INIT_ROOT_USER_PW='changeit' \
|
||||
LDAP_INIT_PPOLICY_DEFAULT_DN='cn=DefaultPasswordPolicy,ou=Policies,${LDAP_INIT_ORG_DN}' \
|
||||
LDAP_INIT_PPOLICY_PW_MIN_LENGTH=8 \
|
||||
LDAP_INIT_PPOLICY_MAX_FAILURES=3 \
|
||||
LDAP_INIT_PPOLICY_LOCKOUT_DURATION=300 \
|
||||
LDAP_INIT_RFC2307BIS_SCHEMA=0 \
|
||||
LDAP_PPOLICY_PQCHECKER_RULE='0|01010101' \
|
||||
LDAP_NOFILE_LIMIT=1024 \
|
||||
LDAP_LOG_LEVELS='Config Stats' \
|
||||
# Format is "HH:MM", i.e. 24-hour format with minute precision
|
||||
LDAP_BACKUP_TIME='02:00' \
|
||||
LDAP_BACKUP_FILE='/var/lib/ldap/data.ldif' \
|
||||
LDAP_OPENLDAP_UID='' \
|
||||
LDAP_OPENLDAP_GID=''
|
||||
|
||||
EXPOSE 389
|
||||
|
||||
ENTRYPOINT ["/bin/sh", "-c"]
|
||||
|
||||
# exec is required for propagating SIGTERM from docker to child process
|
||||
CMD ["exec /bin/bash /opt/run.sh"]
|
||||
12
image/ldifs/init_frontend.ldif
Normal file
12
image/ldifs/init_frontend.ldif
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
version: 1
|
||||
|
||||
# Global Database Options @ https://linux.die.net/man/5/slapd-config
|
||||
|
||||
dn: olcDatabase={-1}frontend,cn=config
|
||||
changetype: modify
|
||||
replace: olcPasswordHash
|
||||
olcPasswordHash: {SSHA}
|
||||
-
|
||||
# maximum number of seconds (in real time) slapd will spend answering a search request
|
||||
replace: olcTimeLimit
|
||||
olcTimeLimit: 60
|
||||
20
image/ldifs/init_mdb.ldif
Normal file
20
image/ldifs/init_mdb.ldif
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
version: 1
|
||||
|
||||
# General Database Options @ https://linux.die.net/man/5/slapd-config
|
||||
|
||||
dn: olcDatabase={1}mdb,cn=config
|
||||
changetype: modify
|
||||
########################
|
||||
# configure Base DN
|
||||
########################
|
||||
replace: olcSuffix
|
||||
olcSuffix: ${LDAP_INIT_ORG_DN}
|
||||
-
|
||||
########################
|
||||
# configure root user
|
||||
########################
|
||||
replace: olcRootDN
|
||||
olcRootDN: ${LDAP_INIT_ROOT_USER_DN}
|
||||
-
|
||||
replace: olcRootPW
|
||||
olcRootPW: ${LDAP_INIT_ROOT_USER_PW_HASHED}
|
||||
37
image/ldifs/init_mdb_acls.ldif
Normal file
37
image/ldifs/init_mdb_acls.ldif
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
version: 1
|
||||
|
||||
# General Database Options @ https://linux.die.net/man/5/slapd-config
|
||||
|
||||
dn: olcDatabase={1}mdb,cn=config
|
||||
changetype: modify
|
||||
########################
|
||||
# configure ACLs
|
||||
########################
|
||||
replace: olcAccess
|
||||
olcAccess: {0}to attrs=userPassword
|
||||
by dn="${LDAP_INIT_ROOT_USER_DN}" write
|
||||
by group/groupOfUniqueNames/uniqueMember="${LDAP_INIT_ADMIN_GROUP_DN}" write
|
||||
by self write
|
||||
by anonymous auth
|
||||
by * none
|
||||
olcAccess: {1}to attrs=shadowLastChange
|
||||
by self write
|
||||
by users read
|
||||
by * none
|
||||
olcAccess: {2}to attrs=sshPublicKey
|
||||
by dn="${LDAP_INIT_ROOT_USER_DN}" write
|
||||
by group/groupOfUniqueNames/uniqueMember="${LDAP_INIT_ADMIN_GROUP_DN}" write
|
||||
by self write
|
||||
by users read
|
||||
by * none
|
||||
# This ACL gives incoming connections the ability to read the rootDSE.
|
||||
# It is important to allow this, as clients may need to obtain information from the base level (such as your supported SASL Mechanisms).
|
||||
# The ".base" portion of the ACL restricts clients to querying only the top level
|
||||
olcAccess: {3}to dn.base=""
|
||||
by * read
|
||||
olcAccess: {4}to *
|
||||
by dn="${LDAP_INIT_ROOT_USER_DN}" write
|
||||
by group/groupOfUniqueNames/uniqueMember="${LDAP_INIT_ADMIN_GROUP_DN}" write
|
||||
by users read
|
||||
by anonymous auth
|
||||
by * none
|
||||
15
image/ldifs/init_mdb_indexes.ldif
Normal file
15
image/ldifs/init_mdb_indexes.ldif
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
version: 1
|
||||
|
||||
# General Database Options @ https://linux.die.net/man/5/slapd-config
|
||||
|
||||
dn: olcDatabase={1}mdb,cn=config
|
||||
changetype: modify
|
||||
########################
|
||||
# configure DB indexes
|
||||
########################
|
||||
replace: olcDbIndex
|
||||
olcDbIndex: objectClass pres,eq
|
||||
olcDbIndex: uid,mail pres,eq
|
||||
olcDbIndex: uidNumber,gidNumber eq
|
||||
olcDbIndex: cn,givenName,sn,ou pres,eq,approx,sub
|
||||
olcDbIndex: member,memberUid,memberOf,uniqueMember pres,eq
|
||||
31
image/ldifs/init_module_memberof.ldif
Normal file
31
image/ldifs/init_module_memberof.ldif
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
version: 1
|
||||
|
||||
dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: memberof
|
||||
olcModuleLoad: refint
|
||||
|
||||
dn: olcOverlay=memberof,olcDatabase={1}mdb,cn=config
|
||||
objectClass: top
|
||||
objectClass: olcConfig
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcMemberOf
|
||||
olcOverlay: memberof
|
||||
olcMemberOfDangling: ignore
|
||||
olcMemberOfRefInt: TRUE
|
||||
olcMemberOfGroupOC: groupOfUniqueNames
|
||||
olcMemberOfMemberAD: uniqueMember
|
||||
olcMemberOfMemberOfAD: memberOf
|
||||
|
||||
dn: olcOverlay=refint,olcDatabase={1}mdb,cn=config
|
||||
objectClass: top
|
||||
objectClass: olcConfig
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcRefintConfig
|
||||
olcOverlay: refint
|
||||
olcRefintAttribute: owner
|
||||
olcRefintAttribute: manager
|
||||
olcRefintAttribute: member
|
||||
olcRefintAttribute: memberOf
|
||||
olcRefintAttribute: uniqueMember
|
||||
18
image/ldifs/init_module_ppolicy.ldif
Normal file
18
image/ldifs/init_module_ppolicy.ldif
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
version: 1
|
||||
|
||||
dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: ppolicy
|
||||
|
||||
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
|
||||
objectClass: top
|
||||
objectClass: olcConfig
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcPPolicyConfig
|
||||
olcOverlay: ppolicy
|
||||
olcPPolicyDefault: ${LDAP_INIT_PPOLICY_DEFAULT_DN}
|
||||
olcPPolicyHashCleartext: TRUE
|
||||
# return AccountLocked instead of InvalidCredentials error:
|
||||
olcPPolicyUseLockout: TRUE
|
||||
olcPPolicyForwardUpdates: FALSE
|
||||
18
image/ldifs/init_module_unique.ldif
Normal file
18
image/ldifs/init_module_unique.ldif
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
version: 1
|
||||
|
||||
dn: cn=module{0},cn=config
|
||||
changetype: modify
|
||||
add: olcModuleLoad
|
||||
olcModuleLoad: unique
|
||||
|
||||
dn: olcOverlay=unique,olcDatabase={1}mdb,cn=config
|
||||
objectClass: top
|
||||
objectClass: olcConfig
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcUniqueConfig
|
||||
olcOverlay: unique
|
||||
olcUniqueURI: ldap:///${LDAP_INIT_ORG_DN}?cn?sub
|
||||
olcUniqueURI: ldap:///${LDAP_INIT_ORG_DN}?uid?sub
|
||||
olcUniqueURI: ldap:///ou=Users,${LDAP_INIT_ORG_DN}?mail?sub
|
||||
olcUniqueURI: ldap:///ou=Users,${LDAP_INIT_ORG_DN}?gidNumber?sub
|
||||
olcUniqueURI: ldap:///ou=Users,${LDAP_INIT_ORG_DN}?uidNumber?sub
|
||||
95
image/ldifs/init_org_entries.ldif
Normal file
95
image/ldifs/init_org_entries.ldif
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
version: 1
|
||||
|
||||
##############################
|
||||
# Internal Users
|
||||
##############################
|
||||
dn: uid=employee1,ou=Internal,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Internal
|
||||
ou: Users
|
||||
description: Employee 1
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
objectClass: ldapPublicKey
|
||||
uid: employee1
|
||||
cn: Employee1
|
||||
sn: Employee1
|
||||
givenName: Employee1
|
||||
mail: employee1@example.com
|
||||
userPassword: changeit
|
||||
|
||||
|
||||
##############################
|
||||
# External Users
|
||||
##############################
|
||||
dn: uid=guest1,ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: External
|
||||
ou: Users
|
||||
description: Guest 1
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
uid: guest1
|
||||
cn: Guest1
|
||||
sn: Guest1
|
||||
givenName: Guest1
|
||||
mail: guest1@example.com
|
||||
userPassword: changeit
|
||||
|
||||
|
||||
##############################
|
||||
# Technical Users
|
||||
##############################
|
||||
dn: uid=machine1,ou=TechnicalAccounts,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: External
|
||||
ou: Users
|
||||
description: Machine 1
|
||||
objectClass: top
|
||||
objectClass: inetOrgPerson
|
||||
objectClass: organizationalPerson
|
||||
objectClass: person
|
||||
objectClass: ldapPublicKey
|
||||
uid: machine1
|
||||
cn: Machine1
|
||||
sn: Machine1
|
||||
givenName: Machine1
|
||||
mail: machine1@example.com
|
||||
userPassword: changeit
|
||||
|
||||
|
||||
##############################
|
||||
# Groups
|
||||
##############################
|
||||
dn: cn=ldapadmins,ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
objectClass: top
|
||||
objectClass: groupOfUniqueNames
|
||||
cn: ldapadmins
|
||||
description: Ldap Admin Group
|
||||
uniqueMember: uid=employee1,ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
|
||||
dn: cn=employees,ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
objectClass: top
|
||||
objectClass: groupOfUniqueNames
|
||||
cn: employees
|
||||
description: Employees Group
|
||||
uniqueMember: uid=employee1,ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
|
||||
dn: cn=guests,ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
objectClass: top
|
||||
objectClass: groupOfUniqueNames
|
||||
cn: guests
|
||||
description: Guests Group
|
||||
uniqueMember: uid=guest1,ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
|
||||
dn: cn=machines,ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
objectClass: top
|
||||
objectClass: groupOfUniqueNames
|
||||
cn: machines
|
||||
description: Machines Group
|
||||
uniqueMember: uid=machine1,ou=TechnicalAccounts,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
40
image/ldifs/init_org_ppolicy.ldif
Normal file
40
image/ldifs/init_org_ppolicy.ldif
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
version: 1
|
||||
|
||||
##############################
|
||||
# Password Policy
|
||||
##############################
|
||||
dn: ou=Policies,${LDAP_INIT_ORG_DN}
|
||||
ou: Policies
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: cn=DefaultPasswordPolicy,ou=Policies,${LDAP_INIT_ORG_DN}
|
||||
objectClass: top
|
||||
objectClass: device
|
||||
objectClass: pwdPolicy
|
||||
objectClass: pwdPolicyChecker
|
||||
cn: DefaultPasswordPolicy
|
||||
pwdAttribute: userPassword
|
||||
# 0=reset count of consecutive password failures only on successful authentication
|
||||
pwdFailureCountInterval: 0
|
||||
# maximum number of consecutive password failures locking the account
|
||||
pwdMaxFailure: ${LDAP_INIT_PPOLICY_MAX_FAILURES:-3}
|
||||
pwdMinAge: 0
|
||||
pwdMustChange: TRUE
|
||||
# if TRUE user must send current password during password modification operation
|
||||
pwdSafeModify: FALSE
|
||||
# number of passwords maintained in a list of previously used passwords
|
||||
pwdInHistory: 0
|
||||
# number of further bind operations after a password has expired
|
||||
pwdGraceAuthNLimit: 0
|
||||
# account lock duration in seconds (300=5min)
|
||||
pwdLockoutDuration: ${LDAP_INIT_PPOLICY_LOCKOUT_DURATION:-300}
|
||||
pwdAllowUserChange: TRUE
|
||||
#0=do not show expiration warning on bind
|
||||
pwdExpireWarning: 0
|
||||
pwdLockout: TRUE
|
||||
pwdMaxAge: 0
|
||||
# Password Quality
|
||||
pwdMinLength: ${LDAP_INIT_PPOLICY_PW_MIN_LENGTH:-8}
|
||||
pwdCheckQuality: 2
|
||||
pwdCheckModule: /usr/lib/ldap/pqchecker.so
|
||||
43
image/ldifs/init_org_tree.ldif
Normal file
43
image/ldifs/init_org_tree.ldif
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
version: 1
|
||||
|
||||
##############################
|
||||
# LDAP tree definition
|
||||
##############################
|
||||
dn: ${LDAP_INIT_ORG_DN}
|
||||
description: ${LDAP_INIT_ORG_NAME}
|
||||
objectClass: top
|
||||
objectClass: organization
|
||||
${LDAP_INIT_ORG_DN_ATTR}
|
||||
|
||||
dn: ou=Groups,${LDAP_INIT_ORG_DN}
|
||||
ou: Groups
|
||||
description: Groups
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Users
|
||||
description: Users Accounts
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=Internal,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: Internal
|
||||
ou: Users
|
||||
description: Internal Users (Employees)
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=External,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: External
|
||||
ou: Users
|
||||
description: External Users (Contractors, Customers)
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
|
||||
dn: ou=TechnicalAccounts,ou=Users,${LDAP_INIT_ORG_DN}
|
||||
ou: TechnicalAccounts
|
||||
ou: Users
|
||||
description: Technical Accounts
|
||||
objectClass: top
|
||||
objectClass: organizationalUnit
|
||||
15
image/ldifs/schema_ldapPublicKey.ldif
Normal file
15
image/ldifs/schema_ldapPublicKey.ldif
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
dn: cn=openssh-lpk,cn=schema,cn=config
|
||||
objectClass: olcSchemaConfig
|
||||
cn: openssh-lpk
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.24552.500.1.1.1.13
|
||||
NAME 'sshPublicKey'
|
||||
DESC 'MANDATORY: OpenSSH Public key'
|
||||
EQUALITY octetStringMatch
|
||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
|
||||
)
|
||||
olcObjectClasses: ( 1.3.6.1.4.1.24552.500.1.1.2.0
|
||||
NAME 'ldapPublicKey'
|
||||
DESC 'MANDATORY: OpenSSH LPK objectclass'
|
||||
SUP top
|
||||
AUXILIARY MAY ( sshPublicKey $ uid )
|
||||
)
|
||||
53
image/ldifs/schema_rfc2307bis02.ldif
Normal file
53
image/ldifs/schema_rfc2307bis02.ldif
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
# https://tools.ietf.org/html/draft-howard-rfc2307bis-02
|
||||
dn: cn=rfc2307bis,cn=schema,cn=config
|
||||
objectClass: olcSchemaConfig
|
||||
cn: rfc2307bis
|
||||
olcAttributeTypes: ( 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.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 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 1.3.6.1.1.1.1.12 NAME 'memberUid' EQUALITY caseExactMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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: ( 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 )
|
||||
olcAttributeTypes: ( 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 )
|
||||
olcAttributeTypes: ( 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: ( 1.3.6.1.1.1.2.0 NAME 'posixAccount' DESC 'Abstraction of an account with POSIX attributes' SUP top AUXILIARY MUST ( cn $ uid $ uidNumber $ gidNumber $ homeDirectory ) MAY ( userPassword $ loginShell $ gecos $ description ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount' DESC 'Additional attributes for shadow passwords' SUP top AUXILIARY MUST uid MAY ( userPassword $ description $ shadowLastChange $ shadowMin $ shadowMax $ shadowWarning $ shadowInactive $ shadowExpire $ shadowFlag ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.2 NAME 'posixGroup' DESC 'Abstraction of a group of accounts' SUP top AUXILIARY MUST gidNumber MAY ( userPassword $ memberUid $ description ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.3 NAME 'ipService' 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' SUP top STRUCTURAL MUST ( cn $ ipServicePort $ ipServiceProtocol ) MAY description )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.4 NAME 'ipProtocol' 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' SUP top STRUCTURAL MUST ( cn $ ipProtocolNumber ) MAY description )
|
||||
olcObjectClasses: ( 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 $ oncRpcNumber ) MAY description )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.6 NAME 'ipHost' 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' SUP top AUXILIARY MUST ( cn $ ipHostNumber ) MAY ( userPassword $ l $ description $ manager ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.7 NAME 'ipNetwork' DESC 'Abstraction of a network. The distinguished value of the cn attribute denotes the network canonical name' SUP top STRUCTURAL MUST ipNetworkNumber MAY ( cn $ ipNetmaskNumber $ l $ description $ manager ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.8 NAME 'nisNetgroup' DESC 'Abstraction of a netgroup. May refer to other netgroups' SUP top STRUCTURAL MUST cn MAY ( nisNetgroupTriple $ memberNisNetgroup $ description ) )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.9 NAME 'nisMap' DESC 'A generic abstraction of a NIS map' SUP top STRUCTURAL MUST nisMapName MAY description )
|
||||
olcObjectClasses: ( 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: ( 1.3.6.1.1.1.2.11 NAME 'ieee802Device' DESC 'A device with a MAC address; device SHOULD be used as a structural class' SUP top AUXILIARY MAY macAddress )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.12 NAME 'bootableDevice' DESC 'A device with boot parameters; device SHOULD be used as a structural class' SUP top AUXILIARY MAY ( bootFile $ bootParameter ) )
|
||||
olcObjectClasses: ( 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: ( 1.3.6.1.1.1.2.15 NAME 'nisDomainObject' DESC 'Associates a NIS domain with a naming context' SUP top AUXILIARY MUST nisDomain )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL MUST automountMapName MAY description )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.17 NAME 'automount' DESC 'Automount information' SUP top STRUCTURAL MUST ( automountKey $ automountInformation ) MAY description )
|
||||
olcObjectClasses: ( 1.3.6.1.1.1.2.18 NAME 'groupOfMembers' DESC 'A group with members (DNs)' SUP top STRUCTURAL MUST cn MAY ( businessCategory $ seeAlso $ owner $ ou $ o $ description $ member ) )
|
||||
11
image/ldifs/schema_sudo.ldif
Normal file
11
image/ldifs/schema_sudo.ldif
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
dn: cn=sudo,cn=schema,cn=config
|
||||
objectClass: olcSchemaConfig
|
||||
cn: sudo
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.1 NAME 'sudoUser' DESC 'User(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.2 NAME 'sudoHost' DESC 'Host(s) who may run sudo' EQUALITY caseExactIA5Match SUBSTR caseExactIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.3 NAME 'sudoCommand' DESC 'Command(s) to be executed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.4 NAME 'sudoRunAs' DESC 'User(s) impersonated by sudo (deprecated)' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.5 NAME 'sudoOption' DESC 'Options(s) followed by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.6 NAME 'sudoRunAsUser' DESC 'User(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcAttributeTypes: ( 1.3.6.1.4.1.15953.9.1.7 NAME 'sudoRunAsGroup' DESC 'Group(s) impersonated by sudo' EQUALITY caseExactIA5Match SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 )
|
||||
olcObjectClasses: ( 1.3.6.1.4.1.15953.9.2.1 NAME 'sudoRole' DESC 'Sudoer Entries' SUP top STRUCTURAL MUST cn MAY ( sudoUser $ sudoHost $ sudoCommand $ sudoRunAs $ sudoRunAsUser $ sudoRunAsGroup $ sudoOption $ description ) )
|
||||
238
image/run.sh
Normal file
238
image/run.sh
Normal file
|
|
@ -0,0 +1,238 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright 2019-2020 by Vegard IT GmbH, Germany, https://vegardit.com
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
# @author Sebastian Thomschke, Vegard IT GmbH
|
||||
#
|
||||
# https://github.com/vegardit/docker-openldap
|
||||
#
|
||||
|
||||
set -e -u
|
||||
if [ -z "${BASH_VERSINFO:-}" ]; then /usr/bin/env bash "$0" "$@"; exit; fi
|
||||
set -o pipefail
|
||||
trap 'echo >&2 "$(date +%H:%M:%S) Error - exited with status $? at line $LINENO:"; pr -tn $0 | tail -n+$((LINENO - 3)) | head -n7' ERR
|
||||
|
||||
if [ "${DEBUG_RUN_SH:-}" == "1" ]; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
cat <<'EOF'
|
||||
_ __ __ __________
|
||||
| | / /__ ____ _____ __________/ / / _/_ __/
|
||||
| | / / _ \/ __ `/ __ `/ ___/ __ / / / / /
|
||||
| |/ / __/ /_/ / /_/ / / / /_/ / _/ / / /
|
||||
|___/\___/\__, /\__,_/_/ \__,_/ /___/ /_/
|
||||
/____/
|
||||
|
||||
EOF
|
||||
|
||||
cat /opt/build_info
|
||||
echo
|
||||
|
||||
if [ -f "$INIT_SH_FILE" ]; then
|
||||
source "$INIT_SH_FILE"
|
||||
fi
|
||||
|
||||
|
||||
function log() {
|
||||
if [ -p /dev/stdin ]; then
|
||||
while read line; do
|
||||
echo "[$(date "+%Y-%m-%d %H:%M:%S") ${BASH_SOURCE}:${BASH_LINENO}] $line"
|
||||
done
|
||||
else
|
||||
echo "[$(date "+%Y-%m-%d %H:%M:%S") ${BASH_SOURCE}:${BASH_LINENO}] ${@}"
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# display slapd build info
|
||||
slapd -VVV 2>&1 | log || true
|
||||
|
||||
|
||||
# Limit maximum number of open file descriptors otherwise slapd consumes two
|
||||
# orders of magnitude more of RAM, see https://github.com/docker/docker/issues/8231
|
||||
ulimit -n $LDAP_NOFILE_LIMIT
|
||||
|
||||
|
||||
#################################################################
|
||||
# Adjust UID/GID and file permissions based on env var config
|
||||
#################################################################
|
||||
if [ -n "${LDAP_OPENLDAP_UID:-}" ]; then
|
||||
effective_uid=$(id -u openldap)
|
||||
if [ "$LDAP_OPENLDAP_UID" != "$effective_uid" ]; then
|
||||
log "Changing UID of openldap user from $effective_uid to $LDAP_OPENLDAP_UID..."
|
||||
usermod -o -u "$LDAP_OPENLDAP_UID" openldap
|
||||
fi
|
||||
fi
|
||||
if [ -n "${LDAP_OPENLDAP_GID:-}" ]; then
|
||||
effective_gid=$(id -g openldap)
|
||||
if [ "$LDAP_OPENLDAP_GID" != "$effective_gid" ]; then
|
||||
log "Changing GID of openldap user from $effective_gid to $LDAP_OPENLDAP_GID..."
|
||||
usermod -o -u "$LDAP_OPENLDAP_GID" openldap
|
||||
fi
|
||||
fi
|
||||
chown -R openldap:openldap /etc/ldap
|
||||
chown -R openldap:openldap /var/lib/ldap
|
||||
chown -R openldap:openldap /var/lib/ldap_orig
|
||||
chown -R openldap:openldap /var/run/slapd
|
||||
|
||||
|
||||
#################################################################
|
||||
# Configure LDAP server on initial container launch
|
||||
#################################################################
|
||||
if [ ! -e /etc/ldap/slapd.d/initialized ]; then
|
||||
|
||||
function interpolate_vars() {
|
||||
# https://stackoverflow.com/a/40167919
|
||||
local line lineEscaped
|
||||
while IFS= read -r line || [ -n "$line" ]; do # the `||` clause ensures that the last line is read even if it doesn't end with \n
|
||||
# escape all chars that could trigger an expansion
|
||||
IFS= read -r lineEscaped < <(echo "$line" | tr '`([$' '\1\2\3\4')
|
||||
# selectively re-enable ${ references
|
||||
lineEscaped=${lineEscaped//$'\4'{/\${}
|
||||
# escape embedded double quotes to preserve them
|
||||
lineEscaped=${lineEscaped//\"/\\\"}
|
||||
eval "printf '%s\n' \"$lineEscaped\"" | tr '\1\2\3\4' '`([$'
|
||||
done
|
||||
}
|
||||
|
||||
function substr_before() {
|
||||
echo "${1%%$2*}"
|
||||
}
|
||||
|
||||
function str_replace() {
|
||||
IFS= read -r -d $'\0' str
|
||||
echo "${str/$1/$2}"
|
||||
}
|
||||
|
||||
function ldif() {
|
||||
log "--------------------------------------------"
|
||||
local action=$1 && shift
|
||||
local file=${!#}
|
||||
log "Loading [$file]..."
|
||||
interpolate_vars < $file > /tmp/$(basename $file)
|
||||
ldap$action -H ldapi:/// "${@:1:${#}-1}" -f /tmp/$(basename $file)
|
||||
}
|
||||
|
||||
# interpolate variable placeholders in env vars starting with "LDAP_INIT_"
|
||||
for name in ${!LDAP_INIT_*}; do
|
||||
declare "${name}=$(echo "${!name}" | interpolate_vars)"
|
||||
done
|
||||
|
||||
# pre-populate folders in case they are empty
|
||||
for folder in "/var/lib/ldap" "/etc/ldap/slapd.d"; do
|
||||
if [ "$folder" -ef "${folder}_orig" ]; then
|
||||
continue
|
||||
fi
|
||||
if [ -z "$(ls $folder)" ]; then
|
||||
log "Initializing [$folder]..."
|
||||
cp -r --preserve=all ${folder}_orig/. $folder
|
||||
fi
|
||||
done
|
||||
|
||||
LDAP_INIT_ROOT_USER_PW_HASHED=$(slappasswd -s "${LDAP_INIT_ROOT_USER_PW}")
|
||||
/etc/init.d/slapd start
|
||||
sleep 3
|
||||
|
||||
if [ "${LDAP_INIT_RFC2307BIS_SCHEMA:-}" == "1" ]; then
|
||||
log "Replacing NIS (RFC2307) schema with RFC2307bis schema..."
|
||||
ldapdelete -Y EXTERNAL cn={2}nis,cn=schema,cn=config
|
||||
ldif add -Y EXTERNAL /opt/ldifs/schema_rfc2307bis02.ldif
|
||||
fi
|
||||
|
||||
ldif add -Y EXTERNAL /etc/ldap/schema/ppolicy.ldif
|
||||
ldif add -Y EXTERNAL /opt/ldifs/schema_sudo.ldif
|
||||
ldif add -Y EXTERNAL /opt/ldifs/schema_ldapPublicKey.ldif
|
||||
|
||||
ldif modify -Y EXTERNAL /opt/ldifs/init_frontend.ldif
|
||||
ldif add -Y EXTERNAL /opt/ldifs/init_module_memberof.ldif
|
||||
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb.ldif
|
||||
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb_acls.ldif
|
||||
ldif modify -Y EXTERNAL /opt/ldifs/init_mdb_indexes.ldif
|
||||
ldif add -Y EXTERNAL /opt/ldifs/init_module_unique.ldif
|
||||
ldif add -Y EXTERNAL /opt/ldifs/init_module_ppolicy.ldif
|
||||
|
||||
LDAP_INIT_ORG_DN_ATTR=$(substr_before $LDAP_INIT_ORG_DN "," | str_replace "=" ": ") # referenced by init_org_tree.ldif
|
||||
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_tree.ldif
|
||||
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_ppolicy.ldif
|
||||
ldif add -x -D "$LDAP_INIT_ROOT_USER_DN" -w "$LDAP_INIT_ROOT_USER_PW" /opt/ldifs/init_org_entries.ldif
|
||||
|
||||
log "--------------------------------------------"
|
||||
|
||||
echo "1" > /etc/ldap/slapd.d/initialized
|
||||
rm -f /tmp/*.ldif
|
||||
|
||||
log "Creating periodic LDAP backup at [$LDAP_BACKUP_FILE]..."
|
||||
slapcat -n 1 -l $LDAP_BACKUP_FILE || true
|
||||
|
||||
/etc/init.d/slapd stop
|
||||
sleep 3
|
||||
fi
|
||||
|
||||
echo "$LDAP_PPOLICY_PQCHECKER_RULE" > /etc/ldap/pqchecker/pqparams.dat
|
||||
|
||||
|
||||
#################################################################
|
||||
# Configure LDAP backup task
|
||||
#################################################################
|
||||
if [ -n "${LDAP_BACKUP_TIME:-}" ]; then
|
||||
log "--------------------------------------------"
|
||||
log "Configuring LDAP backup task to run daily: time=[${LDAP_BACKUP_TIME}] file=[$LDAP_BACKUP_FILE]..."
|
||||
function backup_ldap() {
|
||||
while true; do
|
||||
while [ "$(date +%H:%M)" != "${LDAP_BACKUP_TIME}" ]; do
|
||||
sleep 10s
|
||||
done
|
||||
log "Creating periodic LDAP backup at [$LDAP_BACKUP_FILE]..."
|
||||
slapcat -n 1 -l $LDAP_BACKUP_FILE || true
|
||||
sleep 23h
|
||||
done
|
||||
}
|
||||
|
||||
backup_ldap &
|
||||
fi
|
||||
|
||||
|
||||
#################################################################
|
||||
# Start LDAP service
|
||||
#################################################################
|
||||
log "--------------------------------------------"
|
||||
log "Starting OpenLDAP: slapd..."
|
||||
|
||||
#required for propagating SIGTERM from docker to service process
|
||||
#https://unix.stackexchange.com/questions/146756/forward-sigterm-to-child-in-bash/444676#444676
|
||||
function trap_handler() {
|
||||
local signal=$1
|
||||
if [ -n "${service_process_pid:-}" ]; then
|
||||
log "Sending [$signal] to PID [$service_process_pid] ..."
|
||||
kill -s $signal $service_process_pid 2>/dev/null
|
||||
else
|
||||
log "Received [$signal] before service started."
|
||||
sig_received_before_service_started=$signal
|
||||
fi
|
||||
}
|
||||
|
||||
trap 'trap_handler TERM' SIGTERM SIGINT SIGHUP # https://github.com/openldap/openldap/search?q=SIGTERM
|
||||
trap 'trap_handler QUIT' SIGQUIT
|
||||
trap 'trap_handler USR1' SIGUSR1 # https://github.com/openldap/openldap/search?q=SIGUSR1
|
||||
trap 'trap_handler USR2' SIGUSR2 # https://github.com/openldap/openldap/search?q=SIGUSR2
|
||||
|
||||
/usr/sbin/slapd \
|
||||
$(for logLevel in ${LDAP_LOG_LEVELS:-}; do echo -n "-d $logLevel "; done) \
|
||||
-h "ldap:/// ldapi:///" \
|
||||
-u openldap -g openldap \
|
||||
-F /etc/ldap/slapd.d 2>&1 | log &
|
||||
|
||||
service_process_pid=$(jobs -p | tail -1)
|
||||
log "OpenLDAP PID: $service_process_pid"
|
||||
|
||||
if [ -n "${sig_received_before_service_started:-}" ]; then
|
||||
kill -s $sig_received_before_service_started $service_process_pid 2>/dev/null
|
||||
fi
|
||||
|
||||
wait $service_process_pid
|
||||
trap - TERM INT
|
||||
wait $service_process_pid
|
||||
exit_status=$?
|
||||
exit $exit_status
|
||||
Loading…
Reference in a new issue