Compare commits

...

12 Commits

Author SHA1 Message Date
82f6d6f4f4 Update INSTALL.md 2025-12-14 13:59:52 -05:00
cd5f0b8ada Delete index.php.tls 2025-12-14 13:55:26 -05:00
3ec502bfc0 Delete dockerlog 2025-12-14 13:55:09 -05:00
30504afd6c Added phpLDAPadmin autoinstallation 2025-12-08 10:09:49 -03:00
26e78904ac Fixed Apache SSL 2025-12-07 12:16:33 -03:00
78017f9e87 Upload files to "/" 2025-12-05 12:36:55 -05:00
cb7dcffc3b Upload files to "media" 2025-11-30 10:16:05 -05:00
e72c842b43 Upload files to "/" 2025-11-30 10:15:02 -05:00
026b02aa51 Upload files to "/" 2025-11-29 17:01:07 -05:00
110e2c10e4 Add dockerlog 2025-11-29 15:56:29 -05:00
e64b9e46d8 Upload files to "/" 2025-11-29 11:58:52 -05:00
c004efafc9 Upload files to "/" 2025-11-29 11:57:39 -05:00
5 changed files with 282 additions and 173 deletions

View File

@ -366,26 +366,65 @@ root@example:/etc/ldap/certs# export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem
root@example:/etc/ldap/certs# echo 'export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem' >> ~/.bashrc
root@example:/etc/ldap/certs# source ~/.bashrc
```
\
Check STARTTLS
```
root@example:/etc/ldap/certs# ldapwhoami -x -ZZ -H ldap://${LDAP_HOST}
```
Check SSL/ldaps
```
root@example:/etc/ldap/certs# ldapwhoami -x -H ldaps://${LDAP_HOST}
```
Both should return Anonymous.
## _6- Connect to OpenLDAP server via StartTLS/SSL_
Another example to try STARTTLS/ldap it is working:
Vital checks of different levels to test **openLDAP's StartTLS and SSL**:\
1.Check StartTLS and SSL, both should output "anonymous"
```
openssl s_client -connect ${LDAP_HOST}:389 -starttls ldap -servername ${LDAP_HOST}
root@example:/# ldapwhoami -x -ZZ -H ldap://${LDAP_HOST}
anonymous
root@example:/# ldapwhoami -x -H ldaps://${LDAP_HOST}
anonymous
```
SSL/ldaps
\
2.Check direct connection via openssl to confirm certificates are working properly:
```
openssl s_client -connect ${LDAP_HOST}:636 -servername ${LDAP_HOST}
root@example:/# openssl s_client -connect ${LDAP_HOST}:389 -starttls ldap -servername ${LDAP_HOST} #StartTLS
CONNECTED(00000003)
depth=1 CN = Example Company CA
verify return:1
depth=0 O = Example Company, CN = example.com
verify return:1
...
SSL handshake has read 2977 bytes and written 424 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
root@example:/# openssl s_client -connect ${LDAP_HOST}:636 -servername ${LDAP_HOST} #SSL
CONNECTED(00000003)
depth=1 CN = Example Company CA
verify return:1
depth=0 O = Example Company, CN = example.com
verify return:1
...
SSL handshake has read 2963 bytes and written 393 bytes
Verification: OK
---
New, TLSv1.3, Cipher is TLS_AES_256_GCM_SHA384
Server public key is 2048 bit
Secure Renegotiation IS NOT supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
Early data was not sent
Verify return code: 0 (ok)
```
The output of both of these commands should be similar. Also, both will show the openLDAP's server CN (example.com in this case). You can terminate the connection with Ctrl+C.
3.A very important check is to make sure connections as users from the OpenLDAP's tree other than admin works:
```
root@example:/# ldapwhoami -x -D "uid=marisa,ou=People,dc=example,dc=com" -w MarisaNewPass2025 -H ldap://127.0.0.1 #StartTLS
dn:uid=marisa,ou=People,dc=example,dc=com
root@example:/# ldapwhoami -x -D "uid=marisa,ou=People,dc=example,dc=com" -w MarisaNewPass2025 -H ldap://127.0.0.1 #SSL
dn:uid=marisa,ou=People,dc=example,dc=com
```
Both will show the connection to the openLDAP server showing the CN(dc=example,dc=com)
To connect to the server via `STARTTLS`, use port 389, to connect to the server via `SSL`, use port 636, both auth method Simple.
If asked, accept the certificate as with any certificate, or copy the CA file that resides inside ldapdock from out of the container to our host system certificate trust directory (/usr/local/share/ca-certificates/ works for any Debian based distribution):
@ -395,5 +434,9 @@ If asked, accept the certificate as with any certificate, or copy the CA file th
> sudo update-ca-certificates
```
In both cases, providing -h ${LDAP_HOST}, by default the login "user" and password are:\
BIND DN=cn=admin,dc=example,dc=com\
As admin:
BIND DN="cn=admin,dc=example,dc=com"\
BIND password=admin
As marisa:
BIND DN="uid=marisa,ou=People,dc=example,dc=com"\
BIND password=MarisaNewPass2025

View File

@ -1,22 +1,43 @@
FROM ubuntu:22.04
# set container hostname
# set container hostname and DN in case we don't set it on the docker build/run command
ARG LDAP_HOST=example.com
ENV LDAP_HOST=${LDAP_HOST}
# set non-interactive TERM for docker
ENV DEBIAN_FRONTEND=noninteractive
# install slapd, ldap-utils, and packages needed for ldapdock to work
#──────────────────────────────────────────────────────────────
# install OpenLDAP, ldap-utils, and packages needed for ldapdock to work
#──────────────────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
slapd ldap-utils gnutls-bin ssl-cert ca-certificates schema2ldif vim mc && apt-get clean
#──────────────────────────────────────────────────────────────
# APACHE && PHP && neccesary related software
#──────────────────────────────────────────────────────────────
RUN apt-get update && apt-get install -y --no-install-recommends \
apache2 \
php libapache2-mod-php \
php-ldap php-mbstring php-xml php-curl php-intl wget \
&& rm -rf /var/lib/apt/lists/*
# Enable required Apache modules
RUN a2enmod rewrite headers ssl
# Use mpm_prefork (required for PHP)
RUN a2dismod mpm_event && a2enmod mpm_prefork
# Clean up default Apache site
RUN rm -rf /var/www/html/* && \
echo "<?php phpinfo(); ?>" > /var/www/html/info.php
# preconfigure slapd installation without using systemd
RUN echo "slapd slapd/password1 password admin" | debconf-set-selections && \
echo "slapd slapd/password2 password admin" | debconf-set-selections && \
echo "slapd slapd/domain string example.com" | debconf-set-selections && \
echo "slapd slapd/no_configuration boolean false" | debconf-set-selections && \
echo "slapd slapd/purge_database boolean true" | debconf-set-selections && \
echo "slapd slapd/ldapi_tls boolean false" | debconf-set-selections && \
echo "slapd slapd/move_old_database boolean true" | debconf-set-selections
# make use of debconf-set-selections
@ -26,21 +47,27 @@ RUN dpkg-reconfigure -f noninteractive slapd
COPY entrypoint.sh ./entrypoint.sh
RUN chmod +x ./entrypoint.sh
# open up LDAP simple port
# open up LDAP StartTLS and SSL ports, and Apache ports
EXPOSE 389
EXPOSE 636
EXPOSE 80
EXPOSE 443
#──────────────────────────────────────────────────────────────
# Create directory for exporting certs to host
RUN mkdir -p /export-certs
#──────────────────────────────────────────────────────────────
# set salvable volumes for LDAP data, configuration, certs
VOLUME ["/var/lib/ldap", "/etc/ldap/slapd.d", "/etc/ldap/certs","/export-certs"]
# set correct permissions for openldap user
RUN chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d
#RUN chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d
#──────────────────────────────────────────────────────────────
# ENTRYPOINT ensures this sh file ALWAYS runs first before any CMD or command line instruction
ENTRYPOINT ["./entrypoint.sh"]
#──────────────────────────────────────────────────────────────
# CMD provides the default command (/bin/bash) which is passed as an argument to the ENTRYPOINT script
CMD ["/bin/bash"]

View File

@ -1,32 +1,64 @@
#!/bin/bash
# this script runs INSIDE the container
# set -e # exit on any error?
#set -euo pipefail
# Fix permissions
chown -R openldap:openldap /var/lib/ldap /etc/ldap/slapd.d /etc/ldap/certs 2>/dev/null || true
chmod -R 777 /export-certs 2>/dev/null || true
#──────────────────────────────────────────────────────────────
# Correct base DN and hostname
export LDAP_HOST="${LDAP_HOST:-$(hostname)}"
export LDAP_BASE_DN=$(echo "$LDAP_HOST" | sed 's/\.\([^.]*\)/,dc=\1/g; s/^/dc=/')
echo "--> Using LDAP base DN: ${LDAP_BASE_DN}"
#──────────────────────────────────────────────────────────────
echo "--> Starting ldapdock 0.10"
echo "--> Launching slapd (temp)..."
# start slapd temporarily for setup
/usr/sbin/slapd -h "ldap:/// ldapi:///" -g openldap -u openldap &
sleep 3
# Temporarily "relax" strict security on start to configure stuff
if [ -d "/etc/ldap/slapd.d" ] && ls /etc/ldap/slapd.d/* >/dev/null 2>&1; then
echo "--> Temporarily relaxing security for init"
slapd -h "ldap:/// ldapi:///" -u openldap -g openldap &
sleep 6
ldapmodify -Y EXTERNAL -H ldapi:/// >/dev/null 2>&1 <<EOF || true
dn: cn=config
changetype: modify
delete: olcLocalSSF
-
delete: olcSecurity
-
EOF
pkill slapd || true
sleep 2
fi
# populate with user & group
echo "--> Populating directory with users and groups..."
cat > /tmp/add_content.ldif << EOF
dn: ou=People,dc=${LDAP_HOST}
# Start temporary slapd for Users and Groups addition
echo "--> Starting temporary slapd"
slapd -h "ldap:/// ldapi:///" -u openldap -g openldap &
SLAPD_PID=$!
sleep 8
# Full tree with root entry
cat > /tmp/base.ldif <<EOF
dn: ${LDAP_BASE_DN}
objectClass: top
objectClass: dcObject
objectClass: organization
o: Example Company
dn: ou=People,${LDAP_BASE_DN}
objectClass: organizationalUnit
ou: People
dn: ou=Groups,dc=${LDAP_HOST}
dn: ou=Groups,${LDAP_BASE_DN}
objectClass: organizationalUnit
ou: Groups
dn: cn=mages,ou=Groups,dc=${LDAP_HOST}
dn: cn=mages,ou=Groups,${LDAP_BASE_DN}
objectClass: posixGroup
cn: mages
gidNumber: 5000
memberUid: marisa
dn: uid=marisa,ou=People,dc=${LDAP_HOST}
dn: uid=marisa,ou=People,${LDAP_BASE_DN}
objectClass: inetOrgPerson
objectClass: posixAccount
objectClass: shadowAccount
@ -38,64 +70,22 @@ displayName: Marisa Kirisame
uidNumber: 10000
gidNumber: 5000
userPassword: {CRYPT}x
gecos: Marisa Kirisame
loginShell: /bin/bash
homeDirectory: /home/marisa
EOF
sleep 2
# add the structure — ignore "already exists" errors only here
echo "--> Adding base structure..."
ldapadd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -f /tmp/add_content.ldif || \
echo "--> Some entries already exist — continuing (this is normal)"
# setting up user marisa of group People password
ldappasswd -x -D "cn=admin,dc=${LDAP_HOST}" -w admin -s qwerty "uid=marisa,ou=People,dc=${LDAP_HOST}"
sleep 2
# load and enable policies module
echo "--> Loading policies module..."
cat > modify_ppolicy_module.ldif << EOF
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: ppolicy.so
gecos: Marisa Kirisame
EOF
ldapmodify -Q -Y EXTERNAL -H ldapi:/// -f modify_ppolicy_module.ldif
# restarting slapd to load ppolicy.so
echo "--> Adding base structure"
ldapadd -c -x -D "cn=admin,dc=example,dc=com" -w admin -f /tmp/base.ldif || true
slapd -h "ldap:/// ldapi:/// ldaps:///" -u openldap -g openldap &
sleep 3
cat > enable_ppolicy.ldif << EOF
dn: olcOverlay=ppolicy,olcDatabase={1}mdb,cn=config
changetype: add
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: ppolicy
EOF
#olcPPolicyDefault: cn=default,ou=policies,dc=${LDAP_HOST}
ldapadd -Q -Y EXTERNAL -H ldapi:/// -f enable_ppolicy.ldif
# display schemas loaded by default
echo "--> Schemas loaded by default..."
ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b cn=schema,cn=config dn
# kill temp slapd
pkill slapd
sleep 3
# === CERTIFICATES: ONLY IF NOT ALREADY EXPORTED ===
#──────────────────────────────────────────────────────────────
# TLS BLOCK
#──────────────────────────────────────────────────────────────
if [ ! -f "/export-certs/mycacert.crt" ]; then
echo "--> No CA found in /export-certs → generating certificates..."
echo "--> No CA found → generating certificates..."
mkdir -p /etc/ldap/certs
cd /etc/ldap/certs
# CA
certtool --generate-privkey --bits 4096 --outfile ca-key.pem
cat > ca.info <<EOF
cn = Example Company CA
@ -104,8 +94,6 @@ cert_signing_key
expiration_days = 3650
EOF
certtool --generate-self-signed --load-privkey ca-key.pem --template ca.info --outfile ca-cert.pem
# server
certtool --generate-privkey --bits 2048 --outfile ldap01_slapd_key.pem
cat > ldap01.info <<EOF
organization = Example Company
@ -121,21 +109,14 @@ EOF
--load-ca-privkey ca-key.pem \
--template ldap01.info \
--outfile ldap01_slapd_cert.pem
# permissions
chgrp openldap ldap01_slapd_key.pem
chmod 640 ldap01_slapd_key.pem
# bundle
cat ldap01_slapd_cert.pem ca-cert.pem > ldap01_slapd_cert_full.pem
chown root:openldap ldap01_slapd_cert_full.pem
chmod 640 ldap01_slapd_cert_full.pem
# start temp slapd to apply config
echo "--> Starting second temporary slapd to apply TLS config"
slapd -h "ldap:/// ldapi:///" -u openldap -g openldap &
sleep 3
# apply TLS config
sleep 4
cat > /tmp/certinfo.ldif <<EOF
dn: cn=config
changetype: modify
@ -149,41 +130,154 @@ replace: olcTLSCertificateKeyFile
olcTLSCertificateKeyFile: /etc/ldap/certs/ldap01_slapd_key.pem
EOF
ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/certinfo.ldif
# trust locally
cp /etc/ldap/certs/ca-cert.pem /usr/local/share/ca-certificates/mycacert.crt
update-ca-certificates
# kill temp
pkill slapd
pkill slapd || true
sleep 2
# === EXPORT TO HOST (always, since volume is mounted) ===
echo "--> Exporting CA to /export-certs..."
echo "--> Exporting certificates to host volume..."
cp /etc/ldap/certs/ca-cert.pem /export-certs/mycacert.crt
cp /etc/ldap/certs/ldap01_slapd_cert_full.pem /export-certs/server-cert.pem
echo "--> Certificate READY at ./hosts-certs/mycacert.crt on host"
else
echo "--> CA already exists at /export-certs/mycacert.crt → skipping generation"
echo "--> Certificates already exist — skipping generation and using existing ones"
fi
# === FINAL SLAPD START ===
echo "--> Starting final slapd with LDAPS..."
export LDAPTLS_REQCERT=allow
# ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
# NEW: Save and restore the LDIF — no changes to TLS block
if [ ! -f "/export-certs/certinfo.ldif" ]; then
echo "--> Saving TLS config LDIF for future restarts"
cp /tmp/certinfo.ldif /export-certs/certinfo.ldif
fi
if [ -f "/export-certs/certinfo.ldif" ]; then
echo "--> Restoring TLS config LDIF from persistent volume"
cp /export-certs/certinfo.ldif /tmp/certinfo.ldif
fi
# ←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←←
# Set Marisa password (full LDIF — so ldapmodify knows what to modify)
echo "--> Setting Marisa password to 'MarisaNewPass2025' using Admin Bind"
ADMIN_DN="cn=admin,${LDAP_BASE_DN}"
ADMIN_PW="admin"
slappasswd -h '{SSHA}' -s MarisaNewPass2025 | \
ldapmodify -x -D "$ADMIN_DN" -w "$ADMIN_PW" <<EOF >/dev/null 2>&1
dn: uid=marisa,ou=People,${LDAP_BASE_DN}
changetype: modify
replace: userPassword
userPassword: $(< /dev/stdin)
EOF
# Kill temporary slapd
kill $SLAPD_PID 2>/dev/null || true
wait $SLAPD_PID 2>/dev/null || true
# Kill any stray slapd that might be holding ports
pkill -9 slapd 2>/dev/null || true
sleep 2
# Start final OpenLDAP
echo "--> Starting final OpenLDAP (background)"
slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 &
sleep 3
SLAPD_PID=$!
sleep 8
# === ENABLE TLS FOR ALL CLIENT TOOLS INSIDE CONTAINER ===
export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem
echo "LDAPTLS_CACERT=$LDAPTLS_CACERT (all ldap* commands now work with TLS)"
echo 'export LDAPTLS_CACERT=/etc/ldap/certs/ca-cert.pem' >> ~/.bashrc
source ~/.bashrc
# Apply TLS config to final slapd
echo "--> Applying TLS config to final slapd"
ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/certinfo.ldif
echo "--> ldapdock framework ready."
# Restart slapd to load the new TLS config (required for OpenLDAP)
echo "--> Restarting slapd to load TLS config"
kill $SLAPD_PID 2>/dev/null || true
wait $SLAPD_PID 2>/dev/null || true
slapd -h "ldap:/// ldaps:/// ldapi:///" -u openldap -g openldap -d 0 &
SLAPD_PID=$!
sleep 8
# === KEEP CONTAINER ALIVE AND CONTINUE ===
# Make the container trust its own CA — every time
cp /etc/ldap/certs/ca-cert.pem /usr/local/share/ca-certificates/mycacert.crt 2>/dev/null || true
update-ca-certificates --fresh >/dev/null 2>&1 || true
# 'exec' replaces the script process with the command (e.g., /bin/bash),
# ensuring the container stays alive as long as that command runs interactively.
echo "Executing: $@"
# Start Apache inside APACHE_PID variable in background
echo "--> Starting Apache + PHP (background)"
/usr/sbin/apache2ctl -D FOREGROUND &
APACHE_PID=$!
sleep 5
# HTTPS setup — using the real LDAP certificates
echo "--> Configuring Apache for HTTPS with real certificates"
export DEBIAN_FRONTEND=noninteractive # Silence a2ensite prompts
APACHE_CERT_FILE="/etc/ldap/certs/ldap01_slapd_cert_full.pem"
APACHE_KEY_FILE="/etc/ldap/certs/ldap01_slapd_key.pem"
# Enable the site silently
a2ensite default-ssl.conf >/dev/null 2>&1
# Replace the snakeoil certs with your real ones
sed -i -E "s|^\s*SSLCertificateFile\s+.*|SSLCertificateFile ${APACHE_CERT_FILE}|g" \
/etc/apache2/sites-available/default-ssl.conf
sed -i -E "s|^\s*SSLCertificateKeyFile\s+.*|SSLCertificateKeyFile ${APACHE_KEY_FILE}|g" \
/etc/apache2/sites-available/default-ssl.conf
# Reload Apache gracefully (updates config without killing)
apache2ctl graceful >/dev/null 2>&1
sleep 5
# ──────────────────────────────
# phpLDAPadmin — auto-installed, no rebuild, works forever
# ──────────────────────────────
echo "--> Installing phpLDAPadmin"
# Only install once — use a flag file
if [ ! -f "/var/www/html/phpldapadmin-installed" ]; then
cd /var/www/html
# Download and extract (direct tarball, no git needed)
wget -q -O phpldapadmin.tgz \
https://github.com/leenooks/phpLDAPadmin/archive/refs/tags/1.2.6.7.tar.gz
tar xzf phpldapadmin.tgz
mv phpLDAPadmin-1.2.6.7 phpldapadmin
rm phpldapadmin.tgz
# Copy config and apply minimal working settings
cp phpldapadmin/config/config.php.example phpldapadmin/config/config.php
cat > phpldapadmin/config/config.php <<EOF
<?php
\$servers = new Datastore();
\$servers->newServer('ldap_pla');
\$servers->setValue('server','name','Local OpenLDAP');
\$servers->setValue('server','host','127.0.0.1');
\$servers->setValue('server','port',389);
\$servers->setValue('server','base',array('${LDAP_BASE_DN}'));
\$servers->setValue('server','tls',true);
\$servers->setValue('login','auth_type','session');
\$servers->setValue('login','bind_id','cn=admin,${LDAP_BASE_DN}');
\$servers->setValue('login','bind_pass','admin');
?>
EOF
# Mark as installed
touch /var/www/html/phpldapadmin-installed
echo "--> phpLDAPadmin installed → https://localhost/phpldapadmin"
else
echo "--> phpLDAPadmin already installed"
fi
# Victory message
echo "--> ldapdock ready — OpenLDAP + Apache + PHP running"
echo " → LDAP: 389/636"
echo " → PHPinfo: https://localhost/info.php"
echo " → Shell: /bin/bash"
echo " → Exit with CTRL+D or 'exit' command"
# THIS IS THE MAGIC LINE THAT KILLS CHILD PROCESSES ON EXIT
trap 'echo "Stopping services..."; kill $SLAPD_PID $APACHE_PID 2>/dev/null; wait' SIGINT SIGTERM
# Give you your interactive shell — forever
exec "$@"

View File

@ -1,55 +0,0 @@
<?php
$host = $_SERVER['HTTP_HOST']; // works for example.com or any LDAP_HOST
$msg = '';
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$uid = trim($_POST['uid'] ?? '');
$password = $_POST['password'] ?? '';
if ($uid && $password) {
// DIRECT LDAPS CONNECTION — NO STARTTLS NEEDED
$ldap = ldap_connect("ldaps://127.0.0.1:636");
// Allow self-signed cert for ldaps://
putenv('LDAPTLS_REQCERT=allow');
if (!$ldap) {
$msg = "<p style='color:red'>Cannot connect to LDAP server</p>";
} else {
ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3);
ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0);
$bind_dn = "uid=$uid,ou=People,dc=$host";
if (@ldap_bind($ldap, $bind_dn, $password)) {
$msg = "<p style='color:green;font-weight:bold'>Login successful! Welcome $uid 🎉</p>";
} else {
$msg = "<p style='color:red'>Invalid credentials</p>";
}
ldap_close($ldap);
}
} else {
$msg = "<p style='color:red'>uid=$uid,ou=People,dc=$host Please fill both fields</p>";
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>ldapdock LDAP login</title>
<style>
body { font-family: Arial, sans-serif; max-width: 400px; margin: 100px auto; text-align: center; }
input, button { padding: 10px; margin: 5px; width: 100%; font-size: 16px; }
button { background: #007cba; color: white; cursor: pointer; }
</style>
</head>
<body>
<h1>ldapdock login</h1>
<p>Server: <strong><?= htmlspecialchars($host) ?></strong></p>
<?= $msg ?>
<form method="post">
<input type="text" name="uid" placeholder="uid (e.g. marisa)" required autofocus><br>
<input type="password" name="password" placeholder="password" required><br>
<button type="submit">Login</button>
</form>
<hr>
<small>Test user: marisa / q*****</small>
</body>
</html>

BIN
media/devall.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 227 KiB