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