LDAP Queries in Mission Control Desktop

Previously, we saw that Mozilla MCD can inspect a user’s environment using getEnv().  It can also retrieve information from an LDAP directory.  I use this feature to inform Firefox and Thunderbird of the user in detail.  The corporate directory knows the user’s full name, mail server and authentication credentials.  autoconfig takes this and, among other useful things, constructs an email account for Thunderbird without user intervention.

The javascript API to deal with LDAP is a bit hackish, however it is all we have.  The first task is to define a function called processLDAPValues() which accepts a queryResults string as its only argument.  Inside processLDAPValues you extract return data from queryResults.

Instead of invoking processLDAPValues() directly, you call getLDAPAttributes() which in turn gets you to your function.  To illustrate, here is the code I use to query the corporate directory server and save the values for later use.

var userInfo = new Object();  // This will hold LDAP results
 
userInfo.envUser = getenv("LOGNAME");   // Unix UID
userInfo.envHome = getenv("HOME");      // User home directory
 
var ldapHost = "ldap.example.com";
var ldapBase = "dc=example,dc=com";
 
if( userInfo.envUser )
{  var ldapFilter = "uid=" + userInfo.envUser;  }
else
{  throw("Couldn't get UID from the environment");  }
 
// LDAP attributes to retrieve from the server
var ldapAttrs = new Array( "cn", "email", "employeenumber", "givenname", "mailhost", "sn", "uid" );
 
// Define how to process LDAP results before we make the call
function processLDAPValues(queryResults)
{  if( queryResults )
   {  // Build the userInfo object for later use
      for( var attr in ldapAttrs )
      {  userInfo[ ldapAttrs[attr] ] = getLDAPValue( queryResults, ldapAttrs[attr] );  }
   } else
   {  throw( "No LDAP results" );  }
}
 
// Call upon LDAP for the values in ldapAttrs array
// Uses the previous processLDAPValues()
getLDAPAttributes( ldapHost, ldapBase, ldapFilter, ldapAttrs.join(",") );

The first thing I do is create a userInfo object that will hold LDAP results for use later in the autoconfig.  To that object I add attributes for the user’s login name and home directory.

The next bit sets variables to contain the directory server’s hostname, base DN and the LDAP filter to use in the search. It’s a good idea to throw an error if there is no $LOGNAME.  (In a later post I will show how to enhance autoconfig error reporting.)

The ldapAttrs array names the attributes I want to return from LDAP.  Change this array to suit your environment.  The last line of code joins the array together with commas and feeds it to getLDAPAttributes along with the hostname, base DN and filter.  getLDAPAttributes is defined in MOZILLA_HOME/defaults/autoconfig/prefcalls.js and does the work to perform the query, then call your predefined processLDAPValues() function.

The example autoconfig script at developer.mozilla.org set preferences inside processLDAPValues, however this is a bad convention.  There are many preferences that require user information and separating pref() calls away from the main block of preference setting can be confusing.  As you can see here I simply run through the array of attributes I’m interested in and get the result from the LDAP query for that attribute, assigning it to the userInfo object.

Later on in the script I ask the userInfo object for those stored LDAP attributes. To set the hostname of the user’s mail server, for example, I call

// IMAP server name from corporate LDAP directory
defaultPref("mail.server.server1.hostname", userInfo.mailhost );

LDAP directories are a great resource. What attributes could you store in your corporate server?

9 thoughts on “LDAP Queries in Mission Control Desktop”

  1. This works great at my site! I’ve been banging my head against the wall, however, with one more thing I’m trying to do. I want some of my settings to be conditional upon posixGroups that the user is a member of, i.e. (&(cn=”Admin Group”)(memberUid=userInfo.envUser)).

    I’m no js expert, but it appears that getLDAPAttributes assumes that your query result is a single user record, and no way to look at attributes of pertinent groups.

    Since processLDAPValues is a function, I don’t think I can define it twice and call getLDAPAttributes twice to do a second query.

    Is there any way to get information from more than one entity in the LDAP database, or am I barking up the wrong tree?

  2. Glad to it helps.

    getLDAPAttributes passes processLDAPValues a string argument (queryResults). I don’t remember the format of the string, but it may support multiple results. The getLDAPValue function munches the string and returns the value of the attribute. Try using displayError or print inside processLDAPValues to display the queryResults. Like I said, the LDAP handling is hackish. It’s enlightening to read $MOZ_HOME/defaults/autoconfig/prefcalls.js.

    *zilla products support real LDAP queries and if I were still working with Thunderbird & Firefox I would be writing a more object-oriented way. Sadly, jobs change. Check the XPCOM reference.

  3. You’re welcome. Thanks for sharing a link to this post on the tb-enterprise mailing list.

  4. I run into a problem with mobile computers. If a user starts Thunderbird outside of our LAN, Thunderbird reads the failover.jsc, the local copy of the centralized settings, but of course can’t connect to the LDAP server. Then, all settings are available, but all LDAP Valures are “undefined”.

    I helped myself to disable the use of failover.jsc wenn not in LAN with lockPref(“autoadmin.failover_to_cached”, false); but found that now only settings with pref are memorized (saved in the pref.js in the user profile). The use of defaultPref und lockPref in the global settings file was not possible this way.

  5. Our corporate policy does not allow for anonymous binds to the LDAP server. Is there a way to pass the binddn and password to the array?

Leave a Reply