remove some compiler warning due to unused pinfo parameter
[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 -X -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 #include <epan/asn1.h>
99
100 #include "packet-frame.h"
101 #include "packet-ldap.h"
102 #include "packet-ntlmssp.h"
103
104 #include "packet-ber.h"
105 #include "packet-per.h"
106
107 #define PNAME  "Lightweight-Directory-Access-Protocol"
108 #define PSNAME "LDAP"
109 #define PFNAME "ldap"
110
111 /* Initialize the protocol and registered fields */
112 static int ldap_tap = -1;
113 static int proto_ldap = -1;
114 static int proto_cldap = -1;
115
116 static int hf_ldap_sasl_buffer_length = -1;
117 static int hf_ldap_response_in = -1;
118 static int hf_ldap_response_to = -1;
119 static int hf_ldap_time = -1;
120 static int hf_ldap_guid = -1;
121
122 static int hf_mscldap_netlogon_type = -1;
123 static int hf_mscldap_netlogon_flags = -1;
124 static int hf_mscldap_netlogon_flags_pdc = -1;
125 static int hf_mscldap_netlogon_flags_gc = -1;
126 static int hf_mscldap_netlogon_flags_ldap = -1;
127 static int hf_mscldap_netlogon_flags_ds = -1;
128 static int hf_mscldap_netlogon_flags_kdc = -1;
129 static int hf_mscldap_netlogon_flags_timeserv = -1;
130 static int hf_mscldap_netlogon_flags_closest = -1;
131 static int hf_mscldap_netlogon_flags_writable = -1;
132 static int hf_mscldap_netlogon_flags_good_timeserv = -1;
133 static int hf_mscldap_netlogon_flags_ndnc = -1;
134 static int hf_mscldap_domain_guid = -1;
135 static int hf_mscldap_forest = -1;
136 static int hf_mscldap_domain = -1;
137 static int hf_mscldap_hostname = -1;
138 static int hf_mscldap_nb_domain = -1;
139 static int hf_mscldap_nb_hostname = -1;
140 static int hf_mscldap_username = -1;
141 static int hf_mscldap_sitename = -1;
142 static int hf_mscldap_clientsitename = -1;
143 static int hf_mscldap_netlogon_version = -1;
144 static int hf_mscldap_netlogon_lm_token = -1;
145 static int hf_mscldap_netlogon_nt_token = -1;
146 static int hf_ldap_sid = -1;
147 static int hf_ldap_AccessMask_ADS_CREATE_CHILD = -1;
148 static int hf_ldap_AccessMask_ADS_DELETE_CHILD = -1;
149 static int hf_ldap_AccessMask_ADS_LIST = -1;
150 static int hf_ldap_AccessMask_ADS_SELF_WRITE = -1;
151 static int hf_ldap_AccessMask_ADS_READ_PROP = -1;
152 static int hf_ldap_AccessMask_ADS_WRITE_PROP = -1;
153 static int hf_ldap_AccessMask_ADS_DELETE_TREE = -1;
154 static int hf_ldap_AccessMask_ADS_LIST_OBJECT = -1;
155 static int hf_ldap_AccessMask_ADS_CONTROL_ACCESS = -1;
156
157
158 /*--- Included file: packet-ldap-hf.c ---*/
159 #line 1 "packet-ldap-hf.c"
160 static int hf_ldap_LDAPMessage_PDU = -1;          /* LDAPMessage */
161 static int hf_ldap_SearchControlValue_PDU = -1;   /* SearchControlValue */
162 static int hf_ldap_SortKeyList_PDU = -1;          /* SortKeyList */
163 static int hf_ldap_SortResult_PDU = -1;           /* SortResult */
164 static int hf_ldap_ReplControlValue_PDU = -1;     /* ReplControlValue */
165 static int hf_ldap_messageID = -1;                /* MessageID */
166 static int hf_ldap_protocolOp = -1;               /* ProtocolOp */
167 static int hf_ldap_controls = -1;                 /* Controls */
168 static int hf_ldap_bindRequest = -1;              /* BindRequest */
169 static int hf_ldap_bindResponse = -1;             /* BindResponse */
170 static int hf_ldap_unbindRequest = -1;            /* UnbindRequest */
171 static int hf_ldap_searchRequest = -1;            /* SearchRequest */
172 static int hf_ldap_searchResEntry = -1;           /* SearchResultEntry */
173 static int hf_ldap_searchResDone = -1;            /* SearchResultDone */
174 static int hf_ldap_searchResRef = -1;             /* SearchResultReference */
175 static int hf_ldap_modifyRequest = -1;            /* ModifyRequest */
176 static int hf_ldap_modifyResponse = -1;           /* ModifyResponse */
177 static int hf_ldap_addRequest = -1;               /* AddRequest */
178 static int hf_ldap_addResponse = -1;              /* AddResponse */
179 static int hf_ldap_delRequest = -1;               /* DelRequest */
180 static int hf_ldap_delResponse = -1;              /* DelResponse */
181 static int hf_ldap_modDNRequest = -1;             /* ModifyDNRequest */
182 static int hf_ldap_modDNResponse = -1;            /* ModifyDNResponse */
183 static int hf_ldap_compareRequest = -1;           /* CompareRequest */
184 static int hf_ldap_compareResponse = -1;          /* CompareResponse */
185 static int hf_ldap_abandonRequest = -1;           /* AbandonRequest */
186 static int hf_ldap_extendedReq = -1;              /* ExtendedRequest */
187 static int hf_ldap_extendedResp = -1;             /* ExtendedResponse */
188 static int hf_ldap_AttributeDescriptionList_item = -1;  /* AttributeDescription */
189 static int hf_ldap_attributeDesc = -1;            /* AttributeDescription */
190 static int hf_ldap_assertionValue = -1;           /* AssertionValue */
191 static int hf_ldap_type = -1;                     /* AttributeDescription */
192 static int hf_ldap_vals = -1;                     /* SET_OF_AttributeValue */
193 static int hf_ldap_vals_item = -1;                /* AttributeValue */
194 static int hf_ldap_resultCode = -1;               /* T_resultCode */
195 static int hf_ldap_matchedDN = -1;                /* LDAPDN */
196 static int hf_ldap_errorMessage = -1;             /* ErrorMessage */
197 static int hf_ldap_referral = -1;                 /* Referral */
198 static int hf_ldap_Referral_item = -1;            /* LDAPURL */
199 static int hf_ldap_Controls_item = -1;            /* Control */
200 static int hf_ldap_controlType = -1;              /* ControlType */
201 static int hf_ldap_criticality = -1;              /* BOOLEAN */
202 static int hf_ldap_controlValue = -1;             /* T_controlValue */
203 static int hf_ldap_version = -1;                  /* INTEGER_1_127 */
204 static int hf_ldap_name = -1;                     /* LDAPDN */
205 static int hf_ldap_authentication = -1;           /* AuthenticationChoice */
206 static int hf_ldap_simple = -1;                   /* Simple */
207 static int hf_ldap_sasl = -1;                     /* SaslCredentials */
208 static int hf_ldap_ntlmsspNegotiate = -1;         /* T_ntlmsspNegotiate */
209 static int hf_ldap_ntlmsspAuth = -1;              /* T_ntlmsspAuth */
210 static int hf_ldap_mechanism = -1;                /* Mechanism */
211 static int hf_ldap_credentials = -1;              /* Credentials */
212 static int hf_ldap_bindResponse_resultCode = -1;  /* BindResponse_resultCode */
213 static int hf_ldap_matchedDN_01 = -1;             /* T_matchedDN */
214 static int hf_ldap_serverSaslCreds = -1;          /* ServerSaslCreds */
215 static int hf_ldap_baseObject = -1;               /* LDAPDN */
216 static int hf_ldap_scope = -1;                    /* T_scope */
217 static int hf_ldap_derefAliases = -1;             /* T_derefAliases */
218 static int hf_ldap_sizeLimit = -1;                /* INTEGER_0_maxInt */
219 static int hf_ldap_timeLimit = -1;                /* INTEGER_0_maxInt */
220 static int hf_ldap_typesOnly = -1;                /* BOOLEAN */
221 static int hf_ldap_filter = -1;                   /* T_filter */
222 static int hf_ldap_searchRequest_attributes = -1;  /* AttributeDescriptionList */
223 static int hf_ldap_and = -1;                      /* T_and */
224 static int hf_ldap_and_item = -1;                 /* T_and_item */
225 static int hf_ldap_or = -1;                       /* T_or */
226 static int hf_ldap_or_item = -1;                  /* T_or_item */
227 static int hf_ldap_not = -1;                      /* T_not */
228 static int hf_ldap_equalityMatch = -1;            /* T_equalityMatch */
229 static int hf_ldap_substrings = -1;               /* SubstringFilter */
230 static int hf_ldap_greaterOrEqual = -1;           /* T_greaterOrEqual */
231 static int hf_ldap_lessOrEqual = -1;              /* T_lessOrEqual */
232 static int hf_ldap_present = -1;                  /* T_present */
233 static int hf_ldap_approxMatch = -1;              /* T_approxMatch */
234 static int hf_ldap_extensibleMatch = -1;          /* T_extensibleMatch */
235 static int hf_ldap_substringFilter_substrings = -1;  /* T_substringFilter_substrings */
236 static int hf_ldap_substringFilter_substrings_item = -1;  /* T_substringFilter_substrings_item */
237 static int hf_ldap_initial = -1;                  /* LDAPString */
238 static int hf_ldap_any = -1;                      /* LDAPString */
239 static int hf_ldap_final = -1;                    /* LDAPString */
240 static int hf_ldap_matchingRule = -1;             /* MatchingRuleId */
241 static int hf_ldap_matchValue = -1;               /* AssertionValue */
242 static int hf_ldap_dnAttributes = -1;             /* T_dnAttributes */
243 static int hf_ldap_objectName = -1;               /* LDAPDN */
244 static int hf_ldap_searchResultEntry_attributes = -1;  /* PartialAttributeList */
245 static int hf_ldap_PartialAttributeList_item = -1;  /* PartialAttributeList_item */
246 static int hf_ldap_SearchResultReference_item = -1;  /* LDAPURL */
247 static int hf_ldap_object = -1;                   /* LDAPDN */
248 static int hf_ldap_modifyRequest_modification = -1;  /* ModifyRequest_modification */
249 static int hf_ldap_modifyRequest_modification_item = -1;  /* T_modifyRequest_modification_item */
250 static int hf_ldap_operation = -1;                /* T_operation */
251 static int hf_ldap_modification = -1;             /* AttributeTypeAndValues */
252 static int hf_ldap_entry = -1;                    /* LDAPDN */
253 static int hf_ldap_attributes = -1;               /* AttributeList */
254 static int hf_ldap_AttributeList_item = -1;       /* AttributeList_item */
255 static int hf_ldap_newrdn = -1;                   /* RelativeLDAPDN */
256 static int hf_ldap_deleteoldrdn = -1;             /* BOOLEAN */
257 static int hf_ldap_newSuperior = -1;              /* LDAPDN */
258 static int hf_ldap_ava = -1;                      /* AttributeValueAssertion */
259 static int hf_ldap_requestName = -1;              /* LDAPOID */
260 static int hf_ldap_requestValue = -1;             /* OCTET_STRING */
261 static int hf_ldap_extendedResponse_resultCode = -1;  /* ExtendedResponse_resultCode */
262 static int hf_ldap_responseName = -1;             /* ResponseName */
263 static int hf_ldap_response = -1;                 /* OCTET_STRING */
264 static int hf_ldap_size = -1;                     /* INTEGER */
265 static int hf_ldap_cookie = -1;                   /* OCTET_STRING */
266 static int hf_ldap_SortKeyList_item = -1;         /* SortKeyList_item */
267 static int hf_ldap_attributeType = -1;            /* AttributeDescription */
268 static int hf_ldap_orderingRule = -1;             /* MatchingRuleId */
269 static int hf_ldap_reverseOrder = -1;             /* BOOLEAN */
270 static int hf_ldap_sortResult = -1;               /* T_sortResult */
271 static int hf_ldap_parentsFirst = -1;             /* INTEGER */
272 static int hf_ldap_maxReturnLength = -1;          /* INTEGER */
273
274 /*--- End of included file: packet-ldap-hf.c ---*/
275 #line 150 "packet-ldap-template.c"
276
277 /* Initialize the subtree pointers */
278 static gint ett_ldap = -1;
279 static gint ett_ldap_msg = -1;
280 static gint ett_ldap_sasl_blob = -1;
281 static guint ett_ldap_payload = -1;
282 static gint ett_mscldap_netlogon_flags = -1;
283
284
285 /*--- Included file: packet-ldap-ett.c ---*/
286 #line 1 "packet-ldap-ett.c"
287 static gint ett_ldap_LDAPMessage = -1;
288 static gint ett_ldap_ProtocolOp = -1;
289 static gint ett_ldap_AttributeDescriptionList = -1;
290 static gint ett_ldap_AttributeValueAssertion = -1;
291 static gint ett_ldap_Attribute = -1;
292 static gint ett_ldap_SET_OF_AttributeValue = -1;
293 static gint ett_ldap_LDAPResult = -1;
294 static gint ett_ldap_Referral = -1;
295 static gint ett_ldap_Controls = -1;
296 static gint ett_ldap_Control = -1;
297 static gint ett_ldap_BindRequest = -1;
298 static gint ett_ldap_AuthenticationChoice = -1;
299 static gint ett_ldap_SaslCredentials = -1;
300 static gint ett_ldap_BindResponse = -1;
301 static gint ett_ldap_SearchRequest = -1;
302 static gint ett_ldap_Filter = -1;
303 static gint ett_ldap_T_and = -1;
304 static gint ett_ldap_T_or = -1;
305 static gint ett_ldap_SubstringFilter = -1;
306 static gint ett_ldap_T_substringFilter_substrings = -1;
307 static gint ett_ldap_T_substringFilter_substrings_item = -1;
308 static gint ett_ldap_MatchingRuleAssertion = -1;
309 static gint ett_ldap_SearchResultEntry = -1;
310 static gint ett_ldap_PartialAttributeList = -1;
311 static gint ett_ldap_PartialAttributeList_item = -1;
312 static gint ett_ldap_SearchResultReference = -1;
313 static gint ett_ldap_ModifyRequest = -1;
314 static gint ett_ldap_ModifyRequest_modification = -1;
315 static gint ett_ldap_T_modifyRequest_modification_item = -1;
316 static gint ett_ldap_AttributeTypeAndValues = -1;
317 static gint ett_ldap_AddRequest = -1;
318 static gint ett_ldap_AttributeList = -1;
319 static gint ett_ldap_AttributeList_item = -1;
320 static gint ett_ldap_ModifyDNRequest = -1;
321 static gint ett_ldap_CompareRequest = -1;
322 static gint ett_ldap_ExtendedRequest = -1;
323 static gint ett_ldap_ExtendedResponse = -1;
324 static gint ett_ldap_SearchControlValue = -1;
325 static gint ett_ldap_SortKeyList = -1;
326 static gint ett_ldap_SortKeyList_item = -1;
327 static gint ett_ldap_SortResult = -1;
328 static gint ett_ldap_ReplControlValue = -1;
329
330 /*--- End of included file: packet-ldap-ett.c ---*/
331 #line 159 "packet-ldap-template.c"
332
333 static dissector_table_t ldap_name_dissector_table=NULL;
334 static const char *object_identifier_id = NULL; /* LDAP OID */
335
336 /* desegmentation of LDAP */
337 static gboolean ldap_desegment = TRUE;
338 static guint    ldap_tcp_port = 389;
339
340 static gboolean do_protocolop = FALSE;
341 static gchar    *attr_type = NULL;
342 static gboolean is_binary_attr_type = FALSE;
343
344 #define TCP_PORT_LDAP                   389
345 #define UDP_PORT_CLDAP                  389
346 #define TCP_PORT_GLOBALCAT_LDAP         3268 /* Windows 2000 Global Catalog */
347
348 static dissector_handle_t gssapi_handle;
349 static dissector_handle_t gssapi_wrap_handle;
350 static dissector_handle_t ntlmssp_handle = NULL;
351 static dissector_handle_t spnego_handle;
352
353 /* different types of rpc calls ontop of ms cldap */
354 #define MSCLDAP_RPC_NETLOGON    1
355
356 /* Message type Choice values */
357 static const value_string ldap_ProtocolOp_choice_vals[] = {
358   {   0, "bindRequest" },
359   {   1, "bindResponse" },
360   {   2, "unbindRequest" },
361   {   3, "searchRequest" },
362   {   4, "searchResEntry" },
363   {   5, "searchResDone" },
364   {       6, "searchResRef" },
365   {   7, "modifyRequest" },
366   {   8, "modifyResponse" },
367   {   9, "addRequest" },
368   {  10, "addResponse" },
369   {  11, "delRequest" },
370   {  12, "delResponse" },
371   {  13, "modDNRequest" },
372   {  14, "modDNResponse" },
373   {  15, "compareRequest" },
374   {  16, "compareResponse" },
375   {  17, "abandonRequest" },
376   {  18, "extendedReq" },
377   {  19, "extendedResp" },
378   { 0, NULL }
379 };
380 /*
381  * Data structure attached to a conversation, giving authentication
382  * information from a bind request.
383  * We keep a linked list of them, so that we can free up all the
384  * authentication mechanism strings.
385  */
386 typedef struct ldap_conv_info_t {
387   struct ldap_conv_info_t *next;
388   guint auth_type;              /* authentication type */
389   char *auth_mech;              /* authentication mechanism */
390   guint32 first_auth_frame;     /* first frame that would use a security layer */
391   GHashTable *unmatched;
392   GHashTable *matched;
393   gboolean is_mscldap;
394   guint32  num_results;
395 } ldap_conv_info_t;
396 static ldap_conv_info_t *ldap_info_items;
397
398 static guint
399 ldap_info_hash_matched(gconstpointer k)
400 {
401   const ldap_call_response_t *key = k;
402
403   return key->messageId;
404 }
405
406 static gint
407 ldap_info_equal_matched(gconstpointer k1, gconstpointer k2)
408 {
409   const ldap_call_response_t *key1 = k1;
410   const ldap_call_response_t *key2 = k2;
411
412   if( key1->req_frame && key2->req_frame && (key1->req_frame!=key2->req_frame) ){
413     return 0;
414   }
415   /* a response may span multiple frames
416   if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
417     return 0;
418   }
419   */
420
421   return key1->messageId==key2->messageId;
422 }
423
424 static guint
425 ldap_info_hash_unmatched(gconstpointer k)
426 {
427   const ldap_call_response_t *key = k;
428
429   return key->messageId;
430 }
431
432 static gint
433 ldap_info_equal_unmatched(gconstpointer k1, gconstpointer k2)
434 {
435   const ldap_call_response_t *key1 = k1;
436   const ldap_call_response_t *key2 = k2;
437
438   return key1->messageId==key2->messageId;
439 }
440
441 /* This string contains the last LDAPString that was decoded */
442 static char *attributedesc_string=NULL;
443
444 /* This string contains the last AssertionValue that was decoded */
445 static char *ldapvalue_string=NULL;
446
447 /* if the octet string contain all printable ASCII characters, then
448  * display it as a string, othervise just display it in hex.
449  */
450 static int
451 dissect_ldap_AssertionValue(gboolean implicit_tag, tvbuff_t *tvb, int offset, asn1_ctx_t *actx _U_, proto_tree *tree, int hf_index)
452 {
453         gint8 class;
454         gboolean pc, ind, is_ascii;
455         gint32 tag;
456         guint32 len, i;
457         const guchar *str;
458
459         if(!implicit_tag){
460                 offset=get_ber_identifier(tvb, offset, &class, &pc, &tag);
461                 offset=get_ber_length(NULL, tvb, offset, &len, &ind);
462         } else {
463                 len=tvb_length_remaining(tvb,offset);
464         }
465
466         if(len==0){
467                 return offset;
468         }
469
470
471         /*
472          * Some special/wellknown attributes in common LDAP (read AD)
473          * are neither ascii strings nor blobs of hex data.
474          * Special case these attributes and decode them more nicely.
475          *
476          * Add more special cases as required to prettify further
477          * (there cant be that many ones that are truly interesting)
478          */
479         if(attributedesc_string && !strncmp("DomainSid", attributedesc_string, 9)){
480                 tvbuff_t *sid_tvb;
481                 char *tmpstr;
482
483                 /* this octet string contains an NT SID */
484                 sid_tvb=tvb_new_subset(tvb, offset, len, len);
485                 dissect_nt_sid(sid_tvb, 0, tree, "SID", &tmpstr, hf_index);
486                 ldapvalue_string=tmpstr;
487
488                 goto finished;
489         } else if ( (len==16) /* GUIDs are always 16 bytes */
490         && (attributedesc_string && !strncmp("DomainGuid", attributedesc_string, 10))) {
491                 guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
492                 e_uuid_t uuid;
493
494                 /* This octet string contained a GUID */
495                 dissect_dcerpc_uuid_t(tvb, offset, actx->pinfo, tree, drep, hf_ldap_guid, &uuid);
496
497                 ldapvalue_string=ep_alloc(1024);
498                 g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
499                           uuid.Data1, uuid.Data2, uuid.Data3,
500                           uuid.Data4[0], uuid.Data4[1],
501                           uuid.Data4[2], uuid.Data4[3],
502                           uuid.Data4[4], uuid.Data4[5],
503                           uuid.Data4[6], uuid.Data4[7]);
504
505                 goto finished;
506         }
507
508         /*
509          * It was not one of our "wellknown" attributes so make the best
510          * we can and just try to see if it is an ascii string or if it
511          * is a binary blob.
512          *
513          * XXX - should we support reading RFC 2252-style schemas
514          * for LDAP, and using that to determine how to display
515          * attribute values and assertion values?
516          *
517          * -- I dont think there are full schemas available that describe the
518          *  interesting cases i.e. AD -- ronnie
519          */
520         str=tvb_get_ptr(tvb, offset, len);
521         is_ascii=TRUE;
522         for(i=0;i<len;i++){
523                 if(!isascii(str[i]) || !isprint(str[i])){
524                         is_ascii=FALSE;
525                         break;
526                 }
527         }
528
529         /* convert the string into a printable string */
530         if(is_ascii){
531                 ldapvalue_string=ep_alloc(len+1);
532                 memcpy(ldapvalue_string,str,len);
533                 ldapvalue_string[i]=0;
534         } else {
535                 ldapvalue_string=ep_alloc(3*len);
536                 for(i=0;i<len;i++){
537                         g_snprintf(ldapvalue_string+i*3,3,"%02x",str[i]&0xff);
538                         ldapvalue_string[3*i+2]=':';
539                 }
540                 ldapvalue_string[3*len-1]=0;
541         }
542
543         proto_tree_add_string(tree, hf_index, tvb, offset, len, ldapvalue_string);
544
545
546 finished:
547         offset+=len;
548         return offset;
549 }
550
551 /* This string contains the last Filter item that was decoded */
552 static char *Filter_string=NULL;
553 static char *and_filter_string=NULL;
554 static char *or_filter_string=NULL;
555 static char *substring_value=NULL;
556 static char *substring_item_init=NULL;
557 static char *substring_item_any=NULL;
558 static char *substring_item_final=NULL;
559 static char *matching_rule_string=NULL;
560 static gboolean matching_rule_dnattr=FALSE;
561
562 /* Global variables */
563 char *mechanism = NULL;
564 static gint MessageID =-1;
565 static gint ProtocolOp = -1;
566 static gint result = 0;
567 static proto_item *ldm_tree = NULL; /* item to add text to */
568
569 static void ldap_do_protocolop(packet_info *pinfo)
570 {
571   const gchar* valstr;
572
573   if (do_protocolop)  {
574
575     valstr = val_to_str(ProtocolOp, ldap_ProtocolOp_choice_vals, "Unknown (%%u)");
576
577     if(check_col(pinfo->cinfo, COL_INFO))
578       col_append_fstr(pinfo->cinfo, COL_INFO, "%s(%u) ", valstr, MessageID);
579
580     if(ldm_tree)
581       proto_item_append_text(ldm_tree, " %s(%d)", valstr, MessageID);
582
583     do_protocolop = FALSE;
584
585   }
586 }
587
588 static ldap_call_response_t *
589 ldap_match_call_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint messageId, guint protocolOpTag)
590 {
591   ldap_call_response_t lcr, *lcrp=NULL;
592   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)pinfo->private_data;
593
594   /* first see if we have already matched this */
595
596       lcr.messageId=messageId;
597       switch(protocolOpTag){
598         case LDAP_REQ_BIND:
599         case LDAP_REQ_SEARCH:
600         case LDAP_REQ_MODIFY:
601         case LDAP_REQ_ADD:
602         case LDAP_REQ_DELETE:
603         case LDAP_REQ_MODRDN:
604         case LDAP_REQ_COMPARE:
605           lcr.is_request=TRUE;
606           lcr.req_frame=pinfo->fd->num;
607           lcr.rep_frame=0;
608           break;
609         case LDAP_RES_BIND:
610         case LDAP_RES_SEARCH_ENTRY:
611         case LDAP_RES_SEARCH_REF:
612         case LDAP_RES_SEARCH_RESULT:
613         case LDAP_RES_MODIFY:
614         case LDAP_RES_ADD:
615         case LDAP_RES_DELETE:
616         case LDAP_RES_MODRDN:
617         case LDAP_RES_COMPARE:
618           lcr.is_request=FALSE;
619           lcr.req_frame=0;
620           lcr.rep_frame=pinfo->fd->num;
621           break;
622       }
623       lcrp=g_hash_table_lookup(ldap_info->matched, &lcr);
624
625       if(lcrp){
626
627         lcrp->is_request=lcr.is_request;
628
629       } else {
630
631                   /* we haven't found a match - try and match it up */
632
633   switch(protocolOpTag){
634       case LDAP_REQ_BIND:
635       case LDAP_REQ_SEARCH:
636       case LDAP_REQ_MODIFY:
637       case LDAP_REQ_ADD:
638       case LDAP_REQ_DELETE:
639       case LDAP_REQ_MODRDN:
640       case LDAP_REQ_COMPARE:
641
642                 /* this a a request - add it to the unmatched list */
643
644         /* check that we dont already have one of those in the
645            unmatched list and if so remove it */
646
647         lcr.messageId=messageId;
648         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
649         if(lcrp){
650           g_hash_table_remove(ldap_info->unmatched, lcrp);
651         }
652         /* if we cant reuse the old one, grab a new chunk */
653         if(!lcrp){
654           lcrp=se_alloc(sizeof(ldap_call_response_t));
655         }
656         lcrp->messageId=messageId;
657         lcrp->req_frame=pinfo->fd->num;
658         lcrp->req_time=pinfo->fd->abs_ts;
659         lcrp->rep_frame=0;
660         lcrp->protocolOpTag=protocolOpTag;
661         lcrp->is_request=TRUE;
662         g_hash_table_insert(ldap_info->unmatched, lcrp, lcrp);
663         return NULL;
664         break;
665       case LDAP_RES_BIND:
666       case LDAP_RES_SEARCH_ENTRY:
667       case LDAP_RES_SEARCH_REF:
668       case LDAP_RES_SEARCH_RESULT:
669       case LDAP_RES_MODIFY:
670       case LDAP_RES_ADD:
671       case LDAP_RES_DELETE:
672       case LDAP_RES_MODRDN:
673       case LDAP_RES_COMPARE:
674
675                 /* this is a result - it should be in our unmatched list */
676
677         lcr.messageId=messageId;
678         lcrp=g_hash_table_lookup(ldap_info->unmatched, &lcr);
679
680         if(lcrp){
681
682           if(!lcrp->rep_frame){
683             g_hash_table_remove(ldap_info->unmatched, lcrp);
684             lcrp->rep_frame=pinfo->fd->num;
685             lcrp->is_request=FALSE;
686             g_hash_table_insert(ldap_info->matched, lcrp, lcrp);
687           }
688         }
689
690         break;
691           }
692
693         }
694     /* we have found a match */
695
696     if(lcrp){
697       proto_item *it;
698
699       if(lcrp->is_request){
700         it=proto_tree_add_uint(tree, hf_ldap_response_in, tvb, 0, 0, lcrp->rep_frame);
701         PROTO_ITEM_SET_GENERATED(it);
702       } else {
703         nstime_t ns;
704         it=proto_tree_add_uint(tree, hf_ldap_response_to, tvb, 0, 0, lcrp->req_frame);
705         PROTO_ITEM_SET_GENERATED(it);
706         nstime_delta(&ns, &pinfo->fd->abs_ts, &lcrp->req_time);
707         it=proto_tree_add_time(tree, hf_ldap_time, tvb, 0, 0, &ns);
708         PROTO_ITEM_SET_GENERATED(it);
709       }
710     }
711
712     return lcrp;
713 }
714
715
716 /*--- Included file: packet-ldap-fn.c ---*/
717 #line 1 "packet-ldap-fn.c"
718 /*--- Cyclic dependencies ---*/
719
720 /* Filter -> Filter/and -> Filter/and/_item -> Filter */
721 /* Filter -> Filter/or -> Filter/or/_item -> Filter */
722 /* Filter -> Filter/not -> Filter */
723 static int dissect_ldap_Filter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_);
724
725
726
727
728 static int
729 dissect_ldap_MessageID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
730 #line 67 "ldap.cnf"
731
732     offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
733                                   &MessageID);
734
735   
736   ldm_tree = tree;
737
738
739
740   return offset;
741 }
742
743
744
745 static int
746 dissect_ldap_INTEGER_1_127(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
747   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
748                                   NULL);
749
750   return offset;
751 }
752
753
754
755 static int
756 dissect_ldap_LDAPString(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
757 #line 266 "ldap.cnf"
758   tvbuff_t      *parameter_tvb = NULL;
759   char          *ldapstring;
760   gchar         *sc = NULL; /* semi-colon pointer */
761  
762     offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
763                                        &parameter_tvb);
764
765
766   if (parameter_tvb || (hf_index == hf_ldap_baseObject)) {
767   
768      ldap_do_protocolop(actx->pinfo);
769
770      if(parameter_tvb)
771         ldapstring = tvb_get_ephemeral_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb, 0));
772      else
773         ldapstring = "<ROOT>";
774
775      if(hf_index == hf_ldap_baseObject) {
776         /* this is search - put it on the scanline */
777         if(check_col(actx->pinfo->cinfo, COL_INFO)) 
778           col_append_fstr(actx->pinfo->cinfo, COL_INFO, "\"%s\" ", ldapstring);
779   
780         if(ldm_tree)
781           proto_item_append_text(ldm_tree, " \"%s\"", ldapstring); 
782
783
784         if(!parameter_tvb) {
785
786           proto_item_append_text(ber_last_created_item, " (%s)", ldapstring); 
787         }
788
789      } else if ((hf_index == hf_ldap_errorMessage) && result) { /* only show message if not success */
790         if(check_col(actx->pinfo->cinfo, COL_INFO)) 
791           col_append_fstr(actx->pinfo->cinfo, COL_INFO, "(%s) ", ldapstring);     
792
793         if(ldm_tree)
794           proto_item_append_text(ldm_tree, " (%s)", ldapstring); 
795      } else if (hf_index == hf_ldap_objectName) {
796         if(check_col(actx->pinfo->cinfo, COL_INFO)) 
797           col_append_fstr(actx->pinfo->cinfo, COL_INFO, "\"%s\" ", ldapstring);     
798
799         if(ldm_tree)
800           proto_item_append_text(ldm_tree, " \"%s\"", ldapstring); 
801      } else if (hf_index == hf_ldap_attributeDesc){
802         /* remember the attribute description */
803         attributedesc_string=ldapstring;
804      } else if (hf_index == hf_ldap_initial){
805         /* remember the substring item */
806         substring_item_init=ldapstring;
807      } else if (hf_index == hf_ldap_any){
808         /* remember the substring item */
809         substring_item_any=ldapstring;
810      } else if (hf_index == hf_ldap_final){
811         /* remember the substring item */
812         substring_item_final=ldapstring;
813      } else if (hf_index == hf_ldap_matchingRule){
814         /* remember the matching rule */
815         matching_rule_string=ldapstring;
816      } else if (hf_index == hf_ldap_present){
817         /* remember the present name */
818         Filter_string=ldapstring;
819      } else if (hf_index == hf_ldap_type) {
820         /* remember attribute type name */
821         attr_type = ep_strdup(ldapstring);
822
823         /* append it to the parent entry */
824         proto_item_append_text(tree, " %s", attr_type);
825
826         /* remove the ";binary" component if present */
827         if((sc = strchr(attr_type, ';')) != NULL) {
828                 if(!strcmp(sc, ";binary")) {
829                         *sc = '\0'; /* terminate the string */
830                         is_binary_attr_type = TRUE;
831                 }
832         } else {
833                 is_binary_attr_type = FALSE;
834         }
835
836      }
837      
838   }
839
840
841
842   return offset;
843 }
844
845
846
847 static int
848 dissect_ldap_LDAPDN(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
849   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, actx, tree, hf_index);
850
851   return offset;
852 }
853
854
855
856 static int
857 dissect_ldap_Simple(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
858 #line 117 "ldap.cnf"
859 ldap_conv_info_t *ldap_info;
860
861   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
862                                        NULL);
863
864         
865         ldap_info = actx->pinfo->private_data;
866         ldap_info->auth_type = LDAP_AUTH_SIMPLE;
867
868         actx->pinfo->private_data = ldap_info;
869
870
871
872   return offset;
873 }
874
875
876
877 static int
878 dissect_ldap_Mechanism(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
879 #line 127 "ldap.cnf"
880
881 ldap_conv_info_t *ldap_info;
882 tvbuff_t        *parameter_tvb;
883 char *mechanism = NULL;
884   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
885                                        &parameter_tvb);
886
887         ldap_info = actx->pinfo->private_data;
888         ldap_info->auth_type = LDAP_AUTH_SASL;
889
890         if (!parameter_tvb)
891                 return offset;
892
893     /*
894      * We need to remember the authentication type and mechanism for this
895      * conversation.
896      *
897      * XXX - actually, we might need to remember more than one
898      * type and mechanism, if you can unbind and rebind with a
899      * different type and/or mechanism.
900      */
901     mechanism = tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
902     ldap_info->first_auth_frame = 0;    /* not known until we see the bind reply */
903     /*
904      * If the mechanism in this request is an empty string (which is
905      * returned as a null pointer), use the saved mechanism instead.
906      * Otherwise, if the saved mechanism is an empty string (null),
907      * save this mechanism.
908      */
909     if (mechanism == NULL)
910         mechanism = ldap_info->auth_mech;
911     else {
912       if (ldap_info->auth_mech == NULL) {
913         g_free(ldap_info->auth_mech);
914       }
915       ldap_info->auth_mech = mechanism;
916     }
917         actx->pinfo->private_data = ldap_info;
918
919
920
921   return offset;
922 }
923
924
925
926 static int
927 dissect_ldap_Credentials(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
928 #line 165 "ldap.cnf"
929
930 tvbuff_t        *parameter_tvb;
931 ldap_conv_info_t *ldap_info;
932 gint8 class;
933 gboolean pc;
934 gint32 tag;
935
936   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
937                                        &parameter_tvb);
938
939
940         if (!parameter_tvb)
941                 return offset;
942
943         ldap_info = actx->pinfo->private_data;
944         get_ber_identifier(parameter_tvb, 0, &class, &pc, &tag);
945
946         /*if ((ldap_info->auth_mech != NULL) && (strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) && (class==BER_CLASS_CON)) {*/
947         if ((ldap_info->auth_mech != NULL) && (class==BER_CLASS_CON)) {
948           /*
949            * This is a GSS-API token ancapsulated within GSS-SPNEGO.
950            * We need to check the first byte to check whether the blob
951            * contains SPNEGO or GSSAPI.
952            * All SPNEGO PDUs are of class CONSTRUCTED while
953            * GSS PDUs are class APPLICATION
954            */
955           if (parameter_tvb && (tvb_length(parameter_tvb) > 0))
956             call_dissector(spnego_handle, parameter_tvb, actx->pinfo, tree);
957         }
958         /*if ((ldap_info->auth_mech != NULL) && ((strcmp(ldap_info->auth_mech, "GSSAPI") == 0) || (class==BER_CLASS_APP))) {*/
959         if ((ldap_info->auth_mech != NULL) && (class==BER_CLASS_APP)) {
960           /*
961            * This is a raw GSS-API token.
962            */
963           if (parameter_tvb && (tvb_length(parameter_tvb) > 0)) {
964             call_dissector(gssapi_handle, parameter_tvb, actx->pinfo, tree);
965           }
966         }
967         actx->pinfo->private_data = ldap_info;
968
969
970
971
972   return offset;
973 }
974
975
976 static const ber_sequence_t SaslCredentials_sequence[] = {
977   { &hf_ldap_mechanism      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_Mechanism },
978   { &hf_ldap_credentials    , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ldap_Credentials },
979   { NULL, 0, 0, 0, NULL }
980 };
981
982 static int
983 dissect_ldap_SaslCredentials(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
984   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
985                                    SaslCredentials_sequence, hf_index, ett_ldap_SaslCredentials);
986
987   return offset;
988 }
989
990
991
992 static int
993 dissect_ldap_T_ntlmsspNegotiate(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
994 #line 619 "ldap.cnf"
995         /* make sure the protocol op comes first */
996         ldap_do_protocolop(actx->pinfo);
997
998         call_dissector(ntlmssp_handle, tvb, actx->pinfo, tree);
999         offset+=tvb_length_remaining(tvb, offset);
1000
1001
1002
1003   return offset;
1004 }
1005
1006
1007
1008 static int
1009 dissect_ldap_T_ntlmsspAuth(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1010 #line 626 "ldap.cnf"
1011         /* make sure the protocol op comes first */
1012         ldap_do_protocolop(actx->pinfo);
1013
1014         call_dissector(ntlmssp_handle, tvb, actx->pinfo, tree);
1015         offset+=tvb_length_remaining(tvb, offset);
1016
1017
1018
1019   return offset;
1020 }
1021
1022
1023 static const value_string ldap_AuthenticationChoice_vals[] = {
1024   {   0, "simple" },
1025   {   3, "sasl" },
1026   {  10, "ntlmsspNegotiate" },
1027   {  11, "ntlmsspAuth" },
1028   { 0, NULL }
1029 };
1030
1031 static const ber_choice_t AuthenticationChoice_choice[] = {
1032   {   0, &hf_ldap_simple         , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ldap_Simple },
1033   {   3, &hf_ldap_sasl           , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_ldap_SaslCredentials },
1034   {  10, &hf_ldap_ntlmsspNegotiate, BER_CLASS_CON, 10, BER_FLAGS_IMPLTAG, dissect_ldap_T_ntlmsspNegotiate },
1035   {  11, &hf_ldap_ntlmsspAuth    , BER_CLASS_CON, 11, BER_FLAGS_IMPLTAG, dissect_ldap_T_ntlmsspAuth },
1036   { 0, NULL, 0, 0, 0, NULL }
1037 };
1038
1039 static int
1040 dissect_ldap_AuthenticationChoice(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1041 #line 440 "ldap.cnf"
1042   gint branch = -1;
1043   gint auth = -1;
1044   const gchar *valstr;
1045   
1046     offset = dissect_ber_choice(actx, tree, tvb, offset,
1047                                  AuthenticationChoice_choice, hf_index, ett_ldap_AuthenticationChoice,
1048                                  &branch);
1049
1050   
1051   ldap_do_protocolop(actx->pinfo);
1052   
1053   if((branch > -1) && (branch < (gint)(sizeof AuthenticationChoice_choice/sizeof AuthenticationChoice_choice[0])))
1054     auth = AuthenticationChoice_choice[branch].value;
1055
1056   valstr = val_to_str(auth, ldap_AuthenticationChoice_vals, "Unknown auth(%u)");
1057   
1058   /* If auth is NTLM (10 or 11) don't add to column as the NTLM dissection will do this */
1059   if (check_col(actx->pinfo->cinfo, COL_INFO) && (auth !=  10) && (auth != 11))
1060     col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%s ", valstr);
1061   
1062   if(ldm_tree)
1063     proto_item_append_text(ldm_tree, " %s", valstr);
1064
1065
1066
1067
1068   return offset;
1069 }
1070
1071
1072 static const ber_sequence_t BindRequest_sequence[] = {
1073   { &hf_ldap_version        , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER_1_127 },
1074   { &hf_ldap_name           , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
1075   { &hf_ldap_authentication , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_AuthenticationChoice },
1076   { NULL, 0, 0, 0, NULL }
1077 };
1078
1079 static int
1080 dissect_ldap_BindRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1081   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1082                                    BindRequest_sequence, hf_index, ett_ldap_BindRequest);
1083
1084   return offset;
1085 }
1086
1087
1088 static const value_string ldap_BindResponse_resultCode_vals[] = {
1089   {   0, "success" },
1090   {   1, "operationsError" },
1091   {   2, "protocolError" },
1092   {   3, "timeLimitExceeded" },
1093   {   4, "sizeLimitExceeded" },
1094   {   5, "compareFalse" },
1095   {   6, "compareTrue" },
1096   {   7, "authMethodNotSupported" },
1097   {   8, "strongAuthRequired" },
1098   {  10, "referral" },
1099   {  11, "adminLimitExceeded" },
1100   {  12, "unavailableCriticalExtension" },
1101   {  13, "confidentialityRequired" },
1102   {  14, "saslBindInProgress" },
1103   {  16, "noSuchAttribute" },
1104   {  17, "undefinedAttributeType" },
1105   {  18, "inappropriateMatching" },
1106   {  19, "constraintViolation" },
1107   {  20, "attributeOrValueExists" },
1108   {  21, "invalidAttributeSyntax" },
1109   {  32, "noSuchObject" },
1110   {  33, "aliasProblem" },
1111   {  34, "invalidDNSyntax" },
1112   {  36, "aliasDereferencingProblem" },
1113   {  48, "inappropriateAuthentication" },
1114   {  49, "invalidCredentials" },
1115   {  50, "insufficientAccessRights" },
1116   {  51, "busy" },
1117   {  52, "unavailable" },
1118   {  53, "unwillingToPerform" },
1119   {  54, "loopDetect" },
1120   {  64, "namingViolation" },
1121   {  65, "objectClassViolation" },
1122   {  66, "notAllowedOnNonLeaf" },
1123   {  67, "notAllowedOnRDN" },
1124   {  68, "entryAlreadyExists" },
1125   {  69, "objectClassModsProhibited" },
1126   {  71, "affectsMultipleDSAs" },
1127   {  80, "other" },
1128   { 0, NULL }
1129 };
1130
1131
1132 static int
1133 dissect_ldap_BindResponse_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1134 #line 384 "ldap.cnf"
1135
1136   const gchar *valstr;
1137
1138     offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1139                                   &result);
1140
1141
1142   ldap_do_protocolop(actx->pinfo);
1143
1144   if(result) {
1145   
1146     valstr = val_to_str(result, ldap_BindResponse_resultCode_vals, "Unknown result(%u)");
1147
1148     if (check_col(actx->pinfo->cinfo, COL_INFO))
1149       col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%s ", valstr);
1150
1151     if(ldm_tree)
1152       proto_item_append_text(ldm_tree, " %s", valstr); 
1153
1154   }
1155
1156   
1157
1158
1159   return offset;
1160 }
1161
1162
1163
1164 static int
1165 dissect_ldap_T_matchedDN(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1166 #line 633 "ldap.cnf"
1167         tvbuff_t *new_tvb=NULL;
1168
1169         offset = dissect_ber_octet_string(FALSE, actx, tree, tvb, offset, hf_ldap_matchedDN, &new_tvb);
1170
1171         if(  new_tvb
1172         &&  (tvb_length(new_tvb)>=7)
1173         &&  (!tvb_memeql(new_tvb, 0, "NTLMSSP", 7))){
1174
1175                 /* make sure the protocol op comes first */
1176                 ldap_do_protocolop(actx->pinfo);
1177
1178                 call_dissector(ntlmssp_handle, new_tvb, actx->pinfo, tree);
1179         }
1180         return offset;
1181
1182
1183
1184   return offset;
1185 }
1186
1187
1188
1189 static int
1190 dissect_ldap_ErrorMessage(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1191   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, actx, tree, hf_index);
1192
1193   return offset;
1194 }
1195
1196
1197
1198 static int
1199 dissect_ldap_LDAPURL(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1200   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
1201                                        NULL);
1202
1203 #line 38 "ldap.cnf"
1204         PROTO_ITEM_SET_URL(get_ber_last_created_item());
1205
1206
1207   return offset;
1208 }
1209
1210
1211 static const ber_sequence_t Referral_sequence_of[1] = {
1212   { &hf_ldap_Referral_item  , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPURL },
1213 };
1214
1215 static int
1216 dissect_ldap_Referral(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1217   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1218                                       Referral_sequence_of, hf_index, ett_ldap_Referral);
1219
1220   return offset;
1221 }
1222
1223
1224
1225 static int
1226 dissect_ldap_ServerSaslCreds(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1227 #line 205 "ldap.cnf"
1228
1229 tvbuff_t        *parameter_tvb;
1230 ldap_conv_info_t *ldap_info;
1231
1232   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
1233                                        &parameter_tvb);
1234
1235         if (!parameter_tvb)
1236                 return offset;
1237         ldap_info = actx->pinfo->private_data;
1238     switch (ldap_info->auth_type) {
1239
1240       /* For Kerberos V4, dissect it as a ticket. */
1241       /* XXX - what about LDAP_AUTH_SIMPLE? */
1242
1243     case LDAP_AUTH_SASL:
1244       /*
1245        * All frames after this are assumed to use a security layer.
1246        *
1247        * XXX - won't work if there's another reply, with the security
1248        * layer, starting in the same TCP segment that ends this
1249        * reply, but as LDAP is a request/response protocol, and
1250        * as the client probably can't start using authentication until
1251        * it gets the bind reply and the server won't send a reply until
1252        * it gets a request, that probably won't happen.
1253        *
1254        * XXX - that assumption is invalid; it's not clear where the
1255        * hell you find out whether there's any security layer.  In
1256        * one capture, we have two GSS-SPNEGO negotiations, both of
1257        * which select MS KRB5, and the only differences in the tokens
1258        * is in the RC4-HMAC ciphertext.  The various
1259        * draft-ietf--cat-sasl-gssapi-NN.txt drafts seem to imply
1260        * that the RFC 2222 spoo with the bitmask and maximum
1261        * output message size stuff is done - but where does that
1262        * stuff show up?  Is it in the ciphertext, which means it's
1263        * presumably encrypted?
1264        *
1265        * Grrr.  We have to do a gross heuristic, checking whether the
1266        * putative LDAP message begins with 0x00 or not, making the
1267        * assumption that we won't have more than 2^24 bytes of
1268        * encapsulated stuff.
1269        */
1270       ldap_info->first_auth_frame = actx->pinfo->fd->num + 1;
1271       if (ldap_info->auth_mech != NULL &&
1272           strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) {
1273         /*
1274          * This is a GSS-API token.
1275          */
1276         if(parameter_tvb && (tvb_length(parameter_tvb) > 0))
1277           call_dissector(spnego_handle, parameter_tvb, actx->pinfo, tree);
1278       } else if (ldap_info->auth_mech != NULL &&
1279           strcmp(ldap_info->auth_mech, "GSSAPI") == 0) {
1280         /*
1281          * This is a GSS-API token.
1282          */
1283         if(parameter_tvb && (tvb_length(parameter_tvb) > 0))
1284           call_dissector(gssapi_handle, parameter_tvb, actx->pinfo, tree);
1285                 }
1286         break;
1287         }
1288         actx->pinfo->private_data = ldap_info;
1289
1290
1291
1292   return offset;
1293 }
1294
1295
1296 static const ber_sequence_t BindResponse_sequence[] = {
1297   { &hf_ldap_bindResponse_resultCode, BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_BindResponse_resultCode },
1298   { &hf_ldap_matchedDN_01   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_T_matchedDN },
1299   { &hf_ldap_errorMessage   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_ErrorMessage },
1300   { &hf_ldap_referral       , BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_Referral },
1301   { &hf_ldap_serverSaslCreds, BER_CLASS_CON, 7, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_ServerSaslCreds },
1302   { NULL, 0, 0, 0, NULL }
1303 };
1304
1305 static int
1306 dissect_ldap_BindResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1307   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1308                                    BindResponse_sequence, hf_index, ett_ldap_BindResponse);
1309
1310   return offset;
1311 }
1312
1313
1314
1315 static int
1316 dissect_ldap_UnbindRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1317 #line 462 "ldap.cnf"
1318
1319  implicit_tag = TRUE; /* correct problem with asn2wrs */
1320
1321    offset = dissect_ber_null(implicit_tag, actx, tree, tvb, offset, hf_index);
1322
1323
1324  ldap_do_protocolop(actx->pinfo);  
1325
1326
1327
1328
1329
1330
1331
1332   return offset;
1333 }
1334
1335
1336 static const value_string ldap_T_scope_vals[] = {
1337   {   0, "baseObject" },
1338   {   1, "singleLevel" },
1339   {   2, "wholeSubtree" },
1340   { 0, NULL }
1341 };
1342
1343
1344 static int
1345 dissect_ldap_T_scope(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1346 #line 347 "ldap.cnf"
1347
1348   gint  scope;
1349   const gchar *valstr;
1350
1351     offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1352                                   &scope);
1353
1354
1355   ldap_do_protocolop(actx->pinfo);
1356
1357   valstr = val_to_str(scope, ldap_T_scope_vals, "Unknown scope(%u)");
1358
1359   if (check_col(actx->pinfo->cinfo, COL_INFO))
1360     col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%s ", valstr);    
1361     
1362   if(ldm_tree)
1363     proto_item_append_text(ldm_tree, " %s", valstr); 
1364
1365
1366
1367   return offset;
1368 }
1369
1370
1371 static const value_string ldap_T_derefAliases_vals[] = {
1372   {   0, "neverDerefAliases" },
1373   {   1, "derefInSearching" },
1374   {   2, "derefFindingBaseObj" },
1375   {   3, "derefAlways" },
1376   { 0, NULL }
1377 };
1378
1379
1380 static int
1381 dissect_ldap_T_derefAliases(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1382   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1383                                   NULL);
1384
1385   return offset;
1386 }
1387
1388
1389
1390 static int
1391 dissect_ldap_INTEGER_0_maxInt(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1392   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
1393                                   NULL);
1394
1395   return offset;
1396 }
1397
1398
1399
1400 static int
1401 dissect_ldap_BOOLEAN(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1402   offset = dissect_ber_boolean(implicit_tag, actx, tree, tvb, offset, hf_index);
1403
1404   return offset;
1405 }
1406
1407
1408
1409 static int
1410 dissect_ldap_T_and_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1411   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, actx, tree, hf_index);
1412
1413 #line 496 "ldap.cnf"
1414         if(and_filter_string){
1415                 and_filter_string=ep_strdup_printf("(&%s%s)",and_filter_string,Filter_string);
1416         } else {
1417                 and_filter_string=Filter_string;
1418         }
1419
1420
1421   return offset;
1422 }
1423
1424
1425 static const ber_sequence_t T_and_set_of[1] = {
1426   { &hf_ldap_and_item       , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_T_and_item },
1427 };
1428
1429 static int
1430 dissect_ldap_T_and(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1431 #line 503 "ldap.cnf"
1432         proto_tree *tr=NULL;
1433         proto_item *it=NULL;
1434         char *old_and_filter_string=and_filter_string;
1435
1436         and_filter_string=NULL;
1437         if(tree){
1438                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "and: ");
1439                 tr=proto_item_add_subtree(it, ett_ldap_T_and);
1440                 tree = tr;
1441         } 
1442
1443   offset = dissect_ber_set_of(implicit_tag, actx, tree, tvb, offset,
1444                                  T_and_set_of, hf_index, ett_ldap_T_and);
1445
1446
1447         proto_item_append_text(it, "%s", and_filter_string);
1448         Filter_string=ep_strdup_printf("%s",and_filter_string);
1449         and_filter_string=old_and_filter_string;
1450
1451
1452
1453   return offset;
1454 }
1455
1456
1457
1458 static int
1459 dissect_ldap_T_or_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1460   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, actx, tree, hf_index);
1461
1462 #line 521 "ldap.cnf"
1463         if(or_filter_string){
1464                 or_filter_string=ep_strdup_printf("(|%s%s)",or_filter_string,Filter_string);
1465         } else {
1466                 or_filter_string=Filter_string;
1467         }
1468
1469
1470
1471   return offset;
1472 }
1473
1474
1475 static const ber_sequence_t T_or_set_of[1] = {
1476   { &hf_ldap_or_item        , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_T_or_item },
1477 };
1478
1479 static int
1480 dissect_ldap_T_or(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1481 #line 529 "ldap.cnf"
1482         proto_tree *tr=NULL;
1483         proto_item *it=NULL;
1484         char *old_or_filter_string=or_filter_string;
1485
1486         or_filter_string=NULL;
1487         if(tree){
1488                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "or: ");
1489                 tr=proto_item_add_subtree(it, ett_ldap_T_or);
1490                 tree = tr;
1491         } 
1492   offset = dissect_ber_set_of(implicit_tag, actx, tree, tvb, offset,
1493                                  T_or_set_of, hf_index, ett_ldap_T_or);
1494
1495         proto_item_append_text(it, "%s", or_filter_string);
1496         Filter_string=ep_strdup_printf("%s",or_filter_string);
1497         or_filter_string=old_or_filter_string;
1498
1499
1500
1501   return offset;
1502 }
1503
1504
1505
1506 static int
1507 dissect_ldap_T_not(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1508   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, actx, tree, hf_index);
1509
1510 #line 548 "ldap.cnf"
1511         Filter_string=ep_strdup_printf("(!%s)",Filter_string);
1512
1513
1514   return offset;
1515 }
1516
1517
1518
1519 static int
1520 dissect_ldap_AttributeDescription(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1521   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, actx, tree, hf_index);
1522
1523   return offset;
1524 }
1525
1526
1527
1528 static const ber_sequence_t AttributeValueAssertion_sequence[] = {
1529   { &hf_ldap_attributeDesc  , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
1530   { &hf_ldap_assertionValue , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AssertionValue },
1531   { NULL, 0, 0, 0, NULL }
1532 };
1533
1534 static int
1535 dissect_ldap_AttributeValueAssertion(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1536   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1537                                    AttributeValueAssertion_sequence, hf_index, ett_ldap_AttributeValueAssertion);
1538
1539   return offset;
1540 }
1541
1542
1543
1544 static int
1545 dissect_ldap_T_equalityMatch(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1546   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, actx, tree, hf_index);
1547
1548 #line 481 "ldap.cnf"
1549         Filter_string=ep_strdup_printf("(%s=%s)",attributedesc_string,ldapvalue_string);
1550
1551
1552
1553   return offset;
1554 }
1555
1556
1557 static const value_string ldap_T_substringFilter_substrings_item_vals[] = {
1558   {   0, "initial" },
1559   {   1, "any" },
1560   {   2, "final" },
1561   { 0, NULL }
1562 };
1563
1564 static const ber_choice_t T_substringFilter_substrings_item_choice[] = {
1565   {   0, &hf_ldap_initial        , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ldap_LDAPString },
1566   {   1, &hf_ldap_any            , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ldap_LDAPString },
1567   {   2, &hf_ldap_final          , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ldap_LDAPString },
1568   { 0, NULL, 0, 0, 0, NULL }
1569 };
1570
1571 static int
1572 dissect_ldap_T_substringFilter_substrings_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1573   offset = dissect_ber_choice(actx, tree, tvb, offset,
1574                                  T_substringFilter_substrings_item_choice, hf_index, ett_ldap_T_substringFilter_substrings_item,
1575                                  NULL);
1576
1577 #line 574 "ldap.cnf"
1578         if (substring_item_final) {
1579                 substring_value=ep_strdup_printf("%s%s",
1580                                                  (substring_value?substring_value:"*"),
1581                                                  substring_item_final);
1582         } else if (substring_item_any) {
1583                 substring_value=ep_strdup_printf("%s%s*",
1584                                                  (substring_value?substring_value:"*"),
1585                                                  substring_item_any);
1586         } else if (substring_item_init) {
1587                 substring_value=ep_strdup_printf("%s*",
1588                                                  substring_item_init);
1589         }
1590
1591
1592   return offset;
1593 }
1594
1595
1596 static const ber_sequence_t T_substringFilter_substrings_sequence_of[1] = {
1597   { &hf_ldap_substringFilter_substrings_item, BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_T_substringFilter_substrings_item },
1598 };
1599
1600 static int
1601 dissect_ldap_T_substringFilter_substrings(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1602   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1603                                       T_substringFilter_substrings_sequence_of, hf_index, ett_ldap_T_substringFilter_substrings);
1604
1605   return offset;
1606 }
1607
1608
1609 static const ber_sequence_t SubstringFilter_sequence[] = {
1610   { &hf_ldap_type           , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
1611   { &hf_ldap_substringFilter_substrings, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_T_substringFilter_substrings },
1612   { NULL, 0, 0, 0, NULL }
1613 };
1614
1615 static int
1616 dissect_ldap_SubstringFilter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1617 #line 588 "ldap.cnf"
1618         proto_tree *tr=NULL;
1619         proto_item *it=NULL;
1620         char *old_substring_value=substring_value;
1621
1622         substring_value=NULL;
1623         substring_item_init=NULL;
1624         substring_item_any=NULL;
1625         substring_item_final=NULL;
1626         if(tree){
1627                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "substring: ");
1628                 tr=proto_item_add_subtree(it, ett_ldap_SubstringFilter);
1629                 tree = tr;
1630         }
1631   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1632                                    SubstringFilter_sequence, hf_index, ett_ldap_SubstringFilter);
1633
1634         Filter_string=ep_strdup_printf("(%s=%s)",attr_type,substring_value);
1635         proto_item_append_text(it, "%s", Filter_string);
1636         substring_value=old_substring_value;
1637
1638
1639
1640   return offset;
1641 }
1642
1643
1644
1645 static int
1646 dissect_ldap_T_greaterOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1647   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, actx, tree, hf_index);
1648
1649 #line 485 "ldap.cnf"
1650         Filter_string=ep_strdup_printf("(%s>=%s)",attributedesc_string,ldapvalue_string);
1651
1652
1653
1654   return offset;
1655 }
1656
1657
1658
1659 static int
1660 dissect_ldap_T_lessOrEqual(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1661   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, actx, tree, hf_index);
1662
1663 #line 489 "ldap.cnf"
1664         Filter_string=ep_strdup_printf("(%s<=%s)",attributedesc_string,ldapvalue_string);
1665
1666
1667
1668   return offset;
1669 }
1670
1671
1672
1673 static int
1674 dissect_ldap_T_present(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1675   offset = dissect_ldap_AttributeDescription(implicit_tag, tvb, offset, actx, tree, hf_index);
1676
1677 #line 545 "ldap.cnf"
1678         Filter_string=ep_strdup_printf("(%s=*)",Filter_string);
1679
1680
1681   return offset;
1682 }
1683
1684
1685
1686 static int
1687 dissect_ldap_T_approxMatch(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1688   offset = dissect_ldap_AttributeValueAssertion(implicit_tag, tvb, offset, actx, tree, hf_index);
1689
1690 #line 493 "ldap.cnf"
1691         Filter_string=ep_strdup_printf("(%s~=%s)",attributedesc_string,ldapvalue_string);
1692
1693
1694   return offset;
1695 }
1696
1697
1698
1699 static int
1700 dissect_ldap_MatchingRuleId(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1701   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, actx, tree, hf_index);
1702
1703   return offset;
1704 }
1705
1706
1707
1708 static int
1709 dissect_ldap_T_dnAttributes(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1710 #line 551 "ldap.cnf"
1711         gboolean val;
1712
1713 offset = dissect_ber_boolean_value(implicit_tag, actx, tree, tvb, offset, hf_index, &val);
1714
1715
1716                 matching_rule_dnattr = val;
1717
1718
1719
1720
1721   return offset;
1722 }
1723
1724
1725 static const ber_sequence_t MatchingRuleAssertion_sequence[] = {
1726   { &hf_ldap_matchingRule   , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_MatchingRuleId },
1727   { &hf_ldap_type           , BER_CLASS_CON, 2, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_AttributeDescription },
1728   { &hf_ldap_matchValue     , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_ldap_AssertionValue },
1729   { &hf_ldap_dnAttributes   , BER_CLASS_CON, 4, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_T_dnAttributes },
1730   { NULL, 0, 0, 0, NULL }
1731 };
1732
1733 static int
1734 dissect_ldap_MatchingRuleAssertion(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1735   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1736                                    MatchingRuleAssertion_sequence, hf_index, ett_ldap_MatchingRuleAssertion);
1737
1738   return offset;
1739 }
1740
1741
1742
1743 static int
1744 dissect_ldap_T_extensibleMatch(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1745 #line 560 "ldap.cnf"
1746         attr_type=NULL;
1747         matching_rule_string=NULL;
1748         ldapvalue_string=NULL;
1749         matching_rule_dnattr=FALSE;
1750
1751
1752   offset = dissect_ldap_MatchingRuleAssertion(implicit_tag, tvb, offset, actx, tree, hf_index);
1753
1754 #line 566 "ldap.cnf"
1755         Filter_string=ep_strdup_printf("(%s:%s%s%s=%s)",
1756                                         (attr_type?attr_type:""),
1757                                         (matching_rule_dnattr?"dn:":""),
1758                                         (matching_rule_string?matching_rule_string:""),
1759                                         (matching_rule_string?":":""),
1760                                         ldapvalue_string);
1761
1762
1763   return offset;
1764 }
1765
1766
1767 static const value_string ldap_Filter_vals[] = {
1768   {   0, "and" },
1769   {   1, "or" },
1770   {   2, "not" },
1771   {   3, "equalityMatch" },
1772   {   4, "substrings" },
1773   {   5, "greaterOrEqual" },
1774   {   6, "lessOrEqual" },
1775   {   7, "present" },
1776   {   8, "approxMatch" },
1777   {   9, "extensibleMatch" },
1778   { 0, NULL }
1779 };
1780
1781 static const ber_choice_t Filter_choice[] = {
1782   {   0, &hf_ldap_and            , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ldap_T_and },
1783   {   1, &hf_ldap_or             , BER_CLASS_CON, 1, BER_FLAGS_IMPLTAG, dissect_ldap_T_or },
1784   {   2, &hf_ldap_not            , BER_CLASS_CON, 2, BER_FLAGS_IMPLTAG, dissect_ldap_T_not },
1785   {   3, &hf_ldap_equalityMatch  , BER_CLASS_CON, 3, BER_FLAGS_IMPLTAG, dissect_ldap_T_equalityMatch },
1786   {   4, &hf_ldap_substrings     , BER_CLASS_CON, 4, BER_FLAGS_IMPLTAG, dissect_ldap_SubstringFilter },
1787   {   5, &hf_ldap_greaterOrEqual , BER_CLASS_CON, 5, BER_FLAGS_IMPLTAG, dissect_ldap_T_greaterOrEqual },
1788   {   6, &hf_ldap_lessOrEqual    , BER_CLASS_CON, 6, BER_FLAGS_IMPLTAG, dissect_ldap_T_lessOrEqual },
1789   {   7, &hf_ldap_present        , BER_CLASS_CON, 7, BER_FLAGS_IMPLTAG, dissect_ldap_T_present },
1790   {   8, &hf_ldap_approxMatch    , BER_CLASS_CON, 8, BER_FLAGS_IMPLTAG, dissect_ldap_T_approxMatch },
1791   {   9, &hf_ldap_extensibleMatch, BER_CLASS_CON, 9, BER_FLAGS_IMPLTAG, dissect_ldap_T_extensibleMatch },
1792   { 0, NULL, 0, 0, 0, NULL }
1793 };
1794
1795 static int
1796 dissect_ldap_Filter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1797 #line 607 "ldap.cnf"
1798         proto_tree *tr=NULL;
1799         proto_item *it=NULL;
1800
1801         if(tree){
1802                 it=proto_tree_add_text(tree, tvb, offset, tvb_length_remaining(tvb, offset), "Filter: ");
1803                 tr=proto_item_add_subtree(it, ett_ldap_Filter);
1804                 tree = tr;
1805         }
1806   offset = dissect_ber_choice(actx, tree, tvb, offset,
1807                                  Filter_choice, hf_index, ett_ldap_Filter,
1808                                  NULL);
1809
1810         proto_item_append_text(it, "%s", Filter_string);
1811
1812
1813
1814   return offset;
1815 }
1816
1817
1818
1819 static int
1820 dissect_ldap_T_filter(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1821 #line 474 "ldap.cnf"
1822         Filter_string=NULL;
1823
1824
1825   offset = dissect_ldap_Filter(implicit_tag, tvb, offset, actx, tree, hf_index);
1826
1827 #line 477 "ldap.cnf"
1828         Filter_string=NULL;
1829         and_filter_string=NULL;
1830
1831
1832   return offset;
1833 }
1834
1835
1836 static const ber_sequence_t AttributeDescriptionList_sequence_of[1] = {
1837   { &hf_ldap_AttributeDescriptionList_item, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
1838 };
1839
1840 static int
1841 dissect_ldap_AttributeDescriptionList(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1842   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1843                                       AttributeDescriptionList_sequence_of, hf_index, ett_ldap_AttributeDescriptionList);
1844
1845   return offset;
1846 }
1847
1848
1849 static const ber_sequence_t SearchRequest_sequence[] = {
1850   { &hf_ldap_baseObject     , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
1851   { &hf_ldap_scope          , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_T_scope },
1852   { &hf_ldap_derefAliases   , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_T_derefAliases },
1853   { &hf_ldap_sizeLimit      , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER_0_maxInt },
1854   { &hf_ldap_timeLimit      , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER_0_maxInt },
1855   { &hf_ldap_typesOnly      , BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_NOOWNTAG, dissect_ldap_BOOLEAN },
1856   { &hf_ldap_filter         , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_T_filter },
1857   { &hf_ldap_searchRequest_attributes, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescriptionList },
1858   { NULL, 0, 0, 0, NULL }
1859 };
1860
1861 static int
1862 dissect_ldap_SearchRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1863   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1864                                    SearchRequest_sequence, hf_index, ett_ldap_SearchRequest);
1865
1866   return offset;
1867 }
1868
1869
1870
1871 static int
1872 dissect_ldap_AttributeValue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1873 #line 405 "ldap.cnf"
1874
1875   tvbuff_t      *next_tvb;
1876   gchar         *string;
1877   guint32       i, len;
1878   proto_item    *pi;
1879   int           old_offset = offset;
1880
1881   /* extract the value of the octetstring */
1882   offset = dissect_ber_octet_string(FALSE, actx, NULL, tvb, offset, hf_index, &next_tvb);
1883
1884   /* if we have an attribute type that isn't binary see if there is a better dissector */
1885   if(!attr_type || !dissector_try_string(ldap_name_dissector_table, attr_type, next_tvb, actx->pinfo, tree)) {
1886         offset = old_offset;
1887         
1888         /* do the default thing */
1889           offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
1890                                        NULL);
1891         
1892
1893   } 
1894
1895   len = tvb_length_remaining(next_tvb, 0);
1896   
1897   for(i = 0; i < len; i++) 
1898     if(!g_ascii_isprint(tvb_get_guint8(next_tvb, i)))
1899       break;
1900   
1901   if(i == len) {
1902     string = tvb_get_string(next_tvb, 0, tvb_length_remaining(next_tvb, 0));
1903  
1904     pi = get_ber_last_created_item();
1905      
1906     proto_item_set_text(pi, "%s", string);
1907
1908   }
1909   
1910
1911
1912   return offset;
1913 }
1914
1915
1916 static const ber_sequence_t SET_OF_AttributeValue_set_of[1] = {
1917   { &hf_ldap_vals_item      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeValue },
1918 };
1919
1920 static int
1921 dissect_ldap_SET_OF_AttributeValue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1922   offset = dissect_ber_set_of(implicit_tag, actx, tree, tvb, offset,
1923                                  SET_OF_AttributeValue_set_of, hf_index, ett_ldap_SET_OF_AttributeValue);
1924
1925   return offset;
1926 }
1927
1928
1929 static const ber_sequence_t PartialAttributeList_item_sequence[] = {
1930   { &hf_ldap_type           , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
1931   { &hf_ldap_vals           , BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_ldap_SET_OF_AttributeValue },
1932   { NULL, 0, 0, 0, NULL }
1933 };
1934
1935 static int
1936 dissect_ldap_PartialAttributeList_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1937   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1938                                    PartialAttributeList_item_sequence, hf_index, ett_ldap_PartialAttributeList_item);
1939
1940   return offset;
1941 }
1942
1943
1944 static const ber_sequence_t PartialAttributeList_sequence_of[1] = {
1945   { &hf_ldap_PartialAttributeList_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_PartialAttributeList_item },
1946 };
1947
1948 static int
1949 dissect_ldap_PartialAttributeList(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1950   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
1951                                       PartialAttributeList_sequence_of, hf_index, ett_ldap_PartialAttributeList);
1952
1953   return offset;
1954 }
1955
1956
1957 static const ber_sequence_t SearchResultEntry_sequence[] = {
1958   { &hf_ldap_objectName     , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
1959   { &hf_ldap_searchResultEntry_attributes, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_PartialAttributeList },
1960   { NULL, 0, 0, 0, NULL }
1961 };
1962
1963 static int
1964 dissect_ldap_SearchResultEntry(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
1965   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
1966                                    SearchResultEntry_sequence, hf_index, ett_ldap_SearchResultEntry);
1967
1968   return offset;
1969 }
1970
1971
1972 static const value_string ldap_T_resultCode_vals[] = {
1973   {   0, "success" },
1974   {   1, "operationsError" },
1975   {   2, "protocolError" },
1976   {   3, "timeLimitExceeded" },
1977   {   4, "sizeLimitExceeded" },
1978   {   5, "compareFalse" },
1979   {   6, "compareTrue" },
1980   {   7, "authMethodNotSupported" },
1981   {   8, "strongAuthRequired" },
1982   {  10, "referral" },
1983   {  11, "adminLimitExceeded" },
1984   {  12, "unavailableCriticalExtension" },
1985   {  13, "confidentialityRequired" },
1986   {  14, "saslBindInProgress" },
1987   {  16, "noSuchAttribute" },
1988   {  17, "undefinedAttributeType" },
1989   {  18, "inappropriateMatching" },
1990   {  19, "constraintViolation" },
1991   {  20, "attributeOrValueExists" },
1992   {  21, "invalidAttributeSyntax" },
1993   {  32, "noSuchObject" },
1994   {  33, "aliasProblem" },
1995   {  34, "invalidDNSyntax" },
1996   {  36, "aliasDereferencingProblem" },
1997   {  48, "inappropriateAuthentication" },
1998   {  49, "invalidCredentials" },
1999   {  50, "insufficientAccessRights" },
2000   {  51, "busy" },
2001   {  52, "unavailable" },
2002   {  53, "unwillingToPerform" },
2003   {  54, "loopDetect" },
2004   {  64, "namingViolation" },
2005   {  65, "objectClassViolation" },
2006   {  66, "notAllowedOnNonLeaf" },
2007   {  67, "notAllowedOnRDN" },
2008   {  68, "entryAlreadyExists" },
2009   {  69, "objectClassModsProhibited" },
2010   {  71, "affectsMultipleDSAs" },
2011   {  80, "other" },
2012   { 0, NULL }
2013 };
2014
2015
2016 static int
2017 dissect_ldap_T_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2018 #line 364 "ldap.cnf"
2019
2020   const gchar *valstr;
2021
2022     offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2023                                   &result);
2024
2025
2026   ldap_do_protocolop(actx->pinfo);
2027
2028   if(result) {
2029   
2030     valstr = val_to_str(result, ldap_T_resultCode_vals, "Unknown result(%u)");
2031
2032     if (check_col(actx->pinfo->cinfo, COL_INFO))
2033       col_append_fstr(actx->pinfo->cinfo, COL_INFO, "%s ", valstr);
2034
2035     if(ldm_tree)
2036       proto_item_append_text(ldm_tree, " %s", valstr); 
2037
2038   }
2039
2040
2041
2042   return offset;
2043 }
2044
2045
2046 static const ber_sequence_t LDAPResult_sequence[] = {
2047   { &hf_ldap_resultCode     , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_T_resultCode },
2048   { &hf_ldap_matchedDN      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2049   { &hf_ldap_errorMessage   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_ErrorMessage },
2050   { &hf_ldap_referral       , BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_Referral },
2051   { NULL, 0, 0, 0, NULL }
2052 };
2053
2054 static int
2055 dissect_ldap_LDAPResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2056   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2057                                    LDAPResult_sequence, hf_index, ett_ldap_LDAPResult);
2058
2059   return offset;
2060 }
2061
2062
2063
2064 static int
2065 dissect_ldap_SearchResultDone(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2066   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2067
2068   return offset;
2069 }
2070
2071
2072 static const ber_sequence_t SearchResultReference_sequence_of[1] = {
2073   { &hf_ldap_SearchResultReference_item, BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPURL },
2074 };
2075
2076 static int
2077 dissect_ldap_SearchResultReference(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2078   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2079                                       SearchResultReference_sequence_of, hf_index, ett_ldap_SearchResultReference);
2080
2081   return offset;
2082 }
2083
2084
2085 static const value_string ldap_T_operation_vals[] = {
2086   {   0, "add" },
2087   {   1, "delete" },
2088   {   2, "replace" },
2089   { 0, NULL }
2090 };
2091
2092
2093 static int
2094 dissect_ldap_T_operation(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2095   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2096                                   NULL);
2097
2098   return offset;
2099 }
2100
2101
2102 static const ber_sequence_t AttributeTypeAndValues_sequence[] = {
2103   { &hf_ldap_type           , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
2104   { &hf_ldap_vals           , BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_ldap_SET_OF_AttributeValue },
2105   { NULL, 0, 0, 0, NULL }
2106 };
2107
2108 static int
2109 dissect_ldap_AttributeTypeAndValues(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2110   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2111                                    AttributeTypeAndValues_sequence, hf_index, ett_ldap_AttributeTypeAndValues);
2112
2113   return offset;
2114 }
2115
2116
2117 static const ber_sequence_t T_modifyRequest_modification_item_sequence[] = {
2118   { &hf_ldap_operation      , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_T_operation },
2119   { &hf_ldap_modification   , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeTypeAndValues },
2120   { NULL, 0, 0, 0, NULL }
2121 };
2122
2123 static int
2124 dissect_ldap_T_modifyRequest_modification_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2125   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2126                                    T_modifyRequest_modification_item_sequence, hf_index, ett_ldap_T_modifyRequest_modification_item);
2127
2128   return offset;
2129 }
2130
2131
2132 static const ber_sequence_t ModifyRequest_modification_sequence_of[1] = {
2133   { &hf_ldap_modifyRequest_modification_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_T_modifyRequest_modification_item },
2134 };
2135
2136 static int
2137 dissect_ldap_ModifyRequest_modification(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2138   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2139                                       ModifyRequest_modification_sequence_of, hf_index, ett_ldap_ModifyRequest_modification);
2140
2141   return offset;
2142 }
2143
2144
2145 static const ber_sequence_t ModifyRequest_sequence[] = {
2146   { &hf_ldap_object         , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2147   { &hf_ldap_modifyRequest_modification, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_ModifyRequest_modification },
2148   { NULL, 0, 0, 0, NULL }
2149 };
2150
2151 static int
2152 dissect_ldap_ModifyRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2153   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2154                                    ModifyRequest_sequence, hf_index, ett_ldap_ModifyRequest);
2155
2156   return offset;
2157 }
2158
2159
2160
2161 static int
2162 dissect_ldap_ModifyResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2163   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2164
2165   return offset;
2166 }
2167
2168
2169 static const ber_sequence_t AttributeList_item_sequence[] = {
2170   { &hf_ldap_type           , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
2171   { &hf_ldap_vals           , BER_CLASS_UNI, BER_UNI_TAG_SET, BER_FLAGS_NOOWNTAG, dissect_ldap_SET_OF_AttributeValue },
2172   { NULL, 0, 0, 0, NULL }
2173 };
2174
2175 static int
2176 dissect_ldap_AttributeList_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2177   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2178                                    AttributeList_item_sequence, hf_index, ett_ldap_AttributeList_item);
2179
2180   return offset;
2181 }
2182
2183
2184 static const ber_sequence_t AttributeList_sequence_of[1] = {
2185   { &hf_ldap_AttributeList_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeList_item },
2186 };
2187
2188 static int
2189 dissect_ldap_AttributeList(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2190   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2191                                       AttributeList_sequence_of, hf_index, ett_ldap_AttributeList);
2192
2193   return offset;
2194 }
2195
2196
2197 static const ber_sequence_t AddRequest_sequence[] = {
2198   { &hf_ldap_entry          , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2199   { &hf_ldap_attributes     , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeList },
2200   { NULL, 0, 0, 0, NULL }
2201 };
2202
2203 static int
2204 dissect_ldap_AddRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2205   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2206                                    AddRequest_sequence, hf_index, ett_ldap_AddRequest);
2207
2208   return offset;
2209 }
2210
2211
2212
2213 static int
2214 dissect_ldap_AddResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2215   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2216
2217   return offset;
2218 }
2219
2220
2221
2222 static int
2223 dissect_ldap_DelRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2224   offset = dissect_ldap_LDAPDN(implicit_tag, tvb, offset, actx, tree, hf_index);
2225
2226   return offset;
2227 }
2228
2229
2230
2231 static int
2232 dissect_ldap_DelResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2233   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2234
2235   return offset;
2236 }
2237
2238
2239
2240 static int
2241 dissect_ldap_RelativeLDAPDN(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2242   offset = dissect_ldap_LDAPString(implicit_tag, tvb, offset, actx, tree, hf_index);
2243
2244   return offset;
2245 }
2246
2247
2248 static const ber_sequence_t ModifyDNRequest_sequence[] = {
2249   { &hf_ldap_entry          , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2250   { &hf_ldap_newrdn         , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_RelativeLDAPDN },
2251   { &hf_ldap_deleteoldrdn   , BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_NOOWNTAG, dissect_ldap_BOOLEAN },
2252   { &hf_ldap_newSuperior    , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_LDAPDN },
2253   { NULL, 0, 0, 0, NULL }
2254 };
2255
2256 static int
2257 dissect_ldap_ModifyDNRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2258   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2259                                    ModifyDNRequest_sequence, hf_index, ett_ldap_ModifyDNRequest);
2260
2261   return offset;
2262 }
2263
2264
2265
2266 static int
2267 dissect_ldap_ModifyDNResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2268   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2269
2270   return offset;
2271 }
2272
2273
2274 static const ber_sequence_t CompareRequest_sequence[] = {
2275   { &hf_ldap_entry          , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2276   { &hf_ldap_ava            , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeValueAssertion },
2277   { NULL, 0, 0, 0, NULL }
2278 };
2279
2280 static int
2281 dissect_ldap_CompareRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2282   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2283                                    CompareRequest_sequence, hf_index, ett_ldap_CompareRequest);
2284
2285   return offset;
2286 }
2287
2288
2289
2290 static int
2291 dissect_ldap_CompareResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2292   offset = dissect_ldap_LDAPResult(implicit_tag, tvb, offset, actx, tree, hf_index);
2293
2294   return offset;
2295 }
2296
2297
2298
2299 static int
2300 dissect_ldap_AbandonRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2301   offset = dissect_ldap_MessageID(implicit_tag, tvb, offset, actx, tree, hf_index);
2302
2303   return offset;
2304 }
2305
2306
2307
2308 static int
2309 dissect_ldap_LDAPOID(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2310 #line 41 "ldap.cnf"
2311
2312         tvbuff_t        *parameter_tvb;
2313         const gchar *name;
2314         proto_item      *item = NULL;
2315
2316
2317   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2318                                        &parameter_tvb);
2319
2320 #line 49 "ldap.cnf"
2321         
2322         object_identifier_id = NULL;
2323
2324         if (!parameter_tvb)
2325                 return offset;
2326
2327         object_identifier_id = tvb_get_string(parameter_tvb, 0, tvb_length_remaining(parameter_tvb,0));
2328         name = get_oid_str_name(object_identifier_id);
2329
2330         if(name){
2331                 item = get_ber_last_created_item();
2332
2333                 proto_item_append_text(item, " (%s)", name);
2334                 proto_item_append_text(tree, " %s", name);      
2335         }
2336
2337
2338
2339   return offset;
2340 }
2341
2342
2343
2344 static int
2345 dissect_ldap_OCTET_STRING(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2346   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2347                                        NULL);
2348
2349   return offset;
2350 }
2351
2352
2353 static const ber_sequence_t ExtendedRequest_sequence[] = {
2354   { &hf_ldap_requestName    , BER_CLASS_CON, 0, BER_FLAGS_IMPLTAG, dissect_ldap_LDAPOID },
2355   { &hf_ldap_requestValue   , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_OCTET_STRING },
2356   { NULL, 0, 0, 0, NULL }
2357 };
2358
2359 static int
2360 dissect_ldap_ExtendedRequest(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2361   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2362                                    ExtendedRequest_sequence, hf_index, ett_ldap_ExtendedRequest);
2363
2364   return offset;
2365 }
2366
2367
2368 static const value_string ldap_ExtendedResponse_resultCode_vals[] = {
2369   {   0, "success" },
2370   {   1, "operationsError" },
2371   {   2, "protocolError" },
2372   {   3, "timeLimitExceeded" },
2373   {   4, "sizeLimitExceeded" },
2374   {   5, "compareFalse" },
2375   {   6, "compareTrue" },
2376   {   7, "authMethodNotSupported" },
2377   {   8, "strongAuthRequired" },
2378   {  10, "referral" },
2379   {  11, "adminLimitExceeded" },
2380   {  12, "unavailableCriticalExtension" },
2381   {  13, "confidentialityRequired" },
2382   {  14, "saslBindInProgress" },
2383   {  16, "noSuchAttribute" },
2384   {  17, "undefinedAttributeType" },
2385   {  18, "inappropriateMatching" },
2386   {  19, "constraintViolation" },
2387   {  20, "attributeOrValueExists" },
2388   {  21, "invalidAttributeSyntax" },
2389   {  32, "noSuchObject" },
2390   {  33, "aliasProblem" },
2391   {  34, "invalidDNSyntax" },
2392   {  36, "aliasDereferencingProblem" },
2393   {  48, "inappropriateAuthentication" },
2394   {  49, "invalidCredentials" },
2395   {  50, "insufficientAccessRights" },
2396   {  51, "busy" },
2397   {  52, "unavailable" },
2398   {  53, "unwillingToPerform" },
2399   {  54, "loopDetect" },
2400   {  64, "namingViolation" },
2401   {  65, "objectClassViolation" },
2402   {  66, "notAllowedOnNonLeaf" },
2403   {  67, "notAllowedOnRDN" },
2404   {  68, "entryAlreadyExists" },
2405   {  69, "objectClassModsProhibited" },
2406   {  71, "affectsMultipleDSAs" },
2407   {  80, "other" },
2408   { 0, NULL }
2409 };
2410
2411
2412 static int
2413 dissect_ldap_ExtendedResponse_resultCode(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2414   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2415                                   NULL);
2416
2417   return offset;
2418 }
2419
2420
2421
2422 static int
2423 dissect_ldap_ResponseName(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2424   offset = dissect_ldap_LDAPOID(implicit_tag, tvb, offset, actx, tree, hf_index);
2425
2426   return offset;
2427 }
2428
2429
2430 static const ber_sequence_t ExtendedResponse_sequence[] = {
2431   { &hf_ldap_extendedResponse_resultCode, BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_ExtendedResponse_resultCode },
2432   { &hf_ldap_matchedDN      , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_LDAPDN },
2433   { &hf_ldap_errorMessage   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_ErrorMessage },
2434   { &hf_ldap_referral       , BER_CLASS_CON, 3, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_Referral },
2435   { &hf_ldap_responseName   , BER_CLASS_CON, 10, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_ResponseName },
2436   { &hf_ldap_response       , BER_CLASS_CON, 11, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_OCTET_STRING },
2437   { NULL, 0, 0, 0, NULL }
2438 };
2439
2440 static int
2441 dissect_ldap_ExtendedResponse(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2442   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2443                                    ExtendedResponse_sequence, hf_index, ett_ldap_ExtendedResponse);
2444
2445   return offset;
2446 }
2447
2448
2449 static const value_string ldap_ProtocolOp_vals[] = {
2450   {   0, "bindRequest" },
2451   {   1, "bindResponse" },
2452   {   2, "unbindRequest" },
2453   {   3, "searchRequest" },
2454   {   4, "searchResEntry" },
2455   {   5, "searchResDone" },
2456   {  19, "searchResRef" },
2457   {   6, "modifyRequest" },
2458   {   7, "modifyResponse" },
2459   {   8, "addRequest" },
2460   {   9, "addResponse" },
2461   {  10, "delRequest" },
2462   {  11, "delResponse" },
2463   {  12, "modDNRequest" },
2464   {  13, "modDNResponse" },
2465   {  14, "compareRequest" },
2466   {  15, "compareResponse" },
2467   {  16, "abandonRequest" },
2468   {  23, "extendedReq" },
2469   {  24, "extendedResp" },
2470   { 0, NULL }
2471 };
2472
2473 static const ber_choice_t ProtocolOp_choice[] = {
2474   {   0, &hf_ldap_bindRequest    , BER_CLASS_APP, 0, BER_FLAGS_NOOWNTAG, dissect_ldap_BindRequest },
2475   {   1, &hf_ldap_bindResponse   , BER_CLASS_APP, 1, BER_FLAGS_NOOWNTAG, dissect_ldap_BindResponse },
2476   {   2, &hf_ldap_unbindRequest  , BER_CLASS_APP, 2, BER_FLAGS_NOOWNTAG, dissect_ldap_UnbindRequest },
2477   {   3, &hf_ldap_searchRequest  , BER_CLASS_APP, 3, BER_FLAGS_NOOWNTAG, dissect_ldap_SearchRequest },
2478   {   4, &hf_ldap_searchResEntry , BER_CLASS_APP, 4, BER_FLAGS_NOOWNTAG, dissect_ldap_SearchResultEntry },
2479   {   5, &hf_ldap_searchResDone  , BER_CLASS_APP, 5, BER_FLAGS_NOOWNTAG, dissect_ldap_SearchResultDone },
2480   {  19, &hf_ldap_searchResRef   , BER_CLASS_APP, 19, BER_FLAGS_NOOWNTAG, dissect_ldap_SearchResultReference },
2481   {   6, &hf_ldap_modifyRequest  , BER_CLASS_APP, 6, BER_FLAGS_NOOWNTAG, dissect_ldap_ModifyRequest },
2482   {   7, &hf_ldap_modifyResponse , BER_CLASS_APP, 7, BER_FLAGS_NOOWNTAG, dissect_ldap_ModifyResponse },
2483   {   8, &hf_ldap_addRequest     , BER_CLASS_APP, 8, BER_FLAGS_NOOWNTAG, dissect_ldap_AddRequest },
2484   {   9, &hf_ldap_addResponse    , BER_CLASS_APP, 9, BER_FLAGS_NOOWNTAG, dissect_ldap_AddResponse },
2485   {  10, &hf_ldap_delRequest     , BER_CLASS_APP, 10, BER_FLAGS_NOOWNTAG, dissect_ldap_DelRequest },
2486   {  11, &hf_ldap_delResponse    , BER_CLASS_APP, 11, BER_FLAGS_NOOWNTAG, dissect_ldap_DelResponse },
2487   {  12, &hf_ldap_modDNRequest   , BER_CLASS_APP, 12, BER_FLAGS_NOOWNTAG, dissect_ldap_ModifyDNRequest },
2488   {  13, &hf_ldap_modDNResponse  , BER_CLASS_APP, 13, BER_FLAGS_NOOWNTAG, dissect_ldap_ModifyDNResponse },
2489   {  14, &hf_ldap_compareRequest , BER_CLASS_APP, 14, BER_FLAGS_NOOWNTAG, dissect_ldap_CompareRequest },
2490   {  15, &hf_ldap_compareResponse, BER_CLASS_APP, 15, BER_FLAGS_NOOWNTAG, dissect_ldap_CompareResponse },
2491   {  16, &hf_ldap_abandonRequest , BER_CLASS_APP, 16, BER_FLAGS_NOOWNTAG, dissect_ldap_AbandonRequest },
2492   {  23, &hf_ldap_extendedReq    , BER_CLASS_APP, 23, BER_FLAGS_NOOWNTAG, dissect_ldap_ExtendedRequest },
2493   {  24, &hf_ldap_extendedResp   , BER_CLASS_APP, 24, BER_FLAGS_NOOWNTAG, dissect_ldap_ExtendedResponse },
2494   { 0, NULL, 0, 0, 0, NULL }
2495 };
2496
2497 static int
2498 dissect_ldap_ProtocolOp(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2499 #line 75 "ldap.cnf"
2500
2501   ldap_call_response_t *lcrp;
2502   ldap_conv_info_t *ldap_info = (ldap_conv_info_t *)actx->pinfo->private_data;
2503   do_protocolop = TRUE;
2504
2505
2506   offset = dissect_ber_choice(actx, tree, tvb, offset,
2507                                  ProtocolOp_choice, hf_index, ett_ldap_ProtocolOp,
2508                                  &ProtocolOp);
2509
2510 #line 81 "ldap.cnf"
2511
2512   lcrp=ldap_match_call_response(tvb, actx->pinfo, tree, MessageID, ProtocolOp);
2513   if(lcrp){
2514     tap_queue_packet(ldap_tap, actx->pinfo, lcrp);
2515   }
2516   
2517   /* XXX: the count will not work if the results span multiple TCP packets */
2518
2519   if(ldap_info && tree) { /* only count once - on tree pass */
2520     switch(ProtocolOp) {
2521   
2522     case LDAP_RES_SEARCH_ENTRY:
2523         ldap_info->num_results++;
2524
2525         proto_item_append_text(tree, " [%d result%s]", 
2526                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2527
2528         break;
2529
2530     case LDAP_RES_SEARCH_RESULT:
2531   
2532         if (check_col(actx->pinfo->cinfo, COL_INFO))
2533           col_append_fstr(actx->pinfo->cinfo, COL_INFO, " [%d result%s]", 
2534                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2535                         
2536         proto_item_append_text(tree, " [%d result%s]", 
2537                         ldap_info->num_results, ldap_info->num_results == 1 ? "" : "s");
2538                         
2539         ldap_info->num_results = 0;
2540         break;
2541      default:
2542         break;
2543     } 
2544   }
2545   
2546
2547   return offset;
2548 }
2549
2550
2551
2552 static int
2553 dissect_ldap_ControlType(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2554   offset = dissect_ldap_LDAPOID(implicit_tag, tvb, offset, actx, tree, hf_index);
2555
2556   return offset;
2557 }
2558
2559
2560
2561 static int
2562 dissect_ldap_T_controlValue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2563 #line 649 "ldap.cnf"
2564         gint8 class;
2565         gboolean pc, ind;
2566         gint32 tag;
2567         guint32 len;
2568         
2569         if((object_identifier_id != NULL) && oid_has_dissector(object_identifier_id)) {
2570                 /* remove the OCTET STRING encoding */          
2571                 offset=dissect_ber_identifier(actx->pinfo, NULL, tvb, offset, &class, &pc, &tag);
2572                 offset=dissect_ber_length(actx->pinfo, NULL, tvb, offset, &len, &ind);
2573
2574                 call_ber_oid_callback(object_identifier_id, tvb, offset, actx->pinfo, tree);
2575
2576                 offset += len;
2577         } else {
2578                   offset = dissect_ber_octet_string(implicit_tag, actx, tree, tvb, offset, hf_index,
2579                                        NULL);
2580
2581         }
2582
2583
2584
2585   return offset;
2586 }
2587
2588
2589 static const ber_sequence_t Control_sequence[] = {
2590   { &hf_ldap_controlType    , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_ControlType },
2591   { &hf_ldap_criticality    , BER_CLASS_UNI, BER_UNI_TAG_BOOLEAN, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ldap_BOOLEAN },
2592   { &hf_ldap_controlValue   , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_OPTIONAL|BER_FLAGS_NOOWNTAG, dissect_ldap_T_controlValue },
2593   { NULL, 0, 0, 0, NULL }
2594 };
2595
2596 static int
2597 dissect_ldap_Control(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2598   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2599                                    Control_sequence, hf_index, ett_ldap_Control);
2600
2601   return offset;
2602 }
2603
2604
2605 static const ber_sequence_t Controls_sequence_of[1] = {
2606   { &hf_ldap_Controls_item  , BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_Control },
2607 };
2608
2609 static int
2610 dissect_ldap_Controls(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2611   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2612                                       Controls_sequence_of, hf_index, ett_ldap_Controls);
2613
2614   return offset;
2615 }
2616
2617
2618 static const ber_sequence_t LDAPMessage_sequence[] = {
2619   { &hf_ldap_messageID      , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_MessageID },
2620   { &hf_ldap_protocolOp     , BER_CLASS_ANY/*choice*/, -1/*choice*/, BER_FLAGS_NOOWNTAG|BER_FLAGS_NOTCHKTAG, dissect_ldap_ProtocolOp },
2621   { &hf_ldap_controls       , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_Controls },
2622   { NULL, 0, 0, 0, NULL }
2623 };
2624
2625 static int
2626 dissect_ldap_LDAPMessage(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2627   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2628                                    LDAPMessage_sequence, hf_index, ett_ldap_LDAPMessage);
2629
2630   return offset;
2631 }
2632
2633
2634
2635
2636
2637 static int
2638 dissect_ldap_INTEGER(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2639   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2640                                   NULL);
2641
2642   return offset;
2643 }
2644
2645
2646 static const ber_sequence_t SearchControlValue_sequence[] = {
2647   { &hf_ldap_size           , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER },
2648   { &hf_ldap_cookie         , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_OCTET_STRING },
2649   { NULL, 0, 0, 0, NULL }
2650 };
2651
2652 static int
2653 dissect_ldap_SearchControlValue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2654   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2655                                    SearchControlValue_sequence, hf_index, ett_ldap_SearchControlValue);
2656
2657   return offset;
2658 }
2659
2660
2661 static const ber_sequence_t SortKeyList_item_sequence[] = {
2662   { &hf_ldap_attributeType  , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_AttributeDescription },
2663   { &hf_ldap_orderingRule   , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_MatchingRuleId },
2664   { &hf_ldap_reverseOrder   , BER_CLASS_CON, 1, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_BOOLEAN },
2665   { NULL, 0, 0, 0, NULL }
2666 };
2667
2668 static int
2669 dissect_ldap_SortKeyList_item(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2670   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2671                                    SortKeyList_item_sequence, hf_index, ett_ldap_SortKeyList_item);
2672
2673   return offset;
2674 }
2675
2676
2677 static const ber_sequence_t SortKeyList_sequence_of[1] = {
2678   { &hf_ldap_SortKeyList_item, BER_CLASS_UNI, BER_UNI_TAG_SEQUENCE, BER_FLAGS_NOOWNTAG, dissect_ldap_SortKeyList_item },
2679 };
2680
2681 static int
2682 dissect_ldap_SortKeyList(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2683   offset = dissect_ber_sequence_of(implicit_tag, actx, tree, tvb, offset,
2684                                       SortKeyList_sequence_of, hf_index, ett_ldap_SortKeyList);
2685
2686   return offset;
2687 }
2688
2689
2690 static const value_string ldap_T_sortResult_vals[] = {
2691   {   0, "success" },
2692   {   1, "operationsError" },
2693   {   3, "timeLimitExceeded" },
2694   {   8, "strongAuthRequired" },
2695   {  11, "adminLimitExceeded" },
2696   {  16, "noSuchAttribute" },
2697   {  18, "inappropriateMatching" },
2698   {  50, "insufficientAccessRights" },
2699   {  51, "busy" },
2700   {  53, "unwillingToPerform" },
2701   {  80, "other" },
2702   { 0, NULL }
2703 };
2704
2705
2706 static int
2707 dissect_ldap_T_sortResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2708   offset = dissect_ber_integer(implicit_tag, actx, tree, tvb, offset, hf_index,
2709                                   NULL);
2710
2711   return offset;
2712 }
2713
2714
2715 static const ber_sequence_t SortResult_sequence[] = {
2716   { &hf_ldap_sortResult     , BER_CLASS_UNI, BER_UNI_TAG_ENUMERATED, BER_FLAGS_NOOWNTAG, dissect_ldap_T_sortResult },
2717   { &hf_ldap_attributeType  , BER_CLASS_CON, 0, BER_FLAGS_OPTIONAL|BER_FLAGS_IMPLTAG, dissect_ldap_AttributeDescription },
2718   { NULL, 0, 0, 0, NULL }
2719 };
2720
2721 static int
2722 dissect_ldap_SortResult(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2723   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2724                                    SortResult_sequence, hf_index, ett_ldap_SortResult);
2725
2726   return offset;
2727 }
2728
2729
2730 static const ber_sequence_t ReplControlValue_sequence[] = {
2731   { &hf_ldap_parentsFirst   , BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER },
2732   { &hf_ldap_maxReturnLength, BER_CLASS_UNI, BER_UNI_TAG_INTEGER, BER_FLAGS_NOOWNTAG, dissect_ldap_INTEGER },
2733   { &hf_ldap_cookie         , BER_CLASS_UNI, BER_UNI_TAG_OCTETSTRING, BER_FLAGS_NOOWNTAG, dissect_ldap_OCTET_STRING },
2734   { NULL, 0, 0, 0, NULL }
2735 };
2736
2737 static int
2738 dissect_ldap_ReplControlValue(gboolean implicit_tag _U_, tvbuff_t *tvb _U_, int offset _U_, asn1_ctx_t *actx _U_, proto_tree *tree _U_, int hf_index _U_) {
2739   offset = dissect_ber_sequence(implicit_tag, actx, tree, tvb, offset,
2740                                    ReplControlValue_sequence, hf_index, ett_ldap_ReplControlValue);
2741
2742   return offset;
2743 }
2744
2745 /*--- PDUs ---*/
2746
2747 static void dissect_LDAPMessage_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {
2748   asn1_ctx_t asn1_ctx;
2749   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2750   dissect_ldap_LDAPMessage(FALSE, tvb, 0, &asn1_ctx, tree, hf_ldap_LDAPMessage_PDU);
2751 }
2752 static void dissect_SearchControlValue_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {
2753   asn1_ctx_t asn1_ctx;
2754   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2755   dissect_ldap_SearchControlValue(FALSE, tvb, 0, &asn1_ctx, tree, hf_ldap_SearchControlValue_PDU);
2756 }
2757 static void dissect_SortKeyList_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {
2758   asn1_ctx_t asn1_ctx;
2759   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2760   dissect_ldap_SortKeyList(FALSE, tvb, 0, &asn1_ctx, tree, hf_ldap_SortKeyList_PDU);
2761 }
2762 static void dissect_SortResult_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {
2763   asn1_ctx_t asn1_ctx;
2764   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2765   dissect_ldap_SortResult(FALSE, tvb, 0, &asn1_ctx, tree, hf_ldap_SortResult_PDU);
2766 }
2767 static void dissect_ReplControlValue_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_) {
2768   asn1_ctx_t asn1_ctx;
2769   asn1_ctx_init(&asn1_ctx, ASN1_ENC_BER, TRUE, pinfo);
2770   dissect_ldap_ReplControlValue(FALSE, tvb, 0, &asn1_ctx, tree, hf_ldap_ReplControlValue_PDU);
2771 }
2772
2773
2774 /*--- End of included file: packet-ldap-fn.c ---*/
2775 #line 543 "packet-ldap-template.c"
2776
2777 static void
2778 dissect_ldap_payload(tvbuff_t *tvb, packet_info *pinfo,
2779                      proto_tree *tree, ldap_conv_info_t *ldap_info,
2780                      gboolean is_mscldap)
2781 {
2782   int offset = 0;
2783   guint length_remaining;
2784   guint msg_len = 0;
2785   int messageOffset = 0;
2786   guint headerLength = 0;
2787   guint length = 0;
2788   tvbuff_t *msg_tvb = NULL;
2789   gint8 class;
2790   gboolean pc, ind = 0;
2791   gint32 ber_tag;
2792
2793
2794 one_more_pdu:
2795
2796     length_remaining = tvb_ensure_length_remaining(tvb, offset);
2797
2798     if (length_remaining < 6) return;
2799
2800     /*
2801      * OK, try to read the "Sequence Of" header; this gets the total
2802      * length of the LDAP message.
2803      */
2804         messageOffset = get_ber_identifier(tvb, offset, &class, &pc, &ber_tag);
2805         messageOffset = get_ber_length(tree, tvb, messageOffset, &msg_len, &ind);
2806
2807     /* sanity check */
2808     if((msg_len<4) || (msg_len>10000000)) return;
2809
2810     if ( (class==BER_CLASS_UNI) && (ber_tag==BER_UNI_TAG_SEQUENCE) ) {
2811         /*
2812          * Add the length of the "Sequence Of" header to the message
2813          * length.
2814          */
2815         headerLength = messageOffset - offset;
2816         msg_len += headerLength;
2817         if (msg_len < headerLength) {
2818             /*
2819              * The message length was probably so large that the total length
2820              * overflowed.
2821              *
2822              * Report this as an error.
2823              */
2824             show_reported_bounds_error(tvb, pinfo, tree);
2825             return;
2826         }
2827     } else {
2828         /*
2829          * We couldn't parse the header; just make it the amount of data
2830          * remaining in the tvbuff, so we'll give up on this segment
2831          * after attempting to parse the message - there's nothing more
2832          * we can do.  "dissect_ldap_message()" will display the error.
2833          */
2834         msg_len = length_remaining;
2835     }
2836
2837     /*
2838      * Construct a tvbuff containing the amount of the payload we have
2839      * available.  Make its reported length the amount of data in the
2840      * LDAP message.
2841      *
2842      * XXX - if reassembly isn't enabled. the subdissector will throw a
2843      * BoundsError exception, rather than a ReportedBoundsError exception.
2844      * We really want a tvbuff where the length is "length", the reported
2845      * length is "plen", and the "if the snapshot length were infinite"
2846      * length is the minimum of the reported length of the tvbuff handed
2847      * to us and "plen", with a new type of exception thrown if the offset
2848      * is within the reported length but beyond that third length, with
2849      * that exception getting the "Unreassembled Packet" error.
2850      */
2851     length = length_remaining;
2852     if (length > msg_len) length = msg_len;
2853     msg_tvb = tvb_new_subset(tvb, offset, length, msg_len);
2854
2855     /*
2856      * Now dissect the LDAP message.
2857      */
2858     ldap_info->is_mscldap = is_mscldap;
2859     pinfo->private_data = ldap_info;
2860     dissect_LDAPMessage_PDU(msg_tvb, pinfo, tree);
2861
2862     offset += msg_len;
2863
2864     /* If this was a sasl blob there might be another PDU following in the
2865      * same blob
2866      */
2867     if(tvb_length_remaining(tvb, offset)>=6){
2868         tvb = tvb_new_subset(tvb, offset, tvb_length_remaining(tvb, offset), -1);
2869         offset = 0;
2870
2871         goto one_more_pdu;
2872     }
2873
2874 }
2875
2876 static void
2877 dissect_ldap_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean is_mscldap)
2878 {
2879   int offset = 0;
2880   conversation_t *conversation;
2881   gboolean doing_sasl_security = FALSE;
2882   guint length_remaining;
2883   ldap_conv_info_t *ldap_info = NULL;
2884   proto_item *ldap_item = NULL;
2885   proto_tree *ldap_tree = NULL;
2886
2887   ldm_tree = NULL;
2888
2889   /*
2890    * Do we have a conversation for this connection?
2891    */
2892   conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2893                                    pinfo->ptype, pinfo->srcport,
2894                                    pinfo->destport, 0);
2895   if (conversation == NULL) {
2896     /* We don't yet have a conversation, so create one. */
2897     conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2898                                     pinfo->ptype, pinfo->srcport,
2899                                     pinfo->destport, 0);
2900
2901   }
2902
2903   /*
2904    * Do we already have a type and mechanism?
2905    */
2906   ldap_info = conversation_get_proto_data(conversation, proto_ldap);
2907   if (ldap_info == NULL) {
2908     /* No.  Attach that information to the conversation, and add
2909      * it to the list of information structures.
2910      */
2911     ldap_info = se_alloc(sizeof(ldap_conv_info_t));
2912     ldap_info->auth_type = 0;
2913     ldap_info->auth_mech = 0;
2914     ldap_info->first_auth_frame = 0;
2915     ldap_info->matched=g_hash_table_new(ldap_info_hash_matched, ldap_info_equal_matched);
2916     ldap_info->unmatched=g_hash_table_new(ldap_info_hash_unmatched, ldap_info_equal_unmatched);
2917     ldap_info->num_results = 0;
2918
2919     conversation_add_proto_data(conversation, proto_ldap, ldap_info);
2920
2921     ldap_info->next = ldap_info_items;
2922     ldap_info_items = ldap_info;
2923
2924   }
2925
2926   switch (ldap_info->auth_type) {
2927     case LDAP_AUTH_SASL:
2928     /*
2929      * It's SASL; are we using a security layer?
2930      */
2931     if (ldap_info->first_auth_frame != 0 &&
2932        pinfo->fd->num >= ldap_info->first_auth_frame) {
2933         doing_sasl_security = TRUE;     /* yes */
2934     }
2935   }
2936
2937     length_remaining = tvb_ensure_length_remaining(tvb, offset);
2938
2939     /* It might still be a packet containing a SASL security layer
2940      * but its just that we never saw the BIND packet.
2941      * check if it looks like it could be a SASL blob here
2942      * and in that case just assume it is GSS-SPNEGO
2943      */
2944     if(!doing_sasl_security && (tvb_bytes_exist(tvb, offset, 5))
2945       &&(tvb_get_ntohl(tvb, offset)<=(guint)(tvb_reported_length_remaining(tvb, offset)-4))
2946       &&(tvb_get_guint8(tvb, offset+4)==0x60) ){
2947         ldap_info->auth_type=LDAP_AUTH_SASL;
2948         ldap_info->first_auth_frame=pinfo->fd->num;
2949         ldap_info->auth_mech=g_strdup("GSS-SPNEGO");
2950         doing_sasl_security=TRUE;
2951     }
2952
2953     /*
2954      * This is the first PDU, set the Protocol column and clear the
2955      * Info column.
2956      */
2957     if (check_col(pinfo->cinfo, COL_PROTOCOL)) col_set_str(pinfo->cinfo, COL_PROTOCOL, pinfo->current_proto);
2958     if (check_col(pinfo->cinfo, COL_INFO)) col_clear(pinfo->cinfo, COL_INFO);
2959
2960     ldap_item = proto_tree_add_item(tree, is_mscldap?proto_cldap:proto_ldap, tvb, 0, -1, FALSE);
2961     ldap_tree = proto_item_add_subtree(ldap_item, ett_ldap);
2962
2963     /*
2964      * Might we be doing a SASL security layer and, if so, *are* we doing
2965      * one?
2966      *
2967      * Just because we've seen a bind reply for SASL, that doesn't mean
2968      * that we're using a SASL security layer; I've seen captures in
2969      * which some SASL negotiations lead to a security layer being used
2970      * and other negotiations don't, and it's not obvious what's different
2971      * in the two negotiations.  Therefore, we assume that if the first
2972      * byte is 0, it's a length for a SASL security layer (that way, we
2973      * never reassemble more than 16 megabytes, protecting us from
2974      * chewing up *too* much memory), and otherwise that it's an LDAP
2975      * message (actually, if it's an LDAP message it should begin with 0x30,
2976      * but we want to parse garbage as LDAP messages rather than really
2977      * huge lengths).
2978      */
2979
2980     if (doing_sasl_security && tvb_get_guint8(tvb, offset) == 0) {
2981       proto_item *sasl_item = NULL;
2982       proto_tree *sasl_tree = NULL;
2983       tvbuff_t *sasl_tvb;
2984       guint sasl_len, sasl_msg_len, length;
2985       /*
2986        * Yes.  The frame begins with a 4-byte big-endian length.
2987        * And we know we have at least 6 bytes
2988        */
2989
2990       /*
2991        * Get the SASL length, which is the length of data in the buffer
2992        * following the length (i.e., it's 4 less than the total length).
2993        *
2994        * XXX - do we need to reassemble buffers?  For now, we
2995        * assume that each LDAP message is entirely contained within
2996        * a buffer.
2997        */
2998       sasl_len = tvb_get_ntohl(tvb, offset);
2999       sasl_msg_len = sasl_len + 4;
3000       if (sasl_msg_len < 4) {
3001         /*
3002          * The message length was probably so large that the total length
3003          * overflowed.
3004          *
3005          * Report this as an error.
3006          */
3007         show_reported_bounds_error(tvb, pinfo, tree);
3008         return;
3009       }
3010
3011       /*
3012        * Construct a tvbuff containing the amount of the payload we have
3013        * available.  Make its reported length the amount of data in the PDU.
3014        *
3015        * XXX - if reassembly isn't enabled. the subdissector will throw a
3016        * BoundsError exception, rather than a ReportedBoundsError exception.
3017        * We really want a tvbuff where the length is "length", the reported
3018        * length is "plen", and the "if the snapshot length were infinite"
3019        * length is the minimum of the reported length of the tvbuff handed
3020        * to us and "plen", with a new type of exception thrown if the offset
3021        * is within the reported length but beyond that third length, with
3022        * that exception getting the "Unreassembled Packet" error.
3023        */
3024       length = length_remaining;
3025       if (length > sasl_msg_len) length = sasl_msg_len;
3026       sasl_tvb = tvb_new_subset(tvb, offset, length, sasl_msg_len);
3027
3028       if (ldap_tree) {
3029         proto_tree_add_uint(ldap_tree, hf_ldap_sasl_buffer_length, sasl_tvb, 0, 4,
3030                             sasl_len);
3031
3032         sasl_item = proto_tree_add_text(ldap_tree, sasl_tvb, 0,  sasl_msg_len, "SASL Buffer");
3033         sasl_tree = proto_item_add_subtree(sasl_item, ett_ldap_sasl_blob);
3034       }
3035
3036       if (ldap_info->auth_mech != NULL &&
3037           ((strcmp(ldap_info->auth_mech, "GSS-SPNEGO") == 0) ||
3038            /* auth_mech may have been set from the bind */
3039            (strcmp(ldap_info->auth_mech, "GSSAPI") == 0))) {
3040           tvbuff_t *gssapi_tvb, *plain_tvb = NULL, *decr_tvb= NULL;
3041           int ver_len;
3042           int length;
3043
3044           /*
3045            * This is GSS-API (using SPNEGO, but we should be done with
3046            * the negotiation by now).
3047            *
3048            * Dissect the GSS_Wrap() token; it'll return the length of
3049            * the token, from which we compute the offset in the tvbuff at
3050            * which the plaintext data, i.e. the LDAP message, begins.
3051            */
3052           length = tvb_length_remaining(sasl_tvb, 4);
3053           if ((guint)length > sasl_len)
3054               length = sasl_len;
3055           gssapi_tvb = tvb_new_subset(sasl_tvb, 4, length, sasl_len);
3056
3057           /* Attempt decryption of the GSSAPI wrapped data if possible */
3058           pinfo->decrypt_gssapi_tvb=DECRYPT_GSSAPI_NORMAL;
3059           pinfo->gssapi_wrap_tvb=NULL;
3060           pinfo->gssapi_encrypted_tvb=NULL;
3061           pinfo->gssapi_decrypted_tvb=NULL;
3062           ver_len = call_dissector(gssapi_wrap_handle, gssapi_tvb, pinfo, sasl_tree);
3063           /* if we could unwrap, do a tvb shuffle */
3064           if(pinfo->gssapi_decrypted_tvb){
3065                 decr_tvb=pinfo->gssapi_decrypted_tvb;
3066           }
3067           /* tidy up */
3068           pinfo->decrypt_gssapi_tvb=0;
3069           pinfo->gssapi_wrap_tvb=NULL;
3070           pinfo->gssapi_encrypted_tvb=NULL;
3071           pinfo->gssapi_decrypted_tvb=NULL;
3072
3073           /*
3074            * if len is 0 it probably mean that we got a PDU that is not
3075            * aligned to the start of the segment.
3076            */
3077           if(ver_len==0){
3078              return;
3079           }
3080
3081           /*
3082            * if we don't have unwrapped data,
3083            * see if the wrapping involved encryption of the
3084            * data; if not, just use the plaintext data.
3085            */
3086           if (!decr_tvb) {
3087             if(!pinfo->gssapi_data_encrypted){
3088               plain_tvb = tvb_new_subset(gssapi_tvb,  ver_len, -1, -1);
3089             }
3090           }
3091
3092           if (decr_tvb) {
3093             proto_item *enc_item = NULL;
3094             proto_tree *enc_tree = NULL;
3095
3096             /*
3097              * The LDAP message was encrypted in the packet, and has
3098              * been decrypted; dissect the decrypted LDAP message.
3099              */
3100             if (check_col(pinfo->cinfo, COL_INFO)) {
3101               col_add_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy (decrypted): ");
3102
3103             }
3104
3105             if (sasl_tree) {
3106               enc_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3107                                 "GSS-API Encrypted payload (%d byte%s)",
3108                                 sasl_len - ver_len,
3109                                 plurality(sasl_len - ver_len, "", "s"));
3110               enc_tree = proto_item_add_subtree(enc_item, ett_ldap_payload);
3111             }
3112             dissect_ldap_payload(decr_tvb, pinfo, enc_tree, ldap_info, is_mscldap);
3113           } else if (plain_tvb) {
3114             proto_item *plain_item = NULL;
3115             proto_tree *plain_tree = NULL;
3116
3117             /*
3118              * The LDAP message wasn't encrypted in the packet;
3119              * dissect the plain LDAP message.
3120              */
3121             if (check_col(pinfo->cinfo, COL_INFO)) {
3122               col_add_str(pinfo->cinfo, COL_INFO, "SASL GSS-API Integrity: ");
3123             }
3124
3125             if (sasl_tree) {
3126               plain_item = proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3127                                 "GSS-API payload (%d byte%s)",
3128                                 sasl_len - ver_len,
3129                                 plurality(sasl_len - ver_len, "", "s"));
3130               plain_tree = proto_item_add_subtree(plain_item, ett_ldap_payload);
3131             }
3132
3133            dissect_ldap_payload(plain_tvb, pinfo, plain_tree, ldap_info, is_mscldap);
3134           } else {
3135             /*
3136              * The LDAP message was encrypted in the packet, and was
3137              * not decrypted; just show it as encrypted data.
3138              */
3139             if (check_col(pinfo->cinfo, COL_INFO)) {
3140                     col_add_fstr(pinfo->cinfo, COL_INFO, "SASL GSS-API Privacy: payload (%d byte%s)",
3141                                  sasl_len - ver_len,
3142                                  plurality(sasl_len - ver_len, "", "s"));
3143             }
3144             if (sasl_tree) {
3145               proto_tree_add_text(sasl_tree, gssapi_tvb, ver_len, -1,
3146                                 "GSS-API Encrypted payload (%d byte%s)",
3147                                 sasl_len - ver_len,
3148                                 plurality(sasl_len - ver_len, "", "s"));
3149             }
3150           }
3151       }
3152       offset += sasl_msg_len;
3153     } else {
3154         /* plain LDAP, so dissect the payload */
3155         dissect_ldap_payload(tvb, pinfo, ldap_tree, ldap_info, is_mscldap);
3156     }
3157 }
3158
3159 static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
3160 {
3161   guint8 len;
3162
3163   len=tvb_get_guint8(tvb, offset);
3164   offset+=1;
3165   *str=0;
3166
3167   while(len){
3168     /* add potential field separation dot */
3169     if(prepend_dot){
3170       if(!maxlen){
3171         *str=0;
3172         return offset;
3173       }
3174       maxlen--;
3175       *str++='.';
3176       *str=0;
3177     }
3178
3179     if(len==0xc0){
3180       int new_offset;
3181       /* ops its a mscldap compressed string */
3182
3183       new_offset=tvb_get_guint8(tvb, offset);
3184       if (new_offset == offset - 1)
3185         THROW(ReportedBoundsError);
3186       offset+=1;
3187
3188       dissect_mscldap_string(tvb, new_offset, str, maxlen, FALSE);
3189
3190       return offset;
3191     }
3192
3193     prepend_dot=TRUE;
3194
3195     if(maxlen<=len){
3196       if(maxlen>3){
3197         *str++='.';
3198         *str++='.';
3199         *str++='.';
3200       }
3201       *str=0;
3202       return offset; /* will mess up offset in caller, is unlikely */
3203     }
3204     tvb_memcpy(tvb, str, offset, len);
3205     str+=len;
3206     *str=0;
3207     maxlen-=len;
3208     offset+=len;
3209
3210
3211     len=tvb_get_guint8(tvb, offset);
3212     offset+=1;
3213   }
3214   *str=0;
3215   return offset;
3216 }
3217
3218 /* These flag bits were found to be defined in the samba sources.
3219  * I hope they are correct (but have serious doubts about the CLOSEST
3220  * bit being used or being meaningful).
3221  */
3222 static const true_false_string tfs_ads_pdc = {
3223         "This is a PDC",
3224         "This is NOT a pdc"
3225 };
3226 static const true_false_string tfs_ads_gc = {
3227         "This is a GLOBAL CATALOGUE of forest",
3228         "This is NOT a global catalog of forest"
3229 };
3230 static const true_false_string tfs_ads_ldap = {
3231         "This is an LDAP server",
3232         "This is NOT an ldap server"
3233 };
3234 static const true_false_string tfs_ads_ds = {
3235         "This dc supports DS",
3236         "This dc does NOT support ds"
3237 };
3238 static const true_false_string tfs_ads_kdc = {
3239         "This is a KDC (kerberos)",
3240         "This is NOT a kdc (kerberos)"
3241 };
3242 static const true_false_string tfs_ads_timeserv = {
3243         "This dc is running TIME SERVICES (ntp)",
3244         "This dc is NOT running time services (ntp)"
3245 };
3246 static const true_false_string tfs_ads_closest = {
3247         "This is the CLOSEST dc (unreliable?)",
3248         "This is NOT the closest dc"
3249 };
3250 static const true_false_string tfs_ads_writable = {
3251         "This dc is WRITABLE",
3252         "This dc is NOT writable"
3253 };
3254 static const true_false_string tfs_ads_good_timeserv = {
3255         "This dc has a GOOD TIME SERVICE (i.e. hardware clock)",
3256         "This dc does NOT have a good time service (i.e. no hardware clock)"
3257 };
3258 static const true_false_string tfs_ads_ndnc = {
3259         "Domain is NON-DOMAIN NC serviced by ldap server",
3260         "Domain is NOT non-domain nc serviced by ldap server"
3261 };
3262 static int dissect_mscldap_netlogon_flags(proto_tree *parent_tree, tvbuff_t *tvb, int offset)
3263 {
3264   guint32 flags;
3265   proto_item *item;
3266   proto_tree *tree=NULL;
3267   guint fields[] = { hf_mscldap_netlogon_flags_ndnc,
3268                      hf_mscldap_netlogon_flags_good_timeserv,
3269                      hf_mscldap_netlogon_flags_writable,
3270                      hf_mscldap_netlogon_flags_closest,
3271                      hf_mscldap_netlogon_flags_timeserv,
3272                      hf_mscldap_netlogon_flags_kdc,
3273                      hf_mscldap_netlogon_flags_ds,
3274                      hf_mscldap_netlogon_flags_ldap,
3275                      hf_mscldap_netlogon_flags_gc,
3276                      hf_mscldap_netlogon_flags_pdc,
3277                      0 };
3278   guint  *field;
3279   header_field_info *hfi;
3280   gboolean one_bit_set = FALSE;
3281
3282   flags=tvb_get_letohl(tvb, offset);
3283   item=proto_tree_add_item(parent_tree, hf_mscldap_netlogon_flags, tvb, offset, 4, TRUE);
3284   if(parent_tree){
3285     tree = proto_item_add_subtree(item, ett_mscldap_netlogon_flags);
3286   }
3287
3288   proto_item_append_text(item, " (");
3289
3290   for(field = fields; *field; field++) {
3291     proto_tree_add_boolean(tree, *field, tvb, offset, 4, flags);
3292     hfi = proto_registrar_get_nth(*field);
3293
3294     if(flags & hfi->bitmask) {
3295
3296       if(one_bit_set)
3297         proto_item_append_text(item, ", ");
3298       else
3299         one_bit_set = TRUE;
3300
3301       proto_item_append_text(item, hfi->name);
3302
3303     }
3304   }
3305
3306   proto_item_append_text(item, ")");
3307
3308   offset += 4;
3309
3310   return offset;
3311 }
3312
3313 static void dissect_NetLogon_PDU(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree)
3314 {
3315   int old_offset, offset=0;
3316   char str[256];
3317
3318   ldm_tree = NULL;
3319
3320 /*qqq*/
3321
3322   /* Type */
3323   /*XXX someone that knows what the type means should add that knowledge here*/
3324   proto_tree_add_item(tree, hf_mscldap_netlogon_type, tvb, offset, 4, TRUE);
3325   offset += 4;
3326
3327   /* Flags */
3328   offset = dissect_mscldap_netlogon_flags(tree, tvb, offset);
3329
3330   /* Domain GUID */
3331   proto_tree_add_item(tree, hf_mscldap_domain_guid, tvb, offset, 16, TRUE);