LDAP – The Lightweight Directory Service

“To err is human but to really screw up things need a computer.”
-Old jungle saying

As all doomsayers had been predicting, computers have taken control of our lives. Computers touch every aspect of our daily lives. We need computers for carry out simple tasks or for performing equally complicated ‘superhuman’ (or inhuman) tasks. All these information is stored in the computer in the form of files. These files are stored in different directory which may be stored on different drives. The first few days of possessing a computer can be termed as a `honeymoon’ period. During this period we seem to remember all the files names along with their storage slots (technically called sub-directories). But with the passage of time the disks start filling up and nobody seems to remember `what is stored where’. To add insult to injury the system boots up only to tell us `missing file so-and-so system halted’ or some equally esoteric message. So what do you do in such a situation. Call the Scotland Yard or the FBI? No, Simply revert to the golden days of MS-DOS. The friendly (or frigid, depending on your perspective) system prompt (c:>, seems to make a mocking face at us) show up. We reply with an equally esoteric message (tit for tat) called `dir <filename> /s’!! Welcome to the world of `Directory Access Services’

These three words seem to `say all but mean nothing’ to ordinary mortals like us. The only advantage it bestows on us is that it allows us entry to many a parties. In the days when DOS was the king having the ability to roll off DOS commands off the back of your hand was enough to guarantee you an entry to any party in town. Although we must admit knowing the ‘dir’ command would get you nowhere. Lets the time off to understand this low profile guy called the ‘dir’. The ‘dir’ command presented us with a list of files in a particular directory. However when we used the command ‘dir <filename>’ it would search the directory for any instances of that file. To add to everyone’s sorrow, the ‘dir’ command would allow us to use various options. So by using commands like ‘dir<filename> /s’ we could scan the entire directory inclusive of all the sub-directory under it. We would love to tell you more about the other options available under ‘dir’, but unfortunately this is not supposed to be a tutorial on the ‘dir’ command. Please don’t blame us for any bias for using DOS commands. We are definitely not paid to use them. Actually we don’t mind being paid for using them (Microsoft are you reading this?). Actually we believed that the ‘dir’ command is one of the most simplest command known to mankind. However other OS users need not loose heart as their OS have their own `dir’ commands like ‘ls’ (UNIX), ‘Find file or folder’ (Windows95) etc. The objective of the whole exercise was to demonstrate the fact that all OS have the means to find and access a file in a directory. This is the genesis of the `Directory Access Service’.

“Man’s (and woman’s) wants cannot be satisfied”
– Basic law of economies.

As wants grew desktops were connected to LAN’s which progressively became WAN and finally got integrated with the mother of all networks the Internet. Primary wants lead to secondary wants -so says the economist. Being connected to the ‘Net lead to the desire to posses the ability to search for a document, user etc. present on the ‘Net. Some soul-searching (& brain storming)sessions enabled the ISO to introduce a standard called the X.500. This was an exhaustive standard by any means and was designed to fulfill the wants of most human beings (and of other beings too, as and when they came along!) However this virtue of X.500 proved to be its nemesis X.500 became very unyielding and implementing it necessitated buying a supercomputer. One fine day University of Michigan decide that they had to do something to make X.500 viable. So they chopped off the extra flab from X.500, but retained the basic flavor of the X.500. Thus they gave birth to a new protocol. Being highly inspired by the World Boxing Federation they decided to name the new protocol as ‘Lightweight Directory Access Protocol’ or LDAP. We would like to thank the people at the University of Michigan for inventing LDAP. They have made life as this planet very much livable. ( Wish they could do something about the global warming).

Stripping the glamour

Yellow pages have became a way of life for us. They are a store houses of information regarding any product or service required. Well LDAP could be loosely termed as the electronic equivalent of the yellow pages. So lets de-glamorize LDAP by stripping it and have a look at its functioning (After stripping the lightweight DAP. We will probably get a flyweight DAP) One of the biggest advantage of LDAP over, X.500 was that it worked over TCP, unlike the latter which worked over other protocols. As the Internet mostly uses the TCP/IP protocol, LDAP was readily accepted by various vendors and hence gained immerse popularity.

Information, the world over is stored in databases. LDAP specifies how this information should be stored. Understanding LDAP is made easier if we visualize information being arranged in tables in databases. LDAP is used to provide the `header tabs’, to the column in there tables (In case of the yellow pages items are classified under various product categories and service categories). Technically LDAP can be conceptualized as a tree diagram. One such tree diagram is as shown below.

Country (c)
|
Organization (o)
|
Person’s name
(cn/sn)

The flow diagram represented by the tree above is the normal procedure adopted to ‘narrow down’ on a person using the LDAP approach. As can be seen the ‘column names’ of our conceptual design act as the members in the tree diagram. Now is the right time to tell you the good news and the bad news. The good news is that X.500 has standardized on the names of these members, but the bad news is that there are hundreds of such members. Hence we cannot discuss each of these names. But this does not stop us from listing some of them so here we go.

  • c – Country
  • sn – Surname
  • o – Organization
  • cn – Common name

These tags are used when we use any of the LDAP services. These services are called as ‘application’ (more jargon) The applications available under LDAP are as follows.

  • BindRequest,
  • BindResponse,
  • UnbindRequest,
  • SearchRequest,
  • SearchResponse,
  • ModifyRequest,
  • ModifyResponse,
  • AddRequest,
  • AddResponse,
  • DelRequest,
  • DelResponse,
  • ModifyRDNRequest,
  • ModifyRDNResponse,
  • CompareRequest,
  • CompareResponse,
  • AbandonRequest,

Most of the application names listed above are self explanatory(we love such names). Disk space being an expensive proposition, we will not waste it by explaining each and every application listed above. (Had Microsoft read the DOS commands & sponsored us we would have given the explanation of the entire listing!) LDAP works on a client-server model(don’t worry, half of the world works an such model) The client is the machine that desires for a service whereas the server is the machine which actually carries out the task(It would have been a better idea to call the server a butler). The client ‘queries’ the server on port 389. The server responds to this query by carrying out the required ‘service’. The time required for carrying out the services depends on the type of service desired. Service may vary from a simple `BindRequest’ to a more sophisticated (or rather complex) `SearchRequest’ with multiple filters. (We love jargons) Before we go over and write some code which can be implemented as an LDAP program let us look at what actually transcribes during an LDAP session. All LDAP sessions follow the following routine.

  1. BindRequest is sent by the client to the server. The BindRequest has to be the first packet that flows during the LDAP session.
  2. the server receives the BindRequest and is willing to provide service to the client, it responds to BindRequest with an acknowledgment called the BindResponse.
  3. receiving the BindResponse the client sends the details of the desired service to the server.
  4. server executes the service required and replies with the desired response. At this point the client may wish for more service or may wish to terminate the session. The session may be re-established at any point of time, the only condition being that the BindRequest be the first data packet flowing across.

The best way to understand an application is to write a program for the same. Below we present few program which use some of the application available under LDAP. So check them out

WARNING: Trying to understand these programs may be difficult if you don’t know ASN.1 and BER implementation of ASN.1 for LDAP so check them out.

Jumping in the dirt- the first program

Welcome to the world of LDAP programming In this program we assume that you have understood the concepts used in the BER implementation of LDAP. We also believe that by now you are conversant with the various application (or their name) available under LDAP. Don’t worry knowing the application names is enough to guarantee you an entry into any party. In the program given below we will use an application called the BindRequest. The BindRequest as the name suggest is a request sent by the client to the server to seek permission for connecting to it. As can be seen from BER encoding a BindRequest is written as 60hex or

0 1 1 0 0 0 0 0

The BindRequest has to be the first packet to flow during an LDAP session

The other unintelligible numbers. that are passed as parts of the BindRequest are known as parameters of BindRequest. They are as follow.

  1. Version no : – The version number of LDAP to be used for the negotiation. On the last count the latest version of LDAP is 3.3. This information is presented for people who believe in ‘staying in tune’ with (or ahead of) time.
  2. Name : – The ‘name for the session’ The name is provided as an octet string. However if a 0 (null) is used, then the login is stated to be an anonymous login (and you always thought that anonymous letters and phone calls were the last word on anonymous communication)
  3. Authentication : – This word sounds music to the ears of the science fiction buffs. As the name suggest authentication is used to provide an option for adopting a method of providing authentication. In our case we have used a null value to signifies simple authentication. In this case the password go out as a clear text password. i.e. the whole world can see it as it is un-encrypted.

Ldap.c

#include <windows.h>
#include <stdio.h>
unsigned char kk[10000],ll[10000];
void abc(char *p)
{
FILE *fp=fopen("c:\\ldap\\z.txt","a+");
fprintf(fp,"%s\n",p);
fclose(fp);
}
int ii,dw,jj;
void abc1(unsigned char p)
{
FILE *fp=fopen("c:\\ldap\\z.txt","a+");
fprintf(fp,"%d%x%d%c\n",jj,p,p,p);
fclose(fp);
}
WNDCLASS a;HWND b;MSG c;char aa[200];SOCKET s;struct hostent h;
WSADATA ws;DWORD e; struct sockaddr_in sa;
long _stdcall zzz (HWND,UINT,WPARAM,LPARAM);
int _stdcall WinMain(HINSTANCE i,HINSTANCE j,char *k,int l)
{
a.lpszClassName="a1";
a.hInstance=i;
a.lpfnWndProc=zzz;
a.hbrBackground=GetStockObject(WHITE_BRUSH);
RegisterClass(&a);
b=CreateWindow("a1","LDAP",WS_OVERLAPPEDWINDOW,1,1,10,20,0,0,i,0);
ShowWindow(b,3);
while ( GetMessage(&c,0,0,0) )
DispatchMessage(&c);
return 1;
}
long _stdcall zzz (HWND w,UINT x,WPARAM y,LPARAM z)
{
if ( x == WM_LBUTTONDOWN)
{	
e=WSAStartup(0x0101,&ws);
sprintf(aa,"WSAStartup e = %ld",e);
s = socket(PF_INET,SOCK_STREAM,0);
sprintf(aa,"socket s = %ld",s);
sa.sin_family=AF_INET;
sa.sin_addr.s_addr = inet_addr("141.211.83.38");
sa.sin_port=htons(389);
connect(s,(struct sockaddr *)&sa,sizeof(sa));

kk[0]=0x30;
kk[1]=12;

kk[2]=0x02;
kk[3]=0x01;
kk[4]=0x01;

kk[5]=0x60;            //Bind Request
kk[6]=7;

kk[7]=0x02;
kk[8]=0x01;
kk[9]=0x02;

kk[10]=0x04;	         //Anonymous request
kk[11]=0x00;

kk[12]=0x80;           //Simple Authentication
kk[13]=0x00;

e=send(s,kk,14,0); 			  
sprintf(aa,"SendTo %ld",e);
ii=recv(s,ll,1000,0);
sprintf(aa,"Recv from %d",ii);
abc(aa);
for (jj=0;jj<ii;jj++)
abc1(ll[jj]);
MessageBox(0,"hi","hi",0);
}
if ( x == WM_DESTROY)
PostQuitMessage(0);
return DefWindowProc(w,x,y,z);
}

In this program we have assumed that you are conversant with windows sockets programming. If you are not then please click here for the greatest sockets tutorial on this side of the table. As can be seen in the above program, we have created a window called ‘LDAP’. When you click on it the bytes are sent across using a socket which was created to work on the TCP/IP suite. A connection is established with the server whose IP address is 141.211.83.38, this incidentally happens to be an LDAP server at the University of Michigan, USA. The helper functions ‘abc’ and ‘abc1’ are used to record the proceedings of the show. This function is used to write to disk the bits and bytes that flow during the data flow. To lend justice to these functions we have reproduced the bits and bytes that constitute the inflow during the course of the execution of the program.

The first byte we send across is 0x30 which stands for ‘universal sequence’. If we break up the byte into it’s individual bits, we get

0 0 1 1 0 0 0 0

The first two bits from the left, when off, imply that the query is universal, i.e. it applies to all fields. The next bit from the left is on and that means that the query is a constructed one. The value of the fourth bit is 16 and that’s Sequence in RFC 1777. So it’s a Universal Sequence.

The next byte we send the LDAP server is 12, which is the length of the packet, minus the first byte and the length byte. This is a format that’s followed throughout; the length never includes the defining byte(s) and the length byte(s).

The next byte, 0x02 means that the information to follow is an Integer i.e. a number. The next byte is the length byte and the third byte is the actual value. These three bytes together form the Message ID field. The Message ID for this packet is 0x01, but it can be anything at all.

Now we have the actual Bind Request. If we break up the number 0x60 into it’s individual bits we get

0 1 1 0 0 0 0 0

When the two leftmost bits are 01, it stands for ‘application’. The next bit tells us that the information to follow is constructed. The last four bits hold the application number and since all the bits are off, it’s 0. So this byte means Application 0. Look up the value in RFC 1777.

The next byte is the length of the data to follow. As usual the length doesn’t include itself or the proceeding bytes in it’s calculations.

The next three bytes hold the version number of the LDAP protocol we’re using. Since the version is a number, the first byte is 0x02 for Integer, the second byte is for the length and the third byte holds the version number, 0x02.

The next byte is 0x04 which means that information to follow is a string. The byte after that holds the length, which is zero! This means that there is no string to send. These bytes are actually supposed to hold the name of the person logging on to the server. A null string means that this is an anonymous request.

The second last byte is 0x80. If we’re to break it up into it’s bits, we get

1 0 0 0 0 0 0 0

Since the first two bits are 01, it means that this byte is Context Specific. The rest of the bits are 0, so the byte is Context specific 0. When we look it up in the RFC, we find that it stands for Choice and under Choice, a 0 stands for Simple. So the Bind is a Simple Bind.

This means that this Bind is context specific. The last byte is 0x00 and thats stands for simple

This packet is a connect packet. Informs the server that we want to connect to it and ask it some questions. The reason we’re only sending a Bind and not any data along with it is to test whether the server is up. If it is, we should get a z.txt file that looks a lot like this.

Z.TXT
Recv from 14

0 30 48 0
1 c 12
2 2 2
3 1 1
4 1 1
5 61 97 a
6 7 7
7 a 10
8 1 1
9 0 0
10 4 4
11 0 0
12 4 4
13 0 0

The first byte is 0x30 and it has the same meaning as the 0x30 in our request. The next byte is the length, which is 12 bytes. The next three bytes hold the Message ID, which is the same as the Message ID of our request packet. It’s only now that the bytes get interesting.

The fifth byte is 0x61 which if broken up into it’s constituent bits is

0 1 1 0 0 0 0 1

01 means application as mention before and the third byte means it’s constructed, but the last bit gives us the application number, which is 1. So look up Application 1 in the RFC. This is the Bind result.

The next byte is the length of the data to follow. The seventh byte is 0x0a which stands for a ‘Enumeration’ or an enumerated data type. It’s length is 1 and the value is zero. The zero tells us that the Bind was successful. The last four bytes are two null string (octet strings always start with 0x04), both of which have zero length.

These bytes imply that the LDAP server at the University of Michigan has allowed us to bind with it. This will allow us to carry out any application with this server. All this and more is explained in our next program.

The mud sticks- the second program

Here the final program for exploiting the capabilities of LDAP (who said exploitation was banned?) In this program we get ‘Net savvy. In the earlier program we were able to connect to the LDAP server at the University of Michigan. This opened up a plethora of opportunities before us. However we decided to rein in our feelings and carry out a simple task like searching for a person. In this program we have given a SearchRequest for a person whose surname happens to be ‘vijay’ .

All the functions in this program have been carried forward from the earlier program and hence perform the same task as in the earlier program. As can be seen the initial part of the program remains the same. This is because of the fact that a ‘BindRequest’ has to be sent as the first packet. The bytes in this packet have been explained in the previous program. The second instance of the array ‘kk’ contain the bytes that make up the various parameters in case of SearchRequest. The various parameter of the search request is as shown below.

  • Scope : – It defines the scope or a extend of the search. In layman terms it means ‘where to look for the information’. In our program we are searching for our target at the University of Michigan in the US of A.
  • SizeLimit : – Defines the number of instances that the target object should be searched for. In layman terms it means ‘How many appearances of the object?’ Here we have used null (0) to signify unlimited size i.e. search for as many as available.
  • TimeLimit : – It means ‘How much time should be spend on searching for the object?’ We have specified null meaning indefinite time i.e. search till all targets are found.
  • Attributes : – Specifies whether we desire only the name occurrences and/or the attributes associated with those name instance. For our friends at Microsoft, we will put it more layman terms. When we use the command ‘dir’ command we get a listing of filename as well as other attribute like filesize, date and time of last modification etc. Whereas when we use ‘dir/w’ we get only the filenames i.e. only the name instance not their attributes.
  • Filter : – Used to provide the option for the search request. In this case we use the ‘OR’ filter other filter include AND, NOT etc.

Now you know all about the program go ahead and check it out.

Ldap.c

#include <windows.h>
#include <stdio.h>
unsigned char kk[10000],ll[10000];
void abc(char *p)
{
FILE *fp=fopen("c:\\ldap\\z.txt","a+");
fprintf(fp,"%s\n",p);
fclose(fp);
}
int ii,dw,jj;
void abc1(unsigned char p)
{
FILE *fp=fopen("c:\\ldap\\z.txt","a+");
fprintf(fp,"%d%x%d%c\n",jj,p,p,p);
fclose(fp);
}
WNDCLASS a;HWND b;MSG c;char aa[200];SOCKET s;struct hostent h;
WSADATA ws;DWORD e;char bb[100];struct sockaddr_in sa;
long _stdcall zzz (HWND,UINT,WPARAM,LPARAM);
int _stdcall WinMain(HINSTANCE i,HINSTANCE j,char *k,int l)
{
a.lpszClassName="a1";
a.hInstance=i;
a.lpfnWndProc=zzz;
a.hbrBackground=GetStockObject(WHITE_BRUSH);
RegisterClass(&a);
b=CreateWindow("a1","time client",WS_OVERLAPPEDWINDOW,1,1,10,20,0,0,i,0);
ShowWindow(b,3);
while ( GetMessage(&c,0,0,0) )
DispatchMessage(&c);
return 1;
}
long _stdcall zzz (HWND w,UINT x,WPARAM y,LPARAM z)
{
if ( x == WM_LBUTTONDOWN)
{	
e=WSAStartup(0x0101,&ws);
sprintf(aa,"WSAStartup e = %ld",e);
s = socket(PF_INET,SOCK_STREAM,0);
sprintf(aa,"socket s = %ld",s);
sa.sin_family=AF_INET;
sa.sin_addr.s_addr = inet_addr("141.211.83.38");
sa.sin_port=htons(389);
connect(s,(struct sockaddr *)&sa,sizeof(sa));

kk[0]=0x30;
kk[1]=12;

kk[2]=0x02;
kk[3]=0x01;
kk[4]=0x01;

kk[5]=0x60;
kk[6]=7;

kk[7]=0x02;
kk[8]=0x01;
kk[9]=0x02;

kk[10]=0x04;
kk[11]=0x00;

kk[12]=0x80;
kk[13]=0x00;

e=send(s,kk,14,0); 			  
sprintf(aa,"SendTo %ld",e);
ii=recv(s,ll,1000,0);
sprintf(aa,"Recv from %d",ii);
abc(aa);
for (jj=0;jj<ii;jj++)
abc1(ll[jj]);

kk[0]=0x30;
kk[1]=68;

kk[2]=0x02;
kk[3]=0x01;
kk[4]=0x02;

kk[5]=0x63;	// the SearchRequest
kk[6]=63;

kk[7]=0x04;	//providing the scope for the search
kk[8]=0x1f;    
kk[9]=' ';
kk[10]='o';     // organization =University of Michigan
kk[11]='=';
kk[12]='U';
kk[13]='n';
kk[14]='i';
kk[15]='v';
kk[16]='e';
kk[17]='r';
kk[18]='s';
kk[19]='i';
kk[20]='t';
kk[21]='y';
kk[22]=' ';
kk[23]='o';
kk[24]='f';
kk[25]=' ';
kk[26]='M';
kk[27]='i';
kk[28]='c';
kk[29]='h';
kk[30]='i';
kk[31]='g';
kk[32]='a';
kk[33]='n';
kk[34]=',';
kk[35]=' ';
kk[36]='c';	 //country = US
kk[37]='=';
kk[38]='U';
kk[39]='S';

kk[40]=0x0a;
kk[41]=0x01;
kk[42]=0x02;

kk[43]=0x0a;
kk[44]=0x01;
kk[45]=0x02;

kk[46]=0x02;	  //Sizelimit = Infinite
kk[47]=0x01;
kk[48]=0x00;

kk[49]=0x02;    //Timelimit = Infinite
kk[50]=0x01;
kk[51]=0x00;

kk[52]=0x01;
kk[53]=0x01;
kk[54]=0x00;

kk[55]=0xa1;
kk[56]=0x0d;

kk[57]=0xa3;
kk[58]=0x0b;

kk[59]=0x04;	   // providing the target
kk[60]=0x02;
kk[61]='s'; 	   // person whose surname is 'vijay'
kk[62]='n';

kk[63]=0x04;
kk[64]=0x05;
kk[65]='V';
kk[66]='i';
kk[67]='j';
kk[68]='a';
kk[69]='y';

e=send(s,kk,70,0); 			  
sprintf(aa,"SendTo %ld",e);
ii=recv(s,ll,10000,0);
sprintf(aa,"Recv from %d",ii);
abc(aa);
for (jj=0;jj<ii;jj++)
abc1(ll[jj]);

MessageBox(0,"hi","hi",0);
}
if ( x == WM_DESTROY)
PostQuitMessage(0);
return DefWindowProc(w,x,y,z);
}

The bytes may seem a little daunting but you ain’t seen nothing yet! Wait till we get to the z.txt file.

The first time we use the array kk[], we send a Bind request, identical to the one explained before. The next time, we use kk[] to actually send some useful information. The explanation that follows is for the second array.

The first byte is 0x30 which stands for ‘Universal Sequence’ as explained before. The next byte is the length of the packet.

Then come three bytes for the Message ID. Since the ID is a number (0x02 in this case), it is labeled an Integer and therefor starts with a 0x02 (kk[2]). Kk[3] is the length of the Integer.

The first byte after the Message ID is 0x63. If cut up into it’s constituent bytes, it looks like this

0 1 1 0 0 0 0 1 1

Since the first three bits are 011, this is a contructed application request and since the last four bits hold the value three, it is ‘Application Three’. Application Three in the RFC stands for a Search Request. The next byte is the length of the data that follows.

The next byte is 0x04 which means that the data that follows is a string. 0x1f is the length of that string. The string is used to provode the scope for the search.

So here, we’ve set the organization to the University of Michigan by saying “o=University of Michigan”. We then have a comma (kk[34]) and the country we want to search in. We’ve set it to the USA, by saying “c=US”. These codes have been standardised by the guys who wrote LDAP.

The next byte are kk[40] is 0x0a which as usual stands for an enumerated data type. The next byte is the length and the byte after that is 0x02 which tells the server to search the whole subtree for the information we want.

The next three bytes are also an enumeration. Here the value is 0x02 which in this context means DerefFindingBaseObj.

Now at kk[46] we have 0x02 which tells us that the byte which comes after the length is an Integer. That integer sets the limits on the size of data to download. Since the integer is zero, the size limit is infinite.

The next three bytes set the Time limit i.e. the amount of time we’re ready to wait for data. That to has been set to zero for infinite.

Now at kk[52] we have 0x01 which tells us that the byte after the length is a Boolean value i.e. it can only be True (1) or False (0). Kk[53] is the length and kk[54] is the actual value. The zero here tells the server that it’s supposed to give us all the data and its attributes too.

Now comes the interesting part. The byte 0xa1 is the choice (the set of filters) of the query. We’ve said 0xa1 which means the choice is set to OR. A1 looks like this

1 0 1 0 0 0 0 1

The first two bits are 10 and that means Context Specific. The next bit is on and that implies that it’s constructed. The last four bits hold the Context Specification number, 1 in this case. If we scan the RFC, we find that Context Specific 1 is an OR.

The stuff that follows is the data with which the server must filter the response. 0x0d is the length of that data.

The byte 0xa3 tells the server to perform an equality match on the data using the filters. This means it should only return data which has fields equal to the filter. The next byte is the length.

Now comes a string “sn” which stands for surname and another string lists that surname; “Vijay”. So our query is ‘send us information about people in the University of Michigan in the US who have the surname ‘Vijay”. Since this is an OR you can place another two strings in the same format telling the server to send information on people who have the surname Vijay OR the common name (cn) Arsalan. Try it, it’s not to difficult.

Now on to the output file

Z.TXT

Recv from 14

0 30 48 0
1 c 12
2 2 2
3 1 1
4 1 1
5 61 97 a
6 7 7
7 a 10
8 1 1
9 0 0
10 4 4
11 0 0
12 4 4
13 0 0

Recv from 1536

0 30 48 structure
1 82 130
2 e 14
3 d3 211
4 2 2
5 1 1
6 2 2
7 64 100 d application 4 i.e. SearchResponse
8 82 130
9 e 14
10 cc 204
11 4 4 octet string of length 121
12 79 121 y
13 63 99 c Found a person whose
14 6e 110 n
15 3d 61 =
16 41 65 A Common name is Aditi
17 64 100 d
18 69 105 i
19 74 116 t
20 69 105 i
21 20 32
22 56 86 V
23 69 105 i
24 6a 106 j
25 61 97 a
26 79 121 y
27 2c 44 ,
28 20 32
29 6f 111 o other details by Aditi Vijay
30 75 117 u
31 3d 61 =
32 22 34
33 43 67 C
34 6f 111 o
35 6c 108 l
36 6c 108 l
37 65 101 e
38 67 103 g
39 65 101 e
40 20 32

Click for the first 400 bytes of the output.

We’ve only given you the first 400 bytes of z.txt ’cause if we’d published the entire file then this page would take forever to download! Beside, the file follows a certain format and once you’ve got that format, you can decode it yourself.

The first 13 bytes are the Bind response and they’ve already been explained earlier. It’s the latter part of the file that must be explained.

The first byte there is 0x30 which stands for a universal sequence. Now things get a wee bit interesting. The next three bytes hold the length of the packet. Unlike earlier, where the packet was smaller than 127 bytes and thus the length could be accommodated in a single byte, here the packet is much larger. What the guys at ISO decided was that the length packet (if the packet is larger than 128) will start with the leftmost bit on. So even if the length was zero, it would show 0x80.

1 0 0 0 0 0 0 0

If the length was less than 128, then the actual length would be displayed, else the rest of the characters would show the number of bytes used to hold the length. So 0x82 is

1 0 0 0 0 0 1 0

So the next two bytes hold the length of the packet. If we multiply 14 with 256 and 211 with 1 and add the results, we get 3795 the length of the packet in bytes.

The next three bytes hold the ID of the packet which is two.

Byte number seven is 0x64 which if broken up becomes

0 1 1 0 0 1 0 0

That means Application Four or Search Response. The next three bytes hold the actual length of the data to follow.

Now comes a massive string with the name of the person the server has found with matching criteria. The cn or common name is Aditi Vijay. Her organizational unit (ou) is The College of Literature, Science and the Arts and so on till byte 133.

Now we have another 0x30 which marks the beginning of a sequence structure within the earlier sequence structure. The bytes after that are the length.

Immediately after that we have (at 138) another sequence structure within the earlier on. This one holds a number of structures and strings which give us the attributes of the person, as she’s entered them. Recall that we’d specifically asked for the data plus the attributes in our query. The attributes go on till 231.

Then we have another set (0x30) which holds even more information about our subject like her common name and her surname and if you dig deeper you’ll find even more information about her, like her postal address and phone number. The structures can easily be deciphered once you know how.

Continue for as long as you like; dig as deep as you want. Try other queries too and if you’re serious about LDAP, read the RFC and try and decipher that! The language used to define the RFC is ASN.1 and it’s very confusing, but if we can decode the RFC, you certainly can!


The above tutorial is a joint effort of Mr. Vijay Mukhi
Ms. Sonal Kotecha
Mr. Arsalan Zaidi
Mr. Vinesh Kurup

(This blog appeared in Vijay Mukhi Technology Cornucopia website in 1996)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s