Accessing and Modifying LDAP Data
OpenLDAP is the core of the user and directory structure for most ClearOS servers. It contains useful information that is used by ClearOS to authenticate users. Sometimes this information can be useful for other systems that you may want to attach to ClearOS. To access this data, you will need to assemble your information and decide the correct balance of access and security.
Ports
OpenLDAP uses 2 ports, port 389 (unsecure) and port 636 (“LDAP over TLS/SSL”). Of these two ports, only 636 is generally open externally while port 389 is available only to local services by default. Additionally, by default, ClearOS does not listen on 636 unless the LDAP policy is published to the network. Take great care in publishing the policy, any user that can access the port will be able to authenticate and list information of other users including their password hashes.
Structure and Access
To connect to the LDAP directory, start locally on the box at command line through a terminal program such as PuTTY (Windows), or Terminal (Mac). There are two ways to access your LDAP directory.
- slapcat
- ldapsearch
slapcat
The tool 'slapcat' can spit out your entire directory to the screen.
slapcat -n3
The parameter '-n3' references the 3rd LDAP database structure. This data can be manipulated to give you helpful information. For example, to backup your LDAP database for review, push the output to a text file:
slapcat -n3 > /root/ldapdump.txt
Or you can search the results for specific information. For example, if you wanted to review the directory to ensure that your Samba domain SIDs are consistent throughout the database, you can search for keywords:
slapcat -n3 | egrep "^sambaSID"
ldapmodify
LDAPModify is an older tool but gives you lots of extra abilities which you can use in scripted methods more effectively that 'slapcat'. For example, you can add some of these methods to your application that may need to search or modify certain parameters. You will need to validate your settings before proceeding to attempt a connection from internal or external sources. This will ensure that you are using correct information.
To connect locally or externally to the server you will need the following information:
- Base DN
- Bind DN
- Bind Credentials
The base DN is the root of the LDAP structure as far as ClearOS is concerned. LDAP is organized in a tree structure and your Base DN is where your pertinent information begins. The Bind DN is the account that you are using to authenticate; it is the equivalent of the 'username' on LDAP. The Bind Credentials is the password of the Bind DN account.
You can obtain all of this information in Webconfig or at command line:
- ClearOS 6.x and ClearOS 7.x
- Webconfig » Server » Directory Server
- cat /var/clearos/openldap/config.php
- ClearOS 5.x
- Directory » Domain and LDAP
Connecting as the LDAP manager is the simplest method. Use the information above and construct a command similar to this:
ldapsearch -D "cn=manager,ou=Internal,dc=domain,dc=net" -b "dc=domain,dc=net" -x -w "password"
Alternately, you can use a user account to accomplish a server as a user:
ldapsearch -D "cn=User Name,ou=Users,ou=Accounts,dc=domain,dc=net" -b "dc=domain,dc=net" -x -w "password"
Once you have validated that you can get the information that you need using the credentials above, you should be able to frame the proper configuration depending on the needs of your application to the data.
ldapsearch -x -b 'dc=domain,dc=net' -s sub 'uid=user' | grep ^dn
Then using the string starting “cn” for the -D parameter. Password checking can all be put into one command:
ldapsearch -D "$(ldapsearch -x -b 'dc=domain,dc=net' -s sub 'uid=user' | grep ^dn | sed 's/dn: //1')" \ -x -v -b 'dc=domain,dc=net' -W
Substitute your user's username and your Base DN. You should see a whole load of text scroll by then, if the check succeeded, just about at the bottom, see a line:
result: 0 Success
BASE_DN=$(grep base_dn /var/clearos/openldap/config.php | awk '{print $3}') && \ ldapsearch -D "$(ldapsearch -x -b $BASE_DN -s sub 'uid=user' | grep ^dn | sed 's/dn: //1')" -x -v -b $BASE_DN -W
Change “user” to the unsename and input the password when prompted.
Looking at the Structure
Next, we will use this data to identify the user that we are referencing or making changes to. When we review the data in the output, please note some of the following general principles:
- Each record is identified by a distinguished name (DN)
- Each record will 'objectClass' items which identifies what type of record it is
- Attributes can be unique or can exist as a multitude. This is defined by the schema which we will not address here
Let's take a selective look at an LDAP entry as recorded in our ldap dump using one of the methods above. From that entry, we identify that the following attributes are involved with the username:
dn: cn=test a,ou=Users,ou=Accounts,dc=example,dc=org sn: a uid: testa cn: test a homeDirectory: /home/testa sambaHomePath: \\EXAMPLE\testa givenName: test
Here is an explanation of some of the attributes:
- dn: Distinguished Name. This is the name of the record in LDAP
- sn: Surname. The person's lastname.
- uid: User Identifier. This is the user's username in ClearOS
- cn: Canonical Name. This is the fullname of the user, or rather the 'givenName' plus the 'sn'
- homeDirectory: This is where the user's files are located locally on a given server. If using a multi-server environment, this should be a distributed volume such as NFS or using some sort of replication method.
- sambaHomePath: This is the UNC path to the user's share if shared by Samba.
- givenName: This is the first name of the user.
Here is an example of what could be change in order to change a user's identity. This is useful if, for example, the user legally changes their name but you want other things to remain in tact. This is what we might want to change the username to:
dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org sn: Bee uid: terryb cn: Terry Bee homeDirectory: /home/terryb sambaHomePath: \\EXAMPLE\terryb givenName: Terry
Because of the change in the home directory, in this example, we'd also need to move the user's data and validate that the permissions are correct. Since we didn't change the user's uidNumber or gidNumber or her sambaSID, the permissions should be ok without manipulation! That, after all, is what one might be trying to preserve when making such modifications directly to LDAP.
Modifying Data
The above sections talked about why and what one might change through a backend manipulation of LDAP, the following talks to the 'how'. You can easily modify LDAP data. There are two methods we can use:
- ldapvi
- ldapsearch, ldapmodify, and ldapadd
If you already understand the workings of 'vi' (the editor.) You can easily make changes to your LDAP database. If you need to script changes or use programatic methods to manipulate LDAP data, you will likely use a combination of ldapsearch, ldapmodify, and ldapadd.
ldapvi
You will need the command line tool 'ldapvi' in order to make changes to your LDAP database. You are free to use other tools like 'ldapmodify' if you need to script changes, but this tool is quite useful for interactive changes. To install 'ldapvi' perform the following (ClearOS 6 and 7):
yum --enablerepo=clearos-epel install ldapvi
Once it is installed, you will need a resource file to make edits. Create the following file:
vi /root/.ldaprc
Populate it with appropriate data for your server. It will look something like this (refer to the settings of your LDAP server using the sections above to collect the relevant data):
HOST localhost BASE dc=example,dc=net BINDDN cn=manager,ou=Internal,dc=example,dc=net # search parameters (uncomment as needed) #DEREF never #SIZELIMIT 0 #TIMELIMIT 0
You will likely need to modify the BASE and BINDDN lines and use your server's information (can be found in the Directory Services module.)
Now you can edit your LDAP config file from command line by issuing the follow command:
ldapvi -w "your-LDAP-password"
Using LDIF via ldapmodify
The beauty of this method is that this method can be scripted, If you just need a casual edit, the previous method is much, much quicker.
We will make two ldif files to accomplish this. First we will rename the DN of the user and once we confirm that change is in effect, we will rename the attributes.
Create an ldif file called atest2TerryBee-dn.ldif with the following data (you can use your favorite editor like vi, emacs, pico, et al):
dn: cn=test a,ou=Users,ou=Accounts,dc=example,dc=org changetype: modrdn newrdn: cn=Terry Bee deleteoldrdn: 0
Now call this file and insert your data for your base DN and password (ie: baseDN=“cn=manager,cn=internal,dc=example,dc=org” and password=“abcdEFGHijklMNOP”):
ldapmodify -h localhost -D "cn=manager,cn=internal,dc=example,dc=org" -x -w abcdEFGHijklMNOP -f ./atest2TerryBee-dn.ldif # This line left blank for easy copy and paste
Now, grab another snapshot of the ldap database and validate the DN change for the user:
slapcat -n3 > /root/ldapdump.todaysdate.1
Once you confirm that the change is good for the DN (edit /root/ldapdump.todaysdate.1 and see if it is changed), we will make changes to the attributes contained in that DN. Make a file called atest2TerryBee-attr.ldif with the following information:
dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify delete: cn cn: test a - dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify replace: sn sn: Bee - dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify replace: uid uid: terryb - dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify replace: homeDirectory homeDirectory: /home/terryb - dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify replace: sambaHomePath sambaHomePath: \\DanburyCO\terryb - dn: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org changetype: modify replace: givenName givenName: Terry -
Now merge this value by running the following:
ldapmodify -h localhost -D "cn=manager,cn=internal,dc=example,dc=org" -x -w abcdEFGHijklMNOP -f ./atest2TerryBee-attr.ldif # This line left blank for easy copy and paste
Lastly, rename the home directory and validate that the user is a member of the correct groups.
mv /home/testa /home/terryb
You can validate the permissions work by running:
ls -la /home |grep terryb
Cleaning up
During the LDIF method we left some bad records in the LDAP database. We can clean those up as well. Find the groups which the old DN was listed. When I search the file I find the following DNs which have 'test a' as a user:
dn: cn=allusers,ou=Groups,ou=Accounts,dc=example,dc=org dn: cn=domain_users,ou=Groups,ou=Accounts,dc=example,dc=org
The user Terry Bee was NOT added to either of these groups when the modifications were made to the group memberships in Webconfig so they will need to be modified here. Make and LDIF file called atest2TerryBee-groups.ldif
dn: cn=allusers,ou=Groups,ou=Accounts,dc=example,dc=org changetype: modify delete: member member: cn=test a,ou=Users,ou=Accounts,dc=example,dc=org - dn: cn=allusers,ou=Groups,ou=Accounts,dc=example,dc=org changetype: modify add: member member: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org - dn: cn=domain_users,ou=Groups,ou=Accounts,dc=example,dc=org changetype: modify delete: member member: cn=test a,ou=Users,ou=Accounts,dc=example,dc=org - dn: cn=domain_users,ou=Groups,ou=Accounts,dc=example,dc=org changetype: modify add: member member: cn=Terry Bee,ou=Users,ou=Accounts,dc=example,dc=org
ldapmodify -h localhost -D "cn=manager,cn=internal,dc=example,dc=org" -x -w abcdEFGHijklMNOP -f ./atest2TerryBee-groups.ldif # This line left blank for easy copy and paste
You should get a response like this:
modifying entry "cn=allusers,ou=Groups,ou=Accounts,dc=example,dc=org" modifying entry "cn=allusers,ou=Groups,ou=Accounts,dc=example,dc=org" modifying entry "cn=domain_users,ou=Groups,ou=Accounts,dc=example,dc=org" modifying entry "cn=domain_users,ou=Groups,ou=Accounts,dc=example,dc=org"
Check through your LDAP directory and see if you see any inconsistencies.