Friday, December 22, 2006

Solaris 10, LDAP, RBAC

I've been trying to get Solaris' role based accounting to work via LDAP for the past couple of days. After a call to sun (more on this later), two late nights, and many google queries I've finally got everything working.

Let me start out by explaining what my goal was. I a secure centralized authorization and authentication environment. I want to make changes in one place and only one place. This centralized authentication store needs to support Solaris clients, Linux clients, and applications.

Simple, right?

As it turns out, it is. It took about an hour to get Sun ONE directory server up and running and authenticating unix users. It took about another hour to setup SSL and figure out how to use certutil to create the cert8.db and key3.db files that Solaris clients use to verify the LDAP server's certificate is valid. This took care of authenticating Solaris and Linux boxes.

One problem with keeping all of your users in a single repository is that, well, all of your users are in a single repository. Every user is on every box. Insanity. Fortunately, there are these things called netgroups. Netgroups are a throwback from the old NIS days and allow you to assign users to groups, and then assign groups to servers.

The next thing on my on my list was Solaris' Role Based Accounting (RBAC). RBAC is pretty stright forward. You assign commands to profiles, profiles to roles, and roles to users. Most of the administrative profiles and commands are preconfigured in Solaris, so all you really need to do is create a role with the access profiles you want and assign it to a user. I hadn't done this before, so I spent a little bit of time getting comfortable with it. Once I was pretty comfortable with it, I decided to load it into the LDAP directory. This is where I first ran into problems.

First off, if you're running Solaris 8 or 9 - good luck. There are several older documents floating around the internet that describe how to do this using an ancient tool called dsimport. Dsimport hasn't been updated since Directory Server 4.0 and doesn't work at all. The script is still bundled with the Directory Server, but the Java classes it calls are not. It took me a bit to figure this out.

Dsimport was replaced by a tool called 'ldapaddent' that ships with Solaris 8 and above. The problem is that the version of ldapaddent that ships with Solaris 8 and 9 is unable to import the RBAC databases. No dsimport and no ldapaddent. I still don't know how you're supposed to load this data into the directory on those systems.

Luckily for me, the Solaris 10 ldapaddent does support these files and can import them into LDAP. Once I got my data into the directory, I changed nsswitch.conf and much to my delight, I saw my roles and profiles when I ran "roles" and "profiles". The only problem is that although I could see the roles and profiles assigned to me, I couldn't actually use them. This is where things got sticky.

After banging my head into the wall for about 4 hours, I decided to give in and call Sun for support. The Directory Server rep I was speaking to didn't even know how to setup LDAP over SSL, let alone troubleshoot my problem. While I was on hold, I finally figured out the problem. When you login, your profile shell (pfksh) queries LDAP for your roles and profiles. Since the profile shell is running as your user, cert8.db and key3.db need to be readable. This fixed RBAC over ldap on Solaris 9 clients, but for some reason Solaris 10 clients still weren't working.

Just for kicks I tried using my unencrypted ldap profile to see if there was any difference. While using an unencrypted SSL session, everything worked. Exact same settings, exact same directory. The only difference was SSL vs. plain text. Since I just fixed the permissions on the certificate files, that couldn't be the problem. Another thing I noticed is that while I could run ldaplist as root, when I tried to do it under my normal userid it failed. I trussed ldaplist as root and then again as my user. The difference was that the root ldaplist was fopening /var/ldap/cert8.db and /var/ldap/key3.db and the unprivileged user was not. Turning on debug logging confirmed my fears, LDAP queries as my user were failing because they could not verify the certificate from the server.

After a couple more hours, I found a sunmanagers message with a similar problem. The answer? The default runtime linking environment in Solaris 10 isn't setup. For some reason, Solaris thought it would be cool to load some weird broken LDAP libraries for me instead of the ones that actually work. I ran these commands and everything worked perfectly.

[root@sol10client /]# crle -u -s /usr/lib/mps
[root@sol10client /]# crle -64 -u -s /usr/lib/mps/64

To make a long story short. RBAC in LDAP isn't very well documented. Use ldapaddent on a Solaris 10 box to populate the data in the LDAP directory. Since RBAC queries LDAP under your UID, you need to make sure that your UID can read the certificate files in /var/ldap. If your client is Solaris 10, you need to configure the runtime linking environment with the commands above.

Hopefully this saves you some gray hairs.

- Mike