add some more oid's
[obnox/wireshark/wip.git] / epan / dissectors / packet-ldap.c
1 /* Do not modify this file.                                                   */
2 /* It is created automatically by the ASN.1 to Wireshark dissector compiler   */
3 /* ./packet-ldap.c                                                            */
4 /* ../../tools/asn2wrs.py -b -e -p ldap -c ldap.cnf -s packet-ldap-template Lightweight-Directory-Access-Protocol-V3.asn */
5
6 /* Input file: packet-ldap-template.c */
7
8 #line 1 "packet-ldap-template.c"
9 /* packet-ldap.c
10  * Routines for ldap packet dissection
11  *
12  * See RFC 1777 (LDAP v2), RFC 2251 (LDAP v3), and RFC 2222 (SASL).
13  *
14  * $Id$
15  *
16  * Wireshark - Network traffic analyzer
17  * By Gerald Combs <gerald@wireshark.org>
18  * Copyright 1998 Gerald Combs
19  *
20  * This program is free software; you can redistribute it and/or
21  * modify it under the terms of the GNU General Public License
22  * as published by the Free Software Foundation; either version 2
23  * of the License, or (at your option) any later version.
24  *
25  * This program is distributed in the hope that it will be useful,
26  * but WITHOUT ANY WARRANTY; without even the implied warranty of
27  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28  * GNU General Public License for more details.
29  *
30  * You should have received a copy of the GNU General Public License
31  * along with this program; if not, write to the Free Software
32  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
33  */
34
35 /*
36  * This is not a complete implementation. It doesn't handle the full version 3, more specifically,
37  * it handles only the commands of version 2, but any additional characteristics of the ver3 command are supported.
38  * It's also missing extensible search filters.
39  *
40  * There should probably be alot more error checking, I simply assume that if we have a full packet, it will be a complete
41  * and correct packet.
42  *
43  * 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
44  * 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
45  * I can do.
46  *
47  * Doug Nazar
48  * nazard@dragoninc.on.ca
49  */
50
51 /*
52  * 11/11/2002 - Fixed problem when decoding LDAP with desegmentation enabled and the
53  *              ASN.1 BER Universal Class Tag: "Sequence Of" header is encapsulated across 2
54  *              TCP segments.
55  *
56  * Ronald W. Henderson
57  * ronald.henderson@cognicaseusa.com
58  */
59
60 /*
61  * 20-JAN-2004 - added decoding of MS-CLDAP netlogon RPC
62  *               using information from the SNIA 2003 conference paper :
63  *               Active Directory Domain Controller Location Service
64  *                    by Anthony Liguori
65  * ronnie sahlberg
66  */
67
68 /*
69  * 17-DEC-2004 - added basic decoding for LDAP Controls
70  * 20-DEC-2004 - added handling for GSS-API encrypted blobs
71  *
72  * Stefan Metzmacher <metze@samba.org>
73  *
74  * 15-NOV-2005 - Changed to use the asn2wrs compiler
75  * Anders Broman <anders.broman@ericsson.com>
76  */
77
78 #ifdef HAVE_CONFIG_H
79 # include "config.h"
80 #endif
81
82 #include <stdio.h>
83 #include <string.h>
84 #include <ctype.h>
85
86 #include <glib.h>
87
88 #include <epan/packet.h>
89 #include <epan/conversation.h>
90 #include <epan/prefs.h>
91 #include <epan/tap.h>
92 #include <epan/emem.h>
93 #include <epan/oid_resolv.h>
94 #include <epan/strutil.h>
95 #include <epan/dissectors/packet-tcp.h>
96 #include <epan/dissectors/packet-windows-common.h>
97 #include <epan/dissectors/packet-dcerpc.h>
98
99 #include "packet-frame.h"
100 #include "packet-ldap.h"
101
102 #include "packet-ber.h"
103 #include "packet-per.h"
104
105 #define PNAME  "Lightweight-Directory-Access-Protocol"
106 #define PSNAME "LDAP"
107 #define PFNAME "ldap"
108
109 /* Initialize the protocol and registered fields */
110 static int ldap_tap = -1;
111 static int proto_ldap = -1;
112 static int proto_cldap = -1;
113
114 static int hf_ldap_sasl_buffer_length = -1;
115 static int hf_ldap_response_in = -1;
116 static int hf_ldap_response_to = -1;
117 static int hf_ldap_time = -1;
118 static int hf_ldap_guid = -1;
119
120 static int hf_mscldap_netlogon_type = -1;
121 static int hf_mscldap_netlogon_flags = -1;
122 static int hf_mscldap_netlogon_flags_pdc = -1;
123 static int hf_mscldap_netlogon_flags_gc = -1;
124 static int hf_mscldap_netlogon_flags_ldap = -1;
125 static int hf_mscldap_netlogon_flags_ds = -1;
126 static int hf_mscldap_netlogon_flags_kdc = -1;
127 static int hf_mscldap_netlogon_flags_timeserv = -1;
128 static int hf_mscldap_netlogon_flags_closest = -1;
129 static int hf_mscldap_netlogon_flags_writable = -1;
130 static int hf_mscldap_netlogon_flags_good_timeserv = -1;
131 static int hf_mscldap_netlogon_flags_ndnc = -1;
132 static int hf_mscldap_domain_guid = -1;
133 static int hf_mscldap_forest = -1;
134 static int hf_mscldap_domain = -1;
135 static int hf_mscldap_hostname = -1;
136 static int hf_mscldap_nb_domain = -1;
137 static int hf_mscldap_nb_hostname = -1;
138 static int hf_mscldap_username = -1;
139 static int hf_mscldap_sitename = -1;
140 static int hf_mscldap_clientsitename = -1;
141 static int hf_mscldap_netlogon_version = -1;
142 static int hf_mscldap_netlogon_lm_token = -1;
143 static int hf_mscldap_netlogon_nt_token = -1;
144
145
146 /*--- Included file: packet-ldap-hf.c ---*/
147 #line 1 "packet-ldap-hf.c"
148 static int hf_ldap_LDAPMessage_PDU = -1;          /* LDAPMessage */
149 static int hf_ldap_messageID = -1;                /* MessageID */
150 static int hf_ldap_protocolOp = -1;               /* ProtocolOp */
151 static int hf_ldap_controls = -1;                 /* Controls */
152 static int hf_ldap_bindRequest = -1;              /* BindRequest */
153 static int hf_ldap_bindResponse = -1;             /* BindResponse */
154 static int hf_ldap_unbindRequest = -1;            /* UnbindRequest */
155 static int hf_ldap_searchRequest = -1;            /* SearchRequest */
156 static int hf_ldap_searchResEntry = -1;           /* SearchResultEntry */
157 static int hf_ldap_searchResDone = -1;            /* SearchResultDone */
158 static int hf_ldap_searchResRef = -1;             /* SearchResultReference */
159 static int hf_ldap_modifyRequest = -1;            /* ModifyRequest */
160 static int hf_ldap_modifyResponse = -1;           /* ModifyResponse */
161 static int hf_ldap_addRequest = -1;               /* AddRequest */
162 static int hf_ldap_addResponse = -1;              /* AddResponse */
163 static int hf_ldap_delRequest = -1;               /* DelRequest */
164 static int hf_ldap_delResponse = -1;              /* DelResponse */
165 static int hf_ldap_modDNRequest = -1;             /* ModifyDNRequest */
166 static int hf_ldap_modDNResponse = -1;            /* ModifyDNResponse */
167 static int hf_ldap_compareRequest = -1;           /* CompareRequest */
168 static int hf_ldap_compareResponse = -1;          /* CompareResponse */
169 static int hf_ldap_abandonRequest = -1;           /* AbandonRequest */
170 static int hf_ldap_extendedReq = -1;              /* ExtendedRequest */
171 static int hf_ldap_extendedResp = -1;             /* ExtendedResponse */
172 static int hf_ldap_AttributeDescriptionList_item = -1;  /* AttributeDescription */
173 static int hf_ldap_attributeDesc = -1;            /* AttributeDescription */
174 static int hf_ldap_assertionValue = -1;           /* AssertionValue */
175 static int hf_ldap_type = -1;                     /* AttributeDescription */
176 static int hf_ldap_vals = -1;                     /* SET_OF_AttributeValue */
177 static int hf_ldap_vals_item = -1;                /* AttributeValue */
178 static int hf_ldap_resultCode = -1;               /* T_resultCode */
179 static int hf_ldap_matchedDN = -1;                /* LDAPDN */
180 static int hf_ldap_errorMessage = -1;             /* ErrorMessage */
181 static int hf_ldap_referral = -1;                 /* Referral */
182 static int hf_ldap_Referral_item = -1;            /* LDAPURL */
183 static int hf_ldap_Controls_item = -1;            /* Control */
184 static int hf_ldap_controlType = -1;              /* ControlType */
185 static int hf_ldap_criticality = -1;              /* BOOLEAN */
186 static int hf_ldap_controlValue = -1;             /* OCTET_STRING */
187 static int hf_ldap_version = -1;                  /* INTEGER_1_127 */
188 static int hf_ldap_name = -1;                     /* LDAPDN */
189 static int hf_ldap_authentication = -1;           /* AuthenticationChoice */
190 static int hf_ldap_simple = -1;                   /* Simple */
191 static int hf_ldap_sasl = -1;                     /* SaslCredentials */
192 static int hf_ldap_mechanism = -1;                /* Mechanism */
193 static int hf_ldap_credentials = -1;              /* Credentials */
194 static int hf_ldap_bindResponse_resultCode = -1;  /* BindResponse_resultCode */
195 static int hf_ldap_serverSaslCreds = -1;          /* ServerSaslCreds */
196 static int hf_ldap_baseObject = -1;               /* LDAPDN */
197 static int hf_ldap_scope = -1;                    /* T_scope */
198 static int hf_ldap_derefAliases = -1;             /* T_derefAliases */
199 static int hf_ldap_sizeLimit = -1;                /* INTEGER_0_maxInt */
200 static int hf_ldap_timeLimit = -1;                /* INTEGER_0_maxInt */
201 static int hf_ldap_typesOnly = -1;                /* BOOLEAN */
202 static int hf_ldap_filter = -1;                   /* T_filter */
203 static int hf_ldap_searchRequest_attributes = -1;  /* AttributeDescriptionList */
204 static int hf_ldap_and = -1;                      /* T_and */
205 static int hf_ldap_and_item = -1;                 /* T_and_item */
206 static int hf_ldap_or = -1;                       /* T_or */
207 static int hf_ldap_or_item = -1;                  /* T_or_item */
208 static int hf_ldap_not = -1;                      /* T_not */
209 static int hf_ldap_equalityMatch = -1;            /* T_equalityMatch */
210 static int hf_ldap_substrings = -1;               /* SubstringFilter */
211 static int hf_ldap_greaterOrEqual = -1;           /* T_greaterOrEqual */
212 static int hf_ldap_lessOrEqual = -1;              /* T_lessOrEqual */
213 static int hf_ldap_present = -1;                  /* T_present */
214 static int hf_ldap_approxMatch = -1;              /* T_approxMatch */
215 static int hf_ldap_extensibleMatch = -1;          /* T_extensibleMatch */
216 static int hf_ldap_substringFilter_substrings = -1;  /* T_substringFilter_substrings */
217 static int hf_ldap_substringFilter_substrings_item = -1;  /* T_substringFilter_substrings_item */
218 static int hf_ldap_initial = -1;                  /* LDAPString */
219 static int hf_ldap_any = -1;                      /* LDAPString */
220 static int hf_ldap_final = -1;                    /* LDAPString */
221 static int hf_ldap_matchingRule = -1;             /* MatchingRuleId */
222 static int hf_ldap_matchValue = -1;               /* AssertionValue */
223 static int hf_ldap_dnAttributes = -1;             /* BOOLEAN */
224 static int hf_ldap_objectName = -1;               /* LDAPDN */
225 static int hf_ldap_searchResultEntry_attributes = -1;  /* PartialAttributeList */
226 static int hf_ldap_PartialAttributeList_item = -1;  /* PartialAttributeList_item */
227 static int hf_ldap_SearchResultReference_item = -1;  /* LDAPURL */
228 static int hf_ldap_object = -1;                   /* LDAPDN */
229 static int hf_ldap_modifyRequest_modification = -1;  /* ModifyRequest_modification */
230 static int hf_ldap_modifyRequest_modification_item = -1;  /* T_modifyRequest_modification_item */
231 static int hf_ldap_operation = -1;                /* T_operation */
232 static int hf_ldap_modification = -1;             /* AttributeTypeAndValues */
233 static int hf_ldap_entry = -1;                    /* LDAPDN */
234 static int hf_ldap_attributes = -1;               /* AttributeList */
235 static int hf_ldap_AttributeList_item = -1;       /* AttributeList_item */
236 static int hf_ldap_newrdn = -1;                   /* RelativeLDAPDN */
237 static int hf_ldap_deleteoldrdn = -1;             /* BOOLEAN */
238 static int hf_ldap_newSuperior = -1;              /* LDAPDN */
239 static int hf_ldap_ava = -1;                      /* AttributeValueAssertion */
240 static int hf_ldap_requestName = -1;              /* LDAPOID */
241 static int hf_ldap_requestValue = -1;             /* OCTET_STRING */
242 static int hf_ldap_extendedResponse_resultCode = -1;  /* ExtendedResponse_resultCode */
243 static int hf_ldap_responseName = -1;             /* ResponseName */
244 static int hf_ldap_response = -1;                 /* OCTET_STRING */
245
246 /*--- End of included file: packet-ldap-hf.c ---*/
247 #line 138 "packet-ldap-template.c"
248
249 /* Initialize the subtree pointers */
250 static gint ett_ldap = -1;
251 static gint ett_ldap_msg = -1;
252 static gint ett_ldap_sasl_blob = -1;
253 static guint ett_ldap_payload = -1;
254 static gint ett_mscldap_netlogon_flags = -1;
255
256
257 /*--- Included file: packet-ldap-ett.c ---*/
258 #line 1 "packet-ldap-ett.c"
259 static gint ett_ldap_LDAPMessage = -1;
260 static gint ett_ldap_ProtocolOp = -1;
261 static gint ett_ldap_AttributeDescriptionList = -1;
262 static gint ett_ldap_AttributeValueAssertion = -1;
263 static gint ett_ldap_Attribute = -1;
264 static gint ett_ldap_SET_OF_AttributeValue = -1;
265 static gint ett_ldap_LDAPResult = -1;
266 static gint ett_ldap_Referral = -1;
267 static gint ett_ldap_Controls = -1;
268 static gint ett_ldap_Control = -1;
269 static gint ett_ldap_BindRequest = -1;
270 static gint ett_ldap_AuthenticationChoice = -1;
271 static gint ett_ldap_SaslCredentials = -1;
272 static gint ett_ldap_BindResponse = -1;
273 static gint ett_ldap_SearchRequest = -1;
274 static gint ett_ldap_Filter = -1;
275 static gint ett_ldap_T_and = -1;
276 static gint ett_ldap_T_or = -1;
277 static gint ett_ldap_SubstringFilter = -1;
278 static gint ett_ldap_T_substringFilter_substrings = -1;
279 static gint ett_ldap_T_substringFilter_substrings_item = -1;
280 static gint ett_ldap_MatchingRuleAssertion = -1;
281 static gint ett_ldap_SearchResultEntry = -1;
282 static gint ett_ldap_PartialAttributeList = -1;
283 static gint ett_ldap_PartialAttributeList_item = -1;
284 static gint ett_ldap_SearchResultReference = -1;
285 static gint ett_ldap_ModifyRequest = -1;
286 static gint ett_ldap_ModifyRequest_modification = -1;
287 static gint ett_ldap_T_modifyRequest_modification_item = -1;
288 static gint ett_ldap_AttributeTypeAndValues = -1;
289 static gint ett_ldap_AddRequest = -1;
290 static gint ett_ldap_AttributeList = -1;
291 static gint ett_ldap_AttributeList_item = -1;
292 static gint ett_ldap_ModifyDNRequest = -1;
293 static gint ett_ldap_CompareRequest = -1;
294 static gint ett_ldap_ExtendedRequest = -1;
295 static gint ett_ldap_ExtendedResponse = -1;
296
297 /*--- End of included file: packet-ldap-ett.c ---*/
298 #line 147 "packet-ldap-template.c"
299
300 static dissector_table_t ldap_name_dissector_table=NULL;
301
302 /* desegmentation of LDAP */
303 static gboolean ldap_desegment = TRUE;
304 static guint    ldap_tcp_port = 389;
305 static gboolean do_protocolop = FALSE;
306 static gchar    *attr_type = NULL;
307 static gboolean is_binary_attr_type = FALSE;
308
309 #define TCP_PORT_LDAP                   389
310 #define UDP_PORT_CLDAP                  389
311 #define TCP_PORT_GLOBALCAT_LDAP         3268 /* Windows 2000 Global Catalog */
312
313 static dissector_handle_t gssapi_handle;
314 static dissector_handle_t gssapi_wrap_handle;
315
316
317 /* different types of rpc calls ontop of ms cldap */
318 #define MSCLDAP_RPC_NETLOGON    1
319
320 /* Message type Choice values */
321 static const value_string ldap_ProtocolOp_choice_vals[] = {
322   {   0, "bindRequest" },
323   {   1, "bindResponse" },
324   {   2, "unbindRequest" },
325   {   3, "searchRequest" },
326   {   4, "searchResEntry" },
327   {   5, "searchResDone" },
328   {       6, "searchResRef" },
329   {   7, "modifyRequest" },
330   {   8, "modifyResponse" },
331   {   9, "addRequest" },
332   {  10, "addResponse" },
333   {  11, "delRequest" },
334   {  12, "delResponse" },
335   {  13, "modDNRequest" },
336   {  14, "modDNResponse" },
337   {  15, "compareRequest" },
338   {  16, "compareResponse" },
339   {  17, "abandonRequest" },
340   {  18, "extendedReq" },
341   {  19, "extendedResp" },
342   { 0, NULL }
343 };
344 /*
345  * Data structure attached to a conversation, giving authentication
346  * information from a bind request.
347  * We keep a linked list of them, so that we can free up all the
348  * authentication mechanism strings.
349  */
350 typedef struct ldap_conv_info_t {
351   struct ldap_conv_info_t *next;
352   guint auth_type;              /* authentication type */
353   char *auth_mech;              /* authentication mechanism */
354   guint32 first_auth_frame;     /* first frame that would use a security layer */
355   GHashTable *unmatched;
356   GHashTable *matched;
357   gboolean is_mscldap;
358   gboolean first_time;
359   guint32  num_results;
360 } ldap_conv_info_t;
361 static ldap_conv_info_t *ldap_info_items;
362
363 static guint
364 ldap_info_hash_matched(gconstpointer k)
365 {
366   const ldap_call_response_t *key = k;
367
368   return key->messageId;
369 }
370
371 static gint
372 ldap_info_equal_matched(gconstpointer k1, gconstpointer k2)
373 {
374   const ldap_call_response_t *key1 = k1;
375   const ldap_call_response_t *key2 = k2;
376
377   if( key1->req_frame && key2->req_frame && (key1->req_frame!=key2->req_frame) ){
378     return 0;
379   }
380   /* a response may span multiple frames
381   if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
382     return 0;
383   }
384   */
385
386   return key1->messageId==key2->messageId;
387 }
388
389 static guint
390 ldap_info_hash_unmatched(gconstpointer k)
391 {
392   const ldap_call_response_t *key = k;
393
394   return key->messageId;
395 }
396
397 static gint
398 ldap_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
399 {
400   const ldap_call_response_t *key1 = k1;
401   const ldap_call_response_t *key2 = k2;
402
403   return key1->messageId==key2->messageId;
404 }
405
406 /* This string contains the last LDAPString that was decoded */
407 static char *attributedesc_string=NULL;
408
409 /* This string contains the last AssertionValue that was decoded */
410 static char *ldapvalue_string=NULL;
411
412 /* if the octet string contain all printable ASCII characters, then
413  * display it as a string, othervise just display it in hex.
414  */
415 static int
416 dissect_ldap_AssertionValue(gboolean implicit_tag, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index)
417 {
418         gint8 class;
419         gboolean pc, ind, is_ascii;
420         gint32 tag;
421         guint32 len, i;
422         const guchar *str;
423
424         if(!implicit_tag){
425                 offset=get_ber_identifier(tvb, offset, &class, &pc, &tag);
426                 offset=get_ber_length(NULL, tvb, offset, &len, &ind);
427         } else {
428                 len=tvb_length_remaining(tvb,offset);
429         }
430
431         if(len==0){
432                 return offset;
433         }
434
435
436         /*
437          * Some special/wellknown attributes in common LDAP (read AD)
438          * are neither ascii strings nor blobs of hex data.
439          * Special case these attributes and decode them more nicely.
440          *
441          * Add more special cases as required to prettify further
442          * (there cant be that many ones that are truly interesting)
443          */
444         if(attributedesc_string && !strncmp("DomainSid", attributedesc_string, 9)){
445                 tvbuff_t *sid_tvb;
446                 char *tmpstr;
447
448                 /* this octet string contains an NT SID */
449                 sid_tvb=tvb_new_subset(tvb, offset, len, len);
450                 dissect_nt_sid(sid_tvb, 0, tree, "SID", &tmpstr, hf_index);
451                 ldapvalue_string=ep_strdup(tmpstr);
452                 g_free(tmpstr);
453
454                 goto finished;
455         } else if ( (len==16) /* GUIDs are always 16 bytes */
456         && (attributedesc_string && !strncmp("DomainGuid", attributedesc_string, 10))) {
457                 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
458                 e_uuid_t uuid;
459
460                 /* This octet string contained a GUID */
461                 dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_ldap_guid, &uuid);
462
463                 ldapvalue_string=ep_alloc(1024);
464                 g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
465                           uuid.Data1, uuid.Data2, uuid.Data3,
466                           uuid.Data4[0], uuid.Data4[1],
467                           uuid.Data4[2], uuid.Data4[3],
468                           uuid.Data4[4], uuid.Data4[5],
469                           uuid.Data4[6], uuid.Data4[7]);
470
471                 goto finished;
472         }
473
474         /*
475          * It was not one of our "wellknown" attributes so make the best
476          * we can and just try to see if it is an ascii string or if it
477          * is a binary blob.
478          *
479          * XXX - should we support reading RFC 2252-style schemas
480          * for LDAP, and using that to determine how to display
481          * attribute values and assertion values?
482          *
483          * -- I dont think there are full schemas available that describe the
484          *  interesting cases i.e. AD -- ronnie
485          */
486         str=tvb_get_ptr(tvb, offset, len);
487         is_ascii=TRUE;
488         for(i=0;i<len;i++){
489                 if(!isascii(str[i]) || !isprint(str[i])){
490                         is_ascii=FALSE;
491                         break;
492                 }
493         }
494
495         /* convert the string into a printable string */
496         if(is_ascii){
497                 ldapvalue_string=ep_alloc(len+1);
498                 memcpy(ldapvalue_string,str,len);
499                 ldapvalue_string[i]=0;
500         } else {
501                 ldapvalue_string=ep_alloc(3*len);
502                 for(i=0;i<len;i++){
503                         g_snprintf(ldapvalue_string+i*3,3,"%02x",str[i]&0xff);
504                         ldapvalue_string[3*i+2]=':';
505                 }
506                 ldapvalue_string[3*len-1]=0;
507         }
508
509         proto_tree_add_string(tree, hf_index, tvb, offset, len, ldapvalue_string);
510
511
512 finished:
513         offset+=len;
514         return offset;
515 }
516
517 /* This string contains the last Filter item that was decoded */
518 static char *Filter_string=NULL;
519 static char *and_filter_string=NULL;
520 static char *or_filter_string=NULL;
521 static char *substring_value=NULL;
522 static char *substring_item_init=NULL;
523 static char *substring_item_any=NULL;
524 static char *substring_item_final=NULL;
525 static char *matching_rule_string=NULL;
526 static gboolean matching_rule_dnattr=FALSE;
527
528 /* Global variables */
529 char *mechanism = NULL;
530 static gint MessageID =-1;
531 static gint ProtocolOp = -1;
532 static gint result = 0;
533 static proto_item *ldm_tree = NULL; /* item to add text to */
534
535 static void ldap_do_protocolop(packet_info *pinfo)
536 {
537   const gchar* valstr;
538
539   if (do_protocolop)  {
540
541     valstr = val_to_str(ProtocolOp, ldap_ProtocolOp_choice_vals, "Unknown (%%u)");
542
543     if(check_col(pinfo->cinfo, COL_INFO))
544       col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", valstr, MessageID);
545
546     if(ldm_tree)
547       proto_item_append_text(ldm_tree, " %s(%d)", valstr, MessageID);
548
549     do_protocolop = FALSE;
550
551   }
552 }
553
554 static ldap_call_response_t *
555 ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint messageId, guint protocolOpTag)
556 {
557   ldap_call_response_t lcr, *lcrp=NULL;
558   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)pinfo->private_data;
559
560   /* first see if we have already matched this */
561
562       lcr.messageId=messageId;
563       switch(protocolOpTag){
564         case LDAP_REQ_BIND:
565         case LDAP_REQ_SEARCH:
566         case LDAP_REQ_MODIFY:
567         case LDAP_REQ_ADD:
568         case LDAP_REQ_DELETE:
569         case LDAP_REQ_MODRDN:
570         case LDAP_REQ_COMPARE:
571           lcr.is_request=TRUE;
572           lcr.req_frame=pinfo->fd->num;
573           lcr.rep_frame=0;
574           break;
575         case LDAP_RES_BIND:
576         case LDAP_RES_SEARCH_ENTRY:
577         case LDAP_RES_SEARCH_REF:
578         case LDAP_RES_SEARCH_RESULT:
579         case LDAP_RES_MODIFY:
580         case LDAP_RES_ADD:
581         case LDAP_RES_DELETE:
582         case LDAP_RES_MODRDN:
583         case LDAP_RES_COMPARE:
584           lcr.is_request=FALSE;
585           lcr.req_frame=0;
586           lcr.rep_frame=pinfo->fd->num;
587           break;
588       }
589       lcrp=g_hash_table_lookup(ldap_info->matched, &lcr);
590
591       if(lcrp){
592
593         lcrp->is_request=lcr.is_request;
594
595       } else {
596
597                   /* we haven't found a match - try and match it up */
598
599   switch(protocolOpTag){
600       case LDAP_REQ_BIND:
601       case LDAP_REQ_SEARCH:
602       case LDAP_REQ_MODIFY:
603       case LDAP_REQ_ADD:
604       case LDAP_REQ_DELETE:
605       case LDAP_REQ_MODRDN:
606       case LDAP_REQ_COMPARE:
607
608                 /* this a a request - add it to the unmatched list */
609
610         /* check that we dont already have one of those in the
611            unmatched list and if so remove it */
612
613         lcr.messageId=messageId;
614         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
615         if(lcrp){
616           g_hash_table_remove(ldap_info->unmatched, lcrp);
617         }
618         /* if we cant reuse the old one, grab a new chunk */
619         if(!lcrp){
620           lcrp=se_alloc(sizeof(ldap_call_response_t));
621         }
622         lcrp->messageId=messageId;
623         lcrp->req_frame=pinfo->fd->num;
624         lcrp->req_time=pinfo->fd->abs_ts;
625         lcrp->rep_frame=0;
626         lcrp->protocolOpTag=protocolOpTag;
627         lcrp->is_request=TRUE;
628         g_hash_table_insert(ldap_info->unmatched, lcrp, lcrp);
629         return NULL;
630         break;
631       case LDAP_RES_BIND:
632       case LDAP_RES_SEARCH_ENTRY:
633       case LDAP_RES_SEARCH_REF:
634       case LDAP_RES_SEARCH_RESULT:
635       case LDAP_RES_MODIFY:
636       case LDAP_RES_ADD:
637       case LDAP_RES_DELETE:
638       case LDAP_RES_MODRDN:
639       case LDAP_RES_COMPARE:
640
641                 /* this is a result - it should be in our unmatched list */
642
643         lcr.messageId=messageId;
644         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
645
646         if(lcrp){
647
648           if(!lcrp->rep_frame){
649             g_hash_table_remove(ldap_info->unmatched, lcrp);
650             lcrp->rep_frame=pinfo->fd->num;
651             lcrp->is_request=FALSE;
652             g_hash_table_insert(ldap_info->matched, lcrp, lcrp);
653           }
654         }
655
656         break;
657           }
658
659         }
660     /* we have found a match */
661
662     if(lcrp){
663       if(lcrp->is_request){
664         proto_tree_add_uint(tree, hf_ldap_response_in, tvb, 0, 0, lcrp->rep_frame);
665       } else {
666         nstime_t ns;
667         proto_tree_add_uint(tree, hf_ldap_response_to, tvb, 0, 0, lcrp->req_frame);
668         nstime_delta(&ns, &pinfo->fd->abs_ts, &lcrp->req_time);
669         proto_tree_add_time(tree, hf_ldap_time, tvb, 0, 0, &ns);
670       }
671     }
672
673     return lcrp;
674 }
675
676
677 /*--- Included file: packet-ldap-fn.c ---*/
678 #line 1 "packet-ldap-fn.c"
679 /*--- Cyclic dependencies ---*/
680
681 /* Filter -> Filter/and -> Filter/and/_item -> Filter */
682 /* Filter -> Filter/or -> Filter/or/_item -> Filter */
683 /* Filter -> Filter/not -> Filter */
684 static int dissect_ldap_Filter(gboolean implicit_tag, tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, int hf_index);
685
686
687
688 /*--- Fields for imported types ---*/
689
690
691
692
693 static int
694 dissect_ldap_MessageID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
695 #line 53 "ldap.cnf"
696
697     offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
698                                   &MessageID);
699
700   
701   ldm_tree = tree;
702
703
704
705   return offset;
706 }
707 static int dissect_messageID(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
708   return dissect_ldap_MessageID(FALSE, tvb, offset, pinfo, tree, hf_ldap_messageID);
709 }
710
711
712
713 static int
714 dissect_ldap_INTEGER_1_127(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
715   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
716                                   NULL);
717
718   return offset;
719 }
720 static int dissect_version(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
721   return dissect_ldap_INTEGER_1_127(FALSE, tvb, offset, pinfo, tree, hf_ldap_version);
722 }
723
724
725
726 static int
727 dissect_ldap_LDAPString(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
728 #line 240 "ldap.cnf"
729   tvbuff_t      *parameter_tvb = NULL;
730   char          *ldapstring;
731   gchar         *sc = NULL; /* semi-colon pointer */
732  
733     offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
734                                        &parameter_tvb);
735
736
737   if (parameter_tvb || (hf_index == hf_ldap_baseObject)) {
738   
739      ldap_do_protocolop(pinfo);
740
741      if(parameter_tvb)
742         ldapstring = tvb_get_ephemeral_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb, 0));
743      else
744         ldapstring = "<ROOT>";
745
746      if(hf_index == hf_ldap_baseObject) {
747         /* this is search - but it on the scanline */
748         if(check_col(pinfo->cinfo, COL_INFO)) 
749           col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\" ", ldapstring);
750   
751         if(ldm_tree)
752           proto_item_append_text(ldm_tree, " \"%s\"", ldapstring); 
753      } else if ((hf_index == hf_ldap_errorMessage) && result) { /* only show message if not success */
754         if(check_col(pinfo->cinfo, COL_INFO)) 
755           col_append_fstr(pinfo->cinfo, COL_INFO, "(%s) ", ldapstring);     
756
757         if(ldm_tree)
758           proto_item_append_text(ldm_tree, " (%s)", ldapstring); 
759      } else if (hf_index == hf_ldap_objectName) {
760         if(check_col(pinfo->cinfo, COL_INFO)) 
761           col_append_fstr(pinfo->cinfo, COL_INFO, "\"%s\" ", ldapstring);     
762
763         if(ldm_tree)
764           proto_item_append_text(ldm_tree, " \"%s\"", ldapstring); 
765      } else if (hf_index == hf_ldap_attributeDesc){
766         /* remember the attribute description */
767         attributedesc_string=ldapstring;
768      } else if (hf_index == hf_ldap_initial){
769         /* remember the substring item */
770         substring_item_init=ldapstring;
771      } else if (hf_index == hf_ldap_any){
772         /* remember the substring item */
773         substring_item_any=ldapstring;
774      } else if (hf_index == hf_ldap_final){
775         /* remember the substring item */
776         substring_item_final=ldapstring;
777      } else if (hf_index == hf_ldap_matchingRule){
778         /* remember the matching rule */
779         matching_rule_string=ldapstring;
780      } else if (hf_index == hf_ldap_present){
781         /* remember the present name */
782         Filter_string=ldapstring;
783      } else if (hf_index == hf_ldap_type) {
784         /* remember attribute type name */
785         attr_type = ep_strdup(ldapstring);
786
787         /* append it to the parent entry */
788         proto_item_append_text(tree, " %s", attr_type);
789
790         /* remove the ";binary" component if present */
791         if((sc = strchr(attr_type, ';')) != NULL) {
792                 if(!strcmp(sc, ";binary")) {
793                         *sc = '\0'; /* terminate the string */
794                         is_binary_attr_type = TRUE;
795                 }
796         } else {
797                 is_binary_attr_type = FALSE;
798         }
799
800      }
801      
802   }
803
804
805
806   return offset;
807 }
808 static int dissect_initial_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
809   return dissect_ldap_LDAPString(TRUE, tvb, offset, pinfo, tree, hf_ldap_initial);
810 }
811 static int dissect_any_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
812   return dissect_ldap_LDAPString(TRUE, tvb, offset, pinfo, tree, hf_ldap_any);
813 }
814 static int dissect_final_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
815   return dissect_ldap_LDAPString(TRUE, tvb, offset, pinfo, tree, hf_ldap_final);
816 }
817
818
819
820 static int
821 dissect_ldap_LDAPDN(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
822   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
823
824   return offset;
825 }
826 static int dissect_matchedDN(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
827   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_matchedDN);
828 }
829 static int dissect_name(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
830   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_name);
831 }
832 static int dissect_baseObject(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
833   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_baseObject);
834 }
835 static int dissect_objectName(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
836   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_objectName);
837 }
838 static int dissect_object(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
839   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_object);
840 }
841 static int dissect_entry(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
842   return dissect_ldap_LDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_entry);
843 }
844 static int dissect_newSuperior_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
845   return dissect_ldap_LDAPDN(TRUE, tvb, offset, pinfo, tree, hf_ldap_newSuperior);
846 }
847
848
849
850 static int
851 dissect_ldap_Simple(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
852 #line 103 "ldap.cnf"
853 ldap_conv_info_t *ldap_info;
854
855   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
856                                        NULL);
857
858         
859         ldap_info = pinfo->private_data;
860         ldap_info->auth_type = LDAP_AUTH_SIMPLE;
861
862         pinfo->private_data = ldap_info;
863
864
865
866   return offset;
867 }
868 static int dissect_simple_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
869   return dissect_ldap_Simple(TRUE, tvb, offset, pinfo, tree, hf_ldap_simple);
870 }
871
872
873
874 static int
875 dissect_ldap_Mechanism(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
876 #line 114 "ldap.cnf"
877
878 ldap_conv_info_t *ldap_info;
879 tvbuff_t        *parameter_tvb;
880 char *mechanism = NULL;
881   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
882                                        &parameter_tvb);
883
884         ldap_info = pinfo->private_data;
885         ldap_info->auth_type = LDAP_AUTH_SASL;
886
887         if (!parameter_tvb)
888                 return offset;
889
890     /*
891      * We need to remember the authentication type and mechanism for this
892      * conversation.
893      *
894      * XXX - actually, we might need to remember more than one
895      * type and mechanism, if you can unbind and rebind with a
896      * different type and/or mechanism.
897      */
898     mechanism = tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
899     ldap_info->first_auth_frame = 0;    /* not known until we see the bind reply */
900     /*
901      * If the mechanism in this request is an empty string (which is
902      * returned as a null pointer), use the saved mechanism instead.
903      * Otherwise, if the saved mechanism is an empty string (null),
904      * save this mechanism.
905      */
906     if (mechanism == NULL)
907         mechanism = ldap_info->auth_mech;
908     else {
909       if (ldap_info->auth_mech == NULL) {
910         g_free(ldap_info->auth_mech);
911       }
912       ldap_info->auth_mech = mechanism;
913     }
914         pinfo->private_data = ldap_info;
915
916
917
918   return offset;
919 }
920 static int dissect_mechanism(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
921   return dissect_ldap_Mechanism(FALSE, tvb, offset, pinfo, tree, hf_ldap_mechanism);
922 }
923
924
925
926 static int
927 dissect_ldap_Credentials(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
928 #line 153 "ldap.cnf"
929
930 tvbuff_t        *parameter_tvb;
931 ldap_conv_info_t *ldap_info;
932
933   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
934                                        &parameter_tvb);
935
936         if (!parameter_tvb)
937                 return offset;
938
939         ldap_info = pinfo->private_data;
940         if (ldap_info->auth_mech != NULL && strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
941                 /*
942          * This is a GSS-API token ancapsulated within GSS-SPNEGO.
943                  */
944                  if (parameter_tvb)
945                         call_dissector(gssapi_handle, parameter_tvb, pinfo, tree);
946         } else if (ldap_info->auth_mech != NULL && strcmp(ldap_info->auth_mech, "GSSAPI") == 0) {
947         /*
948          * This is a raw GSS-API token.
949          */
950                  if (parameter_tvb)
951                         call_dissector(gssapi_handle, parameter_tvb, pinfo, tree);
952         }
953         pinfo->private_data = ldap_info;
954
955
956
957   return offset;
958 }
959 static int dissect_credentials(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
960   return dissect_ldap_Credentials(FALSE, tvb, offset, pinfo, tree, hf_ldap_credentials);
961 }
962
963
964 static const ber_sequence_t SaslCredentials_sequence[] = {
965   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_mechanism },
966   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_credentials },
967   { 0, 0, 0, NULL }
968 };
969
970 static int
971 dissect_ldap_SaslCredentials(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
972   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
973                                    SaslCredentials_sequence, hf_index, ett_ldap_SaslCredentials);
974
975   return offset;
976 }
977 static int dissect_sasl_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
978   return dissect_ldap_SaslCredentials(TRUE, tvb, offset, pinfo, tree, hf_ldap_sasl);
979 }
980
981
982 static const value_string ldap_AuthenticationChoice_vals[] = {
983   {   0, "simple" },
984   {   3, "sasl" },
985   { 0, NULL }
986 };
987
988 static const ber_choice_t AuthenticationChoice_choice[] = {
989   {   0, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_simple_impl },
990   {   3, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_sasl_impl },
991   { 0, 0, 0, 0, NULL }
992 };
993
994 static int
995 dissect_ldap_AuthenticationChoice(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
996 #line 415 "ldap.cnf"
997   gint branch = -1;
998   gint auth = -1;
999   const gchar *valstr;
1000   
1001     offset = dissect_ber_choice(pinfo, tree, tvb, offset,
1002                                  AuthenticationChoice_choice, hf_index, ett_ldap_AuthenticationChoice,
1003                                  &branch);
1004
1005   
1006   ldap_do_protocolop(pinfo);
1007   
1008   if((branch > -1) && (branch < (gint)(sizeof AuthenticationChoice_choice/sizeof AuthenticationChoice_choice[0])))
1009     auth = AuthenticationChoice_choice[branch].value;
1010
1011   valstr = val_to_str(auth, ldap_AuthenticationChoice_vals, "Unknown auth(%u)");
1012   
1013   if (check_col(pinfo->cinfo, COL_INFO))
1014     col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", valstr);
1015   
1016   if(ldm_tree)
1017     proto_item_append_text(ldm_tree, " %s", valstr);
1018
1019
1020
1021
1022   return offset;
1023 }
1024 static int dissect_authentication(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1025   return dissect_ldap_AuthenticationChoice(FALSE, tvb, offset, pinfo, tree, hf_ldap_authentication);
1026 }
1027
1028
1029 static const ber_sequence_t BindRequest_sequence[] = {
1030   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_version },
1031   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_name },
1032   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_authentication },
1033   { 0, 0, 0, NULL }
1034 };
1035
1036 static int
1037 dissect_ldap_BindRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1038   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1039                                    BindRequest_sequence, hf_index, ett_ldap_BindRequest);
1040
1041   return offset;
1042 }
1043 static int dissect_bindRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1044   return dissect_ldap_BindRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_bindRequest);
1045 }
1046
1047
1048 static const value_string ldap_BindResponse_resultCode_vals[] = {
1049   {   0, "success" },
1050   {   1, "operationsError" },
1051   {   2, "protocolError" },
1052   {   3, "timeLimitExceeded" },
1053   {   4, "sizeLimitExceeded" },
1054   {   5, "compareFalse" },
1055   {   6, "compareTrue" },
1056   {   7, "authMethodNotSupported" },
1057   {   8, "strongAuthRequired" },
1058   {  10, "referral" },
1059   {  11, "adminLimitExceeded" },
1060   {  12, "unavailableCriticalExtension" },
1061   {  13, "confidentialityRequired" },
1062   {  14, "saslBindInProgress" },
1063   {  16, "noSuchAttribute" },
1064   {  17, "undefinedAttributeType" },
1065   {  18, "inappropriateMatching" },
1066   {  19, "constraintViolation" },
1067   {  20, "attributeOrValueExists" },
1068   {  21, "invalidAttributeSyntax" },
1069   {  32, "noSuchObject" },
1070   {  33, "aliasProblem" },
1071   {  34, "invalidDNSyntax" },
1072   {  36, "aliasDereferencingProblem" },
1073   {  48, "inappropriateAuthentication" },
1074   {  49, "invalidCredentials" },
1075   {  50, "insufficientAccessRights" },
1076   {  51, "busy" },
1077   {  52, "unavailable" },
1078   {  53, "unwillingToPerform" },
1079   {  54, "loopDetect" },
1080   {  64, "namingViolation" },
1081   {  65, "objectClassViolation" },
1082   {  66, "notAllowedOnNonLeaf" },
1083   {  67, "notAllowedOnRDN" },
1084   {  68, "entryAlreadyExists" },
1085   {  69, "objectClassModsProhibited" },
1086   {  71, "affectsMultipleDSAs" },
1087   {  80, "other" },
1088   { 0, NULL }
1089 };
1090
1091
1092 static int
1093 dissect_ldap_BindResponse_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1094 #line 357 "ldap.cnf"
1095
1096   const gchar *valstr;
1097
1098     offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1099                                   &result);
1100
1101
1102   ldap_do_protocolop(pinfo);
1103
1104   if(result) {
1105   
1106     valstr = val_to_str(result, ldap_BindResponse_resultCode_vals, "Unknown result(%u)");
1107
1108     if (check_col(pinfo->cinfo, COL_INFO))
1109       col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", valstr);
1110
1111     if(ldm_tree)
1112       proto_item_append_text(ldm_tree, " %s", valstr); 
1113
1114   }
1115
1116   
1117
1118
1119   return offset;
1120 }
1121 static int dissect_bindResponse_resultCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1122   return dissect_ldap_BindResponse_resultCode(FALSE, tvb, offset, pinfo, tree, hf_ldap_bindResponse_resultCode);
1123 }
1124
1125
1126
1127 static int
1128 dissect_ldap_ErrorMessage(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1129   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1130
1131   return offset;
1132 }
1133 static int dissect_errorMessage(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1134   return dissect_ldap_ErrorMessage(FALSE, tvb, offset, pinfo, tree, hf_ldap_errorMessage);
1135 }
1136
1137
1138
1139 static int
1140 dissect_ldap_LDAPURL(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1141   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1142
1143   return offset;
1144 }
1145 static int dissect_Referral_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1146   return dissect_ldap_LDAPURL(FALSE, tvb, offset, pinfo, tree, hf_ldap_Referral_item);
1147 }
1148 static int dissect_SearchResultReference_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1149   return dissect_ldap_LDAPURL(FALSE, tvb, offset, pinfo, tree, hf_ldap_SearchResultReference_item);
1150 }
1151
1152
1153 static const ber_sequence_t Referral_sequence_of[1] = {
1154   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_Referral_item },
1155 };
1156
1157 static int
1158 dissect_ldap_Referral(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1159   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
1160                                       Referral_sequence_of, hf_index, ett_ldap_Referral);
1161
1162   return offset;
1163 }
1164 static int dissect_referral_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1165   return dissect_ldap_Referral(TRUE, tvb, offset, pinfo, tree, hf_ldap_referral);
1166 }
1167
1168
1169
1170 static int
1171 dissect_ldap_ServerSaslCreds(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1172 #line 179 "ldap.cnf"
1173
1174 tvbuff_t        *parameter_tvb;
1175 ldap_conv_info_t *ldap_info;
1176
1177   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1178                                        &parameter_tvb);
1179
1180         if (!parameter_tvb)
1181                 return offset;
1182         ldap_info = pinfo->private_data;
1183     switch (ldap_info->auth_type) {
1184
1185       /* For Kerberos V4, dissect it as a ticket. */
1186       /* XXX - what about LDAP_AUTH_SIMPLE? */
1187
1188     case LDAP_AUTH_SASL:
1189       /*
1190        * All frames after this are assumed to use a security layer.
1191        *
1192        * XXX - won't work if there's another reply, with the security
1193        * layer, starting in the same TCP segment that ends this
1194        * reply, but as LDAP is a request/response protocol, and
1195        * as the client probably can't start using authentication until
1196        * it gets the bind reply and the server won't send a reply until
1197        * it gets a request, that probably won't happen.
1198        *
1199        * XXX - that assumption is invalid; it's not clear where the
1200        * hell you find out whether there's any security layer.  In
1201        * one capture, we have two GSS-SPNEGO negotiations, both of
1202        * which select MS KRB5, and the only differences in the tokens
1203        * is in the RC4-HMAC ciphertext.  The various
1204        * draft-ietf--cat-sasl-gssapi-NN.txt drafts seem to imply
1205        * that the RFC 2222 spoo with the bitmask and maximum
1206        * output message size stuff is done - but where does that
1207        * stuff show up?  Is it in the ciphertext, which means it's
1208        * presumably encrypted?
1209        *
1210        * Grrr.  We have to do a gross heuristic, checking whether the
1211        * putative LDAP message begins with 0x00 or not, making the
1212        * assumption that we won't have more than 2^24 bytes of
1213        * encapsulated stuff.
1214        */
1215       ldap_info->first_auth_frame = pinfo->fd->num + 1;
1216       if (ldap_info->auth_mech != NULL &&
1217           strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
1218         /*
1219          * This is a GSS-API token.
1220          */
1221         call_dissector(gssapi_handle, parameter_tvb, pinfo, tree);
1222       } else if (ldap_info->auth_mech != NULL &&
1223           strcmp(ldap_info->auth_mech, "GSSAPI") == 0) {
1224         /*
1225          * This is a GSS-API token.
1226          */
1227         call_dissector(gssapi_handle, parameter_tvb, pinfo, tree);
1228                 }
1229         break;
1230         }
1231         pinfo->private_data = ldap_info;
1232
1233
1234
1235   return offset;
1236 }
1237 static int dissect_serverSaslCreds_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1238   return dissect_ldap_ServerSaslCreds(TRUE, tvb, offset, pinfo, tree, hf_ldap_serverSaslCreds);
1239 }
1240
1241
1242 static const ber_sequence_t BindResponse_sequence[] = {
1243   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_bindResponse_resultCode },
1244   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_matchedDN },
1245   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_errorMessage },
1246   { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_referral_impl },
1247   { BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_serverSaslCreds_impl },
1248   { 0, 0, 0, NULL }
1249 };
1250
1251 static int
1252 dissect_ldap_BindResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1253   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1254                                    BindResponse_sequence, hf_index, ett_ldap_BindResponse);
1255
1256   return offset;
1257 }
1258 static int dissect_bindResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1259   return dissect_ldap_BindResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_bindResponse);
1260 }
1261
1262
1263
1264 static int
1265 dissect_ldap_UnbindRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1266 #line 436 "ldap.cnf"
1267
1268  implicit_tag = TRUE; /* correct problem with asn2wrs */
1269
1270    offset = dissect_ber_null(implicit_tag, pinfo, tree, tvb, offset, hf_index);
1271
1272
1273  ldap_do_protocolop(pinfo);  
1274
1275
1276
1277
1278
1279
1280
1281   return offset;
1282 }
1283 static int dissect_unbindRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1284   return dissect_ldap_UnbindRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_unbindRequest);
1285 }
1286
1287
1288 static const value_string ldap_T_scope_vals[] = {
1289   {   0, "baseObject" },
1290   {   1, "singleLevel" },
1291   {   2, "wholeSubtree" },
1292   { 0, NULL }
1293 };
1294
1295
1296 static int
1297 dissect_ldap_T_scope(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1298 #line 316 "ldap.cnf"
1299
1300   gint  scope;
1301   const gchar *valstr;
1302
1303     offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1304                                   &scope);
1305
1306
1307   ldap_do_protocolop(pinfo);
1308
1309   valstr = val_to_str(scope, ldap_T_scope_vals, "Unknown scope(%u)");
1310
1311   if (check_col(pinfo->cinfo, COL_INFO))
1312     col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", valstr);    
1313     
1314   if(ldm_tree)
1315     proto_item_append_text(ldm_tree, " %s", valstr); 
1316
1317
1318
1319   return offset;
1320 }
1321 static int dissect_scope(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1322   return dissect_ldap_T_scope(FALSE, tvb, offset, pinfo, tree, hf_ldap_scope);
1323 }
1324
1325
1326 static const value_string ldap_T_derefAliases_vals[] = {
1327   {   0, "neverDerefAliases" },
1328   {   1, "derefInSearching" },
1329   {   2, "derefFindingBaseObj" },
1330   {   3, "derefAlways" },
1331   { 0, NULL }
1332 };
1333
1334
1335 static int
1336 dissect_ldap_T_derefAliases(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1337   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1338                                   NULL);
1339
1340   return offset;
1341 }
1342 static int dissect_derefAliases(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1343   return dissect_ldap_T_derefAliases(FALSE, tvb, offset, pinfo, tree, hf_ldap_derefAliases);
1344 }
1345
1346
1347
1348 static int
1349 dissect_ldap_INTEGER_0_maxInt(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1350   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1351                                   NULL);
1352
1353   return offset;
1354 }
1355 static int dissect_sizeLimit(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1356   return dissect_ldap_INTEGER_0_maxInt(FALSE, tvb, offset, pinfo, tree, hf_ldap_sizeLimit);
1357 }
1358 static int dissect_timeLimit(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1359   return dissect_ldap_INTEGER_0_maxInt(FALSE, tvb, offset, pinfo, tree, hf_ldap_timeLimit);
1360 }
1361
1362
1363
1364 static int
1365 dissect_ldap_BOOLEAN(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1366 #line 529 "ldap.cnf"
1367         gboolean val;
1368
1369         offset = dissect_ber_boolean_value(implicit_tag, pinfo, tree, tvb, offset, hf_index, &val);
1370
1371         if (hf_index == hf_ldap_dnAttributes) {
1372                 matching_rule_dnattr = val;
1373         }
1374
1375
1376
1377   return offset;
1378 }
1379 static int dissect_criticality(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1380   return dissect_ldap_BOOLEAN(FALSE, tvb, offset, pinfo, tree, hf_ldap_criticality);
1381 }
1382 static int dissect_typesOnly(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1383   return dissect_ldap_BOOLEAN(FALSE, tvb, offset, pinfo, tree, hf_ldap_typesOnly);
1384 }
1385 static int dissect_dnAttributes_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1386   return dissect_ldap_BOOLEAN(TRUE, tvb, offset, pinfo, tree, hf_ldap_dnAttributes);
1387 }
1388 static int dissect_deleteoldrdn(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1389   return dissect_ldap_BOOLEAN(FALSE, tvb, offset, pinfo, tree, hf_ldap_deleteoldrdn);
1390 }
1391
1392
1393
1394 static int
1395 dissect_ldap_T_and_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1396   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1397
1398 #line 470 "ldap.cnf"
1399         if(and_filter_string){
1400                 and_filter_string=ep_strdup_printf("(&%s%s)",and_filter_string,Filter_string);
1401         } else {
1402                 and_filter_string=Filter_string;
1403         }
1404
1405
1406   return offset;
1407 }
1408 static int dissect_and_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1409   return dissect_ldap_T_and_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_and_item);
1410 }
1411
1412
1413 static const ber_sequence_t T_and_set_of[1] = {
1414   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_and_item },
1415 };
1416
1417 static int
1418 dissect_ldap_T_and(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1419 #line 477 "ldap.cnf"
1420         const ber_sequence_t and_set_of[1] = {  { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_and_item },
1421 };
1422         proto_tree *tr=NULL;
1423         proto_item *it=NULL;
1424         char *old_and_filter_string=and_filter_string;
1425
1426         and_filter_string=NULL;
1427         if(tree){
1428                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "and: ");
1429                 tr=proto_item_add_subtree(it, ett_ldap_T_and);
1430         } 
1431         offset = dissect_ber_set_of(implicit_tag, pinfo, tr, tvb, offset,
1432                                  and_set_of, -1, ett_ldap_T_and);
1433
1434         proto_item_append_text(it, "%s", and_filter_string);
1435         Filter_string=ep_strdup_printf("%s",and_filter_string);
1436         and_filter_string=old_and_filter_string;
1437
1438
1439
1440   return offset;
1441 }
1442 static int dissect_and_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1443   return dissect_ldap_T_and(TRUE, tvb, offset, pinfo, tree, hf_ldap_and);
1444 }
1445
1446
1447
1448 static int
1449 dissect_ldap_T_or_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1450   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1451
1452 #line 496 "ldap.cnf"
1453         if(or_filter_string){
1454                 or_filter_string=ep_strdup_printf("(|%s%s)",or_filter_string,Filter_string);
1455         } else {
1456                 or_filter_string=Filter_string;
1457         }
1458
1459
1460
1461   return offset;
1462 }
1463 static int dissect_or_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1464   return dissect_ldap_T_or_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_or_item);
1465 }
1466
1467
1468 static const ber_sequence_t T_or_set_of[1] = {
1469   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_or_item },
1470 };
1471
1472 static int
1473 dissect_ldap_T_or(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1474 #line 504 "ldap.cnf"
1475         const ber_sequence_t or_set_of[1] = {  { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_or_item },
1476 };
1477         proto_tree *tr=NULL;
1478         proto_item *it=NULL;
1479         char *old_or_filter_string=or_filter_string;
1480
1481         or_filter_string=NULL;
1482         if(tree){
1483                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "or: ");
1484                 tr=proto_item_add_subtree(it, ett_ldap_T_or);
1485         } 
1486         offset = dissect_ber_set_of(implicit_tag, pinfo, tr, tvb, offset,
1487                                  or_set_of, -1, ett_ldap_T_or);
1488
1489         proto_item_append_text(it, "%s", or_filter_string);
1490         Filter_string=ep_strdup_printf("%s",or_filter_string);
1491         or_filter_string=old_or_filter_string;
1492
1493
1494
1495   return offset;
1496 }
1497 static int dissect_or_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1498   return dissect_ldap_T_or(TRUE, tvb, offset, pinfo, tree, hf_ldap_or);
1499 }
1500
1501
1502
1503 static int
1504 dissect_ldap_T_not(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1505   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1506
1507 #line 526 "ldap.cnf"
1508         Filter_string=ep_strdup_printf("(!%s)",Filter_string);
1509
1510
1511   return offset;
1512 }
1513 static int dissect_not_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1514   return dissect_ldap_T_not(TRUE, tvb, offset, pinfo, tree, hf_ldap_not);
1515 }
1516
1517
1518
1519 static int
1520 dissect_ldap_AttributeDescription(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1521   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1522
1523   return offset;
1524 }
1525 static int dissect_AttributeDescriptionList_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1526   return dissect_ldap_AttributeDescription(FALSE, tvb, offset, pinfo, tree, hf_ldap_AttributeDescriptionList_item);
1527 }
1528 static int dissect_attributeDesc(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1529   return dissect_ldap_AttributeDescription(FALSE, tvb, offset, pinfo, tree, hf_ldap_attributeDesc);
1530 }
1531 static int dissect_type(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1532   return dissect_ldap_AttributeDescription(FALSE, tvb, offset, pinfo, tree, hf_ldap_type);
1533 }
1534 static int dissect_type_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1535   return dissect_ldap_AttributeDescription(TRUE, tvb, offset, pinfo, tree, hf_ldap_type);
1536 }
1537
1538 static int dissect_assertionValue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1539   return dissect_ldap_AssertionValue(FALSE, tvb, offset, pinfo, tree, hf_ldap_assertionValue);
1540 }
1541 static int dissect_matchValue_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1542   return dissect_ldap_AssertionValue(TRUE, tvb, offset, pinfo, tree, hf_ldap_matchValue);
1543 }
1544
1545
1546 static const ber_sequence_t AttributeValueAssertion_sequence[] = {
1547   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_attributeDesc },
1548   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_assertionValue },
1549   { 0, 0, 0, NULL }
1550 };
1551
1552 static int
1553 dissect_ldap_AttributeValueAssertion(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1554   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1555                                    AttributeValueAssertion_sequence, hf_index, ett_ldap_AttributeValueAssertion);
1556
1557   return offset;
1558 }
1559 static int dissect_ava(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1560   return dissect_ldap_AttributeValueAssertion(FALSE, tvb, offset, pinfo, tree, hf_ldap_ava);
1561 }
1562
1563
1564
1565 static int
1566 dissect_ldap_T_equalityMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1567   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1568
1569 #line 455 "ldap.cnf"
1570         Filter_string=ep_strdup_printf("(%s=%s)",attributedesc_string,ldapvalue_string);
1571
1572
1573
1574   return offset;
1575 }
1576 static int dissect_equalityMatch_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1577   return dissect_ldap_T_equalityMatch(TRUE, tvb, offset, pinfo, tree, hf_ldap_equalityMatch);
1578 }
1579
1580
1581 static const value_string ldap_T_substringFilter_substrings_item_vals[] = {
1582   {   0, "initial" },
1583   {   1, "any" },
1584   {   2, "final" },
1585   { 0, NULL }
1586 };
1587
1588 static const ber_choice_t T_substringFilter_substrings_item_choice[] = {
1589   {   0, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_initial_impl },
1590   {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_any_impl },
1591   {   2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_final_impl },
1592   { 0, 0, 0, 0, NULL }
1593 };
1594
1595 static int
1596 dissect_ldap_T_substringFilter_substrings_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1597   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
1598                                  T_substringFilter_substrings_item_choice, hf_index, ett_ldap_T_substringFilter_substrings_item,
1599                                  NULL);
1600
1601 #line 552 "ldap.cnf"
1602         if (substring_item_final) {
1603                 substring_value=ep_strdup_printf("%s%s",
1604                                                  (substring_value?substring_value:"*"),
1605                                                  substring_item_final);
1606         } else if (substring_item_any) {
1607                 substring_value=ep_strdup_printf("%s%s*",
1608                                                  (substring_value?substring_value:"*"),
1609                                                  substring_item_any);
1610         } else if (substring_item_init) {
1611                 substring_value=ep_strdup_printf("%s*",
1612                                                  substring_item_init);
1613         }
1614
1615
1616   return offset;
1617 }
1618 static int dissect_substringFilter_substrings_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1619   return dissect_ldap_T_substringFilter_substrings_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_substringFilter_substrings_item);
1620 }
1621
1622
1623 static const ber_sequence_t T_substringFilter_substrings_sequence_of[1] = {
1624   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_substringFilter_substrings_item },
1625 };
1626
1627 static int
1628 dissect_ldap_T_substringFilter_substrings(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1629   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
1630                                       T_substringFilter_substrings_sequence_of, hf_index, ett_ldap_T_substringFilter_substrings);
1631
1632   return offset;
1633 }
1634 static int dissect_substringFilter_substrings(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1635   return dissect_ldap_T_substringFilter_substrings(FALSE, tvb, offset, pinfo, tree, hf_ldap_substringFilter_substrings);
1636 }
1637
1638
1639 static const ber_sequence_t SubstringFilter_sequence[] = {
1640   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_type },
1641   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_substringFilter_substrings },
1642   { 0, 0, 0, NULL }
1643 };
1644
1645 static int
1646 dissect_ldap_SubstringFilter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1647 #line 566 "ldap.cnf"
1648         proto_tree *tr=NULL;
1649         proto_item *it=NULL;
1650         char *old_substring_value=substring_value;
1651
1652         substring_value=NULL;
1653         substring_item_init=NULL;
1654         substring_item_any=NULL;
1655         substring_item_final=NULL;
1656         if(tree){
1657                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "substring: ");
1658                 tr=proto_item_add_subtree(it, ett_ldap_SubstringFilter);
1659         }
1660         offset = dissect_ber_sequence(implicit_tag, pinfo, tr, tvb, offset,
1661                                       SubstringFilter_sequence, hf_index,
1662                                       ett_ldap_SubstringFilter);
1663
1664         Filter_string=ep_strdup_printf("(%s=%s)",attr_type,substring_value);
1665         proto_item_append_text(it, "%s", Filter_string);
1666         substring_value=old_substring_value;
1667
1668
1669
1670   return offset;
1671 }
1672 static int dissect_substrings_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1673   return dissect_ldap_SubstringFilter(TRUE, tvb, offset, pinfo, tree, hf_ldap_substrings);
1674 }
1675
1676
1677
1678 static int
1679 dissect_ldap_T_greaterOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1680   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1681
1682 #line 459 "ldap.cnf"
1683         Filter_string=ep_strdup_printf("(%s>=%s)",attributedesc_string,ldapvalue_string);
1684
1685
1686
1687   return offset;
1688 }
1689 static int dissect_greaterOrEqual_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1690   return dissect_ldap_T_greaterOrEqual(TRUE, tvb, offset, pinfo, tree, hf_ldap_greaterOrEqual);
1691 }
1692
1693
1694
1695 static int
1696 dissect_ldap_T_lessOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1697   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1698
1699 #line 463 "ldap.cnf"
1700         Filter_string=ep_strdup_printf("(%s<=%s)",attributedesc_string,ldapvalue_string);
1701
1702
1703
1704   return offset;
1705 }
1706 static int dissect_lessOrEqual_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1707   return dissect_ldap_T_lessOrEqual(TRUE, tvb, offset, pinfo, tree, hf_ldap_lessOrEqual);
1708 }
1709
1710
1711
1712 static int
1713 dissect_ldap_T_present(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1714   offset = dissect_ldap_AttributeDescription(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1715
1716 #line 523 "ldap.cnf"
1717         Filter_string=ep_strdup_printf("(%s=*)",Filter_string);
1718
1719
1720   return offset;
1721 }
1722 static int dissect_present_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1723   return dissect_ldap_T_present(TRUE, tvb, offset, pinfo, tree, hf_ldap_present);
1724 }
1725
1726
1727
1728 static int
1729 dissect_ldap_T_approxMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1730   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1731
1732 #line 467 "ldap.cnf"
1733         Filter_string=ep_strdup_printf("(%s~=%s)",attributedesc_string,ldapvalue_string);
1734
1735
1736   return offset;
1737 }
1738 static int dissect_approxMatch_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1739   return dissect_ldap_T_approxMatch(TRUE, tvb, offset, pinfo, tree, hf_ldap_approxMatch);
1740 }
1741
1742
1743
1744 static int
1745 dissect_ldap_MatchingRuleId(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1746   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1747
1748   return offset;
1749 }
1750 static int dissect_matchingRule_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1751   return dissect_ldap_MatchingRuleId(TRUE, tvb, offset, pinfo, tree, hf_ldap_matchingRule);
1752 }
1753
1754
1755 static const ber_sequence_t MatchingRuleAssertion_sequence[] = {
1756   { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_matchingRule_impl },
1757   { BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_type_impl },
1758   { BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_matchValue_impl },
1759   { BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_dnAttributes_impl },
1760   { 0, 0, 0, NULL }
1761 };
1762
1763 static int
1764 dissect_ldap_MatchingRuleAssertion(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1765   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1766                                    MatchingRuleAssertion_sequence, hf_index, ett_ldap_MatchingRuleAssertion);
1767
1768   return offset;
1769 }
1770
1771
1772
1773 static int
1774 dissect_ldap_T_extensibleMatch(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1775 #line 538 "ldap.cnf"
1776         attr_type=NULL;
1777         matching_rule_string=NULL;
1778         ldapvalue_string=NULL;
1779         matching_rule_dnattr=FALSE;
1780
1781
1782   offset = dissect_ldap_MatchingRuleAssertion(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1783
1784 #line 544 "ldap.cnf"
1785         Filter_string=ep_strdup_printf("(%s:%s%s%s=%s)",
1786                                         (attr_type?attr_type:""),
1787                                         (matching_rule_dnattr?"dn:":""),
1788                                         (matching_rule_string?matching_rule_string:""),
1789                                         (matching_rule_string?":":""),
1790                                         ldapvalue_string);
1791
1792
1793   return offset;
1794 }
1795 static int dissect_extensibleMatch_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1796   return dissect_ldap_T_extensibleMatch(TRUE, tvb, offset, pinfo, tree, hf_ldap_extensibleMatch);
1797 }
1798
1799
1800 static const value_string ldap_Filter_vals[] = {
1801   {   0, "and" },
1802   {   1, "or" },
1803   {   2, "not" },
1804   {   3, "equalityMatch" },
1805   {   4, "substrings" },
1806   {   5, "greaterOrEqual" },
1807   {   6, "lessOrEqual" },
1808   {   7, "present" },
1809   {   8, "approxMatch" },
1810   {   9, "extensibleMatch" },
1811   { 0, NULL }
1812 };
1813
1814 static const ber_choice_t Filter_choice[] = {
1815   {   0, BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_and_impl },
1816   {   1, BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_or_impl },
1817   {   2, BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_not_impl },
1818   {   3, BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_equalityMatch_impl },
1819   {   4, BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_substrings_impl },
1820   {   5, BER_CLASS_CON, 5, BER_FLAGS_IMPLTAG, dissect_greaterOrEqual_impl },
1821   {   6, BER_CLASS_CON, 6, BER_FLAGS_IMPLTAG, dissect_lessOrEqual_impl },
1822   {   7, BER_CLASS_CON, 7, BER_FLAGS_IMPLTAG, dissect_present_impl },
1823   {   8, BER_CLASS_CON, 8, BER_FLAGS_IMPLTAG, dissect_approxMatch_impl },
1824   {   9, BER_CLASS_CON, 9, BER_FLAGS_IMPLTAG, dissect_extensibleMatch_impl },
1825   { 0, 0, 0, 0, NULL }
1826 };
1827
1828 static int
1829 dissect_ldap_Filter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1830 #line 587 "ldap.cnf"
1831         proto_tree *tr=NULL;
1832         proto_item *it=NULL;
1833
1834         if(tree){
1835                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Filter: ");
1836                 tr=proto_item_add_subtree(it, ett_ldap_Filter);
1837         }
1838         offset = dissect_ber_choice(pinfo, tr, tvb, offset,
1839                                  Filter_choice, -1, ett_ldap_Filter,
1840                                  NULL);
1841
1842         proto_item_append_text(it, "%s", Filter_string);
1843
1844
1845
1846   return offset;
1847 }
1848
1849
1850
1851 static int
1852 dissect_ldap_T_filter(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1853 #line 448 "ldap.cnf"
1854         Filter_string=NULL;
1855
1856
1857   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, pinfo, tree, hf_index);
1858
1859 #line 451 "ldap.cnf"
1860         Filter_string=NULL;
1861         and_filter_string=NULL;
1862
1863
1864   return offset;
1865 }
1866 static int dissect_filter(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1867   return dissect_ldap_T_filter(FALSE, tvb, offset, pinfo, tree, hf_ldap_filter);
1868 }
1869
1870
1871 static const ber_sequence_t AttributeDescriptionList_sequence_of[1] = {
1872   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_AttributeDescriptionList_item },
1873 };
1874
1875 static int
1876 dissect_ldap_AttributeDescriptionList(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1877   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
1878                                       AttributeDescriptionList_sequence_of, hf_index, ett_ldap_AttributeDescriptionList);
1879
1880   return offset;
1881 }
1882 static int dissect_searchRequest_attributes(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1883   return dissect_ldap_AttributeDescriptionList(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchRequest_attributes);
1884 }
1885
1886
1887 static const ber_sequence_t SearchRequest_sequence[] = {
1888   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_baseObject },
1889   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_scope },
1890   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_derefAliases },
1891   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_sizeLimit },
1892   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_timeLimit },
1893   { BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_NOOWNTAG, dissect_typesOnly },
1894   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_filter },
1895   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_searchRequest_attributes },
1896   { 0, 0, 0, NULL }
1897 };
1898
1899 static int
1900 dissect_ldap_SearchRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1901   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1902                                    SearchRequest_sequence, hf_index, ett_ldap_SearchRequest);
1903
1904   return offset;
1905 }
1906 static int dissect_searchRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1907   return dissect_ldap_SearchRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchRequest);
1908 }
1909
1910
1911
1912 static int
1913 dissect_ldap_AttributeValue(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1914 #line 378 "ldap.cnf"
1915
1916   tvbuff_t      *next_tvb;
1917   gchar         *string;
1918   guint32       i, len;
1919   proto_item    *pi;
1920   int           old_offset = offset;
1921
1922   /* extract the value of the octetstring */
1923   offset = dissect_ber_octet_string(FALSE, pinfo, NULL, tvb, offset, hf_index, &next_tvb);
1924
1925   /* if we have an attribute type that isn't binary see if there is a better dissector */
1926   if(!attr_type || !dissector_try_string(ldap_name_dissector_table, attr_type, next_tvb, pinfo, tree)) {
1927         offset = old_offset;
1928         
1929         /* do the default thing */
1930           offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
1931                                        NULL);
1932         
1933
1934   } 
1935
1936   len = tvb_length_remaining(next_tvb, 0);
1937   
1938   for(i = 0; i < len; i++) 
1939     if(!g_ascii_isprint(tvb_get_guint8(next_tvb, i)))
1940       break;
1941   
1942   if(i == len) {
1943     string = tvb_get_string(next_tvb, 0, tvb_length_remaining(next_tvb, 0));
1944  
1945     pi = get_ber_last_created_item();
1946      
1947     proto_item_set_text(pi, "%s", string);
1948
1949   }
1950   
1951
1952
1953   return offset;
1954 }
1955 static int dissect_vals_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1956   return dissect_ldap_AttributeValue(FALSE, tvb, offset, pinfo, tree, hf_ldap_vals_item);
1957 }
1958
1959
1960 static const ber_sequence_t SET_OF_AttributeValue_set_of[1] = {
1961   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_vals_item },
1962 };
1963
1964 static int
1965 dissect_ldap_SET_OF_AttributeValue(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1966   offset = dissect_ber_set_of(implicit_tag, pinfo, tree, tvb, offset,
1967                                  SET_OF_AttributeValue_set_of, hf_index, ett_ldap_SET_OF_AttributeValue);
1968
1969   return offset;
1970 }
1971 static int dissect_vals(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1972   return dissect_ldap_SET_OF_AttributeValue(FALSE, tvb, offset, pinfo, tree, hf_ldap_vals);
1973 }
1974
1975
1976 static const ber_sequence_t PartialAttributeList_item_sequence[] = {
1977   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_type },
1978   { BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_vals },
1979   { 0, 0, 0, NULL }
1980 };
1981
1982 static int
1983 dissect_ldap_PartialAttributeList_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
1984   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
1985                                    PartialAttributeList_item_sequence, hf_index, ett_ldap_PartialAttributeList_item);
1986
1987   return offset;
1988 }
1989 static int dissect_PartialAttributeList_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
1990   return dissect_ldap_PartialAttributeList_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_PartialAttributeList_item);
1991 }
1992
1993
1994 static const ber_sequence_t PartialAttributeList_sequence_of[1] = {
1995   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_PartialAttributeList_item },
1996 };
1997
1998 static int
1999 dissect_ldap_PartialAttributeList(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2000   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
2001                                       PartialAttributeList_sequence_of, hf_index, ett_ldap_PartialAttributeList);
2002
2003   return offset;
2004 }
2005 static int dissect_searchResultEntry_attributes(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2006   return dissect_ldap_PartialAttributeList(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchResultEntry_attributes);
2007 }
2008
2009
2010 static const ber_sequence_t SearchResultEntry_sequence[] = {
2011   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_objectName },
2012   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_searchResultEntry_attributes },
2013   { 0, 0, 0, NULL }
2014 };
2015
2016 static int
2017 dissect_ldap_SearchResultEntry(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2018   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2019                                    SearchResultEntry_sequence, hf_index, ett_ldap_SearchResultEntry);
2020
2021   return offset;
2022 }
2023 static int dissect_searchResEntry(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2024   return dissect_ldap_SearchResultEntry(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchResEntry);
2025 }
2026
2027
2028 static const value_string ldap_T_resultCode_vals[] = {
2029   {   0, "success" },
2030   {   1, "operationsError" },
2031   {   2, "protocolError" },
2032   {   3, "timeLimitExceeded" },
2033   {   4, "sizeLimitExceeded" },
2034   {   5, "compareFalse" },
2035   {   6, "compareTrue" },
2036   {   7, "authMethodNotSupported" },
2037   {   8, "strongAuthRequired" },
2038   {  10, "referral" },
2039   {  11, "adminLimitExceeded" },
2040   {  12, "unavailableCriticalExtension" },
2041   {  13, "confidentialityRequired" },
2042   {  14, "saslBindInProgress" },
2043   {  16, "noSuchAttribute" },
2044   {  17, "undefinedAttributeType" },
2045   {  18, "inappropriateMatching" },
2046   {  19, "constraintViolation" },
2047   {  20, "attributeOrValueExists" },
2048   {  21, "invalidAttributeSyntax" },
2049   {  32, "noSuchObject" },
2050   {  33, "aliasProblem" },
2051   {  34, "invalidDNSyntax" },
2052   {  36, "aliasDereferencingProblem" },
2053   {  48, "inappropriateAuthentication" },
2054   {  49, "invalidCredentials" },
2055   {  50, "insufficientAccessRights" },
2056   {  51, "busy" },
2057   {  52, "unavailable" },
2058   {  53, "unwillingToPerform" },
2059   {  54, "loopDetect" },
2060   {  64, "namingViolation" },
2061   {  65, "objectClassViolation" },
2062   {  66, "notAllowedOnNonLeaf" },
2063   {  67, "notAllowedOnRDN" },
2064   {  68, "entryAlreadyExists" },
2065   {  69, "objectClassModsProhibited" },
2066   {  71, "affectsMultipleDSAs" },
2067   {  80, "other" },
2068   { 0, NULL }
2069 };
2070
2071
2072 static int
2073 dissect_ldap_T_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2074 #line 335 "ldap.cnf"
2075
2076   const gchar *valstr;
2077
2078     offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
2079                                   &result);
2080
2081
2082   ldap_do_protocolop(pinfo);
2083
2084   if(result) {
2085   
2086     valstr = val_to_str(result, ldap_T_resultCode_vals, "Unknown result(%u)");
2087
2088     if (check_col(pinfo->cinfo, COL_INFO))
2089       col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", valstr);
2090
2091     if(ldm_tree)
2092       proto_item_append_text(ldm_tree, " %s", valstr); 
2093
2094   }
2095
2096
2097
2098   return offset;
2099 }
2100 static int dissect_resultCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2101   return dissect_ldap_T_resultCode(FALSE, tvb, offset, pinfo, tree, hf_ldap_resultCode);
2102 }
2103
2104
2105 static const ber_sequence_t LDAPResult_sequence[] = {
2106   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_resultCode },
2107   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_matchedDN },
2108   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_errorMessage },
2109   { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_referral_impl },
2110   { 0, 0, 0, NULL }
2111 };
2112
2113 static int
2114 dissect_ldap_LDAPResult(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2115   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2116                                    LDAPResult_sequence, hf_index, ett_ldap_LDAPResult);
2117
2118   return offset;
2119 }
2120
2121
2122
2123 static int
2124 dissect_ldap_SearchResultDone(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2125   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2126
2127   return offset;
2128 }
2129 static int dissect_searchResDone(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2130   return dissect_ldap_SearchResultDone(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchResDone);
2131 }
2132
2133
2134 static const ber_sequence_t SearchResultReference_sequence_of[1] = {
2135   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_SearchResultReference_item },
2136 };
2137
2138 static int
2139 dissect_ldap_SearchResultReference(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2140   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
2141                                       SearchResultReference_sequence_of, hf_index, ett_ldap_SearchResultReference);
2142
2143   return offset;
2144 }
2145 static int dissect_searchResRef(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2146   return dissect_ldap_SearchResultReference(FALSE, tvb, offset, pinfo, tree, hf_ldap_searchResRef);
2147 }
2148
2149
2150 static const value_string ldap_T_operation_vals[] = {
2151   {   0, "add" },
2152   {   1, "delete" },
2153   {   2, "replace" },
2154   { 0, NULL }
2155 };
2156
2157
2158 static int
2159 dissect_ldap_T_operation(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2160   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
2161                                   NULL);
2162
2163   return offset;
2164 }
2165 static int dissect_operation(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2166   return dissect_ldap_T_operation(FALSE, tvb, offset, pinfo, tree, hf_ldap_operation);
2167 }
2168
2169
2170 static const ber_sequence_t AttributeTypeAndValues_sequence[] = {
2171   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_type },
2172   { BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_vals },
2173   { 0, 0, 0, NULL }
2174 };
2175
2176 static int
2177 dissect_ldap_AttributeTypeAndValues(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2178   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2179                                    AttributeTypeAndValues_sequence, hf_index, ett_ldap_AttributeTypeAndValues);
2180
2181   return offset;
2182 }
2183 static int dissect_modification(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2184   return dissect_ldap_AttributeTypeAndValues(FALSE, tvb, offset, pinfo, tree, hf_ldap_modification);
2185 }
2186
2187
2188 static const ber_sequence_t T_modifyRequest_modification_item_sequence[] = {
2189   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_operation },
2190   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_modification },
2191   { 0, 0, 0, NULL }
2192 };
2193
2194 static int
2195 dissect_ldap_T_modifyRequest_modification_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2196   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2197                                    T_modifyRequest_modification_item_sequence, hf_index, ett_ldap_T_modifyRequest_modification_item);
2198
2199   return offset;
2200 }
2201 static int dissect_modifyRequest_modification_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2202   return dissect_ldap_T_modifyRequest_modification_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_modifyRequest_modification_item);
2203 }
2204
2205
2206 static const ber_sequence_t ModifyRequest_modification_sequence_of[1] = {
2207   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_modifyRequest_modification_item },
2208 };
2209
2210 static int
2211 dissect_ldap_ModifyRequest_modification(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2212   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
2213                                       ModifyRequest_modification_sequence_of, hf_index, ett_ldap_ModifyRequest_modification);
2214
2215   return offset;
2216 }
2217 static int dissect_modifyRequest_modification(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2218   return dissect_ldap_ModifyRequest_modification(FALSE, tvb, offset, pinfo, tree, hf_ldap_modifyRequest_modification);
2219 }
2220
2221
2222 static const ber_sequence_t ModifyRequest_sequence[] = {
2223   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_object },
2224   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_modifyRequest_modification },
2225   { 0, 0, 0, NULL }
2226 };
2227
2228 static int
2229 dissect_ldap_ModifyRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2230   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2231                                    ModifyRequest_sequence, hf_index, ett_ldap_ModifyRequest);
2232
2233   return offset;
2234 }
2235 static int dissect_modifyRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2236   return dissect_ldap_ModifyRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_modifyRequest);
2237 }
2238
2239
2240
2241 static int
2242 dissect_ldap_ModifyResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2243   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2244
2245   return offset;
2246 }
2247 static int dissect_modifyResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2248   return dissect_ldap_ModifyResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_modifyResponse);
2249 }
2250
2251
2252 static const ber_sequence_t AttributeList_item_sequence[] = {
2253   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_type },
2254   { BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_vals },
2255   { 0, 0, 0, NULL }
2256 };
2257
2258 static int
2259 dissect_ldap_AttributeList_item(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2260   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2261                                    AttributeList_item_sequence, hf_index, ett_ldap_AttributeList_item);
2262
2263   return offset;
2264 }
2265 static int dissect_AttributeList_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2266   return dissect_ldap_AttributeList_item(FALSE, tvb, offset, pinfo, tree, hf_ldap_AttributeList_item);
2267 }
2268
2269
2270 static const ber_sequence_t AttributeList_sequence_of[1] = {
2271   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_AttributeList_item },
2272 };
2273
2274 static int
2275 dissect_ldap_AttributeList(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2276   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
2277                                       AttributeList_sequence_of, hf_index, ett_ldap_AttributeList);
2278
2279   return offset;
2280 }
2281 static int dissect_attributes(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2282   return dissect_ldap_AttributeList(FALSE, tvb, offset, pinfo, tree, hf_ldap_attributes);
2283 }
2284
2285
2286 static const ber_sequence_t AddRequest_sequence[] = {
2287   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_entry },
2288   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_attributes },
2289   { 0, 0, 0, NULL }
2290 };
2291
2292 static int
2293 dissect_ldap_AddRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2294   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2295                                    AddRequest_sequence, hf_index, ett_ldap_AddRequest);
2296
2297   return offset;
2298 }
2299 static int dissect_addRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2300   return dissect_ldap_AddRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_addRequest);
2301 }
2302
2303
2304
2305 static int
2306 dissect_ldap_AddResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2307   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2308
2309   return offset;
2310 }
2311 static int dissect_addResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2312   return dissect_ldap_AddResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_addResponse);
2313 }
2314
2315
2316
2317 static int
2318 dissect_ldap_DelRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2319   offset = dissect_ldap_LDAPDN(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2320
2321   return offset;
2322 }
2323 static int dissect_delRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2324   return dissect_ldap_DelRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_delRequest);
2325 }
2326
2327
2328
2329 static int
2330 dissect_ldap_DelResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2331   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2332
2333   return offset;
2334 }
2335 static int dissect_delResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2336   return dissect_ldap_DelResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_delResponse);
2337 }
2338
2339
2340
2341 static int
2342 dissect_ldap_RelativeLDAPDN(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2343   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2344
2345   return offset;
2346 }
2347 static int dissect_newrdn(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2348   return dissect_ldap_RelativeLDAPDN(FALSE, tvb, offset, pinfo, tree, hf_ldap_newrdn);
2349 }
2350
2351
2352 static const ber_sequence_t ModifyDNRequest_sequence[] = {
2353   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_entry },
2354   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_newrdn },
2355   { BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_NOOWNTAG, dissect_deleteoldrdn },
2356   { BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_newSuperior_impl },
2357   { 0, 0, 0, NULL }
2358 };
2359
2360 static int
2361 dissect_ldap_ModifyDNRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2362   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2363                                    ModifyDNRequest_sequence, hf_index, ett_ldap_ModifyDNRequest);
2364
2365   return offset;
2366 }
2367 static int dissect_modDNRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2368   return dissect_ldap_ModifyDNRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_modDNRequest);
2369 }
2370
2371
2372
2373 static int
2374 dissect_ldap_ModifyDNResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2375   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2376
2377   return offset;
2378 }
2379 static int dissect_modDNResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2380   return dissect_ldap_ModifyDNResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_modDNResponse);
2381 }
2382
2383
2384 static const ber_sequence_t CompareRequest_sequence[] = {
2385   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_entry },
2386   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ava },
2387   { 0, 0, 0, NULL }
2388 };
2389
2390 static int
2391 dissect_ldap_CompareRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2392   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2393                                    CompareRequest_sequence, hf_index, ett_ldap_CompareRequest);
2394
2395   return offset;
2396 }
2397 static int dissect_compareRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2398   return dissect_ldap_CompareRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_compareRequest);
2399 }
2400
2401
2402
2403 static int
2404 dissect_ldap_CompareResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2405   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2406
2407   return offset;
2408 }
2409 static int dissect_compareResponse(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2410   return dissect_ldap_CompareResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_compareResponse);
2411 }
2412
2413
2414
2415 static int
2416 dissect_ldap_AbandonRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2417   offset = dissect_ldap_MessageID(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2418
2419   return offset;
2420 }
2421 static int dissect_abandonRequest(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2422   return dissect_ldap_AbandonRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_abandonRequest);
2423 }
2424
2425
2426
2427 static int
2428 dissect_ldap_LDAPOID(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2429 #line 33 "ldap.cnf"
2430
2431         tvbuff_t        *parameter_tvb;
2432         const gchar *name;
2433         proto_item      *item = NULL;
2434
2435
2436
2437   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
2438                                        &parameter_tvb);
2439
2440 #line 40 "ldap.cnf"
2441         if (!parameter_tvb)
2442                 return offset;
2443         item = get_ber_last_created_item();
2444         name = get_oid_str_name(tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0)));
2445         if(name){
2446                 proto_item_append_text(item, " (%s)", name);
2447                 proto_item_append_text(tree, " %s", name);      
2448         }
2449
2450
2451
2452   return offset;
2453 }
2454 static int dissect_requestName_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2455   return dissect_ldap_LDAPOID(TRUE, tvb, offset, pinfo, tree, hf_ldap_requestName);
2456 }
2457
2458
2459
2460 static int
2461 dissect_ldap_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2462   offset = dissect_ber_octet_string(implicit_tag, pinfo, tree, tvb, offset, hf_index,
2463                                        NULL);
2464
2465   return offset;
2466 }
2467 static int dissect_controlValue(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2468   return dissect_ldap_OCTET_STRING(FALSE, tvb, offset, pinfo, tree, hf_ldap_controlValue);
2469 }
2470 static int dissect_requestValue_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2471   return dissect_ldap_OCTET_STRING(TRUE, tvb, offset, pinfo, tree, hf_ldap_requestValue);
2472 }
2473 static int dissect_response_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2474   return dissect_ldap_OCTET_STRING(TRUE, tvb, offset, pinfo, tree, hf_ldap_response);
2475 }
2476
2477
2478 static const ber_sequence_t ExtendedRequest_sequence[] = {
2479   { BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_requestName_impl },
2480   { BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_requestValue_impl },
2481   { 0, 0, 0, NULL }
2482 };
2483
2484 static int
2485 dissect_ldap_ExtendedRequest(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2486   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2487                                    ExtendedRequest_sequence, hf_index, ett_ldap_ExtendedRequest);
2488
2489   return offset;
2490 }
2491 static int dissect_extendedReq(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2492   return dissect_ldap_ExtendedRequest(FALSE, tvb, offset, pinfo, tree, hf_ldap_extendedReq);
2493 }
2494
2495
2496 static const value_string ldap_ExtendedResponse_resultCode_vals[] = {
2497   {   0, "success" },
2498   {   1, "operationsError" },
2499   {   2, "protocolError" },
2500   {   3, "timeLimitExceeded" },
2501   {   4, "sizeLimitExceeded" },
2502   {   5, "compareFalse" },
2503   {   6, "compareTrue" },
2504   {   7, "authMethodNotSupported" },
2505   {   8, "strongAuthRequired" },
2506   {  10, "referral" },
2507   {  11, "adminLimitExceeded" },
2508   {  12, "unavailableCriticalExtension" },
2509   {  13, "confidentialityRequired" },
2510   {  14, "saslBindInProgress" },
2511   {  16, "noSuchAttribute" },
2512   {  17, "undefinedAttributeType" },
2513   {  18, "inappropriateMatching" },
2514   {  19, "constraintViolation" },
2515   {  20, "attributeOrValueExists" },
2516   {  21, "invalidAttributeSyntax" },
2517   {  32, "noSuchObject" },
2518   {  33, "aliasProblem" },
2519   {  34, "invalidDNSyntax" },
2520   {  36, "aliasDereferencingProblem" },
2521   {  48, "inappropriateAuthentication" },
2522   {  49, "invalidCredentials" },
2523   {  50, "insufficientAccessRights" },
2524   {  51, "busy" },
2525   {  52, "unavailable" },
2526   {  53, "unwillingToPerform" },
2527   {  54, "loopDetect" },
2528   {  64, "namingViolation" },
2529   {  65, "objectClassViolation" },
2530   {  66, "notAllowedOnNonLeaf" },
2531   {  67, "notAllowedOnRDN" },
2532   {  68, "entryAlreadyExists" },
2533   {  69, "objectClassModsProhibited" },
2534   {  71, "affectsMultipleDSAs" },
2535   {  80, "other" },
2536   { 0, NULL }
2537 };
2538
2539
2540 static int
2541 dissect_ldap_ExtendedResponse_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2542   offset = dissect_ber_integer(implicit_tag, pinfo, tree, tvb, offset, hf_index,
2543                                   NULL);
2544
2545   return offset;
2546 }
2547 static int dissect_extendedResponse_resultCode(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2548   return dissect_ldap_ExtendedResponse_resultCode(FALSE, tvb, offset, pinfo, tree, hf_ldap_extendedResponse_resultCode);
2549 }
2550
2551
2552
2553 static int
2554 dissect_ldap_ResponseName(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2555   offset = dissect_ldap_LDAPOID(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2556
2557   return offset;
2558 }
2559 static int dissect_responseName_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2560   return dissect_ldap_ResponseName(TRUE, tvb, offset, pinfo, tree, hf_ldap_responseName);
2561 }
2562
2563
2564 static const ber_sequence_t ExtendedResponse_sequence[] = {
2565   { BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_extendedResponse_resultCode },
2566   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_matchedDN },
2567   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_errorMessage },
2568   { BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_referral_impl },
2569   { BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_responseName_impl },
2570   { BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_response_impl },
2571   { 0, 0, 0, NULL }
2572 };
2573
2574 static int
2575 dissect_ldap_ExtendedResponse(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2576   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2577                                    ExtendedResponse_sequence, hf_index, ett_ldap_ExtendedResponse);
2578
2579   return offset;
2580 }
2581 static int dissect_extendedResp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2582   return dissect_ldap_ExtendedResponse(FALSE, tvb, offset, pinfo, tree, hf_ldap_extendedResp);
2583 }
2584
2585
2586 static const value_string ldap_ProtocolOp_vals[] = {
2587   {   0, "bindRequest" },
2588   {   1, "bindResponse" },
2589   {   2, "unbindRequest" },
2590   {   3, "searchRequest" },
2591   {   4, "searchResEntry" },
2592   {   5, "searchResDone" },
2593   {  19, "searchResRef" },
2594   {   6, "modifyRequest" },
2595   {   7, "modifyResponse" },
2596   {   8, "addRequest" },
2597   {   9, "addResponse" },
2598   {  10, "delRequest" },
2599   {  11, "delResponse" },
2600   {  12, "modDNRequest" },
2601   {  13, "modDNResponse" },
2602   {  14, "compareRequest" },
2603   {  15, "compareResponse" },
2604   {  16, "abandonRequest" },
2605   {  23, "extendedReq" },
2606   {  24, "extendedResp" },
2607   { 0, NULL }
2608 };
2609
2610 static const ber_choice_t ProtocolOp_choice[] = {
2611   {   0, BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_bindRequest },
2612   {   1, BER_CLASS_APP, 1, BER_FLAGS_NOOWNTAG, dissect_bindResponse },
2613   {   2, BER_CLASS_APP, 2, BER_FLAGS_NOOWNTAG, dissect_unbindRequest },
2614   {   3, BER_CLASS_APP, 3, BER_FLAGS_NOOWNTAG, dissect_searchRequest },
2615   {   4, BER_CLASS_APP, 4, BER_FLAGS_NOOWNTAG, dissect_searchResEntry },
2616   {   5, BER_CLASS_APP, 5, BER_FLAGS_NOOWNTAG, dissect_searchResDone },
2617   {  19, BER_CLASS_APP, 19, BER_FLAGS_NOOWNTAG, dissect_searchResRef },
2618   {   6, BER_CLASS_APP, 6, BER_FLAGS_NOOWNTAG, dissect_modifyRequest },
2619   {   7, BER_CLASS_APP, 7, BER_FLAGS_NOOWNTAG, dissect_modifyResponse },
2620   {   8, BER_CLASS_APP, 8, BER_FLAGS_NOOWNTAG, dissect_addRequest },
2621   {   9, BER_CLASS_APP, 9, BER_FLAGS_NOOWNTAG, dissect_addResponse },
2622   {  10, BER_CLASS_APP, 10, BER_FLAGS_NOOWNTAG, dissect_delRequest },
2623   {  11, BER_CLASS_APP, 11, BER_FLAGS_NOOWNTAG, dissect_delResponse },
2624   {  12, BER_CLASS_APP, 12, BER_FLAGS_NOOWNTAG, dissect_modDNRequest },
2625   {  13, BER_CLASS_APP, 13, BER_FLAGS_NOOWNTAG, dissect_modDNResponse },
2626   {  14, BER_CLASS_APP, 14, BER_FLAGS_NOOWNTAG, dissect_compareRequest },
2627   {  15, BER_CLASS_APP, 15, BER_FLAGS_NOOWNTAG, dissect_compareResponse },
2628   {  16, BER_CLASS_APP, 16, BER_FLAGS_NOOWNTAG, dissect_abandonRequest },
2629   {  23, BER_CLASS_APP, 23, BER_FLAGS_NOOWNTAG, dissect_extendedReq },
2630   {  24, BER_CLASS_APP, 24, BER_FLAGS_NOOWNTAG, dissect_extendedResp },
2631   { 0, 0, 0, 0, NULL }
2632 };
2633
2634 static int
2635 dissect_ldap_ProtocolOp(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2636 #line 61 "ldap.cnf"
2637
2638   ldap_call_response_t *lcrp;
2639   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)pinfo->private_data;
2640   do_protocolop = TRUE;
2641
2642
2643   offset = dissect_ber_choice(pinfo, tree, tvb, offset,
2644                                  ProtocolOp_choice, hf_index, ett_ldap_ProtocolOp,
2645                                  &ProtocolOp);
2646
2647 #line 67 "ldap.cnf"
2648
2649   lcrp=ldap_match_call_response(tvb, pinfo, tree, MessageID, ProtocolOp);
2650   if(lcrp){
2651     tap_queue_packet(ldap_tap, pinfo, lcrp);
2652   }
2653   
2654   /* XXX: the count will not work if the results span multiple TCP packets */
2655
2656   if(ldap_info && tree) { /* only count once - on tree pass */
2657     switch(ProtocolOp) {
2658   
2659     case LDAP_RES_SEARCH_ENTRY:
2660         ldap_info->num_results++;
2661
2662         proto_item_append_text(tree, " [%d result%s]", 
2663                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2664
2665         break;
2666
2667     case LDAP_RES_SEARCH_RESULT:
2668   
2669         if (check_col(pinfo->cinfo, COL_INFO))
2670           col_append_fstr(pinfo->cinfo, COL_INFO, " [%d result%s]", 
2671                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2672                         
2673         proto_item_append_text(tree, " [%d result%s]", 
2674                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2675                         
2676         ldap_info->num_results = 0;
2677         break;
2678      default:
2679         break;
2680     } 
2681   }
2682   
2683
2684   return offset;
2685 }
2686 static int dissect_protocolOp(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2687   return dissect_ldap_ProtocolOp(FALSE, tvb, offset, pinfo, tree, hf_ldap_protocolOp);
2688 }
2689
2690
2691
2692 static int
2693 dissect_ldap_ControlType(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2694   offset = dissect_ldap_LDAPOID(implicit_tag, tvb, offset, pinfo, tree, hf_index);
2695
2696   return offset;
2697 }
2698 static int dissect_controlType(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2699   return dissect_ldap_ControlType(FALSE, tvb, offset, pinfo, tree, hf_ldap_controlType);
2700 }
2701
2702
2703 static const ber_sequence_t Control_sequence[] = {
2704   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_controlType },
2705   { BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_criticality },
2706   { BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_controlValue },
2707   { 0, 0, 0, NULL }
2708 };
2709
2710 static int
2711 dissect_ldap_Control(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2712   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2713                                    Control_sequence, hf_index, ett_ldap_Control);
2714
2715   return offset;
2716 }
2717 static int dissect_Controls_item(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2718   return dissect_ldap_Control(FALSE, tvb, offset, pinfo, tree, hf_ldap_Controls_item);
2719 }
2720
2721
2722 static const ber_sequence_t Controls_sequence_of[1] = {
2723   { BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_Controls_item },
2724 };
2725
2726 static int
2727 dissect_ldap_Controls(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2728   offset = dissect_ber_sequence_of(implicit_tag, pinfo, tree, tvb, offset,
2729                                       Controls_sequence_of, hf_index, ett_ldap_Controls);
2730
2731   return offset;
2732 }
2733 static int dissect_controls_impl(packet_info *pinfo, proto_tree *tree, tvbuff_t *tvb, int offset) {
2734   return dissect_ldap_Controls(TRUE, tvb, offset, pinfo, tree, hf_ldap_controls);
2735 }
2736
2737
2738 static const ber_sequence_t LDAPMessage_sequence[] = {
2739   { BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_messageID },
2740   { BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_protocolOp },
2741   { BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_controls_impl },
2742   { 0, 0, 0, NULL }
2743 };
2744
2745 static int
2746 dissect_ldap_LDAPMessage(gboolean implicit_tag _U_, tvbuff_t *tvb, int offset, packet_info *pinfo _U_, proto_tree *tree, int hf_index _U_) {
2747   offset = dissect_ber_sequence(implicit_tag, pinfo, tree, tvb, offset,
2748                                    LDAPMessage_sequence, hf_index, ett_ldap_LDAPMessage);
2749
2750   return offset;
2751 }
2752
2753
2754
2755 /*--- PDUs ---*/
2756
2757 static void dissect_LDAPMessage_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
2758   dissect_ldap_LDAPMessage(FALSE, tvb, 0, pinfo, tree, hf_ldap_LDAPMessage_PDU);
2759 }
2760
2761
2762 /*--- End of included file: packet-ldap-fn.c ---*/
2763 #line 525 "packet-ldap-template.c"
2764
2765 static void
2766 dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
2767                      proto_tree *tree, ldap_conv_info_t *ldap_info,
2768                      gboolean rest_is_pad, gboolean is_mscldap)
2769 {
2770   int offset = 0;
2771   gboolean first_time = TRUE;
2772   guint length_remaining;
2773   guint msg_len = 0;
2774   int messageOffset = 0;
2775   guint headerLength = 0;
2776   guint length = 0;
2777   tvbuff_t *msg_tvb = NULL;
2778   gint8 class;
2779   gboolean pc, ind = 0;
2780   gint32 ber_tag;
2781
2782   while (tvb_reported_length_remaining(tvb, offset) > 0) {
2783     /*
2784      * This will throw an exception if we don't have any data left.
2785      * That's what we want.  (See "tcp_dissect_pdus()", which is
2786      * similar)
2787      */
2788     length_remaining = tvb_ensure_length_remaining(tvb, offset);
2789
2790     if (rest_is_pad && length_remaining < 6) return;
2791
2792     /*
2793      * OK, try to read the "Sequence Of" header; this gets the total
2794      * length of the LDAP message.
2795      */
2796         messageOffset = get_ber_identifier(tvb, offset, &class, &pc, &ber_tag);
2797         messageOffset = get_ber_length(tree, tvb, messageOffset, &msg_len, &ind);
2798
2799     if (ber_tag == BER_UNI_TAG_SEQUENCE) {
2800         /*
2801          * Add the length of the "Sequence Of" header to the message
2802          * length.
2803          */
2804         headerLength = messageOffset - offset;
2805         msg_len += headerLength;
2806         if (msg_len < headerLength) {
2807             /*
2808              * The message length was probably so large that the total length
2809              * overflowed.
2810              *
2811              * Report this as an error.
2812              */
2813             show_reported_bounds_error(tvb, pinfo, tree);
2814             return;
2815         }
2816     } else {
2817         /*
2818          * We couldn't parse the header; just make it the amount of data
2819          * remaining in the tvbuff, so we'll give up on this segment
2820          * after attempting to parse the message - there's nothing more
2821          * we can do.  "dissect_ldap_message()" will display the error.
2822          */
2823         msg_len = length_remaining;
2824     }
2825
2826     /*
2827      * Construct a tvbuff containing the amount of the payload we have
2828      * available.  Make its reported length the amount of data in the
2829      * LDAP message.
2830      *
2831      * XXX - if reassembly isn't enabled. the subdissector will throw a
2832      * BoundsError exception, rather than a ReportedBoundsError exception.
2833      * We really want a tvbuff where the length is "length", the reported
2834      * length is "plen", and the "if the snapshot length were infinite"
2835      * length is the minimum of the reported length of the tvbuff handed
2836      * to us and "plen", with a new type of exception thrown if the offset
2837      * is within the reported length but beyond that third length, with
2838      * that exception getting the "Unreassembled Packet" error.
2839      */
2840     length = length_remaining;
2841     if (length > msg_len) length = msg_len;
2842     msg_tvb = tvb_new_subset(tvb, offset, length, msg_len);
2843
2844     /*
2845      * Now dissect the LDAP message.
2846      */
2847
2848     /*dissect_ldap_message(msg_tvb, 0, pinfo, msg_tree, msg_item, first_time, ldap_info, is_mscldap);*/
2849         ldap_info->first_time= first_time;
2850         ldap_info->is_mscldap = is_mscldap;
2851         pinfo->private_data = ldap_info;
2852         dissect_LDAPMessage_PDU(msg_tvb, pinfo, tree);
2853
2854
2855     offset += msg_len;
2856
2857     first_time = FALSE;
2858   }
2859 }
2860
2861 static void
2862 dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_mscldap)
2863 {
2864   int offset = 0;
2865   conversation_t *conversation;
2866   gboolean doing_sasl_security = FALSE;
2867   guint length_remaining;
2868   ldap_conv_info_t *ldap_info = NULL;
2869   proto_item *ldap_item = NULL;
2870   proto_tree *ldap_tree = NULL;
2871
2872   ldm_tree = NULL;
2873
2874   /*
2875    * Do we have a conversation for this connection?
2876    */
2877   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2878                                    pinfo->ptype, pinfo->srcport,
2879                                    pinfo->destport, 0);
2880   if (conversation == NULL) {
2881     /* We don't yet have a conversation, so create one. */
2882     conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2883                                     pinfo->ptype, pinfo->srcport,
2884                                     pinfo->destport, 0);
2885
2886   }
2887
2888   /*
2889    * Do we already have a type and mechanism?
2890    */
2891   ldap_info = conversation_get_proto_data(conversation, proto_ldap);
2892   if (ldap_info == NULL) {
2893     /* No.  Attach that information to the conversation, and add
2894      * it to the list of information structures.
2895      */
2896     ldap_info = se_alloc(sizeof(ldap_conv_info_t));
2897     ldap_info->auth_type = 0;
2898     ldap_info->auth_mech = 0;
2899     ldap_info->first_auth_frame = 0;
2900     ldap_info->matched=g_hash_table_new(ldap_info_hash_matched, ldap_info_equal_matched);
2901     ldap_info->unmatched=g_hash_table_new(ldap_info_hash_unmatched, ldap_info_equal_unmatched);
2902     ldap_info->num_results = 0;
2903
2904     conversation_add_proto_data(conversation, proto_ldap, ldap_info);
2905
2906     ldap_info->next = ldap_info_items;
2907     ldap_info_items = ldap_info;
2908
2909   }
2910
2911   switch (ldap_info->auth_type) {
2912     case LDAP_AUTH_SASL:
2913     /*
2914      * It's SASL; are we using a security layer?
2915      */
2916     if (ldap_info->first_auth_frame != 0 &&
2917        pinfo->fd->num >= ldap_info->first_auth_frame) {
2918         doing_sasl_security = TRUE;     /* yes */
2919     }
2920   }
2921
2922   while (tvb_reported_length_remaining(tvb, offset) > 0) {
2923
2924     /*
2925      * This will throw an exception if we don't have any data left.
2926      * That's what we want.  (See "tcp_dissect_pdus()", which is
2927      * similar, but doesn't have to deal with the SASL issues.
2928      * XXX - can we make "tcp_dissect_pdus()" provide enough information
2929      * to the "get_pdu_len" routine so that we could have one dealing
2930      * with the SASL issues, have that routine deal with SASL and
2931      * ASN.1, and just use "tcp_dissect_pdus()"?)
2932      */
2933     length_remaining = tvb_ensure_length_remaining(tvb, offset);
2934
2935     /* It might still be a packet containing a SASL security layer
2936      * but its just that we never saw the BIND packet.
2937      * check if it looks like it could be a SASL blob here
2938      * and in that case just assume it is GSS-SPNEGO
2939      */
2940     if(!doing_sasl_security && (tvb_bytes_exist(tvb, offset, 5))
2941       &&(tvb_get_ntohl(tvb, offset)<=(guint)(tvb_reported_length_remaining(tvb, offset)-4))
2942       &&(tvb_get_guint8(tvb, offset+4)==0x60) ){
2943         ldap_info->auth_type=LDAP_AUTH_SASL;
2944         ldap_info->first_auth_frame=pinfo->fd->num;
2945         ldap_info->auth_mech=g_strdup("GSS-SPNEGO");
2946         doing_sasl_security=TRUE;
2947     }
2948
2949     /*
2950      * This is the first PDU, set the Protocol column and clear the
2951      * Info column.
2952      */
2953     if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, pinfo->current_proto);
2954     if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO);
2955
2956     ldap_item = proto_tree_add_item(tree, is_mscldap?proto_cldap:proto_ldap, tvb, 0, -1, FALSE);
2957     ldap_tree = proto_item_add_subtree(ldap_item, ett_ldap);
2958
2959     /*
2960      * Might we be doing a SASL security layer and, if so, *are* we doing
2961      * one?
2962      *
2963      * Just because we've seen a bind reply for SASL, that doesn't mean
2964      * that we're using a SASL security layer; I've seen captures in
2965      * which some SASL negotiations lead to a security layer being used
2966      * and other negotiations don't, and it's not obvious what's different
2967      * in the two negotiations.  Therefore, we assume that if the first
2968      * byte is 0, it's a length for a SASL security layer (that way, we
2969      * never reassemble more than 16 megabytes, protecting us from
2970      * chewing up *too* much memory), and otherwise that it's an LDAP
2971      * message (actually, if it's an LDAP message it should begin with 0x30,
2972      * but we want to parse garbage as LDAP messages rather than really
2973      * huge lengths).
2974      */
2975
2976     if (doing_sasl_security && tvb_get_guint8(tvb, offset) == 0) {
2977       proto_item *sasl_item = NULL;
2978       proto_tree *sasl_tree = NULL;
2979       tvbuff_t *sasl_tvb;
2980       guint sasl_len, sasl_msg_len, length;
2981       /*
2982        * Yes.  The frame begins with a 4-byte big-endian length.
2983        * And we know we have at least 6 bytes
2984        */
2985
2986       /*
2987        * Get the SASL length, which is the length of data in the buffer
2988        * following the length (i.e., it's 4 less than the total length).
2989        *
2990        * XXX - do we need to reassemble buffers?  For now, we
2991        * assume that each LDAP message is entirely contained within
2992        * a buffer.
2993        */
2994       sasl_len = tvb_get_ntohl(tvb, offset);
2995       sasl_msg_len = sasl_len + 4;
2996       if (sasl_msg_len < 4) {
2997         /*
2998          * The message length was probably so large that the total length
2999          * overflowed.
3000          *
3001          * Report this as an error.
3002          */
3003         show_reported_bounds_error(tvb, pinfo, tree);
3004         return;
3005       }
3006
3007       /*
3008        * Construct a tvbuff containing the amount of the payload we have
3009        * available.  Make its reported length the amount of data in the PDU.
3010        *
3011        * XXX - if reassembly isn't enabled. the subdissector will throw a
3012        * BoundsError exception, rather than a ReportedBoundsError exception.
3013        * We really want a tvbuff where the length is "length", the reported
3014        * length is "plen", and the "if the snapshot length were infinite"
3015        * length is the minimum of the reported length of the tvbuff handed
3016        * to us and "plen", with a new type of exception thrown if the offset
3017        * is within the reported length but beyond that third length, with
3018        * that exception getting the "Unreassembled Packet" error.
3019        */
3020       length = length_remaining;
3021       if (length > sasl_msg_len) length = sasl_msg_len;
3022       sasl_tvb = tvb_new_subset(tvb, offset, length, sasl_msg_len);
3023
3024       if (ldap_tree) {
3025         proto_tree_add_uint(ldap_tree, hf_ldap_sasl_buffer_length, sasl_tvb, 0, 4,
3026                             sasl_len);
3027
3028         sasl_item = proto_tree_add_text(ldap_tree, sasl_tvb, 0,  sasl_msg_len, "SASL buffer");
3029         sasl_tree = proto_item_add_subtree(sasl_item, ett_ldap_sasl_blob);
3030       }
3031
3032       if (ldap_info->auth_mech != NULL &&
3033           strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
3034           tvbuff_t *gssapi_tvb, *plain_tvb = NULL, *decr_tvb= NULL;
3035           int ver_len;
3036           int length;
3037
3038           /*
3039            * This is GSS-API (using SPNEGO, but we should be done with
3040            * the negotiation by now).
3041            *
3042            * Dissect the GSS_Wrap() token; it'll return the length of
3043            * the token, from which we compute the offset in the tvbuff at
3044            * which the plaintext data, i.e. the LDAP message, begins.
3045            */
3046           length = tvb_length_remaining(sasl_tvb, 4);
3047           if ((guint)length > sasl_len)
3048               length = sasl_len;
3049           gssapi_tvb = tvb_new_subset(sasl_tvb, 4, length, sasl_len);
3050
3051           /* Attempt decryption of the GSSAPI wrapped data if possible */
3052           pinfo->decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL;
3053           pinfo->gssapi_wrap_tvb=NULL;
3054           pinfo->gssapi_encrypted_tvb=NULL;
3055           pinfo->gssapi_decrypted_tvb=NULL;
3056           ver_len = call_dissector(gssapi_wrap_handle, gssapi_tvb, pinfo, sasl_tree);
3057           /* if we could unwrap, do a tvb shuffle */
3058           if(pinfo->gssapi_decrypted_tvb){
3059                 decr_tvb=pinfo->gssapi_decrypted_tvb;
3060           }
3061           /* tidy up */
3062           pinfo->decrypt_gssapi_tvb=0;
3063           pinfo->gssapi_wrap_tvb=NULL;
3064           pinfo->gssapi_encrypted_tvb=NULL;
3065           pinfo->gssapi_decrypted_tvb=NULL;
3066
3067           /*
3068            * if len is 0 it probably mean that we got a PDU that is not
3069            * aligned to the start of the segment.
3070            */
3071           if(ver_len==0){
3072              return;
3073           }
3074
3075           /*
3076            * if we don't have unwrapped data,
3077            * see if the wrapping involved encryption of the
3078            * data; if not, just use the plaintext data.
3079            */
3080           if (!decr_tvb) {
3081             if(!pinfo->gssapi_data_encrypted){
3082               plain_tvb = tvb_new_subset(gssapi_tvb,  ver_len, -1, -1);
3083             }
3084           }
3085
3086           if (decr_tvb) {
3087             proto_item *enc_item = NULL;
3088             proto_tree *enc_tree = NULL;
3089
3090             /*
3091              * The LDAP message was encrypted in the packet, and has
3092              * been decrypted; dissect the decrypted LDAP message.
3093              */
3094             if (sasl_tree) {
3095               enc_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3096                                 "GSS-API Encrypted payload (%d byte%s)",
3097                                 sasl_len - ver_len,
3098                                 plurality(sasl_len - ver_len, "", "s"));
3099               enc_tree = proto_item_add_subtree(enc_item, ett_ldap_payload);
3100             }
3101             dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, TRUE, is_mscldap);
3102           } else if (plain_tvb) {
3103             proto_item *plain_item = NULL;
3104             proto_tree *plain_tree = NULL;
3105
3106             /*
3107              * The LDAP message wasn't encrypted in the packet;
3108              * dissect the plain LDAP message.
3109              */
3110             if (sasl_tree) {
3111               plain_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3112                                 "GSS-API payload (%d byte%s)",
3113                                 sasl_len - ver_len,
3114                                 plurality(sasl_len - ver_len, "", "s"));
3115               plain_tree = proto_item_add_subtree(plain_item, ett_ldap_payload);
3116             }
3117
3118            dissect_ldap_payload(plain_tvb, pinfo, plain_tree, ldap_info, TRUE, is_mscldap);
3119           } else {
3120             /*
3121              * The LDAP message was encrypted in the packet, and was
3122              * not decrypted; just show it as encrypted data.
3123              */
3124             if (check_col(pinfo->cinfo, COL_INFO)) {
3125                     col_add_fstr(pinfo->cinfo, COL_INFO, "LDAP GSS-API Encrypted payload (%d byte%s)",
3126                                  sasl_len - ver_len,
3127                                  plurality(sasl_len - ver_len, "", "s"));
3128             }
3129             if (sasl_tree) {
3130               proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3131                                 "GSS-API Encrypted payload (%d byte%s)",
3132                                 sasl_len - ver_len,
3133                                 plurality(sasl_len - ver_len, "", "s"));
3134             }
3135           }
3136       }
3137       offset += sasl_msg_len;
3138     } else {
3139         /* plain LDAP, so dissect the payload */
3140         dissect_ldap_payload(tvb, pinfo, ldap_tree, ldap_info, FALSE, is_mscldap);
3141         /* dissect_ldap_payload() has it's own loop so go out here */
3142         break;
3143     }
3144   }
3145 }
3146
3147 static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
3148 {
3149   guint8 len;
3150
3151   len=tvb_get_guint8(tvb, offset);
3152   offset+=1;
3153   *str=0;
3154
3155   while(len){
3156     /* add potential field separation dot */
3157     if(prepend_dot){
3158       if(!maxlen){
3159         *str=0;
3160         return offset;
3161       }
3162       maxlen--;
3163       *str++='.';
3164       *str=0;
3165     }
3166
3167     if(len==0xc0){
3168       int new_offset;
3169       /* ops its a mscldap compressed string */
3170
3171       new_offset=tvb_get_guint8(tvb, offset);
3172       if (new_offset == offset - 1)
3173         THROW(ReportedBoundsError);
3174       offset+=1;
3175
3176       dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
3177
3178       return offset;
3179     }
3180
3181     prepend_dot=TRUE;
3182
3183     if(maxlen<=len){
3184       if(maxlen>3){
3185         *str++='.';
3186         *str++='.';
3187         *str++='.';
3188       }
3189       *str=0;
3190       return offset; /* will mess up offset in caller, is unlikely */
3191     }
3192     tvb_memcpy(tvb, str, offset, len);
3193     str+=len;
3194     *str=0;
3195     maxlen-=len;
3196     offset+=len;
3197
3198
3199     len=tvb_get_guint8(tvb, offset);
3200     offset+=1;
3201   }
3202   *str=0;
3203   return offset;
3204 }
3205
3206 /* These flag bits were found to be defined in the samba sources.
3207  * I hope they are correct (but have serious doubts about the CLOSEST
3208  * bit being used or being meaningful).
3209  */
3210 static const true_false_string tfs_ads_pdc = {
3211         "This is a PDC",
3212         "This is NOT a pdc"
3213 };
3214 static const true_false_string tfs_ads_gc = {
3215         "This is a GLOBAL CATALOGUE of forest",
3216         "This is NOT a global catalog of forest"
3217 };
3218 static const true_false_string tfs_ads_ldap = {
3219         "This is an LDAP server",
3220         "This is NOT an ldap server"
3221 };
3222 static const true_false_string tfs_ads_ds = {
3223         "This dc supports DS",
3224         "This dc does NOT support ds"
3225 };
3226 static const true_false_string tfs_ads_kdc = {
3227         "This is a KDC (kerberos)",
3228         "This is NOT a kdc (kerberos)"
3229 };
3230 static const true_false_string tfs_ads_timeserv = {
3231         "This dc is running TIME SERVICES (ntp)",
3232         "This dc is NOT running time services (ntp)"
3233 };
3234 static const true_false_string tfs_ads_closest = {
3235         "This is the CLOSEST dc (unreliable?)",
3236         "This is NOT the closest dc"
3237 };
3238 static const true_false_string tfs_ads_writable = {
3239         "This dc is WRITABLE",
3240         "This dc is NOT writable"
3241 };
3242 static const true_false_string tfs_ads_good_timeserv = {
3243         "This dc has a GOOD TIME SERVICE (i.e. hardware clock)",
3244         "This dc does NOT have a good time service (i.e. no hardware clock)"
3245 };
3246 static const true_false_string tfs_ads_ndnc = {
3247         "Domain is NON-DOMAIN NC serviced by ldap server",
3248         "Domain is NOT non-domain nc serviced by ldap server"
3249 };
3250 static int dissect_mscldap_netlogon_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3251 {
3252   guint32 flags;
3253   proto_item *item;
3254   proto_tree *tree=NULL;
3255   guint fields[] = { hf_mscldap_netlogon_flags_ndnc,
3256                      hf_mscldap_netlogon_flags_good_timeserv,
3257                      hf_mscldap_netlogon_flags_writable,
3258                      hf_mscldap_netlogon_flags_closest,
3259                      hf_mscldap_netlogon_flags_timeserv,
3260                      hf_mscldap_netlogon_flags_kdc,
3261                      hf_mscldap_netlogon_flags_ds,
3262                      hf_mscldap_netlogon_flags_ldap,
3263                      hf_mscldap_netlogon_flags_gc,
3264                      hf_mscldap_netlogon_flags_pdc,
3265                      0 };
3266   guint  *field;
3267   header_field_info *hfi;
3268   gboolean one_bit_set = FALSE;
3269
3270   flags=tvb_get_letohl(tvb, offset);
3271   item=proto_tree_add_item(parent_tree, hf_mscldap_netlogon_flags, tvb, offset, 4, TRUE);
3272   if(parent_tree){
3273     tree = proto_item_add_subtree(item, ett_mscldap_netlogon_flags);
3274   }
3275
3276   proto_item_append_text(item, " (");
3277
3278   for(field = fields; *field; field++) {
3279     proto_tree_add_boolean(tree, *field, tvb, offset, 4, flags);
3280     hfi = proto_registrar_get_nth(*field);
3281
3282     if(flags & hfi->bitmask) {
3283
3284       if(one_bit_set)
3285         proto_item_append_text(item, ", ");
3286       else
3287         one_bit_set = TRUE;
3288
3289       proto_item_append_text(item, hfi->name);
3290
3291     }
3292   }
3293
3294   proto_item_append_text(item, ")");
3295
3296   offset += 4;
3297
3298   return offset;
3299 }
3300
3301 static void dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3302 {
3303   int old_offset, offset=0;
3304   char str[256];
3305
3306   ldm_tree = NULL;
3307
3308 /*qqq*/
3309
3310   /* Type */
3311   /*XXX someone that knows what the type means should add that knowledge here*/
3312   proto_tree_add_item(tree, hf_mscldap_netlogon_type, tvb, offset, 4, TRUE);
3313   offset += 4;
3314
3315   /* Flags */
3316   offset = dissect_mscldap_netlogon_flags(tree, tvb, offset);
3317
3318   /* Domain GUID */
3319   proto_tree_add_item(tree, hf_mscldap_domain_guid, tvb, offset, 16, TRUE);
3320   offset += 16;
3321
3322   /* Forest */
3323   old_offset=offset;
3324   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3325   proto_tree_add_string(tree, hf_mscldap_forest, tvb, old_offset, offset-old_offset, str);
3326
3327   /* Domain */
3328   old_offset=offset;
3329   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3330   proto_tree_add_string(tree, hf_mscldap_domain, tvb, old_offset, offset-old_offset, str);
3331
3332   /* Hostname */
3333   old_offset=offset;
3334   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3335   proto_tree_add_string(tree, hf_mscldap_hostname, tvb, old_offset, offset-old_offset, str);
3336
3337   /* NetBios Domain */
3338   old_offset=offset;
3339   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3340   proto_tree_add_string(tree, hf_mscldap_nb_domain, tvb, old_offset, offset-old_offset, str);
3341
3342   /* NetBios Hostname */
3343   old_offset=offset;
3344   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3345   proto_tree_add_string(tree, hf_mscldap_nb_hostname, tvb, old_offset, offset-old_offset, str);
3346
3347   /* User */
3348   old_offset=offset;
3349   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3350   proto_tree_add_string(tree, hf_mscldap_username, tvb, old_offset, offset-old_offset, str);
3351
3352   /* Site */
3353   old_offset=offset;
3354   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3355   proto_tree_add_string(tree, hf_mscldap_sitename, tvb, old_offset, offset-old_offset, str);
3356
3357   /* Client Site */
3358   old_offset=offset;
3359   offset=dissect_mscldap_string(tvb, offset, str, 255, FALSE);
3360   proto_tree_add_string(tree, hf_mscldap_clientsitename, tvb, old_offset, offset-old_offset, str);
3361
3362   /* Version */
3363   proto_tree_add_item(tree, hf_mscldap_netlogon_version, tvb, offset, 4, TRUE);
3364   offset += 4;
3365
3366   /* LM Token */
3367   proto_tree_add_item(tree, hf_mscldap_netlogon_lm_token, tvb, offset, 2, TRUE);
3368   offset += 2;
3369
3370   /* NT Token */
3371   proto_tree_add_item(tree, hf_mscldap_netlogon_nt_token, tvb, offset, 2, TRUE);
3372   offset += 2;
3373
3374 }
3375
3376
3377 static guint
3378 get_sasl_ldap_pdu_len(tvbuff_t *tvb, int offset)
3379 {
3380         /* sasl encapsulated ldap is 4 bytes plus the length in size */
3381         return tvb_get_ntohl(tvb, offset)+4;
3382 }
3383
3384 static void
3385 dissect_sasl_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3386 {
3387         dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
3388         return;
3389 }
3390
3391 static guint
3392 get_normal_ldap_pdu_len(tvbuff_t *tvb, int offset)
3393 {
3394         guint32 len;
3395         gboolean ind;
3396         int data_offset;
3397
3398         /* normal ldap is tag+len bytes plus the length
3399          * offset==0 is where the tag is
3400          * offset==1 is where length starts
3401          */
3402         data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
3403         return len+data_offset;
3404 }
3405
3406 static void
3407 dissect_normal_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3408 {
3409         dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
3410         return;
3411 }
3412
3413 static void
3414 dissect_ldap_oid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3415 {
3416         char *oid, *oidname;
3417
3418         /* tvb here contains an ascii string that is really an oid */
3419 /* XXX   we should convert the string oid into a real oid so we can use
3420  *       proto_tree_add_oid() instead.
3421  */
3422
3423         oid=tvb_get_ephemeral_string(tvb, 0, tvb_length(tvb));
3424         if(!oid){
3425                 return;
3426         }
3427
3428         oidname=get_oid_str_name(oid);
3429
3430         if(oidname){
3431                 proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s (%s)",oid,oidname);
3432         } else {
3433                 proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s",oid);
3434         }
3435 }
3436
3437 static void
3438 dissect_ldap_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3439 {
3440         guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
3441         e_uuid_t uuid;
3442
3443         /* This octet string contained a GUID */
3444         dissect_dcerpc_uuid_t(tvb, 0, pinfo, tree, drep, hf_ldap_guid, &uuid);
3445
3446         ldapvalue_string=ep_alloc(1024);
3447         g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
3448                    uuid.Data1, uuid.Data2, uuid.Data3,
3449                    uuid.Data4[0], uuid.Data4[1],
3450                    uuid.Data4[2], uuid.Data4[3],
3451                    uuid.Data4[4], uuid.Data4[5],
3452                    uuid.Data4[6], uuid.Data4[7]);
3453 }
3454
3455 static void
3456 dissect_ldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3457 {
3458         ldm_tree = NULL;
3459
3460         /* Here we must take care of reassembly but this is tricky since
3461          * depending on whether SASL is present or not, the heuristics
3462          * will be very different.
3463          */
3464         if(ldap_desegment && (tvb_length(tvb)==tvb_reported_length(tvb))){
3465                 guint32 len;
3466
3467                 /* check for a SASL header, i.e. four byte integer where the
3468                  * first two bytes are 0x00 and the value is <64k and >2
3469                  * (>2 to fight false positives, 0x00000000 is a common
3470                  *     "random" tcp payload)
3471                  * (no SASL ldap PDUs are ever going to be >64k in size?)
3472                  *
3473                  * Following the SASL header is a GSSAPI blob so the next byte
3474                  * is always 0x60. (only true for MS SASL LDAP, there are other
3475                  * blobs that may follow in real-world)
3476                  */
3477                 len=tvb_get_ntohl(tvb, 0);
3478                 if( (len<65535)
3479                 &&  (len>2)
3480                 &&  (tvb_get_guint8(tvb, 4)==0x60)){
3481                         if(len<=tvb_length_remaining(tvb, 4)){
3482                                 /* we have a full ldap pdu */
3483                                 dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
3484                                 return;
3485                         } else {
3486                                 /* we have to do reassembly */
3487                                 tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
3488                                 return;
3489                         }
3490                 }
3491                 /* check if it is a normal BER encoded LDAP packet
3492                  * i.e. first byte is 0x30 followed by a length that is
3493                  * <64k
3494                  * (no ldap PDUs are ever >64kb? )
3495                  */
3496                 if(tvb_get_guint8(tvb, 0)==0x30){
3497                         gboolean ind;
3498                         int data_offset;
3499
3500                         /* check that length makes sense */
3501                         data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
3502
3503                         /* dont check ind since indefinite length is never used for ldap (famous last words)*/
3504                         if(len<2 || len>65535){
3505                                 return;
3506                         }
3507
3508                         if(len<=tvb_length_remaining(tvb, data_offset)){
3509                                 /* we have a full ldap pdu */
3510                                 dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
3511                                 return;
3512                         } else {
3513                                 /* we have to do reassembly */
3514                                 tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
3515                                 return;
3516                         }
3517                 }
3518         }
3519
3520         dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
3521         return;
3522 }
3523
3524 static void
3525 dissect_mscldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
3526 {
3527         dissect_ldap_pdu(tvb, pinfo, tree, TRUE);
3528         return;
3529 }
3530
3531
3532 static void
3533 ldap_reinit(void)
3534 {
3535   ldap_conv_info_t *ldap_info;
3536
3537   /* Free up state attached to the ldap_info structures */
3538   for (ldap_info = ldap_info_items; ldap_info != NULL; ldap_info = ldap_info->next) {
3539     if (ldap_info->auth_mech != NULL) {
3540       g_free(ldap_info->auth_mech);
3541       ldap_info->auth_mech=NULL;
3542     }
3543     g_hash_table_destroy(ldap_info->matched);
3544     ldap_info->matched=NULL;
3545     g_hash_table_destroy(ldap_info->unmatched);
3546     ldap_info->unmatched=NULL;
3547   }
3548
3549   ldap_info_items = NULL;
3550
3551 }
3552
3553 void
3554 register_ldap_name_dissector_handle(const char *attr_type, dissector_handle_t dissector)
3555 {
3556         dissector_add_string("ldap.name", attr_type, dissector);
3557 }
3558
3559 void
3560 register_ldap_name_dissector(const char *attr_type, dissector_t dissector, int proto)
3561 {
3562         dissector_handle_t dissector_handle;
3563
3564         dissector_handle=create_dissector_handle(dissector, proto);
3565         register_ldap_name_dissector_handle(attr_type, dissector_handle);
3566 }
3567
3568
3569 /*--- proto_register_ldap -------------------------------------------*/
3570 void proto_register_ldap(void) {
3571
3572   /* List of fields */
3573
3574   static hf_register_info hf[] = {
3575
3576                 { &hf_ldap_sasl_buffer_length,
3577                   { "SASL Buffer Length",       "ldap.sasl_buffer_length",
3578                         FT_UINT32, BASE_DEC, NULL, 0x0,
3579                         "SASL Buffer Length", HFILL }},
3580             { &hf_ldap_response_in,
3581               { "Response In", "ldap.response_in",
3582                 FT_FRAMENUM, BASE_DEC, NULL, 0x0,
3583                 "The response to this LDAP request is in this frame", HFILL }},
3584             { &hf_ldap_response_to,
3585               { "Response To", "ldap.response_to",
3586                 FT_FRAMENUM, BASE_DEC, NULL, 0x0,
3587                 "This is a response to the LDAP request in this frame", HFILL }},
3588             { &hf_ldap_time,
3589               { "Time", "ldap.time",
3590                 FT_RELATIVE_TIME, BASE_NONE, NULL, 0x0,
3591                 "The time between the Call and the Reply", HFILL }},
3592
3593     { &hf_mscldap_netlogon_type,
3594       { "Type", "mscldap.netlogon.type",
3595         FT_UINT32, BASE_DEC, NULL, 0x0,
3596         "Type of <please tell Wireshark developers what this type is>", HFILL }},
3597
3598     { &hf_mscldap_netlogon_version,
3599       { "Version", "mscldap.netlogon.version",
3600         FT_UINT32, BASE_DEC, NULL, 0x0,
3601         "Version of <please tell Wireshark developers what this type is>", HFILL }},
3602
3603     { &hf_mscldap_netlogon_lm_token,
3604       { "LM Token", "mscldap.netlogon.lm_token",
3605         FT_UINT16, BASE_HEX, NULL, 0x0,
3606         "LM Token", HFILL }},
3607
3608     { &hf_mscldap_netlogon_nt_token,
3609       { "NT Token", "mscldap.netlogon.nt_token",
3610         FT_UINT16, BASE_HEX, NULL, 0x0,
3611         "NT Token", HFILL }},
3612
3613     { &hf_mscldap_netlogon_flags,
3614       { "Flags", "mscldap.netlogon.flags",
3615         FT_UINT32, BASE_HEX, NULL, 0x0,
3616         "Netlogon flags describing the DC properties", HFILL }},
3617
3618     { &hf_mscldap_domain_guid,
3619       { "Domain GUID", "mscldap.domain.guid",
3620         FT_BYTES, BASE_HEX, NULL, 0x0,
3621         "Domain GUID", HFILL }},
3622
3623     { &hf_mscldap_forest,
3624       { "Forest", "mscldap.forest",
3625         FT_STRING, BASE_NONE, NULL, 0x0,
3626         "Forest", HFILL }},
3627
3628     { &hf_mscldap_domain,
3629       { "Domain", "mscldap.domain",
3630         FT_STRING, BASE_NONE, NULL, 0x0,
3631         "Domainname", HFILL }},
3632
3633     { &hf_mscldap_hostname,
3634       { "Hostname", "mscldap.hostname",
3635         FT_STRING, BASE_NONE, NULL, 0x0,
3636         "Hostname", HFILL }},
3637
3638     { &hf_mscldap_nb_domain,
3639       { "NetBios Domain", "mscldap.nb_domain",
3640         FT_STRING, BASE_NONE, NULL, 0x0,
3641         "NetBios Domainname", HFILL }},
3642
3643     { &hf_mscldap_nb_hostname,
3644       { "NetBios Hostname", "mscldap.nb_hostname",
3645         FT_STRING, BASE_NONE, NULL, 0x0,
3646         "NetBios Hostname", HFILL }},
3647
3648     { &hf_mscldap_username,
3649       { "User", "mscldap.username",
3650         FT_STRING, BASE_NONE, NULL, 0x0,
3651         "User name", HFILL }},
3652
3653     { &hf_mscldap_sitename,
3654       { "Site", "mscldap.sitename",
3655         FT_STRING, BASE_NONE, NULL, 0x0,
3656         "Site name", HFILL }},
3657
3658     { &hf_mscldap_clientsitename,
3659       { "Client Site", "mscldap.clientsitename",
3660         FT_STRING, BASE_NONE, NULL, 0x0,
3661         "Client Site name", HFILL }},
3662
3663     { &hf_mscldap_netlogon_flags_pdc,
3664       { "PDC", "mscldap.netlogon.flags.pdc", FT_BOOLEAN, 32,
3665         TFS(&tfs_ads_pdc), 0x00000001, "Is this DC a PDC or not?", HFILL }},
3666
3667     { &hf_mscldap_netlogon_flags_gc,
3668       { "GC", "mscldap.netlogon.flags.gc", FT_BOOLEAN, 32,
3669         TFS(&tfs_ads_gc), 0x00000004, "Does this dc service as a GLOBAL CATALOGUE?", HFILL }},
3670
3671     { &hf_mscldap_netlogon_flags_ldap,
3672       { "LDAP", "mscldap.netlogon.flags.ldap", FT_BOOLEAN, 32,
3673         TFS(&tfs_ads_ldap), 0x00000008, "Does this DC act as an LDAP server?", HFILL }},
3674
3675     { &hf_mscldap_netlogon_flags_ds,
3676       { "DS", "mscldap.netlogon.flags.ds", FT_BOOLEAN, 32,
3677         TFS(&tfs_ads_ds), 0x00000010, "Does this dc provide DS services?", HFILL }},
3678
3679     { &hf_mscldap_netlogon_flags_kdc,
3680       { "KDC", "mscldap.netlogon.flags.kdc", FT_BOOLEAN, 32,
3681         TFS(&tfs_ads_kdc), 0x00000020, "Does this dc act as a KDC?", HFILL }},
3682
3683     { &hf_mscldap_netlogon_flags_timeserv,
3684       { "Time Serv", "mscldap.netlogon.flags.timeserv", FT_BOOLEAN, 32,
3685         TFS(&tfs_ads_timeserv), 0x00000040, "Does this dc provide time services (ntp) ?", HFILL }},
3686
3687     { &hf_mscldap_netlogon_flags_closest,
3688       { "Closest", "mscldap.netlogon.flags.closest", FT_BOOLEAN, 32,
3689         TFS(&tfs_ads_closest), 0x00000080, "Is this the closest dc? (is this used at all?)", HFILL }},
3690
3691     { &hf_mscldap_netlogon_flags_writable,
3692       { "Writable", "mscldap.netlogon.flags.writable", FT_BOOLEAN, 32,
3693         TFS(&tfs_ads_writable), 0x00000100, "Is this dc writable? (i.e. can it update the AD?)", HFILL }},
3694
3695     { &hf_mscldap_netlogon_flags_good_timeserv,
3696       { "Good Time Serv", "mscldap.netlogon.flags.good_timeserv", FT_BOOLEAN, 32,
3697         TFS(&tfs_ads_good_timeserv), 0x00000200, "Is this a Good Time Server? (i.e. does it have a hardware clock)", HFILL }},
3698
3699     { &hf_mscldap_netlogon_flags_ndnc,
3700       { "NDNC", "mscldap.netlogon.flags.ndnc", FT_BOOLEAN, 32,
3701         TFS(&tfs_ads_ndnc), 0x00000400, "Is this an NDNC dc?", HFILL }},
3702
3703     { &hf_ldap_guid,
3704       { "GUID", "ldap.guid", FT_GUID, BASE_NONE,
3705         NULL, 0, "GUID", HFILL }},
3706
3707
3708 /*--- Included file: packet-ldap-hfarr.c ---*/
3709 #line 1 "packet-ldap-hfarr.c"
3710     { &hf_ldap_LDAPMessage_PDU,
3711       { "LDAPMessage", "ldap.LDAPMessage",
3712         FT_NONE, BASE_NONE, NULL, 0,
3713         "LDAPMessage", HFILL }},
3714     { &hf_ldap_messageID,
3715       { "messageID", "ldap.messageID",
3716         FT_UINT32, BASE_DEC, NULL, 0,
3717         "LDAPMessage/messageID", HFILL }},
3718     { &hf_ldap_protocolOp,
3719       { "protocolOp", "ldap.protocolOp",
3720         FT_UINT32, BASE_DEC, VALS(ldap_ProtocolOp_vals), 0,
3721         "LDAPMessage/protocolOp", HFILL }},
3722     { &hf_ldap_controls,
3723       { "controls", "ldap.controls",
3724         FT_UINT32, BASE_DEC, NULL, 0,
3725         "LDAPMessage/controls", HFILL }},
3726     { &hf_ldap_bindRequest,
3727       { "bindRequest", "ldap.bindRequest",
3728         FT_NONE, BASE_NONE, NULL, 0,
3729         "ProtocolOp/bindRequest", HFILL }},
3730     { &hf_ldap_bindResponse,
3731       { "bindResponse", "ldap.bindResponse",
3732         FT_NONE, BASE_NONE, NULL, 0,
3733         "ProtocolOp/bindResponse", HFILL }},
3734     { &hf_ldap_unbindRequest,
3735       { "unbindRequest", "ldap.unbindRequest",
3736         FT_NONE, BASE_NONE, NULL, 0,
3737         "ProtocolOp/unbindRequest", HFILL }},
3738     { &hf_ldap_searchRequest,
3739       { "searchRequest", "ldap.searchRequest",
3740         FT_NONE, BASE_NONE, NULL, 0,
3741         "ProtocolOp/searchRequest", HFILL }},
3742     { &hf_ldap_searchResEntry,
3743       { "searchResEntry", "ldap.searchResEntry",
3744         FT_NONE, BASE_NONE, NULL, 0,
3745         "ProtocolOp/searchResEntry", HFILL }},
3746     { &hf_ldap_searchResDone,
3747       { "searchResDone", "ldap.searchResDone",
3748         FT_NONE, BASE_NONE, NULL, 0,
3749         "ProtocolOp/searchResDone", HFILL }},
3750     { &hf_ldap_searchResRef,
3751       { "searchResRef", "ldap.searchResRef",
3752         FT_UINT32, BASE_DEC, NULL, 0,
3753         "ProtocolOp/searchResRef", HFILL }},
3754     { &hf_ldap_modifyRequest,
3755       { "modifyRequest", "ldap.modifyRequest",
3756         FT_NONE, BASE_NONE, NULL, 0,
3757         "ProtocolOp/modifyRequest", HFILL }},
3758     { &hf_ldap_modifyResponse,
3759       { "modifyResponse", "ldap.modifyResponse",
3760         FT_NONE, BASE_NONE, NULL, 0,
3761         "ProtocolOp/modifyResponse", HFILL }},
3762     { &hf_ldap_addRequest,
3763       { "addRequest", "ldap.addRequest",
3764         FT_NONE, BASE_NONE, NULL, 0,
3765         "ProtocolOp/addRequest", HFILL }},
3766     { &hf_ldap_addResponse,
3767       { "addResponse", "ldap.addResponse",
3768         FT_NONE, BASE_NONE, NULL, 0,
3769         "ProtocolOp/addResponse", HFILL }},
3770     { &hf_ldap_delRequest,
3771       { "delRequest", "ldap.delRequest",
3772         FT_STRING, BASE_NONE, NULL, 0,
3773         "ProtocolOp/delRequest", HFILL }},
3774     { &hf_ldap_delResponse,
3775       { "delResponse", "ldap.delResponse",
3776         FT_NONE, BASE_NONE, NULL, 0,
3777         "ProtocolOp/delResponse", HFILL }},
3778     { &hf_ldap_modDNRequest,
3779       { "modDNRequest", "ldap.modDNRequest",
3780         FT_NONE, BASE_NONE, NULL, 0,
3781         "ProtocolOp/modDNRequest", HFILL }},
3782     { &hf_ldap_modDNResponse,
3783       { "modDNResponse", "ldap.modDNResponse",
3784         FT_NONE, BASE_NONE, NULL, 0,
3785         "ProtocolOp/modDNResponse", HFILL }},
3786     { &hf_ldap_compareRequest,
3787       { "compareRequest", "ldap.compareRequest",
3788         FT_NONE, BASE_NONE, NULL, 0,
3789         "ProtocolOp/compareRequest", HFILL }},
3790     { &hf_ldap_compareResponse,
3791       { "compareResponse", "ldap.compareResponse",
3792         FT_NONE, BASE_NONE, NULL, 0,
3793         "ProtocolOp/compareResponse", HFILL }},
3794     { &hf_ldap_abandonRequest,
3795       { "abandonRequest", "ldap.abandonRequest",
3796         FT_UINT32, BASE_DEC, NULL, 0,
3797         "ProtocolOp/abandonRequest", HFILL }},
3798     { &hf_ldap_extendedReq,
3799       { "extendedReq", "ldap.extendedReq",
3800         FT_NONE, BASE_NONE, NULL, 0,
3801         "ProtocolOp/extendedReq", HFILL }},
3802     { &hf_ldap_extendedResp,
3803       { "extendedResp", "ldap.extendedResp",
3804         FT_NONE, BASE_NONE, NULL, 0,
3805         "ProtocolOp/extendedResp", HFILL }},
3806     { &hf_ldap_AttributeDescriptionList_item,
3807       { "Item", "ldap.AttributeDescriptionList_item",
3808         FT_STRING, BASE_NONE, NULL, 0,
3809         "AttributeDescriptionList/_item", HFILL }},
3810     { &hf_ldap_attributeDesc,
3811       { "attributeDesc", "ldap.attributeDesc",
3812         FT_STRING, BASE_NONE, NULL, 0,
3813         "AttributeValueAssertion/attributeDesc", HFILL }},
3814     { &hf_ldap_assertionValue,
3815       { "assertionValue", "ldap.assertionValue",
3816         FT_STRING, BASE_NONE, NULL, 0,
3817         "AttributeValueAssertion/assertionValue", HFILL }},
3818     { &hf_ldap_type,
3819       { "type", "ldap.type",
3820         FT_STRING, BASE_NONE, NULL, 0,
3821         "", HFILL }},
3822     { &hf_ldap_vals,
3823       { "vals", "ldap.vals",
3824         FT_UINT32, BASE_DEC, NULL, 0,
3825         "", HFILL }},
3826     { &hf_ldap_vals_item,
3827       { "Item", "ldap.vals_item",
3828         FT_BYTES, BASE_HEX, NULL, 0,
3829         "", HFILL }},
3830     { &hf_ldap_resultCode,
3831       { "resultCode", "ldap.resultCode",
3832         FT_UINT32, BASE_DEC, VALS(ldap_T_resultCode_vals), 0,
3833         "LDAPResult/resultCode", HFILL }},
3834     { &hf_ldap_matchedDN,
3835       { "matchedDN", "ldap.matchedDN",
3836         FT_STRING, BASE_NONE, NULL, 0,
3837         "", HFILL }},
3838     { &hf_ldap_errorMessage,
3839       { "errorMessage", "ldap.errorMessage",
3840         FT_STRING, BASE_NONE, NULL, 0,
3841         "", HFILL }},
3842     { &hf_ldap_referral,
3843       { "referral", "ldap.referral",
3844         FT_UINT32, BASE_DEC, NULL, 0,
3845         "", HFILL }},
3846     { &hf_ldap_Referral_item,
3847       { "Item", "ldap.Referral_item",
3848         FT_STRING, BASE_NONE, NULL, 0,
3849         "Referral/_item", HFILL }},
3850     { &hf_ldap_Controls_item,
3851       { "Item", "ldap.Controls_item",
3852         FT_NONE, BASE_NONE, NULL, 0,
3853         "Controls/_item", HFILL }},
3854     { &hf_ldap_controlType,
3855       { "controlType", "ldap.controlType",
3856         FT_STRING, BASE_NONE, NULL, 0,
3857         "Control/controlType", HFILL }},
3858     { &hf_ldap_criticality,
3859       { "criticality", "ldap.criticality",
3860         FT_BOOLEAN, 8, NULL, 0,
3861         "Control/criticality", HFILL }},
3862     { &hf_ldap_controlValue,
3863       { "controlValue", "ldap.controlValue",
3864         FT_BYTES, BASE_HEX, NULL, 0,
3865         "Control/controlValue", HFILL }},
3866     { &hf_ldap_version,
3867       { "version", "ldap.version",
3868         FT_UINT32, BASE_DEC, NULL, 0,
3869         "BindRequest/version", HFILL }},
3870     { &hf_ldap_name,
3871       { "name", "ldap.name",
3872         FT_STRING, BASE_NONE, NULL, 0,
3873         "BindRequest/name", HFILL }},
3874     { &hf_ldap_authentication,
3875       { "authentication", "ldap.authentication",
3876         FT_UINT32, BASE_DEC, VALS(ldap_AuthenticationChoice_vals), 0,
3877         "BindRequest/authentication", HFILL }},
3878     { &hf_ldap_simple,
3879       { "simple", "ldap.simple",
3880         FT_BYTES, BASE_HEX, NULL, 0,
3881         "AuthenticationChoice/simple", HFILL }},
3882     { &hf_ldap_sasl,
3883       { "sasl", "ldap.sasl",
3884         FT_NONE, BASE_NONE, NULL, 0,
3885         "AuthenticationChoice/sasl", HFILL }},
3886     { &hf_ldap_mechanism,
3887       { "mechanism", "ldap.mechanism",
3888         FT_STRING, BASE_NONE, NULL, 0,
3889         "SaslCredentials/mechanism", HFILL }},
3890     { &hf_ldap_credentials,
3891       { "credentials", "ldap.credentials",
3892         FT_BYTES, BASE_HEX, NULL, 0,
3893         "SaslCredentials/credentials", HFILL }},
3894     { &hf_ldap_bindResponse_resultCode,
3895       { "resultCode", "ldap.resultCode",
3896         FT_UINT32, BASE_DEC, VALS(ldap_BindResponse_resultCode_vals), 0,
3897         "BindResponse/resultCode", HFILL }},
3898     { &hf_ldap_serverSaslCreds,
3899       { "serverSaslCreds", "ldap.serverSaslCreds",
3900         FT_BYTES, BASE_HEX, NULL, 0,
3901         "BindResponse/serverSaslCreds", HFILL }},
3902     { &hf_ldap_baseObject,
3903       { "baseObject", "ldap.baseObject",
3904         FT_STRING, BASE_NONE, NULL, 0,
3905         "SearchRequest/baseObject", HFILL }},
3906     { &hf_ldap_scope,
3907       { "scope", "ldap.scope",
3908         FT_UINT32, BASE_DEC, VALS(ldap_T_scope_vals), 0,
3909         "SearchRequest/scope", HFILL }},
3910     { &hf_ldap_derefAliases,
3911       { "derefAliases", "ldap.derefAliases",
3912         FT_UINT32, BASE_DEC, VALS(ldap_T_derefAliases_vals), 0,
3913         "SearchRequest/derefAliases", HFILL }},
3914     { &hf_ldap_sizeLimit,
3915       { "sizeLimit", "ldap.sizeLimit",
3916         FT_UINT32, BASE_DEC, NULL, 0,
3917         "SearchRequest/sizeLimit", HFILL }},
3918     { &hf_ldap_timeLimit,
3919       { "timeLimit", "ldap.timeLimit",
3920         FT_UINT32, BASE_DEC, NULL, 0,
3921         "SearchRequest/timeLimit", HFILL }},
3922     { &hf_ldap_typesOnly,
3923       { "typesOnly", "ldap.typesOnly",
3924         FT_BOOLEAN, 8, NULL, 0,
3925         "SearchRequest/typesOnly", HFILL }},
3926     { &hf_ldap_filter,
3927       { "filter", "ldap.filter",
3928         FT_UINT32, BASE_DEC, VALS(ldap_Filter_vals), 0,
3929         "SearchRequest/filter", HFILL }},
3930     { &hf_ldap_searchRequest_attributes,
3931       { "attributes", "ldap.attributes",
3932         FT_UINT32, BASE_DEC, NULL, 0,
3933         "SearchRequest/attributes", HFILL }},
3934     { &hf_ldap_and,
3935       { "and", "ldap.and",
3936         FT_UINT32, BASE_DEC, NULL, 0,
3937         "Filter/and", HFILL }},
3938     { &hf_ldap_and_item,
3939       { "Item", "ldap.and_item",
3940         FT_UINT32, BASE_DEC, VALS(ldap_Filter_vals), 0,
3941         "Filter/and/_item", HFILL }},
3942     { &hf_ldap_or,
3943       { "or", "ldap.or",
3944         FT_UINT32, BASE_DEC, NULL, 0,
3945         "Filter/or", HFILL }},
3946     { &hf_ldap_or_item,
3947       { "Item", "ldap.or_item",
3948         FT_UINT32, BASE_DEC, VALS(ldap_Filter_vals), 0,
3949         "Filter/or/_item", HFILL }},
3950     { &hf_ldap_not,
3951       { "not", "ldap.not",
3952         FT_UINT32, BASE_DEC, VALS(ldap_Filter_vals), 0,
3953         "Filter/not", HFILL }},
3954     { &hf_ldap_equalityMatch,
3955       { "equalityMatch", "ldap.equalityMatch",
3956         FT_NONE, BASE_NONE, NULL, 0,
3957         "Filter/equalityMatch", HFILL }},
3958     { &hf_ldap_substrings,
3959       { "substrings", "ldap.substrings",
3960         FT_NONE, BASE_NONE, NULL, 0,
3961         "Filter/substrings", HFILL }},
3962     { &hf_ldap_greaterOrEqual,
3963       { "greaterOrEqual", "ldap.greaterOrEqual",
3964         FT_NONE, BASE_NONE, NULL, 0,
3965         "Filter/greaterOrEqual", HFILL }},
3966     { &hf_ldap_lessOrEqual,
3967       { "lessOrEqual", "ldap.lessOrEqual",
3968         FT_NONE, BASE_NONE, NULL, 0,
3969         "Filter/lessOrEqual", HFILL }},
3970     { &hf_ldap_present,
3971       { "present", "ldap.present",
3972         FT_STRING, BASE_NONE, NULL, 0,
3973         "Filter/present", HFILL }},
3974     { &hf_ldap_approxMatch,
3975       { "approxMatch", "ldap.approxMatch",
3976         FT_NONE, BASE_NONE, NULL, 0,
3977         "Filter/approxMatch", HFILL }},
3978     { &hf_ldap_extensibleMatch,
3979       { "extensibleMatch", "ldap.extensibleMatch",
3980         FT_NONE, BASE_NONE, NULL, 0,
3981         "Filter/extensibleMatch", HFILL }},
3982     { &hf_ldap_substringFilter_substrings,
3983       { "substrings", "ldap.substrings",
3984         FT_UINT32, BASE_DEC, NULL, 0,
3985         "SubstringFilter/substrings", HFILL }},
3986     { &hf_ldap_substringFilter_substrings_item,
3987       { "Item", "ldap.substrings_item",
3988         FT_UINT32, BASE_DEC, VALS(ldap_T_substringFilter_substrings_item_vals), 0,
3989         "SubstringFilter/substrings/_item", HFILL }},
3990     { &hf_ldap_initial,
3991       { "initial", "ldap.initial",
3992         FT_STRING, BASE_NONE, NULL, 0,
3993         "SubstringFilter/substrings/_item/initial", HFILL }},
3994     { &hf_ldap_any,
3995       { "any", "ldap.any",
3996         FT_STRING, BASE_NONE, NULL, 0,
3997         "SubstringFilter/substrings/_item/any", HFILL }},
3998     { &hf_ldap_final,
3999       { "final", "ldap.final",
4000         FT_STRING, BASE_NONE, NULL, 0,
4001         "SubstringFilter/substrings/_item/final", HFILL }},
4002     { &hf_ldap_matchingRule,
4003       { "matchingRule", "ldap.matchingRule",
4004         FT_STRING, BASE_NONE, NULL, 0,
4005         "MatchingRuleAssertion/matchingRule", HFILL }},
4006     { &hf_ldap_matchValue,
4007       { "matchValue", "ldap.matchValue",
4008         FT_STRING, BASE_NONE, NULL, 0,
4009         "MatchingRuleAssertion/matchValue", HFILL }},
4010     { &hf_ldap_dnAttributes,
4011       { "dnAttributes", "ldap.dnAttributes",
4012         FT_BOOLEAN, 8, NULL, 0,
4013         "MatchingRuleAssertion/dnAttributes", HFILL }},
4014     { &hf_ldap_objectName,
4015       { "objectName", "ldap.objectName",
4016         FT_STRING, BASE_NONE, NULL, 0,
4017         "SearchResultEntry/objectName", HFILL }},
4018     { &hf_ldap_searchResultEntry_attributes,
4019       { "attributes", "ldap.attributes",
4020         FT_UINT32, BASE_DEC, NULL, 0,
4021         "SearchResultEntry/attributes", HFILL }},
4022     { &hf_ldap_PartialAttributeList_item,
4023       { "Item", "ldap.PartialAttributeList_item",
4024         FT_NONE, BASE_NONE, NULL, 0,
4025         "PartialAttributeList/_item", HFILL }},
4026     { &hf_ldap_SearchResultReference_item,
4027       { "Item", "ldap.SearchResultReference_item",
4028         FT_STRING, BASE_NONE, NULL, 0,
4029         "SearchResultReference/_item", HFILL }},
4030     { &hf_ldap_object,
4031       { "object", "ldap.object",
4032         FT_STRING, BASE_NONE, NULL, 0,
4033         "ModifyRequest/object", HFILL }},
4034     { &hf_ldap_modifyRequest_modification,
4035       { "modification", "ldap.modification",
4036         FT_UINT32, BASE_DEC, NULL, 0,
4037         "ModifyRequest/modification", HFILL }},
4038     { &hf_ldap_modifyRequest_modification_item,
4039       { "Item", "ldap.modification_item",
4040         FT_NONE, BASE_NONE, NULL, 0,
4041         "ModifyRequest/modification/_item", HFILL }},
4042     { &hf_ldap_operation,
4043       { "operation", "ldap.operation",
4044         FT_UINT32, BASE_DEC, VALS(ldap_T_operation_vals), 0,
4045         "ModifyRequest/modification/_item/operation", HFILL }},
4046     { &hf_ldap_modification,
4047       { "modification", "ldap.modification",
4048         FT_NONE, BASE_NONE, NULL, 0,
4049         "ModifyRequest/modification/_item/modification", HFILL }},
4050     { &hf_ldap_entry,
4051       { "entry", "ldap.entry",
4052         FT_STRING, BASE_NONE, NULL, 0,
4053         "", HFILL }},
4054     { &hf_ldap_attributes,
4055       { "attributes", "ldap.attributes",
4056         FT_UINT32, BASE_DEC, NULL, 0,
4057         "AddRequest/attributes", HFILL }},
4058     { &hf_ldap_AttributeList_item,
4059       { "Item", "ldap.AttributeList_item",
4060         FT_NONE, BASE_NONE, NULL, 0,
4061         "AttributeList/_item", HFILL }},
4062     { &hf_ldap_newrdn,
4063       { "newrdn", "ldap.newrdn",
4064         FT_STRING, BASE_NONE, NULL, 0,
4065         "ModifyDNRequest/newrdn", HFILL }},
4066     { &hf_ldap_deleteoldrdn,
4067       { "deleteoldrdn", "ldap.deleteoldrdn",
4068         FT_BOOLEAN, 8, NULL, 0,
4069         "ModifyDNRequest/deleteoldrdn", HFILL }},
4070     { &hf_ldap_newSuperior,
4071       { "newSuperior", "ldap.newSuperior",
4072         FT_STRING, BASE_NONE, NULL, 0,
4073         "ModifyDNRequest/newSuperior", HFILL }},
4074     { &hf_ldap_ava,
4075       { "ava", "ldap.ava",
4076         FT_NONE, BASE_NONE, NULL, 0,
4077         "CompareRequest/ava", HFILL }},
4078     { &hf_ldap_requestName,
4079       { "requestName", "ldap.requestName",
4080         FT_STRING, BASE_NONE, NULL, 0,
4081         "ExtendedRequest/requestName", HFILL }},
4082     { &hf_ldap_requestValue,
4083       { "requestValue", "ldap.requestValue",
4084         FT_BYTES, BASE_HEX, NULL, 0,
4085         "ExtendedRequest/requestValue", HFILL }},
4086     { &hf_ldap_extendedResponse_resultCode,
4087       { "resultCode", "ldap.resultCode",
4088         FT_UINT32, BASE_DEC, VALS(ldap_ExtendedResponse_resultCode_vals), 0,
4089         "ExtendedResponse/resultCode", HFILL }},
4090     { &hf_ldap_responseName,
4091       { "responseName", "ldap.responseName",
4092         FT_STRING, BASE_NONE, NULL, 0,
4093         "ExtendedResponse/responseName", HFILL }},
4094     { &hf_ldap_response,
4095       { "response", "ldap.response",
4096         FT_BYTES, BASE_HEX, NULL, 0,
4097         "ExtendedResponse/response", HFILL }},
4098
4099 /*--- End of included file: packet-ldap-hfarr.c ---*/
4100 #line 1469 "packet-ldap-template.c"
4101   };
4102
4103   /* List of subtrees */
4104   static gint *ett[] = {
4105     &ett_ldap,
4106     &ett_ldap_payload,
4107     &ett_ldap_sasl_blob,
4108     &ett_ldap_msg,
4109     &ett_mscldap_netlogon_flags,
4110
4111
4112 /*--- Included file: packet-ldap-ettarr.c ---*/
4113 #line 1 "packet-ldap-ettarr.c"
4114     &ett_ldap_LDAPMessage,
4115     &ett_ldap_ProtocolOp,
4116     &ett_ldap_AttributeDescriptionList,
4117     &ett_ldap_AttributeValueAssertion,
4118     &ett_ldap_Attribute,
4119     &ett_ldap_SET_OF_AttributeValue,
4120     &ett_ldap_LDAPResult,
4121     &ett_ldap_Referral,
4122     &ett_ldap_Controls,
4123     &ett_ldap_Control,
4124     &ett_ldap_BindRequest,
4125     &ett_ldap_AuthenticationChoice,
4126     &ett_ldap_SaslCredentials,
4127     &ett_ldap_BindResponse,
4128     &ett_ldap_SearchRequest,
4129     &ett_ldap_Filter,
4130     &ett_ldap_T_and,
4131     &ett_ldap_T_or,
4132     &ett_ldap_SubstringFilter,
4133     &ett_ldap_T_substringFilter_substrings,
4134     &ett_ldap_T_substringFilter_substrings_item,
4135     &ett_ldap_MatchingRuleAssertion,
4136     &ett_ldap_SearchResultEntry,
4137     &ett_ldap_PartialAttributeList,
4138     &ett_ldap_PartialAttributeList_item,
4139     &ett_ldap_SearchResultReference,
4140     &ett_ldap_ModifyRequest,
4141     &ett_ldap_ModifyRequest_modification,
4142     &ett_ldap_T_modifyRequest_modification_item,
4143     &ett_ldap_AttributeTypeAndValues,
4144     &ett_ldap_AddRequest,
4145     &ett_ldap_AttributeList,
4146     &ett_ldap_AttributeList_item,
4147     &ett_ldap_ModifyDNRequest,
4148     &ett_ldap_CompareRequest,
4149     &ett_ldap_ExtendedRequest,
4150     &ett_ldap_ExtendedResponse,
4151
4152 /*--- End of included file: packet-ldap-ettarr.c ---*/
4153 #line 1480 "packet-ldap-template.c"
4154   };
4155
4156     module_t *ldap_module;
4157
4158   /* Register protocol */
4159   proto_ldap = proto_register_protocol(PNAME, PSNAME, PFNAME);
4160   /* Register fields and subtrees */
4161   proto_register_field_array(proto_ldap, hf, array_length(hf));
4162   proto_register_subtree_array(ett, array_length(ett));
4163
4164
4165   register_dissector("ldap", dissect_ldap, proto_ldap);
4166
4167   ldap_module = prefs_register_protocol(proto_ldap, NULL);
4168   prefs_register_bool_preference(ldap_module, "desegment_ldap_messages",
4169     "Reassemble LDAP messages spanning multiple TCP segments",
4170     "Whether the LDAP dissector should reassemble messages spanning multiple TCP segments."
4171     " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings, and disable \"Verify length\" in the BER protocol settings",
4172     &ldap_desegment);
4173
4174   prefs_register_uint_preference(ldap_module, "tcp.port", "LDAP TCP Port",
4175                                  "Set the port for LDAP operations",
4176                                  10, &ldap_tcp_port);
4177
4178   proto_cldap = proto_register_protocol(
4179           "Connectionless Lightweight Directory Access Protocol",
4180           "CLDAP", "cldap");
4181
4182   register_init_routine(ldap_reinit);
4183   ldap_tap=register_tap("ldap");
4184
4185   ldap_name_dissector_table = register_dissector_table("ldap.name", "LDAP Attribute Type Dissectors", FT_STRING, BASE_NONE);
4186
4187 }
4188
4189
4190 /*--- proto_reg_handoff_ldap ---------------------------------------*/
4191 void
4192 proto_reg_handoff_ldap(void)
4193 {
4194         dissector_handle_t ldap_handle, cldap_handle;
4195         ldap_handle = create_dissector_handle(dissect_ldap, proto_ldap);
4196
4197         dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
4198         dissector_add("tcp.port", TCP_PORT_GLOBALCAT_LDAP, ldap_handle);
4199
4200         cldap_handle = create_dissector_handle(dissect_mscldap, proto_cldap);
4201         dissector_add("udp.port", UDP_PORT_CLDAP, cldap_handle);
4202
4203         gssapi_handle = find_dissector("gssapi");
4204         gssapi_wrap_handle = find_dissector("gssapi_verf");
4205
4206 /*  http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dsml/dsml/ldap_controls_and_session_support.asp */
4207         add_oid_str_name("1.2.840.113556.1.4.319","LDAP_PAGED_RESULT_OID_STRING");
4208         add_oid_str_name("1.2.840.113556.1.4.417","LDAP_SERVER_SHOW_DELETED_OID");
4209         add_oid_str_name("1.2.840.113556.1.4.473","LDAP_SERVER_SORT_OID");
4210         add_oid_str_name("1.2.840.113556.1.4.474","LDAP_CONTROL_SORT_RESP_OID");
4211         add_oid_str_name("1.2.840.113556.1.4.521","LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID");
4212         add_oid_str_name("1.2.840.113556.1.4.528","LDAP_SERVER_NOTIFICATION_OID");
4213         add_oid_str_name("1.2.840.113556.1.4.529","LDAP_SERVER_EXTENDED_DN_OID");
4214         add_oid_str_name("1.2.840.113556.1.4.619","LDAP_SERVER_LAZY_COMMIT_OID");
4215         add_oid_str_name("1.2.840.113556.1.4.800","LDAP_CAP_ACTIVE_DIRECTORY_OID");
4216         add_oid_str_name("1.2.840.113556.1.4.801","LDAP_SERVER_SD_FLAGS_OID");
4217         add_oid_str_name("1.2.840.113556.1.4.804","LDAP_OID_COMPARATOR_OR");
4218         add_oid_str_name("1.2.840.113556.1.4.805","LDAP_SERVER_TREE_DELETE_OID");
4219         add_oid_str_name("1.2.840.113556.1.4.841","LDAP_SERVER_DIRSYNC_OID");
4220         add_oid_str_name("1.2.840.113556.1.4.970 ","None");
4221         add_oid_str_name("1.2.840.113556.1.4.1338","LDAP_SERVER_VERIFY_NAME_OID");
4222         add_oid_str_name("1.2.840.113556.1.4.1339","LDAP_SERVER_DOMAIN_SCOPE_OID");
4223         add_oid_str_name("1.2.840.113556.1.4.1340","LDAP_SERVER_SEARCH_OPTIONS_OID");
4224         add_oid_str_name("1.2.840.113556.1.4.1413","LDAP_SERVER_PERMISSIVE_MODIFY_OID");
4225         add_oid_str_name("1.2.840.113556.1.4.1504","LDAP_SERVER_ASQ_OID");
4226         add_oid_str_name("1.2.840.113556.1.4.1670","LDAP_CAP_ACTIVE_DIRECTORY_V51_OID");
4227         add_oid_str_name("1.2.840.113556.1.4.1781","LDAP_SERVER_FAST_BIND_OID");
4228         add_oid_str_name("1.2.840.113556.1.4.1791","LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID");
4229         add_oid_str_name("1.2.840.113556.1.4.1851","LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID");
4230         add_oid_str_name("1.3.6.1.4.1.1466.101.119.1","None");
4231         add_oid_str_name("1.3.6.1.4.1.1466.20037","LDAP_START_TLS_OID");
4232         add_oid_str_name("2.16.840.1.113730.3.4.9","LDAP_CONTROL_VLVREQUEST VLV");
4233         add_oid_str_name("2.16.840.1.113730.3.4.10","LDAP_CONTROL_VLVRESPONSE VLV");
4234
4235         register_ldap_name_dissector("netlogon", dissect_NetLogon_PDU, proto_cldap);
4236         register_ldap_name_dissector("objectGUID", dissect_ldap_guid, proto_ldap);
4237         register_ldap_name_dissector("supportedControl", dissect_ldap_oid, proto_ldap);
4238         register_ldap_name_dissector("supportedCapabilities", dissect_ldap_oid, proto_ldap);
4239 }
4240
4241