Password Policy

Test the OpenLDAP password policy overlay with automated validation of policy enforcement rules.

Project Files

openldap-ppolicy
Explorer
docker-compose.yml
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
services:
  openldap:
    image: ${LDAP_IMAGE:-openldap:local}
    container_name: openldap-password-policy
    hostname: openldap-password-policy
    env_file:
      - .env.password-policy
      # Entry data in this use-case uses inetOrgPerson/posixAccount. Without
      # these schemas ldapadd fails with "objectClass: value #0 invalid per syntax".
      # Kept here rather than in .env.* because .env.* is gitignored.
    environment:
      - INCLUDE_SCHEMAS=cosine,inetorgperson,nis
    ports:
      - "391:389"
      - "638:636"
    volumes:
      - ldap-data:/var/lib/ldap
      - ldap-config:/etc/openldap/slapd.d
      - ./logs:/logs
      - ./test-password-policy.sh:/docker-entrypoint-initdb.d/test-password-policy.sh:ro
    restart: unless-stopped
    
    # Resource limits
    deploy:
      resources:
        limits:
          memory: 1G
          cpus: '1.0'
        reservations:
          memory: 128M
    
    # Log rotation
    logging:
      driver: json-file
      options:
        max-size: "10m"
        max-file: "3"
    
    networks:
      - ldap-shared-network

volumes:
  ldap-data:
  ldap-config:

networks:
  ldap-shared-network:
    external: true
YAMLUTF-8
Ln 493 files

Start

# Create shared network
docker network create ldap-shared-network 2>/dev/null || true

docker compose up -d

# Wait for initialization
sleep 30

Run Tests

./test-password-policy.sh

The script validates:
  1. 1 Overlay loaded — ppolicy overlay exists in cn=config
  2. 2 Policy OU exists — ou=Policies,dc=test,dc=com is created
  3. 3 Default policy exists — cn=default,ou=Policies,dc=test,dc=com with all attributes
  4. 4 Policy enforcement — weak passwords rejected, strong passwords accepted

Default Policy

AttributeValueDescription
pwdMinLength8Minimum password length
pwdMaxFailure5Max consecutive failed logins
pwdLockoutTRUEAccount lockout enabled
pwdLockoutDuration1800Lockout duration (30 minutes)
pwdMaxAge7776000Password expires after 90 days
pwdInHistory5Cannot reuse last 5 passwords
pwdMustChangeTRUEUser must change password on first login

Manual Testing

Check Policy Configuration

ldapsearch -x -H ldap://localhost:391 \
  -D "cn=Manager,dc=test,dc=com" -w admin123 \
  -b "cn=default,ou=Policies,dc=test,dc=com" -s base

Test Weak Password (Should Fail)

ldapadd -x -H ldap://localhost:391 \
  -D "cn=Manager,dc=test,dc=com" -w admin123 <<EOF
dn: uid=weakuser,ou=People,dc=test,dc=com
objectClass: inetOrgPerson
uid: weakuser
cn: Weak User
sn: User
userPassword: 123
EOF

Test Strong Password (Should Succeed)

ldapadd -x -H ldap://localhost:391 \
  -D "cn=Manager,dc=test,dc=com" -w admin123 <<EOF
dn: uid=stronguser,ou=People,dc=test,dc=com
objectClass: inetOrgPerson
uid: stronguser
cn: Strong User
sn: User
userPassword: MySecurePass123!
EOF

Connection Details

SettingValue
Hostlocalhost
LDAP Port391
LDAPS Port638
Bind DNcn=Manager,dc=test,dc=com
Base DNdc=test,dc=com
Passwordadmin123

Troubleshooting

Policy not enforced — Verify overlay is loaded:
ldapsearch -x -H ldap://localhost:391 \
  -D "cn=Manager,dc=test,dc=com" -w admin123 \
  -b "cn=config" "(objectClass=olcPPolicyConfig)"
Policy entry missing — Check the OU:
ldapsearch -x -H ldap://localhost:391 \
  -D "cn=Manager,dc=test,dc=com" -w admin123 \
  -b "ou=Policies,dc=test,dc=com"

Cleanup

docker compose down -v