1. Home
  2. Tutorials
  3. LDAP
  4. Scripts and Tools
Yolinux.com Tutorial

YoLinux LDAP Tutorial: Support scripts and software tools for OpenLDAP directories

A few software tools to help out:

Note that I like to use ".csv" formats. These are "Comma Separated Variables" in a file with the extension ".csv". These can be read by all spreadsheets, word processors and many SQL databases to load a table. If a field contains a comma, then the field is encapsulated in quotes. Each line/record should have the same number of commas. An empty field is NOT represented by a blank but by an empty field.

  • Empty field: ,,
  • Field containing a single blank character: , ,
  • A field which contains a comma: ,"123 Cresent St., Unit A",

Note that the code you write will have to support the database schema and attributes you choose.

LDAP database dump to CSV:

Script to dump the LDAP database into CSV (Comma Separated Variables) format:

If you wish to allow others access to the entire database in a form that other programs such as spread sheets and databases can easily read, dump the LDAP database to a CSV format.

#!/bin/sh
#
# Dump LDAP database
/usr/sbin/ldbmcat -n /var/lib/ldap/stooges/id2entry.gdbm > /home/dbdumps/stooges-`date +%m%d%y`.ldif
sleep 10
#
# Convert ldif format to  csv
/bin/awk -F ': ' -f /opt/bin/ldif2csv-StoogesDumpAll.awk < /home/dbdumps/stooges-`date +%m%d%y`.ldif > /home/dbdumps/StoogesDatabaseAll-`date +%m%d%y`.csv

File: ldif2csv-StoogesDumpAll.awk
# File: ldif2csv-StoogesDumpAll.awk
# Create csv dump for whole database
#
BEGIN {
        last       = ""
        first      = ""
        name       = ""
        address    = ""
        loc        = ""
        state      = ""
        postalcode = ""
        homephone  = ""
        telephonenumber = ""
        mail       = ""
        mobile     = ""
        printf(" last,first,full name,address1,address2,city,state,postalcode,home#,work#,e-mail,phone3\n");
}
/^sn: /              {last=$2}
/^givenName: /       {first=$2}
/^cn: /              {name=$2}
/^street: /          {address=$2}
/^l: /               {loc=$2}
/^st: /              {state=$2}
/^postalCode: /      {postalcode=$2}
/^homePhone: /       {homephone=$2}
/^telephoneNumber: / {telephonenumber=$2}
/^mail: /            {mail=$2}
/^mobile: /          {mobile=$2}
/^dn/ {
        if(last != "" && first != "" && last != "StoogeAdmin") printf("%s,%s,%s,%s,,%s,%s,%s,%s,%s,%s,%s\n",last,first,name,address,loc,state,postalcode,homephone,telephonenumber,mail,mobile)
        last       = ""
        first      = ""
        name       = ""
        address    = ""
        loc        = ""
        state      = ""
        postalcode = ""
        homephone  = ""
        telephonenumber = ""
        mail       = ""
        mobile     = ""
}
# Capture last dn
END {
        if(last != "" && first != "" && last != "StoogeAdmin") printf("%s,%s,%s,%s,,%s,%s,%s,%s,%s,%s,%s\n",last,first,name,address,loc,state,postalcode,homephone,telephonenumber,mail,mobile)
}

CSV to LDAP LDIF format:

File: csvDump2ldif.c
/* File:  csvDump2ldif.c
   Author: Greg Ippolito
   Version: 1.0

   Usage: csvDump2ldf < inputfile.csv > outfile.ldif

   Load into LDAP:
          ldapadd -f stooges.ldif -cxv -D "cn=StoogeAdmin,o=stooges" -W

*/

#include <stdio.h>
#include <string.h>

#define MAX_NUMBER_OF_FIELDS 17
#define MAX_FIELD_LENGTH 132
#define TOTAL_SIZE (MAX_FIELD_LENGTH * MAX_NUMBER_OF_FIELDS)
#define SERVER_ROOT "o=stooges"

int main(int argv, char *argc[])
{
   int i, c;
   int ifield;                      /* Field count */
   int iline=0;                     /* Line count */
   int ignoreCommaFlag = 0;
   char field[MAX_NUMBER_OF_FIELDS][MAX_FIELD_LENGTH];  /* 17 fields */
   char *server_root = SERVER_ROOT;
   int ii, kk, fComma;

   for( ii=1910; ii<2100; ii++ )
   {
      printf("dn: ou=%d,o=stooges\n",ii);
      printf("ou: %d\n",ii);
      printf("objectclass: top\n");
      printf("objectclass: organizationalUnit\n");
      printf("\n");
   }

   bzero((char *)field, (size_t) TOTAL_SIZE);

   i = 0;
   ifield = 0;
   fComma = 0;

   while ((c = getchar()) != EOF)
   {
      if( c == '"' && ignoreCommaFlag ) ignoreCommaFlag = 0;
      else if( c == '"' && !ignoreCommaFlag ) ignoreCommaFlag = 1;
      else if( c == ',' && ignoreCommaFlag )
      {
         field[ifield][i] = ' ';
         i++;
      }
      else if( c == ',' && !ignoreCommaFlag )
      {
         fComma = 1;                            /* Set comma flag */
         field[ifield][i] = '\0';               /* NULL terminate */
         i = 0;
         ifield++;
         /* Found line with bogus number of fields. Keep repeating last field.*/
         if( ifield == MAX_NUMBER_OF_FIELDS ) ifield--;
      }
      else if( c == '\n' )
      {                               /* First field number begins count at 0 */
        iline++;
        field[ifield][i] = '\0';               /* NULL terminate */
        fComma = 0;                              /* Set comma flag */

        if( field[2][0] == '\0' )
                fprintf(stderr,"Error line %d: Blank field 3 - no cn\n", iline);
        else
        {
         printf("dn: cn=%s,ou=%s,%s\n",field[2],field[11],server_root);
         printf("cn: %s\n", field[2]);
         printf("objectClass: top\n");
         printf("objectClass: person\n");
         printf("objectClass: organizationalPerson\n");
         printf("objectClass: inetOrgPerson\n");
         printf("givenname: %s\n", field[1]);
         printf("sn: %s\n", field[0]);
         if( field[11][0] != '\0')
            printf("ou: %s\n", field[11]);  /* Department=organizational unit */
         if( field[12][0] != '\0' ) printf("mail: %s\n", field[12]) ;
         printf("employeetype: A\n");
         if( field[3][0] != 0 && field[4][0] != 0)
                    printf("streetAddress: %s %s\n", field[3], field[4]);
         else if( field[3][0] != 0 && field[4][0] == 0)
                    printf("streetAddress: %s\n", field[3]);
         else if( field[3][0] == 0 && field[4][0] != 0)
                    printf("streetAddress: %s\n", field[4]);
         if( field[5][0] != '\0') printf("l: %s\n",field[5]);
         if( field[6][0] != '\0') printf("st: %s\n", field[6]);
         if( field[7][0] != '\0') printf("postalCode: %s\n", field[7]);
         if( field[10][0] != '\0') printf("telephoneNumber: %s\n", field[10]);
         if( field[9][0]  != '\0') printf("homePhone: %s\n", field[9]);
         if( field[13][0] != '\0') printf("mobile: %s\n", field[13]);
         if( field[11][0] != '\0')
            printf("departmentNumber: %s\n", field[11]);

         printf("\n");

         /* Clear variables */
         bzero((char *)field, (size_t) TOTAL_SIZE);
        }

        i = 0;
        ifield = 0;
      }
      else
      {
         //if( i==0 && c==' ' )
         field[ifield][i] = c;
         i++;
         fComma = 0;                              /* Set comma flag */
      }

   }

}

LDAP LDIF file dump to CSV:

File: ldif2csv.cpp
// ldif2csv.cpp
// Greg Ippolito

// ldif2csv < file.ldif > file.csv

#include <string>
#include <algorithm>
#include <vector>
#include <cctype>
#include <iostream.h>
#include <fstream.h>

main()
{
   const string      sDelim(":");
   string            sLine, sValue;
   string::size_type posBeginIdx, posEndIdx;
   string::size_type ipos;
   string::size_type ilength;
   string            sKeyWord;
   string            cn,givenname,sn,streetaddress,l,st,postalcode;
   string            mail,homephone,telephonenumber,mobile;

   cout << " last,first,full name,address1,address2,city,state,postalcode,country,home#,work#,year,e-mail,phone3" << endl;

   while( getline(std::cin, sLine) )
   {
      if( sLine.empty() );                     // Ignore empty lines
      else
      {
         ipos = 0;
         posEndIdx = sLine.find_first_of( sDelim );
         sKeyWord  = sLine.substr( ipos, posEndIdx ); // Extract word
         posBeginIdx = posEndIdx + 2;  // Beginning of next word (after ': ')

         if( !sKeyWord.compare( "cn" ) ) cn = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "givenname" ) ) givenname = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "sn" ) ) sn = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "streetaddress" ) ) streetaddress = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "l" ) ) l = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "st" ) ) st = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "postalcode" ) ) postalcode = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "mail" ) ) mail = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "homephone" ) ) homephone = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "telephonenumber" ) ) telephonenumber = sLine.substr(posBeginIdx);
         if( !sKeyWord.compare( "mobile" ) ) mobile = sLine.substr(posBeginIdx);

         if( !sKeyWord.compare( "dn" ) && cn.compare("StoogeAdmin")
            && !givenname.empty() && !sn.empty() )
         {
            if(index(cn.c_str(),',' ) )
            {
               cn="\""+cn;
               cn.append("\"");
            }
            if(index(sn.c_str(),',' ) )
            {
               sn="\""+sn;
               sn.append("\"");
            }
            if(index(givenname.c_str(),',' ) )
            {
               givenname="\""+givenname;
               givenname.append("\"");
            }
            if(index(mail.c_str(),',' ) )
            {
               mail="\""+mail;
               mail.append("\"");
            }
            }
            if(index(streetaddress.c_str(),',' ) )
            {
               streetaddress="\""+streetaddress;
               streetaddress.append("\"");
            }
            if(index(telephonenumber.c_str(),',' ) )
            {
               telephonenumber="\""+telephonenumber;
               telephonenumber.append("\"");
            }
            if(index(homephone.c_str(),',' ) )
            {
               homephone="\""+homephone;
               homephone.append("\"");
            }
            if(index(mobile.c_str(),',' ) )
            {
               mobile="\""+mobile;
               mobile.append("\"");
            }
            cout << sn << "," << givenname << "," << cn << "," ;
            cout << streetaddress << ",," << l << "," << st << "," ;
            cout << postalcode << "," << homephone << "," ;
            cout << telephonenumber << ",";
            cout << endl;
            cn.erase();
            givenname.erase();
            sn.erase();
            streetaddress.erase();
            l.erase();
            st.erase();
            postalcode.erase();
            mail.erase();
            homephone.erase();
            telephonenumber.erase();
            mobile.erase();
         }
      }

   }

}

Return to YoLinux LDAP Tutorial