LDAP and BER size

I recently came across a unique problem that didn’t “stand” out until I got to thinking about a couple of different situations that I had tested this in. So the scenario is that I needed to create a static group of unique members in LDAP (Sun Directory Server Enterprise Edition 6.3.1 and/or Oracle Directory Server Enterprise Edition 11.1.5.0) that has a extremely huge amount of members in it. So I created the LDIF file with all 60,000+ uids in it and proceeded to run an ldapadd against the server with the file. Well it immediately would come back with:

adding cn=testgroup,ou=group,dc=sungeek,dc=net

However, when looking in the LDAP, the group never showed up. Also when you look at the access log on the server you would see something similar to this:

[07/Aug/2012:21:22:39 -0400] conn=3 op=-1 msgId=-1 – closing from 127.0.0.1:48160 – B1 – Client request contains an ASN.1 BER tag that is corrupt or connection aborted

Now some times, depending on the versions of LDAP server and ldapadd programs, I got a “broken pipe” right after the adding output.

As you can see from the output in the error log it is not very descriptive on what the actual error is. I know I spent about 6 hours looking in to it to figure out what was actually the problem. Well this morning I was poking around the cn=config docs and found this:

http://docs.oracle.com/cd/E19528-01/820-2495/nsslapd-maxbersize-5dsconf/index.html

What this document shows is the attribute nsslapd-maxbersize, which is:

Defines the maximum size in bytes allowed for an incoming message. This limits the size of LDAP requests that can be handled by Directory Server. Limiting the size of requests prevents some kinds of denial of service attacks.

The limit applies to the total size of the LDAP request. For example, if the request is to add an entry, and the entry in the request is larger than two megabytes, then the add request is denied. Care should be taken when changing this attribute.

So by DEFAULT it is set to 2MB. Well my LDIF file was over 3.5MB in size. Which means that it was too big for the addition. To change it, do an ldapmodify with this ldif:

dn: cn=config
changetype:modify
replace:nsslapd-maxbersize
nsslapd-maxbersize: ########

I changed mine to 6MB, or 6291456, to hopefully cover any sizable additions in the future. Once done I restarted the directory server and tested again, and everything was good. According to the docs, the max size you can make this attribute is 2GB in size, and a size of 0 means default to 2MB, or 2097152. I think Oracle needs to make the error that is in the access log a little more descriptive, like “hey your query/add is too big yo”.

Hope this helps some one..

 

 

AIX LDAP Replication

a while ago I wrote about getting AIX authenticating to a SUN LDAP because of problems with AIX’s LDAP replication that I was having.. I forgot to mention that I “fixed” the AIX LDAP Replication problem. The solution was to put the FQDN of each “master” server in the /etc/hosts file with the IP address associated with it. It seems that IBM’s LDAP server is completely brain dead when it comes to DNS and LDAP, and would not replicate correctly unless I put the master server’s IP’s in the /etc/hosts.. So if you are having problems with getting replication to work with IBM’s LDAP server, try putting the entries in /etc/hosts and I bet it will work..

AIX LDAP to Sun LDAP in 10 Semi Easy Steps

I have been having some problems getting IBM’s Tivoli Directory Server to replicate properly. So I decided to try and see what it would take to move the IBM AIX machines from using IBM’s LDAP Server to using Sun’s LDAP Server. This is what I hope to accomplish:

  1. Setup Sun’s JES Directory Server on a Solaris 10 machine
  2. Configure the DS to have the AIX schema and objectclasses needed for user and group info
  3. Configure a AIX test machine to authenticate against the Sun LDAP Server
  4. Eventually move all AIX machines from the IBM DS to Sun DS, thereby having one set of servers that control all users/passwords for all Sun/Linux/AIX machines

Step 1: AIX Schema
The first thing I had to overcome is how AIX has 4 different ways of using LDAP for authentication. AIX 4.3.3 and AIX 5.1 used a non RFC2307 compliant schema. AIX 5.2 and AIX 5.3 can use this old schema or RFC2307, or a new one called RFC2307AIX, which combines the old with the new (there is also another one that I will not cover). When I originally setup the IBM LDAP I used the RFC2307AIX because it allows me to store ulimits and other info about AIX accounts in LDAP and not on each individual machine. But this also makes it harder to port these things over to Sun’s LDAP. Which lead me to yesterday’s afternoon adventure, creating a schema file that would work. I will link to my final copy below.

Step 2: AIX ObjectClasses
Second up was to create the objectclasses required for AIX Authentication, which consisted of creating the eAccount, AIXAccount,AIXaccessGroup, ibm-SecurityIdentities, container, and account. Some of these may not be needed for a fresh install, but I am trying to move entries from IBM’s LDAP to Sun’s LDAP with the least amount of editing an extremely huge ldap ldif export file. I will link to my final copy of this file below as well.

Step 3: Install JES DS
The third step was to download and install the DS 5.2.P4 on my fresh install of Solaris 10 U3 running on a Sparc machine. I did the custom install as I wanted to change the location of where it was installed to. The other thing I did is not load any sample data. Once the install was done, I ran the /usr/lib/ldap/idsconfig script to setup the DS. This is sort of how it went (copied from another doc):


It is strongly recommended that you BACKUP the directory server
before running idsconfig.

Hit Ctrl-C at any time before the final confirmation to exit.

Do you wish to continue with server setup (y/n/h)? [n] y
Enter the iPlanet Directory Server's (iDS) hostname to setup: ldap2
Enter the port number for iDS (h=help): [389] 389
Enter the directory manager DN: [cn=Directory Manager] cn=Directory Manager
Enter passwd for cn=Directory Manager :
Enter the domainname to be served (h=help): [ldap2.example.com] ldap2.example.com
Enter LDAP Base DN (h=help): [dc=example,dc=com] dc=example,dc=com
Enter the profile name (h=help): [default] default
Default server list (h=help): [192.168.1.2] 192.168.1.2
Preferred server list (h=help):
Choose desired search scope (one, sub, h=help): [one] one
The following are the supported credential levels:
1 anonymous
2 proxy
3 proxy anonymous
Choose Credential level [h=help]: [1] 2
The following are the supported Authentication Methods:
1 none
2 simple
3 sasl/DIGEST-MD5
4 tls:simple
5 tls:sasl/DIGEST-MD5
Choose Authentication Method (h=help): [1] 2

Current authenticationMethod: simple

Do you want to add another Authentication Method? n
Do you want the clients to follow referrals (y/n/h)? [n] y
Do you want to modify the server timelimit value (y/n/h)? [n] n
Do you want to modify the server sizelimit value (y/n/h)? [n] n
Do you want to store passwords in "crypt" format (y/n/h)? [n] y
Do you want to setup a Service Authentication Methods (y/n/h)? [n] n
Client search time limit in seconds (h=help): [30]
Profile Time To Live in seconds (h=help): [43200]
Bind time limit in seconds (h=help): [10]
Do you wish to setup Service Search Descriptors (y/n/h)? [n] n

Summary of Configuration

1 Domain to serve : example.com
2 Base DN to setup : dc=example,dc=com
3 Profile name to create : default
4 Default Server List : 192.168.1.2
5 Preferred Server List :
6 Default Search Scope : one
7 Credential Level : proxy
8 Authentication Method : simple
9 Enable Follow Referrals : TRUE
10 iDS Time Limit :
11 iDS Size Limit :
12 Enable crypt password storage : TRUE
13 Service Auth Method pam_ldap :
14 Service Auth Method keyserv :
15 Service Auth Method passwd-cmd:
16 Search Time Limit : 30
17 Profile Time to Live : 43200
18 Bind Limit : 10
19 Service Search Descriptors Menu

Enter config value to change: (1-19 0=commit changes) [0] 0

Enter DN for proxy agent:
[cn=proxyagent,ou=profile,dc=example,dc=com]
Enter passwd for proxyagent:
Re-enter passwd:

WARNING: About to start committing changes. (y=continue, n=EXIT) y

1. Changed passwordstoragescheme to "crypt" in cn=config.
2. Schema attributes have been updated.
3. Schema objectclass definitions have been added.
4. NisDomainObject added to dc=example,dc=com.
5. Top level "ou" containers complete.
6. automount maps: auto_home auto_direct auto_master auto_shared
processed.
7. ACI for dc=example,dc=com modified to disable self modify.
8. Add of VLV Access Control Information (ACI).
9. Proxy Agent cn=proxyagent,ou=profile,dc=example,dc=com added.
10. Give cn=proxyagent,ou=profile,dc=example,dc=com read permission for password.
11. Generated client profile and loaded on server.
12. Processing eq,pres indexes:
ipHostNumber (eq,pres) Finished indexing.
uidNumber (eq,pres) Finished indexing.
ipNetworkNumber (eq,pres) Finished indexing.
gidnumber (eq,pres) Finished indexing.
oncrpcnumber (eq,pres) Finished indexing.
automountKey (eq,pres) Finished indexing.
13. Processing eq,pres,sub indexes:
membernisnetgroup (eq,pres,sub) Finished indexing.
nisnetgrouptriple (eq,pres,sub) Finished indexing.
14. Processing VLV indexes:
example.com.getgrent vlv_index Entry created
example.com.gethostent vlv_index Entry created
example.com.getnetent vlv_index Entry created
example.com.getpwent vlv_index Entry created
example.com.getrpcent vlv_index Entry created
example.com.getspent vlv_index Entry created

idsconfig: Setup of iDS server ldap2 is complete.

Note: idsconfig has created entries for VLV indexes. Use the
directoryserver(1m) script on ldap2 to stop
the server and then enter the following vlvindex
sub-commands to create the actual VLV indexes:

directoryserver -s <server -instance> vlvindex -n userRoot -T example.com.getgrent
...much deleted...
directoryserver -s <server -instance> vlvindex -n userRoot -T example.com.getspent

Unfortunately the “directoryserver” command does not exist in Solaris 10, so i did the following:

cd /ldapserver/slapd-ldap2
./stop-slapd
./vlvindex -n userRoot -T example.com.getgrent
./vlvindex -n userRoot -T example.com.gethostent
./vlvindex -n userRoot -T example.com.getnetent
./vlvindex -n userRoot -T example.com.getpwent
./vlvindex -n userRoot -T example.com.getrpcent
./vlvindex -n userRoot -T example.com.getspent
./vlvindex -n userRoot -T example.com.getauhoent
./vlvindex -n userRoot -T example.com.getsoluent
./vlvindex -n userRoot -T example.com.getauduent
./vlvindex -n userRoot -T example.com.getauthent
./vlvindex -n userRoot -T example.com.getexecent
./vlvindex -n userRoot -T example.com.getprofent
./vlvindex -n userRoot -T example.com.getmailent
./vlvindex -n userRoot -T example.com.getbootent
./vlvindex -n userRoot -T example.com.getethent
./vlvindex -n userRoot -T example.com.getngrpent
./vlvindex -n userRoot -T example.com.getipnent
./vlvindex -n userRoot -T example.com.getmaskent
./vlvindex -n userRoot -T example.com.getprent
./vlvindex -n userRoot -T example.com.getip4ent
./vlvindex -n userRoot -T example.com.getip6ent
./start-slapd

(I installed the ldap server to /ldapserver)

Now that the indexes are created we can go on to the next step of modifying the schema.

Step 4: Importing new schema
Now I can import the AIXAttributes.ldif and the AIXObjectClasses.ldif files to my fresh newly installed server:


ldapmodify -D"cn=Directory Manager" -w MySuperSecretPass -h localhost -f AIXAttributes.ldif
ldapmodify -D"cn=Directory Manager" -w MySuperSecretPass -h localhost -f AIXObjectClasses.ldif

All should go well on the above imports. There were a couple of quirks that I found when creating the files, like how IBM uses one OID for a value when Sun uses a different one.

Step 5: Creating an OU for AIX data
By this time I have fired up the Console for the LDAP server and was doing things through the gui. The first thing I did was create a new OU for my aix data, i.e. ou=aixdata,dc=example,dc=com. This OU is where all my AIX stuff will be, the ou=people,dc=example,dc=com will be where my Sun users will go. (Can’t combine them yet because of massive amounts of differing UIDS between the AIX users and Sun Users).

After creating this, create 2 more OU’s under the aixdata. The first one will be for all users, ou=aixuser,ou=aixdata,dc=example,dc=com. The second will be for group information, ou=aixgroup,ou=aixdata,dc=example,dc=com.

Step 6: Create and AIX LDAP Admin Account
Because of how the AIX servers need to connect and get/put info into ldap, you will need to create an account that has read/write access to the 2 new ou’s you created. (This account is sort of similar to the Sun proxyagent account created with the idsconfig). I created my user, uid=aixldap,ou=aixdata,dc=example,dc=com. Also set the password for it to never expire (if you make it expire, you will have to update every AIX server every time the password expires). Once this user is created give it full read/write access to the ou=aixuser and ou=aixgroup with ACI’s.

Step 7: Export info from IBM LDAP
Since I am planning on moving from IBM LDAP to Sun LDAP I need to export the data from my IBM LDAP to an ldif format:


db2ldif -o /tmp/ldapexport.ldif

Do the above on the IBM LDAP server, it will put a file called /tmp/ldapexport.ldif. But now I need to “clean” some stuff out of it. Some of the stuff I need to remove is anything that is not User and Group related. For example I had IBM LDAP Replication setup so there are a ton of entries for that. (so the only thing you should have in your ldif file are entries for the dn’s like username=*,ou=aixuser,ou=aixdata,dc=example,dc=com and groupname=*,ou=aixgroup,dc=example,dc=com
)

Step 8: Import users and groups
Next I imported the cleaned file:


ldapadd -D"cn=Directory Manager" -w SuperSecret -f /tmp/ldapexport.ldif

Now all your users and groups should be in the new ldap server.

Step 9: Misc config in Sun LDAP
Some other stuff I did was add a couple indexes to the non-standard attributes that AIX uses:
groupname
username
hostsallowedlogin

The hostsallowedlogin allows us to put an entry in the persons LDAP entry to say which hosts they can log in to. If the attribute does not exist they can log in to any host that is served by this LDAP server. But if they have a value in this attribute, they can only log in to those host(s). (there is also a hostsdeniedlogin, which is the opposite of the hostsallowedlogin, if you want them to log in to every machine but one you can just populate that single host in to the hostsdeniedlogin).

Step 10: Configure AIX to talk to ldap server
One of the fall backs I don’t like about LDAP on AIX is that you have to have a local ldap user, and the ldap client software does not come with the base os. So you will have to install the ldap.client.adt and ldap.client.rte (probably don’t need the adt, but I install it anyways). During this install it usually creates the ldap user and group, which is never where we want it so either create an ldap group and ldap user before you install it, or after it is installed do the following, change the userid and groupid to what you want it to be in /etc/passwd and /etc/group and then run:


find / -user OLDID -exec chown -h ldap {} \;
find / -group OLDID -exec chgrp -h ldap {} \;

Now we can run the mksecldap command:

mksecldap -c -h 'ldap2.example.com' \
-a 'uid=aixldap,ou=aixdata,dc=example,dc=com' -p 'myp@ss' \
-d 'ou=aixdata,dc=example,dc=com' -n '389' -t '0' -T '100'

The above is all on one line. You must make sure the -t is set to 0, if it is not then you will get some weirdness that I will talk about later.

Once this is done, then you need to tell AIX that it is to look in LDAP for it’s info, you will need to edit another file /etc/security/user:

in the “default:” stanza, you will need to change the SYSTEM variable to LDAP, and add a registry variable with the value of LDAP.

I.E.:

default:
admin = false
login = true
su = true
daemon = true
rlogin = true
sugroups = ALL
admgroups =
ttys = ALL
auth1 = SYSTEM
auth2 = NONE
tpath = nosak
umask = 022
expires = 0
SYSTEM = LDAP
registry = LDAP

logintimes =
pwdwarntime = 0
account_locked = false
loginretries = 0
histexpire = 0
histsize = 0
minage = 0
maxage = 0
maxexpired = -1
minalpha = 0
minother = 0
minlen = 0
mindiff = 0
maxrepeats = 8
dictionlist =
pwdchecks =

Now you should be able to do an id username, and see some results:

AIXHost> id unixwiz
uid=106(unixwiz) gid=1(staff) groups=0(system),7(security),9(printq)

Next up try logging in remotely (you may have to create your home directory first). It should work.

Some Notes

  1. If you do not set the cachetimeout to be 0, if you change a users password as root, the user will get thrown in to a loop of changing their passwords. I.E. They will never be able to login as everytime they login it will say their password has expired and make them change it again and then it will kick them off (ie close their ssh session). Lather/rinse/repeat.
  2. After importing the users from an existing IBM server, you can delete the IBM-ENTRYUUID and the control attributes, they are for IBM DS only and have no use in Sun’s LDAP.
  3. Any problems on the import/etc, make sure to look at the ldap server error logs (/ldapserver/slapd-ldap2/logs/error_log) it should tell you exactly what is wrong.
  4. If you replicate this LDAP server, you should probably do a Master/Master relationship because of how AIX always stores info about last logins/etc in LDAP. I have not tested yet if it can follow referrals yet.

Here are the two files I was talking about:

AIXAttributes.ldif
AIXObjectClasses.ldif

Some other links:
IBM’s Redbook : Integrating AIX into Heterogeneous LDAP Environments, which I found was missing some stuff

Sun’s Cookbook for Solaris 8 client with Directory Server 5.1/Solaris 9 which I follow some times if I need to connect Solaris 8 machines in.

Hope this helps some one, if it does leave me a message.

IBM,Sun,LDAP

configuring ldapsearch on MacOSX to work with SSL

To configure the ldapsearch command on MacOSX (10.4 server is what I am working with at the moment) to work with ssl based LDAP servers there are couple of steps you need to do:

First create an key and certificate for the ldapsearch command to use. This can be done by using the following command:

openssl req -new -x509 -nodes -out /etc/openldap/ldap.pem -keyout /etc/openldap/ldap-key.pem -days 999999

This places the key in /etc/openldap/ldap-key.pem and the certificate in /etc/openldap/ldap.pem. Now if you are using a self signed certificate on your LDAP servers place a copy of CA certificate in /etc/openldap/cacerts/

Next edit the file /etc/openldap/ldap.conf and do the following:

First change the line that says : TLS_REQCERT from never to allow
Next add a line to your CACERT:
TLS_CACERT /etc/openldap/cacerts/mycaroot.crt

Then the lines for your client key and cert:
TLS_CERT /etc/openldap/ldap.pem
TLS_KEY /etc/openldap/ldap-key.pem

now you should be able to do an ldap search using ssl like this:


ldapsearch -x -Z -H ldaps://ldap.somehost.com -b"ou=people,dc=root" "(uid=unixwiz)"

IBM AIX LDAP authenication

I have spent over a week trying to get this to work. After going through 3 different level 2 LDAP techs with IBM, it is working, (knocking extremly freaking hard on wood). Here are my suggestions for IBM:

  1. Drop the use of DB2
  2. Drop the requirement of needing 2 seperate userid’s just to get it installed.
  3. Get the documentation on your web site updated, and take down the white papers that are referencing information that is 2 years old.
  4. Call Sun and learn how to do it right.