I am working on enabling ApacheDS (version 2.0.0-M16) to enforce strong passwords - combination of alphanumeric and special characters. I have created my own instance for testing.
As a start, I switched the password quality check to STRICT (2) and changed the minimum length value to 7:
dn: ads-pwdId=default,ou=passwordPolicies,ads-interceptorId=authenticationInterceptor,ou=interceptors,ads-directoryServiceId=default,ou=config
ads-pwdMinLength: 7
ads-pwdinhistory: 5
ads-pwdid: default
ads-pwdCheckQuality: 2
ads-pwdlockout: TRUE
ads-pwdlockoutduration: 0
ads-pwdvalidator: org.apache.directory.server.core.api.authn.ppolicy.DefaultPasswordValidator
ads-pwdmaxfailure: 5
ads-pwdfailurecountinterval: 30
ads-pwdattribute: userPassword
entryParentId: 4f761b8b-c70c-43a2-bb6f-d26e8c297f84
ads-enabled: TRUE
objectclass: top
objectclass: ads-base
objectclass: ads-passwordPolicy
entryuuid: c83189f9-8ee4-4aec-9180-6e3f6d8297c6
ads-pwdgraceauthnlimit: 5
modifyTimestamp: 20140508182112.262Z
entryCSN: 20140508182112.263000Z#000000#001#000000
ads-pwdexpirewarning: 600
modifiersName: 0.9.2342.19200300.100.1.1=admin,2.5.4.11=system
I then tried to import an ldif entry through the Apache Directory Studio with an obviously invalid password but the validation does not kick in. User is created successfully:
dn: cn=SherlockHolmes,ou=people,o=sevenSeas
objectclass: person
objectclass: organizationalPerson
objectclass: inetOrgPerson
objectclass: top
cn: Sherlock Holmes
description: Sherlock Holmes
givenname: Sherlock
sn: Holmes
uid: SHolmes
mail: SHolmes#gmail.com
userpassword: watson
What am I doing wrong?
Also, is there any way I can configure the complexity of the password in the form of a regex? I don't see this in the conf file.
Did you restart the server after updating the password policy?. Server must be restarted to enforce the updated policy.
Related
I am exporting an LDAP database into an LDIF, and I need to clean it up a bit. There are some attributes that I no longer want. If it is a one-line attribute it is simple:
# Entry 23: cn=dwhite,ou=ORG1,o=Root
dn: cn=dwhite,ou=ORG1,o=Root
objectclass: person
objectclass: inetorgperson
objectclass: webadmaccount
sn: white
cn: dwhite
description: don.white#company.com
givenname: Don
mail: 5551234567#txt.att.net
o: ORG1
uid: dwhite
userpassword: {SSHA}YrGx7L7L8xxxiMzuUzL+f0j+i73uFTYEPnu
webadmdata: OpenOTP.RejectCount={wcrypt}eAw+r6VX6l8lioB+1KX/6A==,OpenOTP.Las
tLogin={wcrypt}hQCwWl0KRdsiXyG7UPxPxo/WphEkyD6NPTKor8FCA5E=,OpenOTP.LoginCot
0f5vQVl1ippSdKFiGeACiJbFWHsfs=,DataMode=A8tMd3g=
# Entry 24: ou=ORG2,o=Root
dn: ou=ORG2,o=Root
objectclass: organizationalunit
ou: ORG2
# Entry 25: cn=jlee,ou=ORG2,o=Root
dn: cn=jlee,ou=ORG2,o=Root
objectclass: person
objectclass: inetorgperson
objectclass: webadmaccount
sn: Lee
cn: jlee
userpassword: {SSHA}+CreNAoXMO3XMIWxxaWsA2r3ozyeCBEShn
description: jay.lee#company.com
givenname: Jay
mail: 5551234567#txt.att.net
o: ORG2
uid: jlee
webadmdata: OpenOTP.RejectCount={wcrypt}OrtNikuuHCyBruxUTOq6eg==,OpenOTP.Las
tLogin={wcrypt}WUa965R8rFV9iHx7LrXrfzxEE3Gjd7TGiFz8AEJBmwU=,OpenOTP.LoginCo
unt={wcrypt}Qbamc7jYTL+14K1yaZS9kA==,OpenOTP.LastOTP={wcrypt}t+fDlGfP6kGIse
at8PHJdxJy15LSN4R+tJXr7B7L7+4=,DataMode=A8tMd3g=
In the sample above to remove the 'objectclass: webadmaccount' attribute, a Find and Replace with a regex like: ^objectclass.*webadmaccount$ will do the job. I know that seems a little overkill with the anchors, but elsewhere in the LDIF, you can find that sting embedded in a longer line, so the anchors.
Now, my problem comes when I want to get rid of the 'webadmdata:' attributes. You can see they are multiline, and not all the same length. This is where I am stuck, a regex like this:
^webadmdata:.*[\n\s]+.* will get the first two lines, but then it quits. If I make the .*[\n\s]+.* a capture group and repeat it with '+' at the end: (.*[\n\s]+.*)+ it will select the whole file (or crash vscode ). It seems like I should be able to write a regex that will select everything from ^webadmdata to A8tMd3g=\n\n but I cannot for the life of me get it to work. I hope there is a regex or VSCode guru out there that can help. Thanks in advance.
OK, I don't know why I thought this didn't work before, but it does. The following regex will do what I want:
^webadmdata:.(.|\n)+?A8tMd3G=$\n
Apparently VSCode defaults to lazy qualifier. See below:
screenshot
I've provisions a Keyspace on AWS and in order to make sure it can achieve our desired performance I'm trying to run the cassandra-stress tool on it and compare it to other architectures we're experimenting with.
I managed to connect to it using the following cqlshrc:
[connection]
port = 9142
factory = cqlshlib.ssl.ssl_transport_factory
[ssl]
validate = true
certfile = /root/.cassandra/AmazonRootCA1.pem
And the following command (hoping that soon enough there will be Python3 support, the development was completed this February according to their Jira ticket):
cqlsh cassandra.eu-central-1.amazonaws.com 9142 -u "myuser-at-722222222222" -p "12/12ZmHmtD1klsDk9cgqt/XXXXXXXXxUz6Sy687z/U=" --ssl --cqlversion="3.4.4"
Surprisingly or not, when using the official AWS guides things tend to work.
So I went on and tried connecting the cassandra-stress tool (I have it inside a Docker container, I'd rather keep my OS Java free) to the same Keyspace.
First I converted the AWS AmazonRootCA1.pem into cassandra_truststore.jks using the following commands (explained here):
openssl x509 -outform der -in AmazonRootCA1.pem -out temp_file.der
keytool -import -alias cassandra -keystore cassandra_truststore.jks -file temp_file.der
Now when I'm trying to run the actual tool like this:
./cassandra-stress write -node cassandra.eu-central-1.amazonaws.com -port native=9142 thrift=9142 jmx=9142 -transport truststore=/root/.cassandra/cassandra_truststore.jks truststore-password=mypassword -mode native cql3 user="myuser-at-722222222222" password="12/12ZmHmtD1klsDk9cgqt/XXXXXXXXxUz6Sy687z/U="
I'm getting the following error:
******************** Stress Settings ********************
Command:
Type: write
Count: -1
No Warmup: false
Consistency Level: LOCAL_ONE
Target Uncertainty: 0.020
Minimum Uncertainty Measurements: 30
Maximum Uncertainty Measurements: 200
Key Size (bytes): 10
Counter Increment Distibution: add=fixed(1)
Rate:
Auto: true
Min Threads: 4
Max Threads: 1000
Population:
Sequence: 1..1000000
Order: ARBITRARY
Wrap: true
Insert:
Revisits: Uniform: min=1,max=1000000
Visits: Fixed: key=1
Row Population Ratio: Ratio: divisor=1.000000;delegate=Fixed: key=1
Batch Type: not batching
Columns:
Max Columns Per Key: 5
Column Names: [C0, C1, C2, C3, C4]
Comparator: AsciiType
Timestamp: null
Variable Column Count: false
Slice: false
Size Distribution: Fixed: key=34
Count Distribution: Fixed: key=5
Errors:
Ignore: false
Tries: 10
Log:
No Summary: false
No Settings: false
File: null
Interval Millis: 1000
Level: NORMAL
Mode:
API: JAVA_DRIVER_NATIVE
Connection Style: CQL_PREPARED
CQL Version: CQL3
Protocol Version: V4
Username: myuser-at-722222222222
Password: *suppressed*
Auth Provide Class: null
Max Pending Per Connection: 128
Connections Per Host: 8
Compression: NONE
Node:
Nodes: [cassandra.eu-central-1.amazonaws.com]
Is White List: false
Datacenter: null
Schema:
Keyspace: keyspace1
Replication Strategy: org.apache.cassandra.locator.SimpleStrategy
Replication Strategy Pptions: {replication_factor=1}
Table Compression: null
Table Compaction Strategy: null
Table Compaction Strategy Options: {}
Transport:
factory=org.apache.cassandra.thrift.TFramedTransportFactory; truststore=/root/.cassandra/cassandra_truststore.jks; truststore-password=mypassword; keystore=null; keystore-password=null; ssl-protocol=TLS; ssl-alg=SunX509; store-type=JKS; ssl-ciphers=TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA;
Port:
Native Port: 9142
Thrift Port: 9142
JMX Port: 9142
Send To Daemon:
*not set*
Graph:
File: null
Revision: unknown
Title: null
Operation: WRITE
TokenRange:
Wrap: false
Split Factor: 1
java.lang.RuntimeException: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: cassandra.eu-central-1.amazonaws.com/3.127.48.183:9142 (com.datastax.driver.core.exceptions.TransportException: [cassandra.eu-central-1.amazonaws.com/3.127.48.183] Channel has been closed))
at org.apache.cassandra.stress.settings.StressSettings.getJavaDriverClient(StressSettings.java:220)
at org.apache.cassandra.stress.settings.SettingsSchema.createKeySpacesNative(SettingsSchema.java:79)
at org.apache.cassandra.stress.settings.SettingsSchema.createKeySpaces(SettingsSchema.java:69)
at org.apache.cassandra.stress.settings.StressSettings.maybeCreateKeyspaces(StressSettings.java:228)
at org.apache.cassandra.stress.StressAction.run(StressAction.java:57)
at org.apache.cassandra.stress.Stress.run(Stress.java:143)
at org.apache.cassandra.stress.Stress.main(Stress.java:62)
Caused by: com.datastax.driver.core.exceptions.NoHostAvailableException: All host(s) tried for query failed (tried: cassandra.eu-central-1.amazonaws.com/3.127.48.183:9142 (com.datastax.driver.core.exceptions.TransportException: [cassandra.eu-central-1.amazonaws.com/3.127.48.183] Channel has been closed))
at com.datastax.driver.core.ControlConnection.reconnectInternal(ControlConnection.java:233)
at com.datastax.driver.core.ControlConnection.connect(ControlConnection.java:79)
at com.datastax.driver.core.Cluster$Manager.init(Cluster.java:1424)
at com.datastax.driver.core.Cluster.getMetadata(Cluster.java:403)
at org.apache.cassandra.stress.util.JavaDriverClient.connect(JavaDriverClient.java:160)
at org.apache.cassandra.stress.settings.StressSettings.getJavaDriverClient(StressSettings.java:211)
... 6 more
I've tried changing some parameters such as the jks password etc. (Just in case I was wrong) but I got a different error message so it's probably not the case.
Did I miss something?
Try using TLP Stress instead.
tlp-stress run RandomPartitionAccess -d 10m --host cassandra.us-east-1.amazonaws.com --port 9142 --username alice --password fLyWYFlTCD5J2gzGAZ –ssl --max-requests 4000 --dc us-east-2 --threads 10
https://thelastpickle.com/tlp-stress/
I have a big LDIF file (OpenLDAP) and I want to remove one attribute out of every dataset.
Example:
dn: uid=axx,ou=People,dc=myfirma,dc=net
uid: axx
jpegPhoto:: /9j/4AAQSkZJRgABAQEAAAAAAAD/4QBaRXhpZgAATU0AKgAAAAgAAYKYAAIAAAA3
AAAAGgAAAABUaW1vQ29tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
gICAgICAAAP/sABFEdWNreQABAAQAAABkAAD/4QRuaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS
4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/P
g0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1Q
IENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEyLzAyLzA2LTE0OjU2OjI3ICAgICAgICAiPg0
KCTxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3
ludGF4LW5zIyI+DQoJCTxyZGY6RGVzY3JpcHRpb24gcmRmOmFib3V0PSIiIHhtbG5zOnhtcE1NP
pRRX7d7JHn7s/RD/gnRrMcnwyhXKqqxnGT719IrerjgjJ96KK/Hc+iljqiXc9Cn8KIL67xYytlf
umvzT/ao1dG+MVznjbEMnPP3jxmiivQ4VivrL9Cah5wb8T3e75tpyDzwa9n/Y7vIn+LenkbwuGG
OvbvRRX2mawSws/QKe6P0w0uPFjDt/uL79q0AcHPtRRX4vLc66a6ngn7fT4+E90N2GaFx+lfnjc
Q7oEUsrLtAI9TRRX3nCOtGXqYVirf2MUso28bcc+9foj+wJEYvhXb7ufkGPbmiit+Kb/VkvMVM+
g8YUVT18f8S+bt8h5/Ciivzpbmp+XH7VVqqfGvUNrN80a5HYda83u7aOe02q37wfhRRX7Flb/2a
n6I5am56h+xrcfZ/jHaxsNy7D26Gv0406INYQnH8A/lRRXyPFn8eL8jSDZ//9k=
postalCode: 12345
mail: xxxx#myfirma.com
sn: Hotzenplotz
c: DE
street: Waldstr 2-4
givenName: Maik
o: myfirma Soft- und Hardware GmbH
l: Entenhausen
telephoneNumber: +49 1234 5678 5678
facsimileTelephoneNumber: +49 1234 5678 5676
roomNumber: 03.034
co: Deutschland
employeeActive: TRUE
cn: Maik Hotzenplotz
description: 9400
st: NRW
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: extperson
displayName: Maik Hotzenplotz
structuralObjectClass: inetOrgPerson
entryUUID: c43b735c-2d85-1037-85c2-45672a55bec29
createTimestamp: 20170914104654Z
labeledURI: ldap:///ou=Organization,dc=myfirma,dc=net??sub?(&(objectClass=or
ganizationalRole)(roleOccupant=uid=axx,ou=People,dc=myfirma,dc=net))
userPassword:: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
employeeID: 3564
entryCSN: 20170914105425.815554Z#000000#000#000000
modifiersName: cn=Manager,dc=myfirma,dc=net
modifyTimestamp: 20170914105425Z
dn: uid=yyy,ou=People,dc=myfirma,dc=net
uid: yyy
jpegPhoto:: /9j/4AAQSkZJRgABAQEAAAAAAAD/4QBaRXhpZgAATU0AKgAAAAgAAYKYAAIAAAA3
AAAAGgAAAABUaW1vQ29tICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA
gICAgICAAAP/sABFEdWNreQABAAQAAABkAAD/4QRuaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS
4wLwA8P3hwYWNrZXQgYmVnaW49Iu+7vyIgaWQ9Ilc1TTBNcENlaGlIenJlU3pOVGN6a2M5ZCI/P
g0KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1Q
IENvcmUgNS4zLWMwMTEgNjYuMTQ1NjYxLCAyMDEyLzAyLzA2LTE0OjU2OjI3ICAgICAgICAiPg0
KCTxyZGY6UkRGIHhtbG5zOnJkZj0iaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3
jV8JtK/wARKja+D2z0ooq+a71FOV2yK9lNurOqBi3GRw+B79P8c1jwSq7OzBvM5YgHaw9BRRW0G
eZitZJdDH1S2a/J87EXmEZ8sfdwOMiseG3Z7iK3kXdJI24cjhR0NFFdlPY8rEL925DvE+qzaZ4f
uhJ8y3jiD5h2zkmvnn4g+JW1LxpJZ28MO2P5iUGDjPrRRW8VdHwedVGotGlJq8M/iFbFdPhF3fT
IfOVjuZVAHSvbrLxNc2FlDCsLbY0AGIh6UUVMYo+c9tLlSP/Z
postalCode: 12345
mail: NDimpfelmoser#myfirma.com
sn: Dimpfelmoser
c: DE
street: Waldstr 2-4
givenName: Nadine
o: myfirma Soft- und Hardware GmbH
l: Entenhausen
telephoneNumber: +49 1234 5678 5672
facsimileTelephoneNumber: +49 1234 5678 5673
co: Deutschland
employeeActive: TRUE
cn: Nadine Dimpfelmoser
description: 9800
st: NRW
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: extperson
displayName: Nadine Dimpfelmoser
structuralObjectClass: inetOrgPerson
entryUUID: c4c664da-2d85-1437-85c3-4122a55bec29
createTimestamp: 20170914104654Z
labeledURI: ldap:///ou=Organization,dc=myfirma,dc=net??sub?(&(objectClass=or
ganizationalRole)(roleOccupant=uid=yyy,ou=People,dc=myfirma,dc=net))
userPassword:: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
employeeID: 3978
entryCSN: 20170914105425.922291Z#000000#000#000000
modifiersName: cn=Manager,dc=myfirma,dc=net
modifyTimestamp: 20170914105425Z
The field jpegPhoto shall be deleted.
I tried in an regular expression emulator this term
jpegPhoto::[^:]*(?=\n\w*:)
and it's worked in the emulator.
But I cannot get it to work with sed.
Or shall I use another tool?
Thanks for any hints.
Ciao
Peter Schütt
Yes, there's another powerful tool called awk:
awk '/jpegPhoto/{ f=1 }f && /^[^:]+: /{ f=0 }f{next}1' file
The output:
dn: uid=axx,ou=People,dc=myfirma,dc=net
uid: axx
postalCode: 12345
mail: xxxx#myfirma.com
sn: Hotzenplotz
c: DE
street: Waldstr 2-4
givenName: Maik
o: myfirma Soft- und Hardware GmbH
l: Entenhausen
telephoneNumber: +49 1234 5678 5678
facsimileTelephoneNumber: +49 1234 5678 5676
roomNumber: 03.034
co: Deutschland
employeeActive: TRUE
cn: Maik Hotzenplotz
description: 9400
st: NRW
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: extperson
displayName: Maik Hotzenplotz
structuralObjectClass: inetOrgPerson
entryUUID: c43b735c-2d85-1037-85c2-45672a55bec29
createTimestamp: 20170914104654Z
labeledURI: ldap:///ou=Organization,dc=myfirma,dc=net??sub?(&(objectClass=or
ganizationalRole)(roleOccupant=uid=axx,ou=People,dc=myfirma,dc=net))
userPassword:: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
employeeID: 3564
entryCSN: 20170914105425.815554Z#000000#000#000000
modifiersName: cn=Manager,dc=myfirma,dc=net
modifyTimestamp: 20170914105425Z
dn: uid=yyy,ou=People,dc=myfirma,dc=net
uid: yyy
postalCode: 12345
mail: NDimpfelmoser#myfirma.com
sn: Dimpfelmoser
c: DE
street: Waldstr 2-4
givenName: Nadine
o: myfirma Soft- und Hardware GmbH
l: Entenhausen
telephoneNumber: +49 1234 5678 5672
facsimileTelephoneNumber: +49 1234 5678 5673
co: Deutschland
employeeActive: TRUE
cn: Nadine Dimpfelmoser
description: 9800
st: NRW
objectClass: top
objectClass: person
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: extperson
displayName: Nadine Dimpfelmoser
structuralObjectClass: inetOrgPerson
entryUUID: c4c664da-2d85-1437-85c3-4122a55bec29
createTimestamp: 20170914104654Z
labeledURI: ldap:///ou=Organization,dc=myfirma,dc=net??sub?(&(objectClass=or
ganizationalRole)(roleOccupant=uid=yyy,ou=People,dc=myfirma,dc=net))
userPassword:: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
employeeID: 3978
entryCSN: 20170914105425.922291Z#000000#000#000000
modifiersName: cn=Manager,dc=myfirma,dc=net
modifyTimestamp: 20170914105425Z
sed does not support lookahead. You can do it with a loop:
sed '/^jpegPhoto::/{:a;N;/\n[^:]*:/!ba;s/.*\n//;}' file
If you know postaCode always is the next field, something like this works:
sed '/^postalCode/p; /^jpegPhoto/,/^postalCode/d' infile
I give up with sed and awk.
But RomanPerekhrest answer is fine.
For archivation my slow solution:
This solution works but it is very slow for a big file:
#!/bin/sh
inJpeg=0
while IFS= read -r line
do
if [ "${line:0:9}" == "jpegPhoto" ]; then
inJpeg=1 ;
elif [ $inJpeg == 1 ]; then
if [ "${line:0:1}" != " " ]; then
inJpeg=0 ;
echo "${line}"
fi
else
echo "${line}"
fi
done
If you have a better solution I would appreciate.
Thanks for any hint.
Ciao
Peter Schütt
In my site.yml, I run some common tasks, then include 3 other playbooks.
These 3 playbooks then run a role each.
I do this so I can run a full site.yml install, or I can just run a smaller playbook.
I want to prompt for a username and password in the site.yml, which I can do.
Then in the other 3 playbooks/roles, I want to check if the username and password were already created, if not, then prompt for them.
I do not want to prompt for credentials multiple times.
site.yml
---
- hosts: all
vars_prompt:
- name: "username"
- prompt" "enter username"
- include: 1.yml
1.yml
---
- name: install one
hosts: all
# If username has not been defined - This is
# where I am confused how to check if it was defined in site.yml
vars_prompt:
- name: "userame"
prompt: "enter username"
roles:
- 1role
If I run site.yml, it will get username, then run 1.yml and I don't want it to prompt for username because it was prompted for in site.yml.
If I run just 1.yml, I want it to prompt for the username, as I am not running site.yml in this case.
Is there a way to prompt for credentials from a playbook, then check for them in an included playbook?
You should make a file that ansible writes on host and ansible could then check whether those credentials have been filled in or not yet, or you could use register (probably the best option) and then use when to check (when is like an if statement)
For instance:
site.yml
- name: "username"
- prompt" "enter username"
register: username_check
1.yml
- name: "userame"
prompt: "enter username"
when: username_check is not defined
I hope this helps in some regard. I tried to comment but it wouldn't let me.
I have an LDAP server with "dc=domain1,dc=com" as the olcSuffix. I would like to create a second domain "dc=domain2,dc=com" on the same server.
Using this LDIF file:
dn: olcDatabase={3}bdb
objectClass: olcDatabaseConfig
objectClass: olcBdbConfig
olcDatabase: {3}bdb
olcSuffix: dc=domain2,dc=com
...
I got an error :
"no global superior knowledge" error because dc=domain2,dc=com does not fit below the existing dc=domain1,dc=com tree.
My question is how do I run two separate domains side by side in openldap? Do I have to create a "dc=com" root and move the existing "dc=domain1" beneath that and then create "dc=domain2", or is there someway to support both trees independently in the same server?
As far as I know, One OpenLDAP server can have multiple DIT. I think what you want is to add a new DIT.
To add a new DIT, you should do:
make a directory for it,and set the privilege.
add a config to OpenLDAP server.
add the entry and RootDN.
I now use Ubuntu 14.04.3 LTS,OpenLDAP 2.4.31 (installed by apt-get), some command may need sudo if you not use root account.
First,make the dir for new database
root#hare:~/ldap# mkdir /var/lib/ldap-bdb
root#hare:~/ldap# chown openldap:openldap /var/lib/ldap-bdb
root#hare:~/ldap# vim /etc/apparmor.d/usr.sbin.slapd
# the databases and logs
/var/lib/ldap-bdb/ r,
/var/lib/ldap-bdb/** rwk,
# lock file
/var/lib/ldap-bdb/alock kw,
root#hare:~/ldap# service apparmor reload
Second, config cn=config
check the module
root#hare:~/ldap# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b 'cn=config' "(objectClass=olcModuleList)"
dn: cn=module{0},cn=config
objectClass: olcModuleList
cn: module{0}
olcModulePath: /usr/lib/ldap
olcModuleLoad: {0}back_hdb
olcModuleLoad: {1}back_mdb
if back_bdb is not loaded:
# file load_bdb.ldif
dn: cn=module{0},cn=config
changetype: modify
add: olcModuleLoad
olcModuleLoad: back_bdb
root#hare:~/ldap# ldapmodify -Y EXTERNAL -H ldapi:/// -f load_bdb.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
modifying entry "cn=module{0},cn=config"
check the Backend
root#hare:~/ldap# ldapsearch -Q -LLL -Y EXTERNAL -H ldapi:/// -b 'cn=config' "(objectClass=olcBackendConfig)"
dn: olcBackend={0}hdb,cn=config
objectClass: olcBackendConfig
olcBackend: {0}hdb
dn: olcBackend={1}mdb,cn=config
objectClass: olcBackendConfig
olcBackend: {1}mdb
if no bdb Backend
# file backend_bdb.ldif
dn: olcBackend=bdb,cn=config
changetype: add
objectClass: olcBackendConfig
olcBackend: bdb
root#hare:~/ldap# ldapmodify -Y EXTERNAL -H ldapi:/// -f backend_bdb.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "olcBackend=bdb,cn=config"
generate a password(here the passwd is 123456)
root#hare:~/ldap# slappasswd -h {SSHA}
New password:
Re-enter new password:
{SSHA}e8xGdXmL+mSD3u/389YHeM+dpqFCUSyq
configure the database in cn=config
# file domain2_conf.ldif
dn: olcDatabase=bdb,cn=config
changetype: add
objectClass: olcDatabaseConfig
objectClass: olcBdbConfig
olcDbDirectory: /var/lib/ldap-bdb/
olcDatabase: bdb
olcDbIndex: objectClass eq
olcLastMod: TRUE
olcMonitoring: TRUE
olcDBNoSync: TRUE
olcSuffix: dc=domain2,dc=com
olcAccess: to dn.base="" by * read
olcAccess: to * by dn="cn=admin,dc=domain2,dc=com" write by * read
olcRootDN: cn=admin,dc=domain2,dc=com
olcRootPW: {SSHA}e8xGdXmL+mSD3u/389YHeM+dpqFCUSyq
root#hare:~/ldap# ldapmodify -Y EXTERNAL -H ldapi:/// -f domain2_conf.ldif
SASL/EXTERNAL authentication started
SASL username: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
SASL SSF: 0
adding new entry "olcDatabase=bdb,cn=config"
add the database DIT
# file domain2_db.ldif
dn: dc=domain2,dc=com
objectClass: top
objectClass: dcObject
objectClass: organization
dc: domain2
o: Example Corporation
description: The Example Corporation
dn: cn=admin,dc=domain2,dc=com
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
userPassword: {SSHA}e8xGdXmL+mSD3u/389YHeM+dpqFCUSyq
description: Directory Manager
root#hare:~/ldap# ldapadd -x -D "cn=admin,dc=domain2,dc=com" -w 123456 -f domain2_db.ldif
adding new entry "dc=domain2,dc=com"
adding new entry "cn=admin,dc=domain2,dc=com"
Now, you can access the new DIT (I use LDAP Admin)