remove some compiler warning due to unused pinfo parameter
[obnox/wireshark/wip.git] / asn1 / ldap / packet-ldap-template.c
1 /* packet-ldap.c
2  * Routines for ldap packet dissection
3  *
4  * See RFC 1777 (LDAP v2), RFC 2251 (LDAP v3), and RFC 2222 (SASL).
5  *
6  * $Id$
7  *
8  * Wireshark - Network traffic analyzer
9  * By Gerald Combs <gerald@wireshark.org>
10  * Copyright 1998 Gerald Combs
11  *
12  * This program is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU General Public License
14  * as published by the Free Software Foundation; either version 2
15  * of the License, or (at your option) any later version.
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program; if not, write to the Free Software
24  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
25  */
26
27 /*
28  * This is not a complete implementation. It doesn't handle the full version 3, more specifically,
29  * it handles only the commands of version 2, but any additional characteristics of the ver3 command are supported.
30  * It's also missing extensible search filters.
31  *
32  * There should probably be alot more error checking, I simply assume that if we have a full packet, it will be a complete
33  * and correct packet.
34  *
35  * AFAIK, it will handle all messages used by the OpenLDAP 1.2.9 server and libraries which was my goal. I do plan to add
36  * the remaining commands as time permits but this is not a priority to me. Send me an email if you need it and I'll see what
37  * I can do.
38  *
39  * Doug Nazar
40  * nazard@dragoninc.on.ca
41  */
42
43 /*
44  * 11/11/2002 - Fixed problem when decoding LDAP with desegmentation enabled and the
45  *              ASN.1 BER Universal Class Tag: "Sequence Of" header is encapsulated across 2
46  *              TCP segments.
47  *
48  * Ronald W. Henderson
49  * ronald.henderson@cognicaseusa.com
50  */
51
52 /*
53  * 20-JAN-2004 - added decoding of MS-CLDAP netlogon RPC
54  *               using information from the SNIA 2003 conference paper :
55  *               Active Directory Domain Controller Location Service
56  *                    by Anthony Liguori
57  * ronnie sahlberg
58  */
59
60 /*
61  * 17-DEC-2004 - added basic decoding for LDAP Controls
62  * 20-DEC-2004 - added handling for GSS-API encrypted blobs
63  *
64  * Stefan Metzmacher <metze@samba.org>
65  *
66  * 15-NOV-2005 - Changed to use the asn2wrs compiler
67  * Anders Broman <anders.broman@ericsson.com>
68  */
69
70 #ifdef HAVE_CONFIG_H
71 # include "config.h"
72 #endif
73
74 #include <stdio.h>
75 #include <string.h>
76 #include <ctype.h>
77
78 #include <glib.h>
79
80 #include <epan/packet.h>
81 #include <epan/conversation.h>
82 #include <epan/prefs.h>
83 #include <epan/tap.h>
84 #include <epan/emem.h>
85 #include <epan/oid_resolv.h>
86 #include <epan/strutil.h>
87 #include <epan/dissectors/packet-tcp.h>
88 #include <epan/dissectors/packet-windows-common.h>
89 #include <epan/dissectors/packet-dcerpc.h>
90 #include <epan/asn1.h>
91
92 #include "packet-frame.h"
93 #include "packet-ldap.h"
94 #include "packet-ntlmssp.h"
95
96 #include "packet-ber.h"
97 #include "packet-per.h"
98
99 #define PNAME  "Lightweight-Directory-Access-Protocol"
100 #define PSNAME "LDAP"
101 #define PFNAME "ldap"
102
103 /* Initialize the protocol and registered fields */
104 static int ldap_tap = -1;
105 static int proto_ldap = -1;
106 static int proto_cldap = -1;
107
108 static int hf_ldap_sasl_buffer_length = -1;
109 static int hf_ldap_response_in = -1;
110 static int hf_ldap_response_to = -1;
111 static int hf_ldap_time = -1;
112 static int hf_ldap_guid = -1;
113
114 static int hf_mscldap_netlogon_type = -1;
115 static int hf_mscldap_netlogon_flags = -1;
116 static int hf_mscldap_netlogon_flags_pdc = -1;
117 static int hf_mscldap_netlogon_flags_gc = -1;
118 static int hf_mscldap_netlogon_flags_ldap = -1;
119 static int hf_mscldap_netlogon_flags_ds = -1;
120 static int hf_mscldap_netlogon_flags_kdc = -1;
121 static int hf_mscldap_netlogon_flags_timeserv = -1;
122 static int hf_mscldap_netlogon_flags_closest = -1;
123 static int hf_mscldap_netlogon_flags_writable = -1;
124 static int hf_mscldap_netlogon_flags_good_timeserv = -1;
125 static int hf_mscldap_netlogon_flags_ndnc = -1;
126 static int hf_mscldap_domain_guid = -1;
127 static int hf_mscldap_forest = -1;
128 static int hf_mscldap_domain = -1;
129 static int hf_mscldap_hostname = -1;
130 static int hf_mscldap_nb_domain = -1;
131 static int hf_mscldap_nb_hostname = -1;
132 static int hf_mscldap_username = -1;
133 static int hf_mscldap_sitename = -1;
134 static int hf_mscldap_clientsitename = -1;
135 static int hf_mscldap_netlogon_version = -1;
136 static int hf_mscldap_netlogon_lm_token = -1;
137 static int hf_mscldap_netlogon_nt_token = -1;
138 static int hf_ldap_sid = -1;
139 static int hf_ldap_AccessMask_ADS_CREATE_CHILD = -1;
140 static int hf_ldap_AccessMask_ADS_DELETE_CHILD = -1;
141 static int hf_ldap_AccessMask_ADS_LIST = -1;
142 static int hf_ldap_AccessMask_ADS_SELF_WRITE = -1;
143 static int hf_ldap_AccessMask_ADS_READ_PROP = -1;
144 static int hf_ldap_AccessMask_ADS_WRITE_PROP = -1;
145 static int hf_ldap_AccessMask_ADS_DELETE_TREE = -1;
146 static int hf_ldap_AccessMask_ADS_LIST_OBJECT = -1;
147 static int hf_ldap_AccessMask_ADS_CONTROL_ACCESS = -1;
148
149 #include "packet-ldap-hf.c"
150
151 /* Initialize the subtree pointers */
152 static gint ett_ldap = -1;
153 static gint ett_ldap_msg = -1;
154 static gint ett_ldap_sasl_blob = -1;
155 static guint ett_ldap_payload = -1;
156 static gint ett_mscldap_netlogon_flags = -1;
157
158 #include "packet-ldap-ett.c"
159
160 static dissector_table_t ldap_name_dissector_table=NULL;
161 static const char *object_identifier_id = NULL; /* LDAP OID */
162
163 /* desegmentation of LDAP */
164 static gboolean ldap_desegment = TRUE;
165 static guint    ldap_tcp_port = 389;
166
167 static gboolean do_protocolop = FALSE;
168 static gchar    *attr_type = NULL;
169 static gboolean is_binary_attr_type = FALSE;
170
171 #define TCP_PORT_LDAP                   389
172 #define UDP_PORT_CLDAP                  389
173 #define TCP_PORT_GLOBALCAT_LDAP         3268 /* Windows 2000 Global Catalog */
174
175 static dissector_handle_t gssapi_handle;
176 static dissector_handle_t gssapi_wrap_handle;
177 static dissector_handle_t ntlmssp_handle = NULL;
178 static dissector_handle_t spnego_handle;
179
180 /* different types of rpc calls ontop of ms cldap */
181 #define MSCLDAP_RPC_NETLOGON    1
182
183 /* Message type Choice values */
184 static const value_string ldap_ProtocolOp_choice_vals[] = {
185   {   0, "bindRequest" },
186   {   1, "bindResponse" },
187   {   2, "unbindRequest" },
188   {   3, "searchRequest" },
189   {   4, "searchResEntry" },
190   {   5, "searchResDone" },
191   {       6, "searchResRef" },
192   {   7, "modifyRequest" },
193   {   8, "modifyResponse" },
194   {   9, "addRequest" },
195   {  10, "addResponse" },
196   {  11, "delRequest" },
197   {  12, "delResponse" },
198   {  13, "modDNRequest" },
199   {  14, "modDNResponse" },
200   {  15, "compareRequest" },
201   {  16, "compareResponse" },
202   {  17, "abandonRequest" },
203   {  18, "extendedReq" },
204   {  19, "extendedResp" },
205   { 0, NULL }
206 };
207 /*
208  * Data structure attached to a conversation, giving authentication
209  * information from a bind request.
210  * We keep a linked list of them, so that we can free up all the
211  * authentication mechanism strings.
212  */
213 typedef struct ldap_conv_info_t {
214   struct ldap_conv_info_t *next;
215   guint auth_type;              /* authentication type */
216   char *auth_mech;              /* authentication mechanism */
217   guint32 first_auth_frame;     /* first frame that would use a security layer */
218   GHashTable *unmatched;
219   GHashTable *matched;
220   gboolean is_mscldap;
221   guint32  num_results;
222 } ldap_conv_info_t;
223 static ldap_conv_info_t *ldap_info_items;
224
225 static guint
226 ldap_info_hash_matched(gconstpointer k)
227 {
228   const ldap_call_response_t *key = k;
229
230   return key->messageId;
231 }
232
233 static gint
234 ldap_info_equal_matched(gconstpointer k1, gconstpointer k2)
235 {
236   const ldap_call_response_t *key1 = k1;
237   const ldap_call_response_t *key2 = k2;
238
239   if( key1->req_frame && key2->req_frame && (key1->req_frame!=key2->req_frame) ){
240     return 0;
241   }
242   /* a response may span multiple frames
243   if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
244     return 0;
245   }
246   */
247
248   return key1->messageId==key2->messageId;
249 }
250
251 static guint
252 ldap_info_hash_unmatched(gconstpointer k)
253 {
254   const ldap_call_response_t *key = k;
255
256   return key->messageId;
257 }
258
259 static gint
260 ldap_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
261 {
262   const ldap_call_response_t *key1 = k1;
263   const ldap_call_response_t *key2 = k2;
264
265   return key1->messageId==key2->messageId;
266 }
267
268 /* This string contains the last LDAPString that was decoded */
269 static char *attributedesc_string=NULL;
270
271 /* This string contains the last AssertionValue that was decoded */
272 static char *ldapvalue_string=NULL;
273
274 /* if the octet string contain all printable ASCII characters, then
275  * display it as a string, othervise just display it in hex.
276  */
277 static int
278 dissect_ldap_AssertionValue(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index)
279 {
280         gint8 class;
281         gboolean pc, ind, is_ascii;
282         gint32 tag;
283         guint32 len, i;
284         const guchar *str;
285
286         if(!implicit_tag){
287                 offset=get_ber_identifier(tvb, offset, &class, &pc, &tag);
288                 offset=get_ber_length(NULL, tvb, offset, &len, &ind);
289         } else {
290                 len=tvb_length_remaining(tvb,offset);
291         }
292
293         if(len==0){
294                 return offset;
295         }
296
297
298         /*
299          * Some special/wellknown attributes in common LDAP (read AD)
300          * are neither ascii strings nor blobs of hex data.
301          * Special case these attributes and decode them more nicely.
302          *
303          * Add more special cases as required to prettify further
304          * (there cant be that many ones that are truly interesting)
305          */
306         if(attributedesc_string && !strncmp("DomainSid", attributedesc_string, 9)){
307                 tvbuff_t *sid_tvb;
308                 char *tmpstr;
309
310                 /* this octet string contains an NT SID */
311                 sid_tvb=tvb_new_subset(tvb, offset, len, len);
312                 dissect_nt_sid(sid_tvb, 0, tree, "SID", &tmpstr, hf_index);
313                 ldapvalue_string=tmpstr;
314
315                 goto finished;
316         } else if ( (len==16) /* GUIDs are always 16 bytes */
317         && (attributedesc_string && !strncmp("DomainGuid", attributedesc_string, 10))) {
318                 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
319                 e_uuid_t uuid;
320
321                 /* This octet string contained a GUID */
322                 dissect_dcerpc_uuid_t(tvb, offset, actx->pinfo, tree, drep, hf_ldap_guid, &uuid);
323
324                 ldapvalue_string=ep_alloc(1024);
325                 g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
326                           uuid.Data1, uuid.Data2, uuid.Data3,
327                           uuid.Data4[0], uuid.Data4[1],
328                           uuid.Data4[2], uuid.Data4[3],
329                           uuid.Data4[4], uuid.Data4[5],
330                           uuid.Data4[6], uuid.Data4[7]);
331
332                 goto finished;
333         }
334
335         /*
336          * It was not one of our "wellknown" attributes so make the best
337          * we can and just try to see if it is an ascii string or if it
338          * is a binary blob.
339          *
340          * XXX - should we support reading RFC 2252-style schemas
341          * for LDAP, and using that to determine how to display
342          * attribute values and assertion values?
343          *
344          * -- I dont think there are full schemas available that describe the
345          *  interesting cases i.e. AD -- ronnie
346          */
347         str=tvb_get_ptr(tvb, offset, len);
348         is_ascii=TRUE;
349         for(i=0;i<len;i++){
350                 if(!isascii(str[i]) || !isprint(str[i])){
351                         is_ascii=FALSE;
352                         break;
353                 }
354         }
355
356         /* convert the string into a printable string */
357         if(is_ascii){
358                 ldapvalue_string=ep_alloc(len+1);
359                 memcpy(ldapvalue_string,str,len);
360                 ldapvalue_string[i]=0;
361         } else {
362                 ldapvalue_string=ep_alloc(3*len);
363                 for(i=0;i<len;i++){
364                         g_snprintf(ldapvalue_string+i*3,3,"%02x",str[i]&0xff);
365                         ldapvalue_string[3*i+2]=':';
366                 }
367                 ldapvalue_string[3*len-1]=0;
368         }
369
370         proto_tree_add_string(tree, hf_index, tvb, offset, len, ldapvalue_string);
371
372
373 finished:
374         offset+=len;
375         return offset;
376 }
377
378 /* This string contains the last Filter item that was decoded */
379 static char *Filter_string=NULL;
380 static char *and_filter_string=NULL;
381 static char *or_filter_string=NULL;
382 static char *substring_value=NULL;
383 static char *substring_item_init=NULL;
384 static char *substring_item_any=NULL;
385 static char *substring_item_final=NULL;
386 static char *matching_rule_string=NULL;
387 static gboolean matching_rule_dnattr=FALSE;
388
389 /* Global variables */
390 char *mechanism = NULL;
391 static gint MessageID =-1;
392 static gint ProtocolOp = -1;
393 static gint result = 0;
394 static proto_item *ldm_tree = NULL; /* item to add text to */
395
396 static void ldap_do_protocolop(packet_info *pinfo)
397 {
398   const gchar* valstr;
399
400   if (do_protocolop)  {
401
402     valstr = val_to_str(ProtocolOp, ldap_ProtocolOp_choice_vals, "Unknown (%%u)");
403
404     if(check_col(pinfo->cinfo, COL_INFO))
405       col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", valstr, MessageID);
406
407     if(ldm_tree)
408       proto_item_append_text(ldm_tree, " %s(%d)", valstr, MessageID);
409
410     do_protocolop = FALSE;
411
412   }
413 }
414
415 static ldap_call_response_t *
416 ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint messageId, guint protocolOpTag)
417 {
418   ldap_call_response_t lcr, *lcrp=NULL;
419   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)pinfo->private_data;
420
421   /* first see if we have already matched this */
422
423       lcr.messageId=messageId;
424       switch(protocolOpTag){
425         case LDAP_REQ_BIND:
426         case LDAP_REQ_SEARCH:
427         case LDAP_REQ_MODIFY:
428         case LDAP_REQ_ADD:
429         case LDAP_REQ_DELETE:
430         case LDAP_REQ_MODRDN:
431         case LDAP_REQ_COMPARE:
432           lcr.is_request=TRUE;
433           lcr.req_frame=pinfo->fd->num;
434           lcr.rep_frame=0;
435           break;
436         case LDAP_RES_BIND:
437         case LDAP_RES_SEARCH_ENTRY:
438         case LDAP_RES_SEARCH_REF:
439         case LDAP_RES_SEARCH_RESULT:
440         case LDAP_RES_MODIFY:
441         case LDAP_RES_ADD:
442         case LDAP_RES_DELETE:
443         case LDAP_RES_MODRDN:
444         case LDAP_RES_COMPARE:
445           lcr.is_request=FALSE;
446           lcr.req_frame=0;
447           lcr.rep_frame=pinfo->fd->num;
448           break;
449       }
450       lcrp=g_hash_table_lookup(ldap_info->matched, &lcr);
451
452       if(lcrp){
453
454         lcrp->is_request=lcr.is_request;
455
456       } else {
457
458                   /* we haven't found a match - try and match it up */
459
460   switch(protocolOpTag){
461       case LDAP_REQ_BIND:
462       case LDAP_REQ_SEARCH:
463       case LDAP_REQ_MODIFY:
464       case LDAP_REQ_ADD:
465       case LDAP_REQ_DELETE:
466       case LDAP_REQ_MODRDN:
467       case LDAP_REQ_COMPARE:
468
469                 /* this a a request - add it to the unmatched list */
470
471         /* check that we dont already have one of those in the
472            unmatched list and if so remove it */
473
474         lcr.messageId=messageId;
475         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
476         if(lcrp){
477           g_hash_table_remove(ldap_info->unmatched, lcrp);
478         }
479         /* if we cant reuse the old one, grab a new chunk */
480         if(!lcrp){
481           lcrp=se_alloc(sizeof(ldap_call_response_t));
482         }
483         lcrp->messageId=messageId;
484         lcrp->req_frame=pinfo->fd->num;
485         lcrp->req_time=pinfo->fd->abs_ts;
486         lcrp->rep_frame=0;
487         lcrp->protocolOpTag=protocolOpTag;
488         lcrp->is_request=TRUE;
489         g_hash_table_insert(ldap_info->unmatched, lcrp, lcrp);
490         return NULL;
491         break;
492       case LDAP_RES_BIND:
493       case LDAP_RES_SEARCH_ENTRY:
494       case LDAP_RES_SEARCH_REF:
495       case LDAP_RES_SEARCH_RESULT:
496       case LDAP_RES_MODIFY:
497       case LDAP_RES_ADD:
498       case LDAP_RES_DELETE:
499       case LDAP_RES_MODRDN:
500       case LDAP_RES_COMPARE:
501
502                 /* this is a result - it should be in our unmatched list */
503
504         lcr.messageId=messageId;
505         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
506
507         if(lcrp){
508
509           if(!lcrp->rep_frame){
510             g_hash_table_remove(ldap_info->unmatched, lcrp);
511             lcrp->rep_frame=pinfo->fd->num;
512             lcrp->is_request=FALSE;
513             g_hash_table_insert(ldap_info->matched, lcrp, lcrp);
514           }
515         }
516
517         break;
518           }
519
520         }
521     /* we have found a match */
522
523     if(lcrp){
524       proto_item *it;
525
526       if(lcrp->is_request){
527         it=proto_tree_add_uint(tree, hf_ldap_response_in, tvb, 0, 0, lcrp->rep_frame);
528         PROTO_ITEM_SET_GENERATED(it);
529       } else {
530         nstime_t ns;
531         it=proto_tree_add_uint(tree, hf_ldap_response_to, tvb, 0, 0, lcrp->req_frame);
532         PROTO_ITEM_SET_GENERATED(it);
533         nstime_delta(&ns, &pinfo->fd->abs_ts, &lcrp->req_time);
534         it=proto_tree_add_time(tree, hf_ldap_time, tvb, 0, 0, &ns);
535         PROTO_ITEM_SET_GENERATED(it);
536       }
537     }
538
539     return lcrp;
540 }
541
542 #include "packet-ldap-fn.c"
543
544 static void
545 dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
546                      proto_tree *tree, ldap_conv_info_t *ldap_info,
547                      gboolean is_mscldap)
548 {
549   int offset = 0;
550   guint length_remaining;
551   guint msg_len = 0;
552   int messageOffset = 0;
553   guint headerLength = 0;
554   guint length = 0;
555   tvbuff_t *msg_tvb = NULL;
556   gint8 class;
557   gboolean pc, ind = 0;
558   gint32 ber_tag;
559
560
561 one_more_pdu:
562
563     length_remaining = tvb_ensure_length_remaining(tvb, offset);
564
565     if (length_remaining < 6) return;
566
567     /*
568      * OK, try to read the "Sequence Of" header; this gets the total
569      * length of the LDAP message.
570      */
571         messageOffset = get_ber_identifier(tvb, offset, &class, &pc, &ber_tag);
572         messageOffset = get_ber_length(tree, tvb, messageOffset, &msg_len, &ind);
573
574     /* sanity check */
575     if((msg_len<4) || (msg_len>10000000)) return;
576
577     if ( (class==BER_CLASS_UNI) && (ber_tag==BER_UNI_TAG_SEQUENCE) ) {
578         /*
579          * Add the length of the "Sequence Of" header to the message
580          * length.
581          */
582         headerLength = messageOffset - offset;
583         msg_len += headerLength;
584         if (msg_len < headerLength) {
585             /*
586              * The message length was probably so large that the total length
587              * overflowed.
588              *
589              * Report this as an error.
590              */
591             show_reported_bounds_error(tvb, pinfo, tree);
592             return;
593         }
594     } else {
595         /*
596          * We couldn't parse the header; just make it the amount of data
597          * remaining in the tvbuff, so we'll give up on this segment
598          * after attempting to parse the message - there's nothing more
599          * we can do.  "dissect_ldap_message()" will display the error.
600          */
601         msg_len = length_remaining;
602     }
603
604     /*
605      * Construct a tvbuff containing the amount of the payload we have
606      * available.  Make its reported length the amount of data in the
607      * LDAP message.
608      *
609      * XXX - if reassembly isn't enabled. the subdissector will throw a
610      * BoundsError exception, rather than a ReportedBoundsError exception.
611      * We really want a tvbuff where the length is "length", the reported
612      * length is "plen", and the "if the snapshot length were infinite"
613      * length is the minimum of the reported length of the tvbuff handed
614      * to us and "plen", with a new type of exception thrown if the offset
615      * is within the reported length but beyond that third length, with
616      * that exception getting the "Unreassembled Packet" error.
617      */
618     length = length_remaining;
619     if (length > msg_len) length = msg_len;
620     msg_tvb = tvb_new_subset(tvb, offset, length, msg_len);
621
622     /*
623      * Now dissect the LDAP message.
624      */
625     ldap_info->is_mscldap = is_mscldap;
626     pinfo->private_data = ldap_info;
627     dissect_LDAPMessage_PDU(msg_tvb, pinfo, tree);
628
629     offset += msg_len;
630
631     /* If this was a sasl blob there might be another PDU following in the
632      * same blob
633      */
634     if(tvb_length_remaining(tvb, offset)>=6){
635         tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), -1);
636         offset = 0;
637
638         goto one_more_pdu;
639     }
640
641 }
642
643 static void
644 dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_mscldap)
645 {
646   int offset = 0;
647   conversation_t *conversation;
648   gboolean doing_sasl_security = FALSE;
649   guint length_remaining;
650   ldap_conv_info_t *ldap_info = NULL;
651   proto_item *ldap_item = NULL;
652   proto_tree *ldap_tree = NULL;
653
654   ldm_tree = NULL;
655
656   /*
657    * Do we have a conversation for this connection?
658    */
659   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
660                                    pinfo->ptype, pinfo->srcport,
661                                    pinfo->destport, 0);
662   if (conversation == NULL) {
663     /* We don't yet have a conversation, so create one. */
664     conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
665                                     pinfo->ptype, pinfo->srcport,
666                                     pinfo->destport, 0);
667
668   }
669
670   /*
671    * Do we already have a type and mechanism?
672    */
673   ldap_info = conversation_get_proto_data(conversation, proto_ldap);
674   if (ldap_info == NULL) {
675     /* No.  Attach that information to the conversation, and add
676      * it to the list of information structures.
677      */
678     ldap_info = se_alloc(sizeof(ldap_conv_info_t));
679     ldap_info->auth_type = 0;
680     ldap_info->auth_mech = 0;
681     ldap_info->first_auth_frame = 0;
682     ldap_info->matched=g_hash_table_new(ldap_info_hash_matched, ldap_info_equal_matched);
683     ldap_info->unmatched=g_hash_table_new(ldap_info_hash_unmatched, ldap_info_equal_unmatched);
684     ldap_info->num_results = 0;
685
686     conversation_add_proto_data(conversation, proto_ldap, ldap_info);
687
688     ldap_info->next = ldap_info_items;
689     ldap_info_items = ldap_info;
690
691   }
692
693   switch (ldap_info->auth_type) {
694     case LDAP_AUTH_SASL:
695     /*
696      * It's SASL; are we using a security layer?
697      */
698     if (ldap_info->first_auth_frame != 0 &&
699        pinfo->fd->num >= ldap_info->first_auth_frame) {
700         doing_sasl_security = TRUE;     /* yes */
701     }
702   }
703
704     length_remaining = tvb_ensure_length_remaining(tvb, offset);
705
706     /* It might still be a packet containing a SASL security layer
707      * but its just that we never saw the BIND packet.
708      * check if it looks like it could be a SASL blob here
709      * and in that case just assume it is GSS-SPNEGO
710      */
711     if(!doing_sasl_security && (tvb_bytes_exist(tvb, offset, 5))
712       &&(tvb_get_ntohl(tvb, offset)<=(guint)(tvb_reported_length_remaining(tvb, offset)-4))
713       &&(tvb_get_guint8(tvb, offset+4)==0x60) ){
714         ldap_info->auth_type=LDAP_AUTH_SASL;
715         ldap_info->first_auth_frame=pinfo->fd->num;
716         ldap_info->auth_mech=g_strdup("GSS-SPNEGO");
717         doing_sasl_security=TRUE;
718     }
719
720     /*
721      * This is the first PDU, set the Protocol column and clear the
722      * Info column.
723      */
724     if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, pinfo->current_proto);
725     if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO);
726
727     ldap_item = proto_tree_add_item(tree, is_mscldap?proto_cldap:proto_ldap, tvb, 0, -1, FALSE);
728     ldap_tree = proto_item_add_subtree(ldap_item, ett_ldap);
729
730     /*
731      * Might we be doing a SASL security layer and, if so, *are* we doing
732      * one?
733      *
734      * Just because we've seen a bind reply for SASL, that doesn't mean
735      * that we're using a SASL security layer; I've seen captures in
736      * which some SASL negotiations lead to a security layer being used
737      * and other negotiations don't, and it's not obvious what's different
738      * in the two negotiations.  Therefore, we assume that if the first
739      * byte is 0, it's a length for a SASL security layer (that way, we
740      * never reassemble more than 16 megabytes, protecting us from
741      * chewing up *too* much memory), and otherwise that it's an LDAP
742      * message (actually, if it's an LDAP message it should begin with 0x30,
743      * but we want to parse garbage as LDAP messages rather than really
744      * huge lengths).
745      */
746
747     if (doing_sasl_security && tvb_get_guint8(tvb, offset) == 0) {
748       proto_item *sasl_item = NULL;
749       proto_tree *sasl_tree = NULL;
750       tvbuff_t *sasl_tvb;
751       guint sasl_len, sasl_msg_len, length;
752       /*
753        * Yes.  The frame begins with a 4-byte big-endian length.
754        * And we know we have at least 6 bytes
755        */
756
757       /*
758        * Get the SASL length, which is the length of data in the buffer
759        * following the length (i.e., it's 4 less than the total length).
760        *
761        * XXX - do we need to reassemble buffers?  For now, we
762        * assume that each LDAP message is entirely contained within
763        * a buffer.
764        */
765       sasl_len = tvb_get_ntohl(tvb, offset);
766       sasl_msg_len = sasl_len + 4;
767       if (sasl_msg_len < 4) {
768         /*
769          * The message length was probably so large that the total length
770          * overflowed.
771          *
772          * Report this as an error.
773          */
774         show_reported_bounds_error(tvb, pinfo, tree);
775         return;
776       }
777
778       /*
779        * Construct a tvbuff containing the amount of the payload we have
780        * available.  Make its reported length the amount of data in the PDU.
781        *
782        * XXX - if reassembly isn't enabled. the subdissector will throw a
783        * BoundsError exception, rather than a ReportedBoundsError exception.
784        * We really want a tvbuff where the length is "length", the reported
785        * length is "plen", and the "if the snapshot length were infinite"
786        * length is the minimum of the reported length of the tvbuff handed
787        * to us and "plen", with a new type of exception thrown if the offset
788        * is within the reported length but beyond that third length, with
789        * that exception getting the "Unreassembled Packet" error.
790        */
791       length = length_remaining;
792       if (length > sasl_msg_len) length = sasl_msg_len;
793       sasl_tvb = tvb_new_subset(tvb, offset, length, sasl_msg_len);
794
795       if (ldap_tree) {
796         proto_tree_add_uint(ldap_tree, hf_ldap_sasl_buffer_length, sasl_tvb, 0, 4,
797                             sasl_len);
798
799         sasl_item = proto_tree_add_text(ldap_tree, sasl_tvb, 0,  sasl_msg_len, "SASL Buffer");
800         sasl_tree = proto_item_add_subtree(sasl_item, ett_ldap_sasl_blob);
801       }
802
803       if (ldap_info->auth_mech != NULL &&
804           ((strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) ||
805            /* auth_mech may have been set from the bind */
806            (strcmp(ldap_info->auth_mech, "GSSAPI") == 0))) {
807           tvbuff_t *gssapi_tvb, *plain_tvb = NULL, *decr_tvb= NULL;
808           int ver_len;
809           int length;
810
811           /*
812            * This is GSS-API (using SPNEGO, but we should be done with
813            * the negotiation by now).
814            *
815            * Dissect the GSS_Wrap() token; it'll return the length of
816            * the token, from which we compute the offset in the tvbuff at
817            * which the plaintext data, i.e. the LDAP message, begins.
818            */
819           length = tvb_length_remaining(sasl_tvb, 4);
820           if ((guint)length > sasl_len)
821               length = sasl_len;
822           gssapi_tvb = tvb_new_subset(sasl_tvb, 4, length, sasl_len);
823
824           /* Attempt decryption of the GSSAPI wrapped data if possible */
825           pinfo->decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL;
826           pinfo->gssapi_wrap_tvb=NULL;
827           pinfo->gssapi_encrypted_tvb=NULL;
828           pinfo->gssapi_decrypted_tvb=NULL;
829           ver_len = call_dissector(gssapi_wrap_handle, gssapi_tvb, pinfo, sasl_tree);
830           /* if we could unwrap, do a tvb shuffle */
831           if(pinfo->gssapi_decrypted_tvb){
832                 decr_tvb=pinfo->gssapi_decrypted_tvb;
833           }
834           /* tidy up */
835           pinfo->decrypt_gssapi_tvb=0;
836           pinfo->gssapi_wrap_tvb=NULL;
837           pinfo->gssapi_encrypted_tvb=NULL;
838           pinfo->gssapi_decrypted_tvb=NULL;
839
840           /*
841            * if len is 0 it probably mean that we got a PDU that is not
842            * aligned to the start of the segment.
843            */
844           if(ver_len==0){
845              return;
846           }
847
848           /*
849            * if we don't have unwrapped data,
850            * see if the wrapping involved encryption of the
851            * data; if not, just use the plaintext data.
852            */
853           if (!decr_tvb) {
854             if(!pinfo->gssapi_data_encrypted){
855               plain_tvb = tvb_new_subset(gssapi_tvb,  ver_len, -1, -1);
856             }
857           }
858
859           if (decr_tvb) {
860             proto_item *enc_item = NULL;
861             proto_tree *enc_tree = NULL;
862
863             /*
864              * The LDAP message was encrypted in the packet, and has
865              * been decrypted; dissect the decrypted LDAP message.
866              */
867             if (check_col(pinfo->cinfo, COL_INFO)) {
868               col_add_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
869
870             }
871
872             if (sasl_tree) {
873               enc_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
874                                 "GSS-API Encrypted payload (%d byte%s)",
875                                 sasl_len - ver_len,
876                                 plurality(sasl_len - ver_len, "", "s"));
877               enc_tree = proto_item_add_subtree(enc_item, ett_ldap_payload);
878             }
879             dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
880           } else if (plain_tvb) {
881             proto_item *plain_item = NULL;
882             proto_tree *plain_tree = NULL;
883
884             /*
885              * The LDAP message wasn't encrypted in the packet;
886              * dissect the plain LDAP message.
887              */
888             if (check_col(pinfo->cinfo, COL_INFO)) {
889               col_add_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Integrity: ");
890             }
891
892             if (sasl_tree) {
893               plain_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
894                                 "GSS-API payload (%d byte%s)",
895                                 sasl_len - ver_len,
896                                 plurality(sasl_len - ver_len, "", "s"));
897               plain_tree = proto_item_add_subtree(plain_item, ett_ldap_payload);
898             }
899
900            dissect_ldap_payload(plain_tvb, pinfo, plain_tree, ldap_info, is_mscldap);
901           } else {
902             /*
903              * The LDAP message was encrypted in the packet, and was
904              * not decrypted; just show it as encrypted data.
905              */
906             if (check_col(pinfo->cinfo, COL_INFO)) {
907                     col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
908                                  sasl_len - ver_len,
909                                  plurality(sasl_len - ver_len, "", "s"));
910             }
911             if (sasl_tree) {
912               proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
913                                 "GSS-API Encrypted payload (%d byte%s)",
914                                 sasl_len - ver_len,
915                                 plurality(sasl_len - ver_len, "", "s"));
916             }
917           }
918       }
919       offset += sasl_msg_len;
920     } else {
921         /* plain LDAP, so dissect the payload */
922         dissect_ldap_payload(tvb, pinfo, ldap_tree, ldap_info, is_mscldap);
923     }
924 }
925
926 static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
927 {
928   guint8 len;
929
930   len=tvb_get_guint8(tvb, offset);
931   offset+=1;
932   *str=0;
933
934   while(len){
935     /* add potential field separation dot */
936     if(prepend_dot){
937       if(!maxlen){
938         *str=0;
939         return offset;
940       }
941       maxlen--;
942       *str++='.';
943       *str=0;
944     }
945
946     if(len==0xc0){
947       int new_offset;
948       /* ops its a mscldap compressed string */
949
950       new_offset=tvb_get_guint8(tvb, offset);
951       if (new_offset == offset - 1)
952         THROW(ReportedBoundsError);
953       offset+=1;
954
955       dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
956
957       return offset;
958     }
959
960     prepend_dot=TRUE;
961
962     if(maxlen<=len){
963       if(maxlen>3){
964         *str++='.';
965         *str++='.';
966         *str++='.';
967       }
968       *str=0;
969       return offset; /* will mess up offset in caller, is unlikely */
970     }
971     tvb_memcpy(tvb, str, offset, len);
972     str+=len;
973     *str=0;
974     maxlen-=len;
975     offset+=len;
976
977
978     len=tvb_get_guint8(tvb, offset);
979     offset+=1;
980   }
981   *str=0;
982   return offset;
983 }
984
985 /* These flag bits were found to be defined in the samba sources.
986  * I hope they are correct (but have serious doubts about the CLOSEST
987  * bit being used or being meaningful).
988  */
989 static const true_false_string tfs_ads_pdc = {
990         "This is a PDC",
991         "This is NOT a pdc"
992 };
993 static const true_false_string tfs_ads_gc = {
994         "This is a GLOBAL CATALOGUE of forest",
995         "This is NOT a global catalog of forest"
996 };
997 static const true_false_string tfs_ads_ldap = {
998         "This is an LDAP server",
999         "This is NOT an ldap server"
1000 };
1001 static const true_false_string tfs_ads_ds = {
1002         "This dc supports DS",
1003         "This dc does NOT support ds"
1004 };
1005 static const true_false_string tfs_ads_kdc = {
1006         "This is a KDC (kerberos)",
1007         "This is NOT a kdc (kerberos)"
1008 };
1009 static const true_false_string tfs_ads_timeserv = {
1010         "This dc is running TIME SERVICES (ntp)",
1011         "This dc is NOT running time services (ntp)"
1012 };
1013 static const true_false_string tfs_ads_closest = {
1014         "This is the CLOSEST dc (unreliable?)",
1015         "This is NOT the closest dc"
1016 };
1017 static const true_false_string tfs_ads_writable = {
1018         "This dc is WRITABLE",
1019         "This dc is NOT writable"
1020 };
1021 static const true_false_string tfs_ads_good_timeserv = {
1022         "This dc has a GOOD TIME SERVICE (i.e. hardware clock)",
1023         "This dc does NOT have a good time service (i.e. no hardware clock)"
1024 };
1025 static const true_false_string tfs_ads_ndnc = {
1026         "Domain is NON-DOMAIN NC serviced by ldap server",
1027         "Domain is NOT non-domain nc serviced by ldap server"
1028 };
1029 static int dissect_mscldap_netlogon_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
1030 {
1031   guint32 flags;
1032   proto_item *item;
1033   proto_tree *tree=NULL;
1034   guint fields[] = { hf_mscldap_netlogon_flags_ndnc,
1035                      hf_mscldap_netlogon_flags_good_timeserv,
1036                      hf_mscldap_netlogon_flags_writable,
1037                      hf_mscldap_netlogon_flags_closest,
1038                      hf_mscldap_netlogon_flags_timeserv,
1039                      hf_mscldap_netlogon_flags_kdc,
1040                      hf_mscldap_netlogon_flags_ds,
1041                      hf_mscldap_netlogon_flags_ldap,
1042                      hf_mscldap_netlogon_flags_gc,
1043                      hf_mscldap_netlogon_flags_pdc,
1044                      0 };
1045   guint  *field;
1046   header_field_info *hfi;
1047   gboolean one_bit_set = FALSE;
1048
1049   flags=tvb_get_letohl(tvb, offset);
1050   item=proto_tree_add_item(parent_tree, hf_mscldap_netlogon_flags, tvb, offset, 4, TRUE);
1051   if(parent_tree){
1052     tree = proto_item_add_subtree(item, ett_mscldap_netlogon_flags);
1053   }
1054
1055   proto_item_append_text(item, " (");
1056
1057   for(field = fields; *field; field++) {
1058     proto_tree_add_boolean(tree, *field, tvb, offset, 4, flags);
1059     hfi = proto_registrar_get_nth(*field);
1060
1061     if(flags & hfi->bitmask) {
1062
1063       if(one_bit_set)
1064         proto_item_append_text(item, ", ");
1065       else
1066         one_bit_set = TRUE;
1067
1068       proto_item_append_text(item, hfi->name);
1069
1070     }
1071   }
1072
1073   proto_item_append_text(item, ")");
1074
1075   offset += 4;
1076
1077   return offset;
1078 }
1079
1080 static void dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1081 {
1082   int old_offset, offset=0;
1083   char str[256];
1084
1085   ldm_tree = NULL;
1086
1087 /*qqq*/
1088
1089   /* Type */
1090   /*XXX someone that knows what the type means should add that knowledge here*/
1091   proto_tree_add_item(tree, hf_mscldap_netlogon_type, tvb, offset, 4, TRUE);
1092   offset += 4;
1093
1094   /* Flags */
1095   offset = dissect_mscldap_netlogon_flags(tree, tvb, offset);
1096
1097   /* Domain GUID */
1098   proto_tree_add_item(tree, hf_mscldap_domain_guid, tvb, offset, 16, TRUE);
1099   offset += 16;
1100
1101   /* Forest */
1102   old_offset=offset;
1103   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1104   proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str);
1105
1106   /* Domain */
1107   old_offset=offset;
1108   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1109   proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str);
1110
1111   /* Hostname */
1112   old_offset=offset;
1113   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1114   proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str);
1115
1116   /* NetBios Domain */
1117   old_offset=offset;
1118   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1119   proto_tree_add_string(tree, hf_mscldap_nb_domain, tvb, old_offset, offset-old_offset, str);
1120
1121   /* NetBios Hostname */
1122   old_offset=offset;
1123   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1124   proto_tree_add_string(tree, hf_mscldap_nb_hostname, tvb, old_offset, offset-old_offset, str);
1125
1126   /* User */
1127   old_offset=offset;
1128   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1129   proto_tree_add_string(tree, hf_mscldap_username, tvb, old_offset, offset-old_offset, str);
1130
1131   /* Site */
1132   old_offset=offset;
1133   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1134   proto_tree_add_string(tree, hf_mscldap_sitename, tvb, old_offset, offset-old_offset, str);
1135
1136   /* Client Site */
1137   old_offset=offset;
1138   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
1139   proto_tree_add_string(tree, hf_mscldap_clientsitename, tvb, old_offset, offset-old_offset, str);
1140
1141   /* Version */
1142   proto_tree_add_item(tree, hf_mscldap_netlogon_version, tvb, offset, 4, TRUE);
1143   offset += 4;
1144
1145   /* LM Token */
1146   proto_tree_add_item(tree, hf_mscldap_netlogon_lm_token, tvb, offset, 2, TRUE);
1147   offset += 2;
1148
1149   /* NT Token */
1150   proto_tree_add_item(tree, hf_mscldap_netlogon_nt_token, tvb, offset, 2, TRUE);
1151   offset += 2;
1152
1153 }
1154
1155
1156 static guint
1157 get_sasl_ldap_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1158 {
1159         /* sasl encapsulated ldap is 4 bytes plus the length in size */
1160         return tvb_get_ntohl(tvb, offset)+4;
1161 }
1162
1163 static void
1164 dissect_sasl_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1165 {
1166         dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
1167         return;
1168 }
1169
1170 static guint
1171 get_normal_ldap_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
1172 {
1173         guint32 len;
1174         gboolean ind;
1175         int data_offset;
1176
1177         /* normal ldap is tag+len bytes plus the length
1178          * offset is where the tag is
1179          * offset+1 is where length starts
1180          */
1181         data_offset=get_ber_length(NULL, tvb, offset+1, &len, &ind);
1182         return len+data_offset-offset;
1183 }
1184
1185 static void
1186 dissect_normal_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1187 {
1188         dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
1189         return;
1190 }
1191
1192 static void
1193 dissect_ldap_oid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1194 {
1195         char *oid;
1196         const char *oidname;
1197
1198         /* tvb here contains an ascii string that is really an oid */
1199 /* XXX   we should convert the string oid into a real oid so we can use
1200  *       proto_tree_add_oid() instead.
1201  */
1202
1203         oid=tvb_get_ephemeral_string(tvb, 0, tvb_length(tvb));
1204         if(!oid){
1205                 return;
1206         }
1207
1208         oidname=get_oid_str_name(oid);
1209
1210         if(oidname){
1211                 proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s (%s)",oid,oidname);
1212         } else {
1213                 proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s",oid);
1214         }
1215 }
1216
1217 #define LDAP_ACCESSMASK_ADS_CREATE_CHILD        0x00000001
1218 static const true_false_string ldap_AccessMask_ADS_CREATE_CHILD_tfs = {
1219    "ADS CREATE CHILD is SET",
1220    "Ads create child is NOT set",
1221 };
1222
1223 #define LDAP_ACCESSMASK_ADS_DELETE_CHILD        0x00000002
1224 static const true_false_string ldap_AccessMask_ADS_DELETE_CHILD_tfs = {
1225    "ADS DELETE CHILD is SET",
1226    "Ads delete child is NOT set",
1227 };
1228 #define LDAP_ACCESSMASK_ADS_LIST                0x00000004
1229 static const true_false_string ldap_AccessMask_ADS_LIST_tfs = {
1230    "ADS LIST is SET",
1231    "Ads list is NOT set",
1232 };
1233 #define LDAP_ACCESSMASK_ADS_SELF_WRITE          0x00000008
1234 static const true_false_string ldap_AccessMask_ADS_SELF_WRITE_tfs = {
1235    "ADS SELF WRITE is SET",
1236    "Ads self write is NOT set",
1237 };
1238 #define LDAP_ACCESSMASK_ADS_READ_PROP           0x00000010
1239 static const true_false_string ldap_AccessMask_ADS_READ_PROP_tfs = {
1240    "ADS READ PROP is SET",
1241    "Ads read prop is NOT set",
1242 };
1243 #define LDAP_ACCESSMASK_ADS_WRITE_PROP          0x00000020
1244 static const true_false_string ldap_AccessMask_ADS_WRITE_PROP_tfs = {
1245    "ADS WRITE PROP is SET",
1246    "Ads write prop is NOT set",
1247 };
1248 #define LDAP_ACCESSMASK_ADS_DELETE_TREE         0x00000040
1249 static const true_false_string ldap_AccessMask_ADS_DELETE_TREE_tfs = {
1250    "ADS DELETE TREE is SET",
1251    "Ads delete tree is NOT set",
1252 };
1253 #define LDAP_ACCESSMASK_ADS_LIST_OBJECT         0x00000080
1254 static const true_false_string ldap_AccessMask_ADS_LIST_OBJECT_tfs = {
1255    "ADS LIST OBJECT is SET",
1256    "Ads list object is NOT set",
1257 };
1258 #define LDAP_ACCESSMASK_ADS_CONTROL_ACCESS      0x00000100
1259 static const true_false_string ldap_AccessMask_ADS_CONTROL_ACCESS_tfs = {
1260    "ADS CONTROL ACCESS is SET",
1261    "Ads control access is NOT set",
1262 };
1263
1264 static void
1265 ldap_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 access)
1266 {
1267         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_CONTROL_ACCESS, tvb, offset, 4, access);
1268
1269         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_LIST_OBJECT, tvb, offset, 4, access);
1270
1271         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_DELETE_TREE, tvb, offset, 4, access);
1272
1273         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_WRITE_PROP, tvb, offset, 4, access);
1274
1275         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_READ_PROP, tvb, offset, 4, access);
1276
1277         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_SELF_WRITE, tvb, offset, 4, access);
1278
1279         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_LIST, tvb, offset, 4, access);
1280
1281         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_DELETE_CHILD, tvb, offset, 4, access);
1282
1283         proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_CREATE_CHILD, tvb, offset, 4, access);
1284 }
1285 struct access_mask_info ldap_access_mask_info = {
1286         "LDAP",                 /* Name of specific rights */
1287         ldap_specific_rights,   /* Dissection function */
1288         NULL,                   /* Generic mapping table */
1289         NULL                    /* Standard mapping table */
1290 };
1291
1292 static void
1293 dissect_ldap_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1294 {
1295         dissect_nt_sec_desc(tvb, 0, pinfo, tree, NULL, TRUE, tvb_length(tvb), &ldap_access_mask_info);
1296 }
1297
1298 static void
1299 dissect_ldap_sid(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
1300 {
1301         char *tmpstr;
1302
1303         /* this octet string contains an NT SID */
1304         dissect_nt_sid(tvb, 0, tree, "SID", &tmpstr, hf_ldap_sid);
1305         ldapvalue_string=tmpstr;
1306 }
1307
1308 static void
1309 dissect_ldap_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1310 {
1311         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1312         e_uuid_t uuid;
1313
1314         /* This octet string contained a GUID */
1315         dissect_dcerpc_uuid_t(tvb, 0, pinfo, tree, drep, hf_ldap_guid, &uuid);
1316
1317         ldapvalue_string=ep_alloc(1024);
1318         g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1319                    uuid.Data1, uuid.Data2, uuid.Data3,
1320                    uuid.Data4[0], uuid.Data4[1],
1321                    uuid.Data4[2], uuid.Data4[3],
1322                    uuid.Data4[4], uuid.Data4[5],
1323                    uuid.Data4[6], uuid.Data4[7]);
1324 }
1325
1326 static void
1327 dissect_ldap_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1328 {
1329         guint32 sasl_len;
1330         guint32 gss_len;
1331         guint32 ldap_len;
1332         int offset;
1333         gboolean ind;
1334
1335         ldm_tree = NULL;
1336
1337         /* This is a bit tricky. We have to find out whether SASL is used
1338          * so that we know how big a header we are supposed to pass
1339          * to tcp_dissect_pdus()
1340          */
1341         /* check for a SASL header, i.e. assume it is SASL if 
1342          * 1, first four bytes (SASL length) is an integer 
1343          *    with a value that must be <64k and >2
1344          *    (>2 to fight false positives, 0x00000000 is a common
1345          *        "random" tcp payload)
1346          * (no SASL ldap PDUs are ever going to be >64k in size?)
1347          *
1348          * Following the SASL header is a GSSAPI blob so the next byte
1349          * is always 0x60. (only true for MS SASL LDAP, there are other
1350          * blobs that may follow in real-world)
1351          *
1352          * 2, Then one byte with the value 0x60 indicating the GSSAPI blob
1353          *
1354          * 3, Then X bytes describing the BER encoded lengtyh of the blob.
1355          *    This length should point to the same end-of-pdu as 1,
1356          *
1357          * 4, finally a byte 0x06 indicating that the next object is an OID
1358          */
1359         sasl_len=tvb_get_ntohl(tvb, 0);
1360  
1361         if( sasl_len<2 ){
1362                 goto this_was_not_sasl;
1363         }
1364
1365         if(tvb_get_guint8(tvb, 4)!=0x60){
1366                 goto this_was_not_sasl;
1367         }
1368                 
1369         offset=get_ber_length(NULL, tvb, 5, &gss_len, &ind);
1370         if(sasl_len!=(gss_len+offset-4)){
1371                 goto this_was_not_sasl;
1372         }
1373
1374         if(tvb_get_guint8(tvb, offset)!=0x06){
1375                 goto this_was_not_sasl;
1376         }
1377
1378         tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
1379
1380
1381 this_was_not_sasl:
1382         /* check if it is a normal BER encoded LDAP packet
1383          * i.e. first byte is 0x30 followed by a length that is
1384          * <64k
1385          * (no ldap PDUs are ever >64kb? )
1386          */
1387         if(tvb_get_guint8(tvb, 0)!=0x30){
1388                 goto this_was_not_normal_ldap;
1389         }
1390
1391         /* check that length makes sense */
1392         offset=get_ber_length(NULL, tvb, 1, &ldap_len, &ind);
1393
1394         /* dont check ind since indefinite length is never used for ldap (famous last words)*/
1395         if(ldap_len<2){
1396                 goto this_was_not_normal_ldap;
1397         }
1398
1399         tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
1400
1401
1402 this_was_not_normal_ldap:
1403
1404         return;
1405 }
1406
1407 static void
1408 dissect_mscldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1409 {
1410         dissect_ldap_pdu(tvb, pinfo, tree, TRUE);
1411         return;
1412 }
1413
1414
1415 static void
1416 ldap_reinit(void)
1417 {
1418   ldap_conv_info_t *ldap_info;
1419
1420   /* Free up state attached to the ldap_info structures */
1421   for (ldap_info = ldap_info_items; ldap_info != NULL; ldap_info = ldap_info->next) {
1422     if (ldap_info->auth_mech != NULL) {
1423       g_free(ldap_info->auth_mech);
1424       ldap_info->auth_mech=NULL;
1425     }
1426     g_hash_table_destroy(ldap_info->matched);
1427     ldap_info->matched=NULL;
1428     g_hash_table_destroy(ldap_info->unmatched);
1429     ldap_info->unmatched=NULL;
1430   }
1431
1432   ldap_info_items = NULL;
1433
1434 }
1435
1436 void
1437 register_ldap_name_dissector_handle(const char *attr_type, dissector_handle_t dissector)
1438 {
1439         dissector_add_string("ldap.name", attr_type, dissector);
1440 }
1441
1442 void
1443 register_ldap_name_dissector(const char *attr_type, dissector_t dissector, int proto)
1444 {
1445         dissector_handle_t dissector_handle;
1446
1447         dissector_handle=create_dissector_handle(dissector, proto);
1448         register_ldap_name_dissector_handle(attr_type, dissector_handle);
1449 }
1450
1451
1452 /*--- proto_register_ldap -------------------------------------------*/
1453 void proto_register_ldap(void) {
1454
1455   /* List of fields */
1456
1457   static hf_register_info hf[] = {
1458
1459                 { &hf_ldap_sasl_buffer_length,
1460                   { "SASL Buffer Length",       "ldap.sasl_buffer_length",
1461                         FT_UINT32, BASE_DEC, NULL, 0x0,
1462                         "SASL Buffer Length", HFILL }},
1463             { &hf_ldap_response_in,
1464               { "Response In", "ldap.response_in",
1465                 FT_FRAMENUM, BASE_DEC, NULL, 0x0,
1466                 "The response to this LDAP request is in this frame", HFILL }},
1467             { &hf_ldap_response_to,
1468               { "Response To", "ldap.response_to",
1469                 FT_FRAMENUM, BASE_DEC, NULL, 0x0,
1470                 "This is a response to the LDAP request in this frame", HFILL }},
1471             { &hf_ldap_time,
1472               { "Time", "ldap.time",
1473                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
1474                 "The time between the Call and the Reply", HFILL }},
1475
1476     { &hf_mscldap_netlogon_type,
1477       { "Type", "mscldap.netlogon.type",
1478         FT_UINT32, BASE_DEC, NULL, 0x0,
1479         "Type of <please tell Wireshark developers what this type is>", HFILL }},
1480
1481     { &hf_mscldap_netlogon_version,
1482       { "Version", "mscldap.netlogon.version",
1483         FT_UINT32, BASE_DEC, NULL, 0x0,
1484         "Version of <please tell Wireshark developers what this type is>", HFILL }},
1485
1486     { &hf_mscldap_netlogon_lm_token,
1487       { "LM Token", "mscldap.netlogon.lm_token",
1488         FT_UINT16, BASE_HEX, NULL, 0x0,
1489         "LM Token", HFILL }},
1490
1491     { &hf_mscldap_netlogon_nt_token,
1492       { "NT Token", "mscldap.netlogon.nt_token",
1493         FT_UINT16, BASE_HEX, NULL, 0x0,
1494         "NT Token", HFILL }},
1495
1496     { &hf_mscldap_netlogon_flags,
1497       { "Flags", "mscldap.netlogon.flags",
1498         FT_UINT32, BASE_HEX, NULL, 0x0,
1499         "Netlogon flags describing the DC properties", HFILL }},
1500
1501     { &hf_mscldap_domain_guid,
1502       { "Domain GUID", "mscldap.domain.guid",
1503         FT_BYTES, BASE_HEX, NULL, 0x0,
1504         "Domain GUID", HFILL }},
1505
1506     { &hf_mscldap_forest,
1507       { "Forest", "mscldap.forest",
1508         FT_STRING, BASE_NONE, NULL, 0x0,
1509         "Forest", HFILL }},
1510
1511     { &hf_mscldap_domain,
1512       { "Domain", "mscldap.domain",
1513         FT_STRING, BASE_NONE, NULL, 0x0,
1514         "Domainname", HFILL }},
1515
1516     { &hf_mscldap_hostname,
1517       { "Hostname", "mscldap.hostname",
1518         FT_STRING, BASE_NONE, NULL, 0x0,
1519         "Hostname", HFILL }},
1520
1521     { &hf_mscldap_nb_domain,
1522       { "NetBios Domain", "mscldap.nb_domain",
1523         FT_STRING, BASE_NONE, NULL, 0x0,
1524         "NetBios Domainname", HFILL }},
1525
1526     { &hf_mscldap_nb_hostname,
1527       { "NetBios Hostname", "mscldap.nb_hostname",
1528         FT_STRING, BASE_NONE, NULL, 0x0,
1529         "NetBios Hostname", HFILL }},
1530
1531     { &hf_mscldap_username,
1532       { "User", "mscldap.username",
1533         FT_STRING, BASE_NONE, NULL, 0x0,
1534         "User name", HFILL }},
1535
1536     { &hf_mscldap_sitename,
1537       { "Site", "mscldap.sitename",
1538         FT_STRING, BASE_NONE, NULL, 0x0,
1539         "Site name", HFILL }},
1540
1541     { &hf_mscldap_clientsitename,
1542       { "Client Site", "mscldap.clientsitename",
1543         FT_STRING, BASE_NONE, NULL, 0x0,
1544         "Client Site name", HFILL }},
1545
1546     { &hf_ldap_sid,
1547       { "Sid", "ldap.sid",
1548         FT_STRING, BASE_NONE, NULL, 0x0,
1549         "Sid", HFILL }},
1550
1551     { &hf_mscldap_netlogon_flags_pdc,
1552       { "PDC", "mscldap.netlogon.flags.pdc", FT_BOOLEAN, 32,
1553         TFS(&tfs_ads_pdc), 0x00000001, "Is this DC a PDC or not?", HFILL }},
1554
1555     { &hf_mscldap_netlogon_flags_gc,
1556       { "GC", "mscldap.netlogon.flags.gc", FT_BOOLEAN, 32,
1557         TFS(&tfs_ads_gc), 0x00000004, "Does this dc service as a GLOBAL CATALOGUE?", HFILL }},
1558
1559     { &hf_mscldap_netlogon_flags_ldap,
1560       { "LDAP", "mscldap.netlogon.flags.ldap", FT_BOOLEAN, 32,
1561         TFS(&tfs_ads_ldap), 0x00000008, "Does this DC act as an LDAP server?", HFILL }},
1562
1563     { &hf_mscldap_netlogon_flags_ds,
1564       { "DS", "mscldap.netlogon.flags.ds", FT_BOOLEAN, 32,
1565         TFS(&tfs_ads_ds), 0x00000010, "Does this dc provide DS services?", HFILL }},
1566
1567     { &hf_mscldap_netlogon_flags_kdc,
1568       { "KDC", "mscldap.netlogon.flags.kdc", FT_BOOLEAN, 32,
1569         TFS(&tfs_ads_kdc), 0x00000020, "Does this dc act as a KDC?", HFILL }},
1570
1571     { &hf_mscldap_netlogon_flags_timeserv,
1572       { "Time Serv", "mscldap.netlogon.flags.timeserv", FT_BOOLEAN, 32,
1573         TFS(&tfs_ads_timeserv), 0x00000040, "Does this dc provide time services (ntp) ?", HFILL }},
1574
1575     { &hf_mscldap_netlogon_flags_closest,
1576       { "Closest", "mscldap.netlogon.flags.closest", FT_BOOLEAN, 32,
1577         TFS(&tfs_ads_closest), 0x00000080, "Is this the closest dc? (is this used at all?)", HFILL }},
1578
1579     { &hf_mscldap_netlogon_flags_writable,
1580       { "Writable", "mscldap.netlogon.flags.writable", FT_BOOLEAN, 32,
1581         TFS(&tfs_ads_writable), 0x00000100, "Is this dc writable? (i.e. can it update the AD?)", HFILL }},
1582
1583     { &hf_mscldap_netlogon_flags_good_timeserv,
1584       { "Good Time Serv", "mscldap.netlogon.flags.good_timeserv", FT_BOOLEAN, 32,
1585         TFS(&tfs_ads_good_timeserv), 0x00000200, "Is this a Good Time Server? (i.e. does it have a hardware clock)", HFILL }},
1586
1587     { &hf_mscldap_netlogon_flags_ndnc,
1588       { "NDNC", "mscldap.netlogon.flags.ndnc", FT_BOOLEAN, 32,
1589         TFS(&tfs_ads_ndnc), 0x00000400, "Is this an NDNC dc?", HFILL }},
1590
1591     { &hf_ldap_guid,
1592       { "GUID", "ldap.guid", FT_GUID, BASE_NONE,
1593         NULL, 0, "GUID", HFILL }},
1594
1595     { &hf_ldap_AccessMask_ADS_CREATE_CHILD, 
1596           { "Create Child", "ldap.AccessMask.ADS_CREATE_CHILD", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_CREATE_CHILD_tfs), LDAP_ACCESSMASK_ADS_CREATE_CHILD, "", HFILL }},
1597
1598     { &hf_ldap_AccessMask_ADS_DELETE_CHILD, 
1599           { "Delete Child", "ldap.AccessMask.ADS_DELETE_CHILD", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_DELETE_CHILD_tfs), LDAP_ACCESSMASK_ADS_DELETE_CHILD, "", HFILL }},
1600
1601     { &hf_ldap_AccessMask_ADS_LIST, 
1602           { "List", "ldap.AccessMask.ADS_LIST", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_LIST_tfs), LDAP_ACCESSMASK_ADS_LIST, "", HFILL }},
1603
1604     { &hf_ldap_AccessMask_ADS_SELF_WRITE, 
1605           { "Self Write", "ldap.AccessMask.ADS_SELF_WRITE", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_SELF_WRITE_tfs), LDAP_ACCESSMASK_ADS_SELF_WRITE, "", HFILL }},
1606
1607     { &hf_ldap_AccessMask_ADS_READ_PROP, 
1608           { "Read Prop", "ldap.AccessMask.ADS_READ_PROP", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_READ_PROP_tfs), LDAP_ACCESSMASK_ADS_READ_PROP, "", HFILL }},
1609
1610     { &hf_ldap_AccessMask_ADS_WRITE_PROP, 
1611           { "Write Prop", "ldap.AccessMask.ADS_WRITE_PROP", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_WRITE_PROP_tfs), LDAP_ACCESSMASK_ADS_WRITE_PROP, "", HFILL }},
1612
1613     { &hf_ldap_AccessMask_ADS_DELETE_TREE, 
1614           { "Delete Tree", "ldap.AccessMask.ADS_DELETE_TREE", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_DELETE_TREE_tfs), LDAP_ACCESSMASK_ADS_DELETE_TREE, "", HFILL }},
1615
1616     { &hf_ldap_AccessMask_ADS_LIST_OBJECT, 
1617           { "List Object", "ldap.AccessMask.ADS_LIST_OBJECT", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_LIST_OBJECT_tfs), LDAP_ACCESSMASK_ADS_LIST_OBJECT, "", HFILL }},
1618
1619     { &hf_ldap_AccessMask_ADS_CONTROL_ACCESS, 
1620           { "Control Access", "ldap.AccessMask.ADS_CONTROL_ACCESS", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_CONTROL_ACCESS_tfs), LDAP_ACCESSMASK_ADS_CONTROL_ACCESS, "", HFILL }},
1621
1622 #include "packet-ldap-hfarr.c"
1623   };
1624
1625   /* List of subtrees */
1626   static gint *ett[] = {
1627     &ett_ldap,
1628     &ett_ldap_payload,
1629     &ett_ldap_sasl_blob,
1630     &ett_ldap_msg,
1631     &ett_mscldap_netlogon_flags,
1632
1633 #include "packet-ldap-ettarr.c"
1634   };
1635
1636     module_t *ldap_module;
1637
1638   /* Register protocol */
1639   proto_ldap = proto_register_protocol(PNAME, PSNAME, PFNAME);
1640   /* Register fields and subtrees */
1641   proto_register_field_array(proto_ldap, hf, array_length(hf));
1642   proto_register_subtree_array(ett, array_length(ett));
1643
1644
1645   register_dissector("ldap", dissect_ldap_tcp, proto_ldap);
1646
1647   ldap_module = prefs_register_protocol(proto_ldap, NULL);
1648   prefs_register_bool_preference(ldap_module, "desegment_ldap_messages",
1649     "Reassemble LDAP messages spanning multiple TCP segments",
1650     "Whether the LDAP dissector should reassemble messages spanning multiple TCP segments."
1651     "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
1652     &ldap_desegment);
1653
1654   prefs_register_uint_preference(ldap_module, "tcp.port", "LDAP TCP Port",
1655                                  "Set the port for LDAP operations",
1656                                  10, &ldap_tcp_port);
1657
1658   prefs_register_obsolete_preference(ldap_module, "max_pdu");
1659
1660   proto_cldap = proto_register_protocol(
1661           "Connectionless Lightweight Directory Access Protocol",
1662           "CLDAP", "cldap");
1663
1664   register_init_routine(ldap_reinit);
1665   ldap_tap=register_tap("ldap");
1666
1667   ldap_name_dissector_table = register_dissector_table("ldap.name", "LDAP Attribute Type Dissectors", FT_STRING, BASE_NONE);
1668
1669 }
1670
1671
1672 /*--- proto_reg_handoff_ldap ---------------------------------------*/
1673 void
1674 proto_reg_handoff_ldap(void)
1675 {
1676         dissector_handle_t ldap_handle, cldap_handle;
1677         ldap_handle = create_dissector_handle(dissect_ldap_tcp, proto_ldap);
1678
1679         dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
1680         dissector_add("tcp.port", TCP_PORT_GLOBALCAT_LDAP, ldap_handle);
1681
1682         cldap_handle = create_dissector_handle(dissect_mscldap, proto_cldap);
1683         dissector_add("udp.port", UDP_PORT_CLDAP, cldap_handle);
1684
1685         gssapi_handle = find_dissector("gssapi");
1686         gssapi_wrap_handle = find_dissector("gssapi_verf");
1687         spnego_handle = find_dissector("spnego");
1688
1689         ntlmssp_handle = find_dissector("ntlmssp");
1690
1691 /*  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dsml/dsml/ldap_controls_and_session_support.asp */
1692         add_oid_str_name("1.2.840.113556.1.4.319","LDAP_PAGED_RESULT_OID_STRING");
1693         add_oid_str_name("1.2.840.113556.1.4.417","LDAP_SERVER_SHOW_DELETED_OID");
1694         add_oid_str_name("1.2.840.113556.1.4.473","LDAP_SERVER_SORT_OID");
1695         add_oid_str_name("1.2.840.113556.1.4.474","LDAP_CONTROL_SORT_RESP_OID");
1696         add_oid_str_name("1.2.840.113556.1.4.521","LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID");
1697         add_oid_str_name("1.2.840.113556.1.4.528","LDAP_SERVER_NOTIFICATION_OID");
1698         add_oid_str_name("1.2.840.113556.1.4.529","LDAP_SERVER_EXTENDED_DN_OID");
1699         add_oid_str_name("1.2.840.113556.1.4.582","meetingAdvertiseScope");
1700         add_oid_str_name("1.2.840.113556.1.4.619","LDAP_SERVER_LAZY_COMMIT_OID");
1701         add_oid_str_name("1.2.840.113556.1.4.650","mhsORAddress");
1702         add_oid_str_name("1.2.840.113556.1.4.654","managedObjects");
1703         add_oid_str_name("1.2.840.113556.1.4.800","LDAP_CAP_ACTIVE_DIRECTORY_OID");
1704         add_oid_str_name("1.2.840.113556.1.4.801","LDAP_SERVER_SD_FLAGS_OID");
1705         add_oid_str_name("1.2.840.113556.1.4.804","LDAP_OID_COMPARATOR_OR");
1706         add_oid_str_name("1.2.840.113556.1.4.805","LDAP_SERVER_TREE_DELETE_OID");
1707         add_oid_str_name("1.2.840.113556.1.4.841","LDAP_SERVER_DIRSYNC_OID");
1708         add_oid_str_name("1.2.840.113556.1.4.970 ","None");
1709         add_oid_str_name("1.2.840.113556.1.4.1338","LDAP_SERVER_VERIFY_NAME_OID");
1710         add_oid_str_name("1.2.840.113556.1.4.1339","LDAP_SERVER_DOMAIN_SCOPE_OID");
1711         add_oid_str_name("1.2.840.113556.1.4.1340","LDAP_SERVER_SEARCH_OPTIONS_OID");
1712         add_oid_str_name("1.2.840.113556.1.4.1413","LDAP_SERVER_PERMISSIVE_MODIFY_OID");
1713         add_oid_str_name("1.2.840.113556.1.4.1504","LDAP_SERVER_ASQ_OID");
1714         add_oid_str_name("1.2.840.113556.1.4.1670","LDAP_CAP_ACTIVE_DIRECTORY_V51_OID");
1715         add_oid_str_name("1.2.840.113556.1.4.1781","LDAP_SERVER_FAST_BIND_OID");
1716         add_oid_str_name("1.2.840.113556.1.4.1791","LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID");
1717         add_oid_str_name("1.2.840.113556.1.4.1840","msDS-ObjectReference");
1718         add_oid_str_name("1.2.840.113556.1.4.1848","msDS-QuotaEffective");
1719         add_oid_str_name("1.2.840.113556.1.4.1851","LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID");
1720         add_oid_str_name("1.2.840.113556.1.4.1860","msDS-PortSSL");
1721         add_oid_str_name("1.2.840.113556.1.4.1960","msDS-isRODC");
1722         add_oid_str_name("1.2.840.113556.1.4.1711","msDS-SDReferenceDomain");
1723         add_oid_str_name("1.2.840.113556.1.4.1717","msDS-AdditionalDnsHostName");
1724         add_oid_str_name("1.3.6.1.4.1.1466.101.119.1","None");
1725         add_oid_str_name("1.3.6.1.4.1.1466.20037","LDAP_START_TLS_OID");
1726         add_oid_str_name("2.16.840.1.113730.3.4.9","LDAP_CONTROL_VLVREQUEST VLV");
1727         add_oid_str_name("2.16.840.1.113730.3.4.10","LDAP_CONTROL_VLVRESPONSE VLV");
1728
1729         register_ldap_name_dissector("netlogon", dissect_NetLogon_PDU, proto_cldap);
1730         register_ldap_name_dissector("objectGUID", dissect_ldap_guid, proto_ldap);
1731         register_ldap_name_dissector("supportedControl", dissect_ldap_oid, proto_ldap);
1732         register_ldap_name_dissector("supportedCapabilities", dissect_ldap_oid, proto_ldap);
1733         register_ldap_name_dissector("objectSid", dissect_ldap_sid, proto_ldap);
1734         register_ldap_name_dissector("nTSecurityDescriptor", dissect_ldap_nt_sec_desc, proto_ldap);
1735
1736 #include "packet-ldap-dis-tab.c"
1737         
1738
1739 }
1740
1741