mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

dependabot[bot]
6 hours ago e36f9dc8e309999aa3e017e8cb83bdecf100f8ff
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#!/usr/bin/env bash
# The contents of this file are subject to the terms of the Common Development and
# Distribution License (the License). You may not use this file except in compliance with the
# License.
#
# You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
# specific language governing permission and limitations under the License.
#
# When distributing Covered Software, include this CDDL Header Notice in each file and include
# the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
# Header, with the fields enclosed by brackets [] replaced by your own identifying
# information: "Portions copyright [year] [name of copyright owner]".
#
# Portions copyright 2026 3A Systems, LLC.
 
# Default setup script
#
# What the instance is made of - the server itself, the backend, the entries the backend was
# asked to hold - is left to fail this script, which is what run.sh reads to decide whether
# the container may report itself healthy. The optional schema and data LDIFs below keep the
# tolerance they were written with.
 
echo "Setting up default OpenDJ instance"
 
# A replication server of the background join holds no data (#1178): it gets no backend for
# BASE_DN, and none of the entries below - entries there would replicate nowhere, and be
# served to any client that reaches it. run.sh marks a volume $INITIALIZE_PENDING before its
# bootstrap exactly when the background join runs; without the join the server holds its data
# as any other - one with neither would be healthy and serve nothing - and REPLICATION_ROLE
# is not read. The role is checked here as join.sh checks it, before anything is set up: a
# value the join refuses would otherwise leave a volume set up for another role than the one
# asked for. It is recorded on the volume, where join.sh reads it on every start: the volume
# is what makes the role, whatever REPLICATION_ROLE says later.
HOLDS_DATA=true
if [ -n "$INITIALIZE_PENDING" ] && [ -f "$INITIALIZE_PENDING" ]; then
  role=${REPLICATION_ROLE:-combined}
  case $role in
    combined | directory) ;;
    replication)
      HOLDS_DATA=false
      echo "REPLICATION_ROLE=replication: no backend is created for $BASE_DN, and no entries are loaded" ;;
    *)
      echo "REPLICATION_ROLE=$REPLICATION_ROLE is not one of combined, directory or replication" >&2
      exit 1 ;;
  esac
  printf '%s\n' "$role" >"${REPLICATION_ROLE_FILE:-/opt/opendj/data/.replication-role}" || exit 1
fi
 
# The tools read only the first line of a password file, and a CR ends it as an LF does, so a
# password with a line break would be cut there - silently, as the root password set up would
# not be the one the container was given
cr=$(printf '\r')
nl='
'
case $ROOT_PASSWORD in
  *"$cr"*|*"$nl"*)
    echo "ROOT_PASSWORD must not contain a line break: the tools read only the first line of the password file" >&2
    exit 1 ;;
esac
 
# The tools read the root password from a file, so that any password setup accepts reaches
# them as one value, and it does not show on the command line of a process while the tool
# runs. mktemp creates the file readable by its owner only. The EXIT trap does not run when the
# container is killed during the bootstrap, so the file goes to the tmpfs of /dev/shm where
# there is one, rather than to the writable layer of the container, and run.sh removes what a
# killed bootstrap left behind before anything else. On Kubernetes /dev/shm is shared by all
# the containers of the pod and outlives a restart of this one, which is what the removal in
# run.sh is for there; the name carries ADMIN_PORT, so that it removes only the file of this
# container. Busybox mktemp replaces only the last six X of the template.
PASSWORD_FILE=$(mktemp -p /dev/shm "opendj-setup-password.$ADMIN_PORT.XXXXXX" 2>/dev/null \
  || mktemp "/tmp/opendj-setup-password.$ADMIN_PORT.XXXXXX") || exit 1
# the trap also removes the base entry template below, which a failed import would leave in /tmp
BASE_TEMPLATE=
trap 'rm -f "$PASSWORD_FILE" ${BASE_TEMPLATE:+"$BASE_TEMPLATE"}' EXIT
printf '%s\n' "$ROOT_PASSWORD" >"$PASSWORD_FILE" || exit 1
 
# If any optional LDIF files are present load them
 
# There are multiple types of ldif files.
# This step makes plain copies.
# See below for imports via `ldapmodify`.
if [ -d /opt/opendj/bootstrap/config/schema/ ]; then
  echo "Copying schema:"
  mkdir -p /opt/opendj/template/config/schema
  for file in /opt/opendj/bootstrap/config/schema/*; do
    target_file="/opt/opendj/template/config/schema/$(basename -- "$file")"
    echo "Copying $file to $target_file"
    cp "$file" "$target_file"
  done
fi
 
/opt/opendj/setup \
  --cli \
  -h localhost \
  --ldapPort $PORT \
  --ldapsPort $LDAPS_PORT \
  --enableStartTLS $OPENDJ_SSL_OPTIONS \
  --adminConnectorPort $ADMIN_PORT \
  --rootUserDN "$ROOT_USER_DN" \
  --rootUserPasswordFile "$PASSWORD_FILE" \
  --acceptLicense \
  --no-prompt \
  --noPropertiesFile \
  $SETUP_ARGS || exit 1
 
BACKEND_TYPE=${BACKEND_TYPE:-je}
BACKEND_DB_DIRECTORY=${BACKEND_DB_DIRECTORY:-db}
if [ "$HOLDS_DATA" = true ]; then
  echo "creating backend: $BACKEND_TYPE db-directory: ${BACKEND_DB_DIRECTORY}"
 
  /opt/opendj/bin/dsconfig create-backend -h localhost -p $ADMIN_PORT --bindDN "$ROOT_USER_DN" --bindPasswordFile "$PASSWORD_FILE" \
    --backend-name=userRoot --type $BACKEND_TYPE --set "base-dn:$BASE_DN" --set "db-directory:$BACKEND_DB_DIRECTORY" \
    --set enabled:true --no-prompt --trustAll || exit 1
fi
 
if [ "$HOLDS_DATA" = true ] && [ "$ADD_BASE_ENTRY" = "--addBaseEntry"  ]; then
  BASE_TEMPLATE=$(mktemp)
  if [ ! -z ${SAMPLE_DATA} ]; then
    echo "generating sample data..."
    /opt/opendj/bin/makeldif -o $BASE_TEMPLATE -c suffix="$BASE_DN" -c numusers=$SAMPLE_DATA /opt/opendj/template/config/MakeLDIF/example.template || exit 1
    /opt/opendj/bin/import-ldif --ldifFile $BASE_TEMPLATE \
        --backendID=userRoot --bindDN "$ROOT_USER_DN" --bindPasswordFile "$PASSWORD_FILE" || exit 1
  else
    echo "creating base entry..."
    echo "branch: $BASE_DN" > $BASE_TEMPLATE
    /opt/opendj/bin/import-ldif --templateFile $BASE_TEMPLATE \
        --backendID=userRoot --bindDN "$ROOT_USER_DN" --bindPasswordFile "$PASSWORD_FILE" || exit 1
  fi
  rm $BASE_TEMPLATE
fi
 
 
# There are multiple types of ldif files.
# The steps below import ldifs via `ldapmodify`.
# See above for plain copying of ldif files.
 
if [ -d /opt/opendj/bootstrap/schema/ ]; then
  echo "Loading initial schema:"
  for file in /opt/opendj/bootstrap/schema/*; do
    echo "Loading $file ..."
    /opt/opendj/bin/ldapmodify -D "$ROOT_USER_DN" -h localhost -p $PORT -j "$PASSWORD_FILE" -f "$file"
  done
fi
 
if [ "$HOLDS_DATA" = true ] && [ -d /opt/opendj/bootstrap/data/ ]; then
  # allow pre encoded passwords; the port is named, as the tool would otherwise go to 4444
  # whatever ADMIN_PORT the server listens on, and the entries carrying them would be refused
  /opt/opendj/bin/dsconfig \
    set-password-policy-prop \
    -h localhost \
    -p $ADMIN_PORT \
    --bindDN "$ROOT_USER_DN" \
    --bindPasswordFile "$PASSWORD_FILE" \
    --policy-name "Default Password Policy" \
    --set allow-pre-encoded-passwords:true \
    --trustAll \
    --no-prompt
 
  for file in /opt/opendj/bootstrap/data/*; do
    echo "Loading $file ..."
    /opt/opendj/bin/ldapmodify -D "$ROOT_USER_DN" -h localhost -p $PORT -j "$PASSWORD_FILE" -f "$file" --continueOnError
  done
fi