1 /* packet-ldap-template.c
2 * Routines for ldap packet dissection
4 * See RFC 3494 (LDAP v2), RFC 4511 (LDAP v3), and RFC 2222 (SASL).
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
14 * This is not a complete implementation. It doesn't handle the full version 3, more specifically,
15 * it handles only the commands of version 2, but any additional characteristics of the ver3 command are supported.
16 * It's also missing extensible search filters.
18 * There should probably be a lot more error checking, I simply assume that if we have a full packet, it will be a complete
21 * 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
22 * 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
26 * nazard@dragoninc.on.ca
30 * 11/11/2002 - Fixed problem when decoding LDAP with desegmentation enabled and the
31 * ASN.1 BER Universal Class Tag: "Sequence Of" header is encapsulated across 2
35 * ronald.henderson@cognicaseusa.com
39 * 20-JAN-2004 - added decoding of MS-CLDAP netlogon RPC
40 * using information from the SNIA 2003 conference paper :
41 * Active Directory Domain Controller Location Service
47 * 17-DEC-2004 - added basic decoding for LDAP Controls
48 * 20-DEC-2004 - added handling for GSS-API encrypted blobs
50 * Stefan Metzmacher <metze@samba.org>
52 * 15-NOV-2005 - Changed to use the asn2wrs compiler
53 * Anders Broman <anders.broman@ericsson.com>
57 * 3-AUG-2008 - Extended the cldap support to include all netlogon data types.
58 * Updated cldap_netlogon_flags to include Windows 2008 flags
59 * Expanded the ntver ldap option with bit field
61 * Gary Reynolds <gazzadownunder@yahoo.co.uk>
65 * 09-DEC-2009 - Added support for RFC4533
66 * Content Synchronization Operation (aka syncrepl)
67 * 11-DEC-2009 - Added support for IntermediateResponse (LDAP v3 from RFC 4511)
68 * Mathieu Parent <math.parent@gmail.com>
73 #include <epan/packet.h>
74 #include <epan/exceptions.h>
75 #include <epan/conversation.h>
76 #include <epan/prefs.h>
78 #include <epan/srt_table.h>
79 #include <epan/oids.h>
80 #include <epan/strutil.h>
81 #include <epan/show_exception.h>
82 #include <epan/asn1.h>
83 #include <epan/proto_data.h>
84 #include <epan/expert.h>
86 #include <epan/charsets.h>
88 #include <wsutil/str_util.h>
89 #include <wsutil/array.h>
90 #include "packet-frame.h"
91 #include "packet-tcp.h"
92 #include "packet-windows-common.h"
93 #include "packet-dcerpc.h"
95 #include "packet-ldap.h"
96 #include "packet-ntlmssp.h"
97 #include "packet-tls.h"
98 #include "packet-tls-utils.h"
99 #include "packet-gssapi.h"
100 #include "packet-acdr.h"
102 #include "packet-ber.h"
103 #include "packet-per.h"
104 #include "packet-dns.h"
106 #define PNAME "Lightweight Directory Access Protocol"
107 #define PSNAME "LDAP"
108 #define PFNAME "ldap"
110 void proto_register_ldap(void);
111 void proto_reg_handoff_ldap(void);
113 /* Initialize the protocol and registered fields */
115 static int proto_ldap
;
116 static int proto_cldap
;
118 static int hf_ldap_sasl_buffer_length
;
119 static int hf_ldap_response_in
;
120 static int hf_ldap_response_to
;
121 static int hf_ldap_time
;
122 static int hf_ldap_guid
;
124 static int hf_mscldap_ntver_flags
;
125 static int hf_mscldap_ntver_flags_v1
;
126 static int hf_mscldap_ntver_flags_v5
;
127 static int hf_mscldap_ntver_flags_v5ex
;
128 static int hf_mscldap_ntver_flags_v5ep
;
129 static int hf_mscldap_ntver_flags_vcs
;
130 static int hf_mscldap_ntver_flags_vnt4
;
131 static int hf_mscldap_ntver_flags_vpdc
;
132 static int hf_mscldap_ntver_flags_vip
;
133 static int hf_mscldap_ntver_flags_vl
;
134 static int hf_mscldap_ntver_flags_vgc
;
136 static int hf_mscldap_netlogon_ipaddress_family
;
137 static int hf_mscldap_netlogon_ipaddress_port
;
138 static int hf_mscldap_netlogon_ipaddress
;
139 static int hf_mscldap_netlogon_ipaddress_ipv4
;
140 static int hf_mscldap_netlogon_opcode
;
141 static int hf_mscldap_netlogon_flags
;
142 static int hf_mscldap_netlogon_flags_pdc
;
143 static int hf_mscldap_netlogon_flags_gc
;
144 static int hf_mscldap_netlogon_flags_ldap
;
145 static int hf_mscldap_netlogon_flags_ds
;
146 static int hf_mscldap_netlogon_flags_kdc
;
147 static int hf_mscldap_netlogon_flags_timeserv
;
148 static int hf_mscldap_netlogon_flags_closest
;
149 static int hf_mscldap_netlogon_flags_writable
;
150 static int hf_mscldap_netlogon_flags_good_timeserv
;
151 static int hf_mscldap_netlogon_flags_ndnc
;
152 static int hf_mscldap_netlogon_flags_fnc
;
153 static int hf_mscldap_netlogon_flags_dnc
;
154 static int hf_mscldap_netlogon_flags_dns
;
155 static int hf_mscldap_netlogon_flags_wdc
;
156 static int hf_mscldap_netlogon_flags_rodc
;
157 static int hf_mscldap_domain_guid
;
158 static int hf_mscldap_forest
;
159 static int hf_mscldap_domain
;
160 static int hf_mscldap_hostname
;
161 static int hf_mscldap_nb_domain_z
;
162 static int hf_mscldap_nb_domain
;
163 static int hf_mscldap_nb_hostname_z
;
164 static int hf_mscldap_nb_hostname
;
165 static int hf_mscldap_username_z
;
166 static int hf_mscldap_username
;
167 static int hf_mscldap_sitename
;
168 static int hf_mscldap_clientsitename
;
169 static int hf_mscldap_netlogon_lm_token
;
170 static int hf_mscldap_netlogon_nt_token
;
171 static int hf_ldap_sid
;
172 static int hf_ldap_AccessMask_ADS_CREATE_CHILD
;
173 static int hf_ldap_AccessMask_ADS_DELETE_CHILD
;
174 static int hf_ldap_AccessMask_ADS_LIST
;
175 static int hf_ldap_AccessMask_ADS_SELF_WRITE
;
176 static int hf_ldap_AccessMask_ADS_READ_PROP
;
177 static int hf_ldap_AccessMask_ADS_WRITE_PROP
;
178 static int hf_ldap_AccessMask_ADS_DELETE_TREE
;
179 static int hf_ldap_AccessMask_ADS_LIST_OBJECT
;
180 static int hf_ldap_AccessMask_ADS_CONTROL_ACCESS
;
181 static int hf_ldap_LDAPMessage_PDU
;
182 static int hf_ldap_object_security_flag
;
183 static int hf_ldap_ancestor_first_flag
;
184 static int hf_ldap_public_data_only_flag
;
185 static int hf_ldap_incremental_value_flag
;
186 static int hf_ldap_oid
;
187 static int hf_ldap_gssapi_encrypted_payload
;
189 #include "packet-ldap-hf.c"
191 /* Initialize the subtree pointers */
193 static int ett_ldap_msg
;
194 static int ett_ldap_sasl_blob
;
195 static int ett_ldap_payload
;
196 static int ett_mscldap_netlogon_flags
;
197 static int ett_mscldap_ntver_flags
;
198 static int ett_mscldap_ipdetails
;
199 static int ett_ldap_DirSyncFlagsSubEntry
;
201 #include "packet-ldap-ett.c"
203 static expert_field ei_ldap_exceeded_filter_length
;
204 static expert_field ei_ldap_too_many_filter_elements
;
206 static dissector_table_t ldap_name_dissector_table
;
207 static const char *object_identifier_id
; /* LDAP OID */
209 static bool do_protocolop
;
210 static char *attr_type
;
211 static bool is_binary_attr_type
;
212 static bool ldap_found_in_frame
;
214 #define TCP_PORT_RANGE_LDAP "389,3268" /* 3268 is Windows 2000 Global Catalog */
215 #define TCP_PORT_LDAPS 636
216 #define UDP_PORT_CLDAP 389
218 /* desegmentation of LDAP */
219 static bool ldap_desegment
= true;
220 static unsigned global_ldaps_tcp_port
= TCP_PORT_LDAPS
;
221 static unsigned ssl_port
;
223 static dissector_handle_t gssapi_handle
;
224 static dissector_handle_t gssapi_wrap_handle
;
225 static dissector_handle_t ntlmssp_handle
;
226 static dissector_handle_t spnego_handle
;
227 static dissector_handle_t tls_handle
;
228 static dissector_handle_t ldap_handle
;
229 static dissector_handle_t cldap_handle
;
231 static void prefs_register_ldap(void); /* forward declaration for use in preferences registration */
234 /* different types of rpc calls ontop of ms cldap */
235 #define MSCLDAP_RPC_NETLOGON 1
237 /* Message type Choice values */
238 static const value_string ldap_ProtocolOp_choice_vals
[] = {
239 { 0, "bindRequest" },
240 { 1, "bindResponse" },
241 { 2, "unbindRequest" },
242 { 3, "searchRequest" },
243 { 4, "searchResEntry" },
244 { 5, "searchResDone" },
245 { 6, "searchResRef" },
246 { 7, "modifyRequest" },
247 { 8, "modifyResponse" },
249 { 10, "addResponse" },
250 { 11, "delRequest" },
251 { 12, "delResponse" },
252 { 13, "modDNRequest" },
253 { 14, "modDNResponse" },
254 { 15, "compareRequest" },
255 { 16, "compareResponse" },
256 { 17, "abandonRequest" },
257 { 18, "extendedReq" },
258 { 19, "extendedResp" },
259 { 20, "intermediateResponse" },
263 /* Procedure names (used in Service Response Time */
264 const value_string ldap_procedure_names
[] = {
276 #define LOGON_PRIMARY_QUERY 7
277 #define LOGON_PRIMARY_RESPONSE 12
278 #define LOGON_SAM_LOGON_REQUEST 18
279 #define LOGON_SAM_LOGON_RESPONSE 19
280 #define LOGON_SAM_PAUSE_RESPONSE 20
281 #define LOGON_SAM_USER_UNKNOWN 21
282 #define LOGON_SAM_LOGON_RESPONSE_EX 23
283 #define LOGON_SAM_PAUSE_RESPONSE_EX 24
284 #define LOGON_SAM_USER_UNKNOWN_EX 25
286 static const value_string netlogon_opcode_vals
[] = {
287 { LOGON_PRIMARY_QUERY
, "LOGON_PRIMARY_QUERY" },
288 { LOGON_PRIMARY_RESPONSE
, "LOGON_PRIMARY_RESPONSE" },
289 { LOGON_SAM_LOGON_REQUEST
, "LOGON_SAM_LOGON_REQUEST" },
290 { LOGON_SAM_LOGON_RESPONSE
, "LOGON_SAM_LOGON_RESPONSE" },
291 { LOGON_SAM_PAUSE_RESPONSE
, "LOGON_SAM_PAUSE_RESPONSE" },
292 { LOGON_SAM_LOGON_RESPONSE_EX
, "LOGON_SAM_LOGON_RESPONSE_EX" },
293 { LOGON_SAM_PAUSE_RESPONSE_EX
, "LOGON_SAM_PAUSE_RESPONSE_EX" },
294 { LOGON_SAM_USER_UNKNOWN_EX
, "LOGON_SAM_USER_UNKNOWN_EX" },
298 #define LDAP_NUM_PROCEDURES 24
301 ldapstat_init(struct register_srt
* srt _U_
, GArray
* srt_array
)
303 srt_stat_table
*ldap_srt_table
;
306 ldap_srt_table
= init_srt_table("LDAP Commands", NULL
, srt_array
, LDAP_NUM_PROCEDURES
, NULL
, "ldap.protocolOp", NULL
);
307 for (i
= 0; i
< LDAP_NUM_PROCEDURES
; i
++)
309 init_srt_table_row(ldap_srt_table
, i
, val_to_str_const(i
, ldap_procedure_names
, "<unknown>"));
313 static tap_packet_status
314 ldapstat_packet(void *pldap
, packet_info
*pinfo
, epan_dissect_t
*edt _U_
, const void *psi
, tap_flags_t flags _U_
)
317 srt_stat_table
*ldap_srt_table
;
318 const ldap_call_response_t
*ldap
=(const ldap_call_response_t
*)psi
;
319 srt_data_t
*data
= (srt_data_t
*)pldap
;
321 /* we are only interested in reply packets */
322 if(ldap
->is_request
){
323 return TAP_PACKET_DONT_REDRAW
;
325 /* if we haven't seen the request, just ignore it */
326 if(!ldap
->req_frame
){
327 return TAP_PACKET_DONT_REDRAW
;
330 /* only use the commands we know how to handle */
331 switch(ldap
->protocolOpTag
){
333 case LDAP_REQ_SEARCH
:
334 case LDAP_REQ_MODIFY
:
336 case LDAP_REQ_DELETE
:
337 case LDAP_REQ_MODRDN
:
338 case LDAP_REQ_COMPARE
:
339 case LDAP_REQ_EXTENDED
:
342 return TAP_PACKET_DONT_REDRAW
;
345 ldap_srt_table
= g_array_index(data
->srt_array
, srt_stat_table
*, i
);
347 add_srt_table_data(ldap_srt_table
, ldap
->protocolOpTag
, &ldap
->req_time
, pinfo
);
348 return TAP_PACKET_REDRAW
;
352 * Data structure attached to a conversation, giving authentication
353 * information from a bind request.
355 typedef struct ldap_conv_info_t
{
356 unsigned auth_type
; /* authentication type */
357 char *auth_mech
; /* authentication mechanism */
358 uint32_t first_auth_frame
; /* first frame that would use a security layer */
359 wmem_map_t
*unmatched
;
362 uint32_t num_results
;
363 bool start_tls_pending
;
364 uint32_t start_tls_frame
;
368 ldap_info_hash_matched(const void *k
)
370 const ldap_call_response_t
*key
= (const ldap_call_response_t
*)k
;
372 return key
->messageId
;
376 ldap_info_equal_matched(const void *k1
, const void *k2
)
378 const ldap_call_response_t
*key1
= (const ldap_call_response_t
*)k1
;
379 const ldap_call_response_t
*key2
= (const ldap_call_response_t
*)k2
;
381 if( key1
->req_frame
&& key2
->req_frame
&& (key1
->req_frame
!=key2
->req_frame
) ){
384 /* a response may span multiple frames
385 if( key1->rep_frame && key2->rep_frame && (key1->rep_frame!=key2->rep_frame) ){
390 return key1
->messageId
==key2
->messageId
;
394 ldap_info_hash_unmatched(const void *k
)
396 const ldap_call_response_t
*key
= (const ldap_call_response_t
*)k
;
398 return key
->messageId
;
402 ldap_info_equal_unmatched(const void *k1
, const void *k2
)
404 const ldap_call_response_t
*key1
= (const ldap_call_response_t
*)k1
;
405 const ldap_call_response_t
*key2
= (const ldap_call_response_t
*)k2
;
407 return key1
->messageId
==key2
->messageId
;
411 /* These are the NtVer flags from MS-ADTS section 6.3.1.1
412 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-adts
415 static const true_false_string tfs_ntver_v1
= {
416 "Client requested version 1 netlogon response",
417 "Version 1 netlogon response not requested"
420 static const true_false_string tfs_ntver_v5
= {
421 "Client requested version 5 netlogon response",
422 "Version 5 netlogon response not requested"
424 static const true_false_string tfs_ntver_v5ex
= {
425 "Client requested version 5 extended netlogon response",
426 "Version 5 extended response not requested"
428 static const true_false_string tfs_ntver_v5ep
= {
429 "Client has requested IP address of the server",
430 "IP address of server not requested"
432 static const true_false_string tfs_ntver_vcs
= {
433 "Client has asked for the closest site information",
434 "Closest site information not requested"
436 static const true_false_string tfs_ntver_vnt4
= {
437 "Client is requesting server to avoid NT4 emulation",
438 "Only full AD DS requested"
440 static const true_false_string tfs_ntver_vpdc
= {
441 "Client has requested the Primary Domain Controller",
442 "Primary Domain Controller not requested"
444 static const true_false_string tfs_ntver_vip
= {
445 "Client has requested IP details (obsolete)",
446 "IP details not requested (obsolete)"
448 static const true_false_string tfs_ntver_vl
= {
449 "Client indicated that it is the local machine",
450 "Client is not the local machine"
451 };static const true_false_string tfs_ntver_vgc
= {
452 "Client has requested a Global Catalog server",
453 "Global Catalog not requested"
456 /* Stuff for generation/handling of fields for custom AttributeValues */
457 typedef struct _attribute_type_t
{
458 char* attribute_type
;
459 char* attribute_desc
;
462 static attribute_type_t
* attribute_types
;
463 static unsigned num_attribute_types
;
465 static GHashTable
* attribute_types_hash
;
466 static hf_register_info
* dynamic_hf
;
467 static unsigned dynamic_hf_size
;
470 attribute_types_update_cb(void *r
, char **err
)
472 attribute_type_t
*rec
= (attribute_type_t
*)r
;
475 if (rec
->attribute_type
== NULL
) {
476 *err
= g_strdup("Attribute type can't be empty");
480 g_strstrip(rec
->attribute_type
);
481 if (rec
->attribute_type
[0] == 0) {
482 *err
= g_strdup("Attribute type can't be empty");
486 /* Check for invalid characters (to avoid asserting out when
487 * registering the field).
489 c
= proto_check_field_name(rec
->attribute_type
);
491 *err
= ws_strdup_printf("Attribute type can't contain '%c'", c
);
500 attribute_types_copy_cb(void* n
, const void* o
, size_t siz _U_
)
502 attribute_type_t
* new_rec
= (attribute_type_t
*)n
;
503 const attribute_type_t
* old_rec
= (const attribute_type_t
*)o
;
505 new_rec
->attribute_type
= g_strdup(old_rec
->attribute_type
);
506 new_rec
->attribute_desc
= g_strdup(old_rec
->attribute_desc
);
512 attribute_types_free_cb(void*r
)
514 attribute_type_t
* rec
= (attribute_type_t
*)r
;
516 g_free(rec
->attribute_type
);
517 g_free(rec
->attribute_desc
);
520 UAT_CSTRING_CB_DEF(attribute_types
, attribute_type
, attribute_type_t
)
521 UAT_CSTRING_CB_DEF(attribute_types
, attribute_desc
, attribute_type_t
)
527 get_hf_for_header(char* attribute_type
)
531 if (attribute_types_hash
) {
532 hf_id
= (int*) g_hash_table_lookup(attribute_types_hash
, attribute_type
);
544 deregister_attribute_types(void)
547 /* Deregister all fields */
548 for (unsigned i
= 0; i
< dynamic_hf_size
; i
++) {
549 proto_deregister_field (proto_ldap
, *(dynamic_hf
[i
].p_id
));
550 g_free (dynamic_hf
[i
].p_id
);
553 proto_add_deregistered_data (dynamic_hf
);
558 if (attribute_types_hash
) {
559 g_hash_table_destroy (attribute_types_hash
);
560 attribute_types_hash
= NULL
;
565 attribute_types_post_update_cb(void)
568 char* attribute_type
;
570 deregister_attribute_types();
572 if (num_attribute_types
) {
573 attribute_types_hash
= g_hash_table_new(g_str_hash
, g_str_equal
);
574 dynamic_hf
= g_new0(hf_register_info
,num_attribute_types
);
575 dynamic_hf_size
= num_attribute_types
;
577 for (unsigned i
= 0; i
< dynamic_hf_size
; i
++) {
578 hf_id
= g_new(int,1);
580 attribute_type
= g_strdup(attribute_types
[i
].attribute_type
);
582 dynamic_hf
[i
].p_id
= hf_id
;
583 dynamic_hf
[i
].hfinfo
.name
= attribute_type
;
584 dynamic_hf
[i
].hfinfo
.abbrev
= ws_strdup_printf("ldap.AttributeValue.%s", attribute_type
);
585 dynamic_hf
[i
].hfinfo
.type
= FT_STRING
;
586 dynamic_hf
[i
].hfinfo
.display
= BASE_NONE
;
587 dynamic_hf
[i
].hfinfo
.strings
= NULL
;
588 dynamic_hf
[i
].hfinfo
.bitmask
= 0;
589 dynamic_hf
[i
].hfinfo
.blurb
= g_strdup(attribute_types
[i
].attribute_desc
);
590 HFILL_INIT(dynamic_hf
[i
]);
592 g_hash_table_insert(attribute_types_hash
, attribute_type
, hf_id
);
595 proto_register_field_array(proto_ldap
, dynamic_hf
, dynamic_hf_size
);
600 attribute_types_reset_cb(void)
602 deregister_attribute_types();
605 /* MS-ADTS specification, section 6.3.1.1, NETLOGON_NT_VERSION Options Bits */
606 static int dissect_mscldap_ntver_flags(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
)
608 static int * const flags
[] = {
609 &hf_mscldap_ntver_flags_v1
,
610 &hf_mscldap_ntver_flags_v5
,
611 &hf_mscldap_ntver_flags_v5ex
,
612 &hf_mscldap_ntver_flags_v5ep
,
613 &hf_mscldap_ntver_flags_vcs
,
614 &hf_mscldap_ntver_flags_vnt4
,
615 &hf_mscldap_ntver_flags_vpdc
,
616 &hf_mscldap_ntver_flags_vip
,
617 &hf_mscldap_ntver_flags_vl
,
618 &hf_mscldap_ntver_flags_vgc
,
622 proto_tree_add_bitmask_with_flags(parent_tree
, tvb
, offset
, hf_mscldap_ntver_flags
,
623 ett_mscldap_ntver_flags
, flags
, ENC_LITTLE_ENDIAN
, BMT_NO_FALSE
);
629 /* This string contains the last LDAPString that was decoded */
630 static const char *attributedesc_string
;
632 /* This string contains the last AssertionValue that was decoded */
633 static char *ldapvalue_string
;
635 /* if the octet string contain all printable ASCII characters, then
636 * display it as a string, othervise just display it in hex.
639 dissect_ldap_AssertionValue(bool implicit_tag
, tvbuff_t
*tvb
, int offset
, asn1_ctx_t
*actx _U_
, proto_tree
*tree
, int hf_index
)
642 bool pc
, ind
, is_ascii
;
647 offset
=get_ber_identifier(tvb
, offset
, &ber_class
, &pc
, &tag
);
648 offset
=get_ber_length(tvb
, offset
, &len
, &ind
);
650 len
=tvb_reported_length_remaining(tvb
,offset
);
659 * Some special/wellknown attributes in common LDAP (read AD)
660 * are neither ascii strings nor blobs of hex data.
661 * Special case these attributes and decode them more nicely.
663 * Add more special cases as required to prettify further
664 * (there can't be that many ones that are truly interesting)
666 if(attributedesc_string
&& !strncmp("DomainSid", attributedesc_string
, 9)){
670 /* this octet string contains an NT SID */
671 sid_tvb
=tvb_new_subset_length(tvb
, offset
, len
);
672 dissect_nt_sid(sid_tvb
, 0, tree
, "SID", &tmpstr
, hf_index
);
673 ldapvalue_string
=tmpstr
;
676 } else if ( (len
==16) /* GUIDs are always 16 bytes */
677 && (attributedesc_string
&& !strncmp("DomainGuid", attributedesc_string
, 10))) {
678 uint8_t drep
[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
681 /* This octet string contained a GUID */
682 dissect_dcerpc_uuid_t(tvb
, offset
, actx
->pinfo
, tree
, drep
, hf_ldap_guid
, &uuid
);
684 ldapvalue_string
=(char*)wmem_alloc(actx
->pinfo
->pool
, 1024);
685 snprintf(ldapvalue_string
, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
686 uuid
.data1
, uuid
.data2
, uuid
.data3
, uuid
.data4
[0], uuid
.data4
[1],
687 uuid
.data4
[2], uuid
.data4
[3], uuid
.data4
[4], uuid
.data4
[5],
688 uuid
.data4
[6], uuid
.data4
[7]);
691 } else if (attributedesc_string
&& !strncmp("NtVer", attributedesc_string
, 5)){
695 /* get flag value to populate ldapvalue_string */
696 flags
=tvb_get_letohl(tvb
, offset
);
698 ldapvalue_string
=(char*)wmem_alloc(actx
->pinfo
->pool
, 1024);
699 snprintf(ldapvalue_string
, 1023, "0x%08x",flags
);
701 /* populate bitmask subtree */
702 offset
= dissect_mscldap_ntver_flags(tree
, tvb
, offset
);
710 * It was not one of our "wellknown" attributes so make the best
711 * we can and just try to see if it is an ascii string or if it
714 * XXX - should we support reading RFC 2252-style schemas
715 * for LDAP, and using that to determine how to display
716 * attribute values and assertion values?
718 * -- I don't think there are full schemas available that describe the
719 * interesting cases i.e. AD -- ronnie
721 is_ascii
=tvb_ascii_isprint(tvb
, offset
, len
);
723 /* convert the string into a printable string */
725 ldapvalue_string
= tvb_get_string_enc(actx
->pinfo
->pool
, tvb
, offset
, len
, ENC_UTF_8
|ENC_NA
);
727 ldapvalue_string
= tvb_bytes_to_str_punct(actx
->pinfo
->pool
, tvb
, offset
, len
, ':');
730 proto_tree_add_string(tree
, hf_index
, tvb
, offset
, len
, ldapvalue_string
);
738 /* This string contains the last Filter item that was decoded */
739 static const char *Filter_string
;
740 static const char *and_filter_string
;
741 static const char *or_filter_string
;
742 static const char *substring_value
;
743 static const char *substring_item_init
;
744 static const char *substring_item_any
;
745 static const char *substring_item_final
;
746 static const char *matching_rule_string
;
747 static bool matching_rule_dnattr
=false;
749 #define MAX_FILTER_LEN 4096
750 static int Filter_length
;
752 #define MAX_FILTER_ELEMENTS 200
753 static int Filter_elements
;
755 /* Global variables */
756 static int MessageID
=-1;
757 static int ProtocolOp
= -1;
759 static proto_item
*ldm_tree
; /* item to add text to */
761 static void ldap_do_protocolop(packet_info
*pinfo
)
767 valstr
= val_to_str(ProtocolOp
, ldap_ProtocolOp_choice_vals
, "Unknown (%u)");
769 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s(%u) ", valstr
, MessageID
);
772 proto_item_append_text(ldm_tree
, " %s(%d)", valstr
, MessageID
);
774 do_protocolop
= false;
779 static ldap_call_response_t
*
780 ldap_match_call_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, unsigned messageId
, unsigned protocolOpTag
, ldap_conv_info_t
*ldap_info
)
782 ldap_call_response_t lcr
, *lcrp
=NULL
;
784 /* first see if we have already matched this */
786 lcr
.messageId
=messageId
;
787 switch(protocolOpTag
){
789 case LDAP_REQ_SEARCH
:
790 case LDAP_REQ_MODIFY
:
792 case LDAP_REQ_DELETE
:
793 case LDAP_REQ_MODRDN
:
794 case LDAP_REQ_COMPARE
:
795 case LDAP_REQ_EXTENDED
:
797 lcr
.req_frame
=pinfo
->num
;
801 case LDAP_RES_SEARCH_ENTRY
:
802 case LDAP_RES_SEARCH_REF
:
803 case LDAP_RES_SEARCH_RESULT
:
804 case LDAP_RES_MODIFY
:
806 case LDAP_RES_DELETE
:
807 case LDAP_RES_MODRDN
:
808 case LDAP_RES_COMPARE
:
809 case LDAP_RES_EXTENDED
:
810 case LDAP_RES_INTERMEDIATE
:
811 lcr
.is_request
=false;
813 lcr
.rep_frame
=pinfo
->num
;
818 lcrp
=(ldap_call_response_t
*)wmem_map_lookup(ldap_info
->matched
, &lcr
);
822 lcrp
->is_request
=lcr
.is_request
;
826 /* we haven't found a match - try and match it up */
828 switch(protocolOpTag
){
830 case LDAP_REQ_SEARCH
:
831 case LDAP_REQ_MODIFY
:
833 case LDAP_REQ_DELETE
:
834 case LDAP_REQ_MODRDN
:
835 case LDAP_REQ_COMPARE
:
836 case LDAP_REQ_EXTENDED
:
838 /* this is a request - add it to the unmatched list */
840 /* check that we don't already have one of those in the
841 unmatched list and if so remove it */
843 lcr
.messageId
=messageId
;
844 lcrp
=(ldap_call_response_t
*)wmem_map_lookup(ldap_info
->unmatched
, &lcr
);
846 wmem_map_remove(ldap_info
->unmatched
, lcrp
);
848 /* if we can't reuse the old one, grab a new chunk */
850 lcrp
=wmem_new0(wmem_file_scope(), ldap_call_response_t
);
852 lcrp
->messageId
=messageId
;
853 lcrp
->req_frame
=pinfo
->num
;
854 lcrp
->req_time
=pinfo
->abs_ts
;
856 lcrp
->protocolOpTag
=protocolOpTag
;
857 lcrp
->is_request
=true;
858 wmem_map_insert(ldap_info
->unmatched
, lcrp
, lcrp
);
861 case LDAP_RES_SEARCH_ENTRY
:
862 case LDAP_RES_SEARCH_REF
:
863 case LDAP_RES_SEARCH_RESULT
:
864 case LDAP_RES_MODIFY
:
866 case LDAP_RES_DELETE
:
867 case LDAP_RES_MODRDN
:
868 case LDAP_RES_COMPARE
:
869 case LDAP_RES_EXTENDED
:
870 case LDAP_RES_INTERMEDIATE
:
872 /* this is a result - it should be in our unmatched list */
874 lcr
.messageId
=messageId
;
875 lcrp
=(ldap_call_response_t
*)wmem_map_lookup(ldap_info
->unmatched
, &lcr
);
879 if(!lcrp
->rep_frame
){
880 wmem_map_remove(ldap_info
->unmatched
, lcrp
);
881 lcrp
->rep_frame
=pinfo
->num
;
882 lcrp
->is_request
=false;
883 wmem_map_insert(ldap_info
->matched
, lcrp
, lcrp
);
891 /* we have found a match */
896 if(lcrp
->is_request
){
897 it
=proto_tree_add_uint(tree
, hf_ldap_response_in
, tvb
, 0, 0, lcrp
->rep_frame
);
898 proto_item_set_generated(it
);
901 it
=proto_tree_add_uint(tree
, hf_ldap_response_to
, tvb
, 0, 0, lcrp
->req_frame
);
902 proto_item_set_generated(it
);
903 nstime_delta(&ns
, &pinfo
->abs_ts
, &lcrp
->req_time
);
904 it
=proto_tree_add_time(tree
, hf_ldap_time
, tvb
, 0, 0, &ns
);
905 proto_item_set_generated(it
);
912 #include "packet-ldap-fn.c"
913 static int dissect_LDAPMessage_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, ldap_conv_info_t
*ldap_info
) {
917 asn1_ctx_init(&asn1_ctx
, ASN1_ENC_BER
, true, pinfo
);
919 asn1_ctx
.private_data
= ldap_info
;
920 offset
= dissect_ldap_LDAPMessage(false, tvb
, offset
, &asn1_ctx
, tree
, hf_ldap_LDAPMessage_PDU
);
925 dissect_ldap_payload(tvbuff_t
*tvb
, packet_info
*pinfo
,
926 proto_tree
*tree
, ldap_conv_info_t
*ldap_info
,
930 unsigned length_remaining
;
931 unsigned msg_len
= 0;
932 int messageOffset
= 0;
933 unsigned headerLength
= 0;
935 tvbuff_t
*msg_tvb
= NULL
;
940 attributedesc_string
=NULL
;
945 length_remaining
= tvb_ensure_captured_length_remaining(tvb
, offset
);
947 if (length_remaining
< 6) return;
950 * OK, try to read the "Sequence Of" header; this gets the total
951 * length of the LDAP message.
953 messageOffset
= get_ber_identifier(tvb
, offset
, &ber_class
, &pc
, &ber_tag
);
954 messageOffset
= get_ber_length(tvb
, messageOffset
, &msg_len
, &ind
);
957 if((msg_len
<4) || (msg_len
>10000000)) return;
959 if ( (ber_class
==BER_CLASS_UNI
) && (ber_tag
==BER_UNI_TAG_SEQUENCE
) ) {
961 * Add the length of the "Sequence Of" header to the message
964 headerLength
= messageOffset
- offset
;
965 msg_len
+= headerLength
;
966 if (msg_len
< headerLength
) {
968 * The message length was probably so large that the total length
971 * Report this as an error.
973 show_reported_bounds_error(tvb
, pinfo
, tree
);
978 * We couldn't parse the header; just make it the amount of data
979 * remaining in the tvbuff, so we'll give up on this segment
980 * after attempting to parse the message - there's nothing more
981 * we can do. "dissect_ldap_message()" will display the error.
983 msg_len
= length_remaining
;
987 * Construct a tvbuff containing the amount of the payload we have
988 * available. Make its reported length the amount of data in the
991 * XXX - if reassembly isn't enabled. the subdissector will throw a
992 * BoundsError exception, rather than a ReportedBoundsError exception.
993 * We really want a tvbuff where the length is "length", the reported
994 * length is "plen", and the "if the snapshot length were infinite"
995 * length is the minimum of the reported length of the tvbuff handed
996 * to us and "plen", with a new type of exception thrown if the offset
997 * is within the reported length but beyond that third length, with
998 * that exception getting the "Unreassembled Packet" error.
1000 length
= length_remaining
;
1001 if (length
> msg_len
) length
= msg_len
;
1002 msg_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, length
, msg_len
);
1005 * Now dissect the LDAP message.
1007 ldap_info
->is_mscldap
= is_mscldap
;
1008 dissect_LDAPMessage_PDU(msg_tvb
, pinfo
, tree
, ldap_info
);
1012 /* If this was a sasl blob there might be another PDU following in the
1015 if(tvb_reported_length_remaining(tvb
, offset
)>=6){
1016 tvb
= tvb_new_subset_remaining(tvb
, offset
);
1025 ldap_frame_end(void)
1027 ldap_found_in_frame
= false;
1029 ldapvalue_string
= NULL
;
1031 attributedesc_string
= NULL
;
1032 Filter_string
= NULL
;
1033 and_filter_string
= NULL
;
1034 object_identifier_id
= NULL
;
1035 or_filter_string
= NULL
;
1037 substring_item_any
= NULL
;
1038 substring_item_final
= NULL
;
1039 substring_item_init
= NULL
;
1040 substring_value
= NULL
;
1044 Filter_elements
= 0;
1046 do_protocolop
= false;
1049 /* seems to be ok, but reset just in case */
1050 matching_rule_string
= NULL
;
1054 dissect_ldap_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, bool is_mscldap
)
1057 conversation_t
*conversation
;
1058 bool doing_sasl_security
= false;
1059 unsigned length_remaining
;
1060 ldap_conv_info_t
*ldap_info
= NULL
;
1061 proto_item
*ldap_item
= NULL
;
1062 proto_tree
*ldap_tree
= NULL
;
1063 uint32_t sasl_length
= 0;
1064 uint32_t remaining_length
= 0;
1065 uint8_t sasl_start
[2] = { 0, };
1066 bool detected_sasl_security
= false;
1070 conversation
= find_or_create_conversation(pinfo
);
1073 * Do we already have a type and mechanism?
1075 ldap_info
= (ldap_conv_info_t
*)conversation_get_proto_data(conversation
, proto_ldap
);
1076 if (ldap_info
== NULL
) {
1077 /* No. Attach that information to the conversation, and add
1078 * it to the list of information structures.
1080 ldap_info
= wmem_new0(wmem_file_scope(), ldap_conv_info_t
);
1081 ldap_info
->matched
=wmem_map_new(wmem_file_scope(), ldap_info_hash_matched
, ldap_info_equal_matched
);
1082 ldap_info
->unmatched
=wmem_map_new(wmem_file_scope(), ldap_info_hash_unmatched
, ldap_info_equal_unmatched
);
1084 conversation_add_proto_data(conversation
, proto_ldap
, ldap_info
);
1087 switch (ldap_info
->auth_type
) {
1088 case LDAP_AUTH_SASL
:
1090 * It's SASL; are we using a security layer?
1092 if (ldap_info
->first_auth_frame
!= 0 &&
1093 pinfo
->num
>= ldap_info
->first_auth_frame
) {
1094 doing_sasl_security
= true; /* yes */
1098 length_remaining
= tvb_ensure_captured_length_remaining(tvb
, offset
);
1100 /* It might still be a packet containing a SASL security layer
1101 * but it's just that we never saw the BIND packet.
1102 * check if it looks like it could be a SASL blob here
1103 * and in that case just assume it is GSS-SPNEGO
1105 if(!doing_sasl_security
&& tvb_bytes_exist(tvb
, offset
, 6)) {
1106 sasl_length
= tvb_get_ntohl(tvb
, offset
);
1107 remaining_length
= tvb_reported_length_remaining(tvb
, offset
);
1108 sasl_start
[0] = tvb_get_uint8(tvb
, offset
+4);
1109 sasl_start
[1] = tvb_get_uint8(tvb
, offset
+5);
1111 if ((sasl_length
+ 4) <= remaining_length
) {
1112 if (sasl_start
[0] == 0x05 && sasl_start
[1] == 0x04) {
1114 * Likely modern kerberos signing
1116 detected_sasl_security
= true;
1117 } else if (sasl_start
[0] == 0x60) {
1119 * Likely ASN.1 based kerberos
1121 detected_sasl_security
= true;
1124 if (detected_sasl_security
) {
1125 ldap_info
->auth_type
=LDAP_AUTH_SASL
;
1126 ldap_info
->first_auth_frame
=pinfo
->num
;
1127 ldap_info
->auth_mech
=wmem_strdup(wmem_file_scope(), "GSS-SPNEGO");
1128 doing_sasl_security
=true;
1132 * This is the first PDU, set the Protocol column and clear the
1135 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, pinfo
->current_proto
);
1137 if(ldap_found_in_frame
) {
1138 /* we have already dissected an ldap PDU in this frame - add a separator and set a fence */
1139 col_append_str(pinfo
->cinfo
, COL_INFO
, " | ");
1140 col_set_fence(pinfo
->cinfo
, COL_INFO
);
1142 col_clear(pinfo
->cinfo
, COL_INFO
);
1143 register_frame_end_routine (pinfo
, ldap_frame_end
);
1144 ldap_found_in_frame
= true;
1147 ldap_item
= proto_tree_add_item(tree
, is_mscldap
?proto_cldap
:proto_ldap
, tvb
, 0, -1, ENC_NA
);
1148 ldap_tree
= proto_item_add_subtree(ldap_item
, ett_ldap
);
1151 * Might we be doing a SASL security layer and, if so, *are* we doing
1154 * Just because we've seen a bind reply for SASL, that doesn't mean
1155 * that we're using a SASL security layer; I've seen captures in
1156 * which some SASL negotiations lead to a security layer being used
1157 * and other negotiations don't, and it's not obvious what's different
1158 * in the two negotiations. Therefore, we assume that if the first
1159 * byte is 0, it's a length for a SASL security layer (that way, we
1160 * never reassemble more than 16 megabytes, protecting us from
1161 * chewing up *too* much memory), and otherwise that it's an LDAP
1162 * message (actually, if it's an LDAP message it should begin with 0x30,
1163 * but we want to parse garbage as LDAP messages rather than really
1167 if (doing_sasl_security
&& tvb_get_uint8(tvb
, offset
) == 0) {
1168 proto_tree
*sasl_tree
;
1170 unsigned sasl_len
, sasl_msg_len
, length
;
1172 * Yes. The frame begins with a 4-byte big-endian length.
1173 * And we know we have at least 6 bytes
1177 * Get the SASL length, which is the length of data in the buffer
1178 * following the length (i.e., it's 4 less than the total length).
1180 * XXX - do we need to reassemble buffers? For now, we
1181 * assume that each LDAP message is entirely contained within
1184 sasl_len
= tvb_get_ntohl(tvb
, offset
);
1185 sasl_msg_len
= sasl_len
+ 4;
1186 if (sasl_msg_len
< 4) {
1188 * The message length was probably so large that the total length
1191 * Report this as an error.
1193 show_reported_bounds_error(tvb
, pinfo
, tree
);
1198 * Construct a tvbuff containing the amount of the payload we have
1199 * available. Make its reported length the amount of data in the PDU.
1201 * XXX - if reassembly isn't enabled. the subdissector will throw a
1202 * BoundsError exception, rather than a ReportedBoundsError exception.
1203 * We really want a tvbuff where the length is "length", the reported
1204 * length is "plen", and the "if the snapshot length were infinite"
1205 * length is the minimum of the reported length of the tvbuff handed
1206 * to us and "plen", with a new type of exception thrown if the offset
1207 * is within the reported length but beyond that third length, with
1208 * that exception getting the "Unreassembled Packet" error.
1210 length
= length_remaining
;
1211 if (length
> sasl_msg_len
) length
= sasl_msg_len
;
1212 sasl_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, length
, sasl_msg_len
);
1214 proto_tree_add_uint(ldap_tree
, hf_ldap_sasl_buffer_length
, sasl_tvb
, 0, 4, sasl_len
);
1216 sasl_tree
= proto_tree_add_subtree(ldap_tree
, sasl_tvb
, 4, sasl_msg_len
- 4, ett_ldap_sasl_blob
, NULL
, "SASL Buffer");
1218 if (ldap_info
->auth_mech
!= NULL
&&
1219 ((strcmp(ldap_info
->auth_mech
, "GSS-SPNEGO") == 0) ||
1220 /* auth_mech may have been set from the bind */
1221 (strcmp(ldap_info
->auth_mech
, "GSSAPI") == 0))) {
1222 tvbuff_t
*gssapi_tvb
= NULL
;
1225 gssapi_encrypt_info_t gssapi_encrypt
;
1228 * This is GSS-API (using SPNEGO, but we should be done with
1229 * the negotiation by now).
1231 * Dissect the GSS_Wrap() token; it'll return the length of
1232 * the token, from which we compute the offset in the tvbuff at
1233 * which the plaintext data, i.e. the LDAP message, begins.
1235 tmp_length
= tvb_reported_length_remaining(sasl_tvb
, 4);
1236 if ((unsigned)tmp_length
> sasl_len
)
1237 tmp_length
= sasl_len
;
1238 gssapi_tvb
= tvb_new_subset_length_caplen(sasl_tvb
, 4, tmp_length
, sasl_len
);
1240 /* Attempt decryption of the GSSAPI wrapped data if possible */
1241 memset(&gssapi_encrypt
, 0, sizeof(gssapi_encrypt
));
1242 gssapi_encrypt
.decrypt_gssapi_tvb
=DECRYPT_GSSAPI_NORMAL
;
1243 ver_len
= call_dissector_with_data(gssapi_wrap_handle
, gssapi_tvb
, pinfo
, sasl_tree
, &gssapi_encrypt
);
1245 * If ver_len is 0, it probably means that we got a PDU that is not
1246 * aligned to the start of the segment.
1251 if (gssapi_encrypt
.gssapi_data_encrypted
) {
1252 if (gssapi_encrypt
.gssapi_decrypted_tvb
) {
1253 tvbuff_t
*decr_tvb
= gssapi_encrypt
.gssapi_decrypted_tvb
;
1254 proto_tree
*enc_tree
= NULL
;
1257 * The LDAP payload (blob) was encrypted and we were able to decrypt it.
1258 * The data was signed via a MIC token, sealed (encrypted), and "wrapped"
1259 * within the mechanism's "blob." Call dissect_ldap_payload to dissect
1260 * one or more LDAPMessages such as searchRequest messages within this
1263 col_set_str(pinfo
->cinfo
, COL_INFO
, "SASL GSS-API Privacy (decrypted): ");
1266 unsigned decr_len
= tvb_reported_length(decr_tvb
);
1268 enc_tree
= proto_tree_add_subtree_format(sasl_tree
, decr_tvb
, 0, -1,
1269 ett_ldap_payload
, NULL
, "GSS-API Encrypted payload (%d byte%s)",
1270 decr_len
, plurality(decr_len
, "", "s"));
1273 dissect_ldap_payload(decr_tvb
, pinfo
, enc_tree
, ldap_info
, is_mscldap
);
1276 * The LDAP message was encrypted but couldn't be decrypted so just display the
1277 * encrypted data all of which is found in Packet Bytes.
1279 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "SASL GSS-API Privacy: payload (%d byte%s)",
1280 sasl_len
-ver_len
, plurality(sasl_len
-ver_len
, "", "s"));
1282 proto_tree_add_item(sasl_tree
, hf_ldap_gssapi_encrypted_payload
, gssapi_tvb
, ver_len
, -1, ENC_NA
);
1285 tvbuff_t
*plain_tvb
;
1286 if (gssapi_encrypt
.gssapi_decrypted_tvb
) {
1287 plain_tvb
= gssapi_encrypt
.gssapi_decrypted_tvb
;
1289 plain_tvb
= tvb_new_subset_remaining(gssapi_tvb
, ver_len
);
1291 proto_tree
*plain_tree
= NULL
;
1294 * The payload was not encrypted (sealed) but was signed via a MIC token.
1295 * If krb5_tok_id == KRB_TOKEN_CFX_WRAP, the payload was wrapped within
1296 * the mechanism's blob. Call dissect_ldap_payload to dissect one or more
1297 * LDAPMessages within the payload.
1299 col_set_str(pinfo
->cinfo
, COL_INFO
, "SASL GSS-API Integrity: ");
1302 unsigned plain_len
= tvb_reported_length(plain_tvb
);
1304 plain_tree
= proto_tree_add_subtree_format(sasl_tree
, plain_tvb
, 0, -1,
1305 ett_ldap_payload
, NULL
, "GSS-API payload (%d byte%s)",
1306 plain_len
, plurality(plain_len
, "", "s"));
1309 dissect_ldap_payload(plain_tvb
, pinfo
, plain_tree
, ldap_info
, is_mscldap
);
1314 * The LDAP packet does not contain a SASL security layer. Such messages are typically sent
1315 * prior to the LDAP "bind" negotiation exchange which establishes the "context" of the session.
1316 * This means the data could neither be "signed" (no data origin auth or data integrity
1317 * check) nor "sealed" (encrypted).
1319 dissect_ldap_payload(tvb
, pinfo
, ldap_tree
, ldap_info
, is_mscldap
);
1323 int dissect_mscldap_string(wmem_allocator_t
*scope
, tvbuff_t
*tvb
, int offset
, int max_len
, char **str
)
1329 /* The name data MUST start at offset 0 of the tvb */
1330 compr_len
= get_dns_name(tvb
, offset
, max_len
, 0, &name
, &name_len
);
1331 *str
= get_utf_8_string(scope
, name
, name_len
);
1332 return offset
+ compr_len
;
1336 /* These are the cldap DC flags
1337 http://msdn.microsoft.com/en-us/library/cc201036.aspx
1339 static const true_false_string tfs_ads_pdc
= {
1343 static const true_false_string tfs_ads_gc
= {
1344 "This is a GLOBAL CATALOGUE of forest",
1345 "This is NOT a global catalog of forest"
1347 static const true_false_string tfs_ads_ldap
= {
1348 "This is an LDAP server",
1349 "This is NOT an ldap server"
1351 static const true_false_string tfs_ads_ds
= {
1352 "This dc supports DS",
1353 "This dc does NOT support ds"
1355 static const true_false_string tfs_ads_kdc
= {
1356 "This is a KDC (kerberos)",
1357 "This is NOT a kdc (kerberos)"
1359 static const true_false_string tfs_ads_timeserv
= {
1360 "This dc is running TIME SERVICES (ntp)",
1361 "This dc is NOT running time services (ntp)"
1363 static const true_false_string tfs_ads_closest
= {
1364 "This server is in the same site as the client",
1365 "This server is NOT in the same site as the client"
1367 static const true_false_string tfs_ads_writable
= {
1368 "This dc is WRITABLE",
1369 "This dc is NOT writable"
1371 static const true_false_string tfs_ads_good_timeserv
= {
1372 "This dc has a GOOD TIME SERVICE (i.e. hardware clock)",
1373 "This dc does NOT have a good time service (i.e. no hardware clock)"
1375 static const true_false_string tfs_ads_ndnc
= {
1376 "Domain is NON-DOMAIN NC serviced by ldap server",
1377 "Domain is NOT non-domain nc serviced by ldap server"
1379 static const true_false_string tfs_ads_rodc
= {
1380 "Domain controller is a Windows 2008 RODC",
1381 "Domain controller is not a Windows 2008 RODC"
1383 static const true_false_string tfs_ads_wdc
= {
1384 "Domain controller is a Windows 2008 writable NC",
1385 "Domain controller is not a Windows 2008 writable NC"
1387 static const true_false_string tfs_ads_dns
= {
1388 "Server name is in DNS format (Windows 2008)",
1389 "Server name is not in DNS format (Windows 2008)"
1391 static const true_false_string tfs_ads_dnc
= {
1392 "The NC is the default NC (Windows 2008)",
1393 "The NC is not the default NC (Windows 2008)"
1395 static const true_false_string tfs_ads_fnc
= {
1396 "The NC is the default forest NC(Windows 2008)",
1397 "The NC is not the default forest NC (Windows 2008)"
1399 static int dissect_mscldap_netlogon_flags(proto_tree
*parent_tree
, tvbuff_t
*tvb
, int offset
)
1401 static int * const flags
[] = {
1402 &hf_mscldap_netlogon_flags_fnc
,
1403 &hf_mscldap_netlogon_flags_dnc
,
1404 &hf_mscldap_netlogon_flags_dns
,
1405 &hf_mscldap_netlogon_flags_wdc
,
1406 &hf_mscldap_netlogon_flags_rodc
,
1407 &hf_mscldap_netlogon_flags_ndnc
,
1408 &hf_mscldap_netlogon_flags_good_timeserv
,
1409 &hf_mscldap_netlogon_flags_writable
,
1410 &hf_mscldap_netlogon_flags_closest
,
1411 &hf_mscldap_netlogon_flags_timeserv
,
1412 &hf_mscldap_netlogon_flags_kdc
,
1413 &hf_mscldap_netlogon_flags_ds
,
1414 &hf_mscldap_netlogon_flags_ldap
,
1415 &hf_mscldap_netlogon_flags_gc
,
1416 &hf_mscldap_netlogon_flags_pdc
,
1420 proto_tree_add_bitmask_with_flags(parent_tree
, tvb
, offset
, hf_mscldap_netlogon_flags
,
1421 ett_mscldap_netlogon_flags
, flags
, ENC_LITTLE_ENDIAN
, BMT_NO_FALSE
);
1427 static int dissect_NetLogon_PDU(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1429 int old_offset
, offset
=0;
1440 /* Get the length of the buffer */
1441 len
=tvb_reported_length_remaining(tvb
,offset
);
1443 /* check the len if it is to small return */
1445 return tvb_captured_length(tvb
);
1448 proto_tree_add_item(tree
, hf_mscldap_netlogon_opcode
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1449 itype
= tvb_get_letohs(tvb
, offset
);
1454 case LOGON_SAM_LOGON_RESPONSE
:
1455 /* logon server name; must be aligned on a 2-byte boundary */
1456 if ((offset
& 1) != 0) {
1459 proto_tree_add_item_ret_length(tree
, hf_mscldap_nb_hostname_z
, tvb
,offset
, -1, ENC_UTF_16
|ENC_LITTLE_ENDIAN
, &fn_len
);
1462 /* username; must be aligned on a 2-byte boundary */
1463 if ((offset
& 1) != 0) {
1466 proto_tree_add_item_ret_length(tree
, hf_mscldap_username_z
, tvb
,offset
, -1, ENC_UTF_16
|ENC_LITTLE_ENDIAN
, &fn_len
);
1469 /* domain name; must be aligned on a 2-byte boundary */
1470 if ((offset
& 1) != 0) {
1473 proto_tree_add_item_ret_length(tree
, hf_mscldap_nb_domain_z
, tvb
,offset
, -1, ENC_UTF_16
|ENC_LITTLE_ENDIAN
, &fn_len
);
1476 /* get the version number from the end of the buffer, as the
1477 length is variable and the version determines what fields
1478 need to be decoded */
1479 version
= tvb_get_letohl(tvb
,len
-8);
1481 /* include the extra version 5 fields */
1482 if ((version
& NETLOGON_NT_VERSION_5
) == NETLOGON_NT_VERSION_5
){
1485 proto_tree_add_item(tree
, hf_mscldap_domain_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
1488 /* domain guid part 2
1489 there is another 16 byte guid but this is alway zero, so we will skip it */
1494 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1495 proto_tree_add_string(tree
, hf_mscldap_forest
, tvb
, old_offset
, offset
-old_offset
, str
);
1499 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1500 proto_tree_add_string(tree
, hf_mscldap_domain
, tvb
, old_offset
, offset
-old_offset
, str
);
1504 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1505 proto_tree_add_string(tree
, hf_mscldap_hostname
, tvb
, old_offset
, offset
-old_offset
, str
);
1508 proto_tree_add_item(tree
, hf_mscldap_netlogon_ipaddress
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1512 dissect_mscldap_netlogon_flags(tree
, tvb
, offset
);
1517 case LOGON_SAM_LOGON_RESPONSE_EX
:
1518 /* MS-ADTS 6.3.1.9 */
1519 offset
+= 2; /* Skip over "Sbz" field (MUST be set to 0) */
1522 offset
= dissect_mscldap_netlogon_flags(tree
, tvb
, offset
);
1525 proto_tree_add_item(tree
, hf_mscldap_domain_guid
, tvb
, offset
, 16, ENC_LITTLE_ENDIAN
);
1530 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1531 proto_tree_add_string(tree
, hf_mscldap_forest
, tvb
, old_offset
, offset
-old_offset
, str
);
1535 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1536 proto_tree_add_string(tree
, hf_mscldap_domain
, tvb
, old_offset
, offset
-old_offset
, str
);
1540 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1541 proto_tree_add_string(tree
, hf_mscldap_hostname
, tvb
, old_offset
, offset
-old_offset
, str
);
1543 /* NetBIOS Domain */
1545 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1546 proto_tree_add_string(tree
, hf_mscldap_nb_domain
, tvb
, old_offset
, offset
-old_offset
, str
);
1548 /* NetBIOS Hostname */
1550 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1551 proto_tree_add_string(tree
, hf_mscldap_nb_hostname
, tvb
, old_offset
, offset
-old_offset
, str
);
1555 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1556 proto_tree_add_string(tree
, hf_mscldap_username
, tvb
, old_offset
, offset
-old_offset
, str
);
1560 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1561 proto_tree_add_string(tree
, hf_mscldap_sitename
, tvb
, old_offset
, offset
-old_offset
, str
);
1565 offset
=dissect_mscldap_string(pinfo
->pool
, tvb
, offset
, 255, &str
);
1566 proto_tree_add_string(tree
, hf_mscldap_clientsitename
, tvb
, old_offset
, offset
-old_offset
, str
);
1568 /* get the version number from the end of the buffer, as the
1569 length is variable and the version determines what fields
1570 need to be decoded */
1571 version
= tvb_get_letohl(tvb
,len
-8);
1573 /* include the extra fields for version 5 with IP s */
1574 if ((version
& NETLOGON_NT_VERSION_5EX_WITH_IP
) == NETLOGON_NT_VERSION_5EX_WITH_IP
){
1575 /* The ip address is returned as a sockaddr_in structure
1577 * This section may need to be updated if the base Windows APIs
1578 * are changed to support ipv6, which currently is not the case.
1580 * The dissector assumes the length is based on ipv4 and
1581 * ignores the length
1584 /* skip the length of the sockaddr_in */
1588 /* add IP address and dissect the sockaddr_in structure */
1590 old_offset
= offset
+ 4;
1591 item
= proto_tree_add_item(tree
, hf_mscldap_netlogon_ipaddress
, tvb
, old_offset
, 4, ENC_BIG_ENDIAN
);
1594 proto_tree
*subtree
;
1596 subtree
= proto_item_add_subtree(item
, ett_mscldap_ipdetails
);
1598 /* get sockaddr family */
1599 proto_tree_add_item(subtree
, hf_mscldap_netlogon_ipaddress_family
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1602 /* get sockaddr port */
1603 proto_tree_add_item(subtree
, hf_mscldap_netlogon_ipaddress_port
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1606 /* get IP address */
1607 proto_tree_add_item(subtree
, hf_mscldap_netlogon_ipaddress_ipv4
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
1616 /* complete the decode with the version and token details */
1620 /* NETLOGON_NT_VERSION Options (MS-ADTS 6.3.1.1) */
1621 offset
= dissect_mscldap_ntver_flags(tree
, tvb
, offset
);
1624 proto_tree_add_item(tree
, hf_mscldap_netlogon_lm_token
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1628 proto_tree_add_item(tree
, hf_mscldap_netlogon_nt_token
, tvb
, offset
, 2, ENC_LITTLE_ENDIAN
);
1630 return tvb_captured_length(tvb
);
1635 get_sasl_ldap_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
1636 int offset
, void *data _U_
)
1638 /* sasl encapsulated ldap is 4 bytes plus the length in size */
1639 return tvb_get_ntohl(tvb
, offset
)+4;
1643 dissect_sasl_ldap_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1645 dissect_ldap_pdu(tvb
, pinfo
, tree
, false);
1646 return tvb_captured_length(tvb
);
1650 get_normal_ldap_pdu_len(packet_info
*pinfo _U_
, tvbuff_t
*tvb
,
1651 int offset
, void *data _U_
)
1657 /* normal ldap is tag+len bytes plus the length
1658 * offset is where the tag is
1659 * offset+1 is where length starts
1661 data_offset
=get_ber_length(tvb
, offset
+1, &len
, &ind
);
1662 return len
+data_offset
-offset
;
1666 dissect_normal_ldap_pdu(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1668 dissect_ldap_pdu(tvb
, pinfo
, tree
, false);
1669 return tvb_captured_length(tvb
);
1673 dissect_ldap_oid(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
1676 const char *oidname
;
1678 /* tvb here contains an ascii string that is really an oid */
1679 /* XXX we should convert the string oid into a real oid so we can use
1680 * proto_tree_add_oid() instead.
1683 oid
=tvb_get_string_enc(pinfo
->pool
, tvb
, 0, tvb_reported_length(tvb
), ENC_UTF_8
|ENC_NA
);
1685 return tvb_captured_length(tvb
);
1688 oidname
=oid_resolved_from_string(pinfo
->pool
, oid
);
1691 proto_tree_add_string_format_value(tree
, hf_ldap_oid
, tvb
, 0, tvb_reported_length(tvb
), oid
, "%s (%s)",oid
,oidname
);
1693 proto_tree_add_string(tree
, hf_ldap_oid
, tvb
, 0, tvb_captured_length(tvb
), oid
);
1695 return tvb_captured_length(tvb
);
1698 #define LDAP_ACCESSMASK_ADS_CREATE_CHILD 0x00000001
1699 #define LDAP_ACCESSMASK_ADS_DELETE_CHILD 0x00000002
1700 #define LDAP_ACCESSMASK_ADS_LIST 0x00000004
1701 #define LDAP_ACCESSMASK_ADS_SELF_WRITE 0x00000008
1702 #define LDAP_ACCESSMASK_ADS_READ_PROP 0x00000010
1703 #define LDAP_ACCESSMASK_ADS_WRITE_PROP 0x00000020
1704 #define LDAP_ACCESSMASK_ADS_DELETE_TREE 0x00000040
1705 #define LDAP_ACCESSMASK_ADS_LIST_OBJECT 0x00000080
1706 #define LDAP_ACCESSMASK_ADS_CONTROL_ACCESS 0x00000100
1709 ldap_specific_rights(tvbuff_t
*tvb
, int offset
, proto_tree
*tree
, uint32_t access
)
1711 static int * const access_flags
[] = {
1712 &hf_ldap_AccessMask_ADS_CONTROL_ACCESS
,
1713 &hf_ldap_AccessMask_ADS_LIST_OBJECT
,
1714 &hf_ldap_AccessMask_ADS_DELETE_TREE
,
1715 &hf_ldap_AccessMask_ADS_WRITE_PROP
,
1716 &hf_ldap_AccessMask_ADS_READ_PROP
,
1717 &hf_ldap_AccessMask_ADS_SELF_WRITE
,
1718 &hf_ldap_AccessMask_ADS_LIST
,
1719 &hf_ldap_AccessMask_ADS_DELETE_CHILD
,
1720 &hf_ldap_AccessMask_ADS_CREATE_CHILD
,
1724 proto_tree_add_bitmask_list_value(tree
, tvb
, offset
, 4, access_flags
, access
);
1727 static struct access_mask_info ldap_access_mask_info
= {
1728 "LDAP", /* Name of specific rights */
1729 ldap_specific_rights
, /* Dissection function */
1730 NULL
, /* Generic mapping table */
1731 NULL
/* Standard mapping table */
1735 dissect_ldap_nt_sec_desc(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1737 dissect_nt_sec_desc(tvb
, 0, pinfo
, tree
, NULL
, true, tvb_reported_length(tvb
), &ldap_access_mask_info
);
1738 return tvb_captured_length(tvb
);
1742 dissect_ldap_sid(tvbuff_t
*tvb
, packet_info
*pinfo _U_
, proto_tree
*tree
, void* data _U_
)
1746 /* this octet string contains an NT SID */
1747 dissect_nt_sid(tvb
, 0, tree
, "SID", &tmpstr
, hf_ldap_sid
);
1748 ldapvalue_string
=tmpstr
;
1749 return tvb_captured_length(tvb
);
1753 dissect_ldap_guid(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1755 uint8_t drep
[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
1758 /* This octet string contained a GUID */
1759 dissect_dcerpc_uuid_t(tvb
, 0, pinfo
, tree
, drep
, hf_ldap_guid
, &uuid
);
1761 ldapvalue_string
=(char*)wmem_alloc(pinfo
->pool
, 1024);
1762 snprintf(ldapvalue_string
, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
1763 uuid
.data1
, uuid
.data2
, uuid
.data3
, uuid
.data4
[0], uuid
.data4
[1],
1764 uuid
.data4
[2], uuid
.data4
[3], uuid
.data4
[4], uuid
.data4
[5],
1765 uuid
.data4
[6], uuid
.data4
[7]);
1766 return tvb_captured_length(tvb
);
1770 dissect_ldap_tcp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data
)
1775 conversation_t
*conversation
;
1776 ldap_conv_info_t
*ldap_info
= NULL
;
1779 * Do we have a conversation for this connection?
1781 conversation
= find_conversation_pinfo(pinfo
, 0);
1783 ldap_info
= (ldap_conv_info_t
*)conversation_get_proto_data(conversation
, proto_ldap
);
1788 /* This is a bit tricky. We have to find out whether SASL is used
1789 * so that we know how big a header we are supposed to pass
1790 * to tcp_dissect_pdus()
1791 * We must also cope with the case when a client connects to LDAP
1792 * and performs a few unauthenticated searches of LDAP before
1793 * it performs the bind on the same tcp connection.
1795 /* check for a SASL header, i.e. assume it is SASL if
1796 * 1, first four bytes (SASL length) is an integer
1797 * with a value that must be <LDAP_SASL_MAX_BUF and >2
1798 * (>2 to fight false positives, 0x00000000 is a common
1799 * "random" tcp payload)
1800 * (SASL ldap PDUs might be >64k in size, which is why
1801 * LDAP_SASL_MAX_BUF is used - defined in packet-ldap.h)
1803 * 2, we must have a conversation and the auth type must
1806 sasl_len
=tvb_get_ntohl(tvb
, 0);
1809 goto this_was_not_sasl
;
1812 if( sasl_len
>LDAP_SASL_MAX_BUF
){
1813 goto this_was_not_sasl
;
1816 if((!ldap_info
) || (ldap_info
->auth_type
!=LDAP_AUTH_SASL
) ){
1817 goto this_was_not_sasl
;
1820 tcp_dissect_pdus(tvb
, pinfo
, tree
, ldap_desegment
, 4, get_sasl_ldap_pdu_len
, dissect_sasl_ldap_pdu
, data
);
1821 return tvb_captured_length(tvb
);
1824 /* check if it is a normal BER encoded LDAP packet
1825 * i.e. first byte is 0x30 followed by a length that is
1827 * (no ldap PDUs are ever >64kb? )
1829 if(tvb_get_uint8(tvb
, 0)!=0x30){
1830 goto this_was_not_normal_ldap
;
1833 /* check that length makes sense */
1834 get_ber_length(tvb
, 1, &ldap_len
, &ind
);
1836 /* don't check ind since indefinite length is never used for ldap (famous last words)*/
1838 goto this_was_not_normal_ldap
;
1842 * The minimum size of a LDAP pdu is 7 bytes
1844 * dumpasn1 -hh ldap-unbind-min.dat
1846 * <30 05 02 01 09 42 00>
1851 * 5 0: [APPLICATION 2]
1852 * : Error: Object has zero length.
1855 * dumpasn1 -hh ldap-unbind-windows.dat
1857 * <30 84 00 00 00 05 02 01 09 42 00>
1862 * 9 0: [APPLICATION 2]
1863 * : Error: Object has zero length.
1866 * 6 bytes would also be ok to get the full length of
1867 * the pdu, but as the smallest pdu can be 7 bytes
1870 tcp_dissect_pdus(tvb
, pinfo
, tree
, ldap_desegment
, 7, get_normal_ldap_pdu_len
, dissect_normal_ldap_pdu
, data
);
1874 this_was_not_normal_ldap
:
1876 /* Ok it might be a strange case of SASL still
1877 * It has been seen with Exchange setup to MS AD
1878 * when Exchange pretend that there is SASL but in fact data are still
1880 if ((sasl_len
+ 4) == (uint32_t)tvb_reported_length_remaining(tvb
, 0))
1881 tcp_dissect_pdus(tvb
, pinfo
, tree
, ldap_desegment
, 4, get_sasl_ldap_pdu_len
, dissect_sasl_ldap_pdu
, data
);
1883 return tvb_captured_length(tvb
);
1887 dissect_mscldap(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
1889 dissect_ldap_pdu(tvb
, pinfo
, tree
, true);
1890 return tvb_captured_length(tvb
);
1894 /*--- proto_register_ldap -------------------------------------------*/
1895 void proto_register_ldap(void) {
1897 /* List of fields */
1899 static hf_register_info hf
[] = {
1901 { &hf_ldap_sasl_buffer_length
,
1902 { "SASL Buffer Length", "ldap.sasl_buffer_length",
1903 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
1905 { &hf_ldap_response_in
,
1906 { "Response In", "ldap.response_in",
1907 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_RESPONSE
), 0x0,
1908 "The response to this LDAP request is in this frame", HFILL
}},
1909 { &hf_ldap_response_to
,
1910 { "Response To", "ldap.response_to",
1911 FT_FRAMENUM
, BASE_NONE
, FRAMENUM_TYPE(FT_FRAMENUM_REQUEST
), 0x0,
1912 "This is a response to the LDAP request in this frame", HFILL
}},
1914 { "Time", "ldap.time",
1915 FT_RELATIVE_TIME
, BASE_NONE
, NULL
, 0x0,
1916 "The time between the Call and the Reply", HFILL
}},
1918 { &hf_mscldap_netlogon_opcode
,
1919 { "Operation code", "mscldap.netlogon.opcode",
1920 FT_UINT16
, BASE_DEC
, VALS(netlogon_opcode_vals
), 0x0,
1921 "LDAP ping operation code", HFILL
}},
1923 { &hf_mscldap_netlogon_ipaddress_family
,
1924 { "Family", "mscldap.netlogon.ipaddress.family",
1925 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1928 { &hf_mscldap_netlogon_ipaddress_ipv4
,
1929 { "IPv4", "mscldap.netlogon.ipaddress.ipv4",
1930 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1931 "IP Address", HFILL
}},
1933 { &hf_mscldap_netlogon_ipaddress_port
,
1934 { "Port", "mscldap.netlogon.ipaddress.port",
1935 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1938 { &hf_mscldap_netlogon_ipaddress
,
1939 { "IP Address","mscldap.netlogon.ipaddress",
1940 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1941 "Domain Controller IP Address", HFILL
}},
1943 { &hf_mscldap_netlogon_lm_token
,
1944 { "LM Token", "mscldap.netlogon.lm_token",
1945 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1946 "MUST be set to 0xFFFF", HFILL
}},
1948 { &hf_mscldap_netlogon_nt_token
,
1949 { "NT Token", "mscldap.netlogon.nt_token",
1950 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1951 "MUST be set to 0xFFFF", HFILL
}},
1953 { &hf_mscldap_netlogon_flags
,
1954 { "Flags", "mscldap.netlogon.flags",
1955 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1956 "Netlogon flags describing the DC properties", HFILL
}},
1958 { &hf_mscldap_ntver_flags
,
1959 { "Version Flags", "mscldap.ntver.flags",
1960 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1961 "NETLOGON_NT_VERSION Options Bits", HFILL
}},
1963 { &hf_mscldap_domain_guid
,
1964 { "Domain GUID", "mscldap.domain.guid",
1965 FT_GUID
, BASE_NONE
, NULL
, 0x0,
1966 "Value of the NC's GUID attribute", HFILL
}},
1968 { &hf_mscldap_forest
,
1969 { "Forest", "mscldap.forest",
1970 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1971 "DNS name of the forest", HFILL
}},
1973 { &hf_mscldap_domain
,
1974 { "Domain", "mscldap.domain",
1975 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1976 "DNS name of the NC", HFILL
}},
1978 { &hf_mscldap_hostname
,
1979 { "Hostname", "mscldap.hostname",
1980 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1981 "DNS name of server", HFILL
}},
1983 { &hf_mscldap_nb_domain_z
,
1984 { "NetBIOS Domain", "mscldap.nb_domain",
1985 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
1986 "NetBIOS name of the NC", HFILL
}},
1988 { &hf_mscldap_nb_domain
,
1989 { "NetBIOS Domain", "mscldap.nb_domain",
1990 FT_STRING
, BASE_NONE
, NULL
, 0x0,
1991 "NetBIOS name of the NC", HFILL
}},
1993 { &hf_mscldap_nb_hostname_z
,
1994 { "NetBIOS Hostname", "mscldap.nb_hostname",
1995 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
1996 "NetBIOS name of the server", HFILL
}},
1998 { &hf_mscldap_nb_hostname
,
1999 { "NetBIOS Hostname", "mscldap.nb_hostname",
2000 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2001 "NetBIOS name of the server", HFILL
}},
2003 { &hf_mscldap_username_z
,
2004 { "Username", "mscldap.username",
2005 FT_STRINGZ
, BASE_NONE
, NULL
, 0x0,
2006 "User specified in client's request", HFILL
}},
2008 { &hf_mscldap_username
,
2009 { "Username", "mscldap.username",
2010 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2011 "User specified in client's request", HFILL
}},
2013 { &hf_mscldap_sitename
,
2014 { "Server Site", "mscldap.sitename",
2015 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2016 "Site name of the server", HFILL
}},
2018 { &hf_mscldap_clientsitename
,
2019 { "Client Site", "mscldap.clientsitename",
2020 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2021 "Site name of the client", HFILL
}},
2024 { "Sid", "ldap.sid",
2025 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2028 { &hf_mscldap_ntver_flags_v1
,
2029 { "V1", "mscldap.ntver.searchflags.v1", FT_BOOLEAN
, 32,
2030 TFS(&tfs_ntver_v1
), 0x00000001, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2032 { &hf_mscldap_ntver_flags_v5
,
2033 { "V5", "mscldap.ntver.searchflags.v5", FT_BOOLEAN
, 32,
2034 TFS(&tfs_ntver_v5
), 0x00000002, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2036 { &hf_mscldap_ntver_flags_v5ex
,
2037 { "V5EX", "mscldap.ntver.searchflags.v5ex", FT_BOOLEAN
, 32,
2038 TFS(&tfs_ntver_v5ex
), 0x00000004, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2040 { &hf_mscldap_ntver_flags_v5ep
,
2041 { "V5EP", "mscldap.ntver.searchflags.v5ep", FT_BOOLEAN
, 32,
2042 TFS(&tfs_ntver_v5ep
), 0x00000008, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2044 { &hf_mscldap_ntver_flags_vcs
,
2045 { "VCS", "mscldap.ntver.searchflags.vcs", FT_BOOLEAN
, 32,
2046 TFS(&tfs_ntver_vcs
), 0x00000010, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2048 { &hf_mscldap_ntver_flags_vnt4
,
2049 { "VNT4", "mscldap.ntver.searchflags.vnt4", FT_BOOLEAN
, 32,
2050 TFS(&tfs_ntver_vnt4
), 0x01000000, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2052 { &hf_mscldap_ntver_flags_vpdc
,
2053 { "VPDC", "mscldap.ntver.searchflags.vpdc", FT_BOOLEAN
, 32,
2054 TFS(&tfs_ntver_vpdc
), 0x10000000, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2056 { &hf_mscldap_ntver_flags_vip
,
2057 { "VIP", "mscldap.ntver.searchflags.vip", FT_BOOLEAN
, 32,
2058 TFS(&tfs_ntver_vip
), 0x20000000, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2060 { &hf_mscldap_ntver_flags_vl
,
2061 { "VL", "mscldap.ntver.searchflags.vl", FT_BOOLEAN
, 32,
2062 TFS(&tfs_ntver_vl
), 0x40000000, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2064 { &hf_mscldap_ntver_flags_vgc
,
2065 { "VGC", "mscldap.ntver.searchflags.vgc", FT_BOOLEAN
, 32,
2066 TFS(&tfs_ntver_vgc
), 0x80000000, "See section 6.3.1.1 of MS-ADTS specification", HFILL
}},
2069 { &hf_mscldap_netlogon_flags_pdc
,
2070 { "PDC", "mscldap.netlogon.flags.pdc", FT_BOOLEAN
, 32,
2071 TFS(&tfs_ads_pdc
), 0x00000001, "Is this DC a PDC or not?", HFILL
}},
2073 { &hf_mscldap_netlogon_flags_gc
,
2074 { "GC", "mscldap.netlogon.flags.gc", FT_BOOLEAN
, 32,
2075 TFS(&tfs_ads_gc
), 0x00000004, "Does this dc service as a GLOBAL CATALOGUE?", HFILL
}},
2077 { &hf_mscldap_netlogon_flags_ldap
,
2078 { "LDAP", "mscldap.netlogon.flags.ldap", FT_BOOLEAN
, 32,
2079 TFS(&tfs_ads_ldap
), 0x00000008, "Does this DC act as an LDAP server?", HFILL
}},
2081 { &hf_mscldap_netlogon_flags_ds
,
2082 { "DS", "mscldap.netlogon.flags.ds", FT_BOOLEAN
, 32,
2083 TFS(&tfs_ads_ds
), 0x00000010, "Does this dc provide DS services?", HFILL
}},
2085 { &hf_mscldap_netlogon_flags_kdc
,
2086 { "KDC", "mscldap.netlogon.flags.kdc", FT_BOOLEAN
, 32,
2087 TFS(&tfs_ads_kdc
), 0x00000020, "Does this dc act as a KDC?", HFILL
}},
2089 { &hf_mscldap_netlogon_flags_timeserv
,
2090 { "Time Serv", "mscldap.netlogon.flags.timeserv", FT_BOOLEAN
, 32,
2091 TFS(&tfs_ads_timeserv
), 0x00000040, "Does this dc provide time services (ntp) ?", HFILL
}},
2093 { &hf_mscldap_netlogon_flags_closest
,
2094 { "Closest", "mscldap.netlogon.flags.closest", FT_BOOLEAN
, 32,
2095 TFS(&tfs_ads_closest
), 0x00000080, "Is this the closest dc?", HFILL
}},
2097 { &hf_mscldap_netlogon_flags_writable
,
2098 { "Writable", "mscldap.netlogon.flags.writable", FT_BOOLEAN
, 32,
2099 TFS(&tfs_ads_writable
), 0x00000100, "Is this dc writable?", HFILL
}},
2101 { &hf_mscldap_netlogon_flags_good_timeserv
,
2102 { "Good Time Serv", "mscldap.netlogon.flags.good_timeserv", FT_BOOLEAN
, 32,
2103 TFS(&tfs_ads_good_timeserv
), 0x00000200, "Is this a Good Time Server? (i.e. does it have a hardware clock)", HFILL
}},
2105 { &hf_mscldap_netlogon_flags_ndnc
,
2106 { "NDNC", "mscldap.netlogon.flags.ndnc", FT_BOOLEAN
, 32,
2107 TFS(&tfs_ads_ndnc
), 0x00000400, "Is this an NDNC dc?", HFILL
}},
2109 { &hf_mscldap_netlogon_flags_rodc
,
2110 { "RODC", "mscldap.netlogon.flags.rodc", FT_BOOLEAN
, 32,
2111 TFS(&tfs_ads_rodc
), 0x00000800, "Is this an read only dc?", HFILL
}},
2113 { &hf_mscldap_netlogon_flags_wdc
,
2114 { "WDC", "mscldap.netlogon.flags.writabledc", FT_BOOLEAN
, 32,
2115 TFS(&tfs_ads_wdc
), 0x00001000, "Is this an writable dc (Windows 2008)?", HFILL
}},
2117 { &hf_mscldap_netlogon_flags_dns
,
2118 { "DNS", "mscldap.netlogon.flags.dnsname", FT_BOOLEAN
, 32,
2119 TFS(&tfs_ads_dns
), 0x20000000, "Does the server have a dns name (Windows 2008)?", HFILL
}},
2121 { &hf_mscldap_netlogon_flags_dnc
,
2122 { "DNC", "mscldap.netlogon.flags.defaultnc", FT_BOOLEAN
, 32,
2123 TFS(&tfs_ads_dnc
), 0x40000000, "Is this the default NC (Windows 2008)?", HFILL
}},
2125 { &hf_mscldap_netlogon_flags_fnc
,
2126 { "FDC", "mscldap.netlogon.flags.forestnc", FT_BOOLEAN
, 32,
2127 TFS(&tfs_ads_fnc
), 0x80000000, "Is the NC the default forest root(Windows 2008)?", HFILL
}},
2130 { "GUID", "ldap.guid", FT_GUID
, BASE_NONE
,
2131 NULL
, 0, NULL
, HFILL
}},
2133 { &hf_ldap_AccessMask_ADS_CREATE_CHILD
,
2134 { "Ads Create Child", "ldap.AccessMask.ADS_CREATE_CHILD", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_CREATE_CHILD
, NULL
, HFILL
}},
2136 { &hf_ldap_AccessMask_ADS_DELETE_CHILD
,
2137 { "Ads Delete Child", "ldap.AccessMask.ADS_DELETE_CHILD", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_DELETE_CHILD
, NULL
, HFILL
}},
2139 { &hf_ldap_AccessMask_ADS_LIST
,
2140 { "Ads List", "ldap.AccessMask.ADS_LIST", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_LIST
, NULL
, HFILL
}},
2142 { &hf_ldap_AccessMask_ADS_SELF_WRITE
,
2143 { "Ads Self Write", "ldap.AccessMask.ADS_SELF_WRITE", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_SELF_WRITE
, NULL
, HFILL
}},
2145 { &hf_ldap_AccessMask_ADS_READ_PROP
,
2146 { "Ads Read Prop", "ldap.AccessMask.ADS_READ_PROP", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_READ_PROP
, NULL
, HFILL
}},
2148 { &hf_ldap_AccessMask_ADS_WRITE_PROP
,
2149 { "Ads Write Prop", "ldap.AccessMask.ADS_WRITE_PROP", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_WRITE_PROP
, NULL
, HFILL
}},
2151 { &hf_ldap_AccessMask_ADS_DELETE_TREE
,
2152 { "Ads Delete Tree", "ldap.AccessMask.ADS_DELETE_TREE", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_DELETE_TREE
, NULL
, HFILL
}},
2154 { &hf_ldap_AccessMask_ADS_LIST_OBJECT
,
2155 { "Ads List Object", "ldap.AccessMask.ADS_LIST_OBJECT", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_LIST_OBJECT
, NULL
, HFILL
}},
2157 { &hf_ldap_AccessMask_ADS_CONTROL_ACCESS
,
2158 { "Ads Control Access", "ldap.AccessMask.ADS_CONTROL_ACCESS", FT_BOOLEAN
, 32, TFS(&tfs_set_notset
), LDAP_ACCESSMASK_ADS_CONTROL_ACCESS
, NULL
, HFILL
}},
2160 { &hf_ldap_LDAPMessage_PDU
,
2161 { "LDAPMessage", "ldap.LDAPMessage_element", FT_NONE
, BASE_NONE
, NULL
, 0, NULL
, HFILL
}},
2163 { &hf_ldap_object_security_flag
,
2164 { "Flag Object_Security", "ldap.object_security_flag", FT_BOOLEAN
, 32, NULL
, 0x00000001, NULL
, HFILL
}},
2166 { &hf_ldap_ancestor_first_flag
,
2167 { "Flag Ancestor_First", "ldap.ancestor_first_flag", FT_BOOLEAN
, 32, NULL
, 0x00000800, NULL
, HFILL
}},
2169 { &hf_ldap_public_data_only_flag
,
2170 { "Flag Public_Data_Only", "ldap.public_data_only_flag", FT_BOOLEAN
, 32, NULL
, 0x00002000, NULL
, HFILL
}},
2172 { &hf_ldap_incremental_value_flag
,
2173 { "Flag Incremental_Value", "ldap.incremental_value_flag", FT_BOOLEAN
, 32, NULL
, 0x80000000, NULL
, HFILL
}},
2176 { "OID", "ldap.oid", FT_STRING
, BASE_NONE
,
2177 NULL
, 0, NULL
, HFILL
}},
2179 { &hf_ldap_gssapi_encrypted_payload
,
2180 { "GSS-API Encrypted payload", "ldap.gssapi_encrypted_payload", FT_BYTES
, BASE_NONE
,
2181 NULL
, 0, NULL
, HFILL
}},
2183 #include "packet-ldap-hfarr.c"
2186 /* List of subtrees */
2187 static int *ett
[] = {
2190 &ett_ldap_sasl_blob
,
2192 &ett_mscldap_netlogon_flags
,
2193 &ett_mscldap_ntver_flags
,
2194 &ett_mscldap_ipdetails
,
2195 &ett_ldap_DirSyncFlagsSubEntry
,
2197 #include "packet-ldap-ettarr.c"
2199 /* UAT for header fields */
2200 static uat_field_t custom_attribute_types_uat_fields
[] = {
2201 UAT_FLD_CSTRING(attribute_types
, attribute_type
, "Attribute type", "Attribute type"),
2202 UAT_FLD_CSTRING(attribute_types
, attribute_desc
, "Description", "Description of the value matching type"),
2206 static ei_register_info ei
[] = {
2207 { &ei_ldap_exceeded_filter_length
, { "ldap.exceeded_filter_length", PI_UNDECODED
, PI_ERROR
, "Filter length exceeds number. Giving up", EXPFILL
}},
2208 { &ei_ldap_too_many_filter_elements
, { "ldap.too_many_filter_elements", PI_UNDECODED
, PI_ERROR
, "Found too many filter elements. Giving up.", EXPFILL
}},
2211 expert_module_t
* expert_ldap
;
2212 module_t
*ldap_module
;
2213 uat_t
*attributes_uat
;
2215 /* Register protocol */
2216 proto_ldap
= proto_register_protocol(PNAME
, PSNAME
, PFNAME
);
2217 /* Register fields and subtrees */
2218 proto_register_field_array(proto_ldap
, hf
, array_length(hf
));
2219 proto_register_subtree_array(ett
, array_length(ett
));
2220 expert_ldap
= expert_register_protocol(proto_ldap
);
2221 expert_register_field_array(expert_ldap
, ei
, array_length(ei
));
2223 ldap_handle
= register_dissector("ldap", dissect_ldap_tcp
, proto_ldap
);
2225 ldap_module
= prefs_register_protocol(proto_ldap
, prefs_register_ldap
);
2226 prefs_register_bool_preference(ldap_module
, "desegment_ldap_messages",
2227 "Reassemble LDAP messages spanning multiple TCP segments",
2228 "Whether the LDAP dissector should reassemble messages spanning multiple TCP segments."
2229 " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
2232 prefs_register_uint_preference(ldap_module
, "tls.port", "LDAPS TCP Port",
2233 "Set the port for LDAP operations over TLS",
2234 10, &global_ldaps_tcp_port
);
2235 prefs_register_obsolete_preference(ldap_module
, "ssl.port");
2237 attributes_uat
= uat_new("Custom LDAP AttributeValue types",
2238 sizeof(attribute_type_t
),
2239 "custom_ldap_attribute_types",
2242 &num_attribute_types
,
2243 /* specifies named fields, so affects dissection
2244 and the set of named fields */
2245 UAT_AFFECTS_DISSECTION
|UAT_AFFECTS_FIELDS
,
2247 attribute_types_copy_cb
,
2248 attribute_types_update_cb
,
2249 attribute_types_free_cb
,
2250 attribute_types_post_update_cb
,
2251 attribute_types_reset_cb
,
2252 custom_attribute_types_uat_fields
);
2254 prefs_register_uat_preference(ldap_module
, "custom_ldap_attribute_types",
2255 "Custom AttributeValue types",
2256 "A table to define custom LDAP attribute type values for which fields can be setup and used for filtering/data extraction etc.",
2259 prefs_register_obsolete_preference(ldap_module
, "max_pdu");
2261 proto_cldap
= proto_register_protocol("Connectionless Lightweight Directory Access Protocol", "CLDAP", "cldap");
2262 cldap_handle
= register_dissector("cldap", dissect_mscldap
, proto_cldap
);
2264 ldap_tap
=register_tap("ldap");
2266 ldap_name_dissector_table
= register_dissector_table("ldap.name", "LDAP Attribute Type Dissectors", proto_cldap
, FT_STRING
, STRING_CASE_INSENSITIVE
);
2268 register_srt_table(proto_ldap
, NULL
, 1, ldapstat_packet
, ldapstat_init
, NULL
);
2272 /*--- proto_reg_handoff_ldap ---------------------------------------*/
2274 proto_reg_handoff_ldap(void)
2276 dissector_add_uint_with_preference("udp.port", UDP_PORT_CLDAP
, cldap_handle
);
2278 gssapi_handle
= find_dissector_add_dependency("gssapi", proto_ldap
);
2279 gssapi_wrap_handle
= find_dissector_add_dependency("gssapi_verf", proto_ldap
);
2280 spnego_handle
= find_dissector_add_dependency("spnego", proto_ldap
);
2282 ntlmssp_handle
= find_dissector_add_dependency("ntlmssp", proto_ldap
);
2284 tls_handle
= find_dissector_add_dependency("tls", proto_ldap
);
2286 prefs_register_ldap();
2288 oid_add_from_string("ISO assigned OIDs, USA", "1.2.840");
2290 /* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dsml/dsml/ldap_controls_and_session_support.asp */
2291 /* https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/3c5e87db-4728-4f29-b164-01dd7d7391ea */
2292 oid_add_from_string("LDAP_PAGED_RESULT_OID_STRING","1.2.840.113556.1.4.319");
2293 oid_add_from_string("LDAP_SERVER_SHOW_DELETED_OID","1.2.840.113556.1.4.417");
2294 oid_add_from_string("LDAP_SERVER_SORT_OID","1.2.840.113556.1.4.473");
2295 oid_add_from_string("LDAP_SERVER_RESP_SORT_OID","1.2.840.113556.1.4.474");
2296 oid_add_from_string("LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID","1.2.840.113556.1.4.521");
2297 oid_add_from_string("LDAP_SERVER_NOTIFICATION_OID","1.2.840.113556.1.4.528");
2298 oid_add_from_string("LDAP_SERVER_EXTENDED_DN_OID","1.2.840.113556.1.4.529");
2299 oid_add_from_string("meetingAdvertiseScope","1.2.840.113556.1.4.582");
2300 oid_add_from_string("LDAP_SERVER_LAZY_COMMIT_OID","1.2.840.113556.1.4.619");
2301 oid_add_from_string("mhsORAddress","1.2.840.113556.1.4.650");
2302 oid_add_from_string("managedObjects","1.2.840.113556.1.4.654");
2303 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_OID","1.2.840.113556.1.4.800");
2304 oid_add_from_string("LDAP_SERVER_SD_FLAGS_OID","1.2.840.113556.1.4.801");
2305 oid_add_from_string("LDAP_SERVER_RANGE_OPTION_OID","1.2.840.113556.1.4.802");
2306 oid_add_from_string("LDAP_MATCHING_RULE_BIT_AND", "1.2.840.113556.1.4.803");
2307 oid_add_from_string("LDAP_MATCHING_RULE_BIT_OR","1.2.840.113556.1.4.804");
2308 oid_add_from_string("LDAP_SERVER_TREE_DELETE_OID","1.2.840.113556.1.4.805");
2309 oid_add_from_string("LDAP_SERVER_DIRSYNC_OID","1.2.840.113556.1.4.841");
2310 oid_add_from_string("LDAP_SERVER_GET_STATS_OID","1.2.840.113556.1.4.970");
2311 oid_add_from_string("LDAP_SERVER_VERIFY_NAME_OID","1.2.840.113556.1.4.1338");
2312 oid_add_from_string("LDAP_SERVER_DOMAIN_SCOPE_OID","1.2.840.113556.1.4.1339");
2313 oid_add_from_string("LDAP_SERVER_SEARCH_OPTIONS_OID","1.2.840.113556.1.4.1340");
2314 oid_add_from_string("LDAP_SERVER_RODC_DCPROMO_OID","1.2.840.113556.1.4.1341");
2315 oid_add_from_string("LDAP_SERVER_PERMISSIVE_MODIFY_OID","1.2.840.113556.1.4.1413");
2316 oid_add_from_string("LDAP_SERVER_ASQ_OID","1.2.840.113556.1.4.1504");
2317 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_V51_OID","1.2.840.113556.1.4.1670");
2318 oid_add_from_string("msDS-SDReferenceDomain","1.2.840.113556.1.4.1711");
2319 oid_add_from_string("msDS-AdditionalDnsHostName","1.2.840.113556.1.4.1717");
2320 oid_add_from_string("LDAP_SERVER_FAST_BIND_OID","1.2.840.113556.1.4.1781");
2321 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID","1.2.840.113556.1.4.1791");
2322 oid_add_from_string("msDS-ObjectReference","1.2.840.113556.1.4.1840");
2323 oid_add_from_string("msDS-QuotaEffective","1.2.840.113556.1.4.1848");
2324 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID","1.2.840.113556.1.4.1851");
2325 oid_add_from_string("LDAP_SERVER_QUOTA_CONTROL_OID","1.2.840.113556.1.4.1852");
2326 oid_add_from_string("msDS-PortSSL","1.2.840.113556.1.4.1860");
2327 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_ADAM_DIGEST_OID", "1.2.840.113556.1.4.1880");
2328 oid_add_from_string("LDAP_SERVER_SHUTDOWN_NOTIFY_OID","1.2.840.113556.1.4.1907");
2329 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_PARTIAL_SECRETS_OID", "1.2.840.113556.1.4.1920");
2330 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_V60_OID", "1.2.840.113556.1.4.1935");
2331 oid_add_from_string("LDAP_MATCHING_RULE_TRANSITIVE_EVAL", "1.2.840.113556.1.4.1941");
2332 oid_add_from_string("LDAP_SERVER_RANGE_RETRIEVAL_NOERR_OID","1.2.840.113556.1.4.1948");
2333 oid_add_from_string("msDS-isRODC","1.2.840.113556.1.4.1960");
2334 oid_add_from_string("LDAP_SERVER_FORCE_UPDATE_OID","1.2.840.113556.1.4.1974");
2335 oid_add_from_string("LDAP_SERVER_DN_INPUT_OID","1.2.840.113556.1.4.2026");
2336 oid_add_from_string("LDAP_SERVER_SHOW_RECYCLED_OID","1.2.840.113556.1.4.2064");
2337 oid_add_from_string("LDAP_SERVER_SHOW_DEACTIVATED_LINK_OID","1.2.840.113556.1.4.2065");
2338 oid_add_from_string("LDAP_SERVER_POLICY_HINTS_DEPRECATED_OID","1.2.840.113556.1.4.2066");
2339 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_V61_R2_OID", "1.2.840.113556.1.4.2080");
2340 oid_add_from_string("LDAP_SERVER_DIRSYNC_EX_OID","1.2.840.113556.1.4.2090");
2341 oid_add_from_string("LDAP_SERVER_TREE_DELETE_EX_OID","1.2.840.113556.1.4.2204");
2342 oid_add_from_string("LDAP_SERVER_UPDATE_STATS_OID","1.2.840.113556.1.4.2205");
2343 oid_add_from_string("LDAP_SERVER_SEARCH_HINTS_OID","1.2.840.113556.1.4.2206");
2344 oid_add_from_string("LDAP_SERVER_EXPECTED_ENTRY_COUNT_OID","1.2.840.113556.1.4.2211");
2345 oid_add_from_string("LDAP_SERVER_BATCH_REQUEST_OID", "1.2.840.113556.1.4.2212");
2346 oid_add_from_string("LDAP_CAP_ACTIVE_DIRECTORY_W8_OID", "1.2.840.113556.1.4.2237");
2347 oid_add_from_string("LDAP_SERVER_POLICY_HINTS_OID","1.2.840.113556.1.4.2239");
2348 oid_add_from_string("LDAP_MATCHING_RULE_DN_WITH_DATA", "1.2.840.113556.1.4.2253");
2349 oid_add_from_string("LDAP_SERVER_SET_OWNER_OID","1.2.840.113556.1.4.2255");
2350 oid_add_from_string("LDAP_SERVER_BYPASS_QUOTA_OID","1.2.840.113556.1.4.2256");
2351 oid_add_from_string("LDAP_SERVER_LINK_TTL_OID","1.2.840.113556.1.4.2309");
2352 oid_add_from_string("LDAP_SERVER_SET_CORRELATION_ID_OID","1.2.840.113556.1.4.2330");
2353 oid_add_from_string("LDAP_SERVER_THREAD_TRACE_OVERRIDE_OID","1.2.840.113556.1.4.2354");
2356 oid_add_from_string("LDAP_SERVER_WHO_AM_I_OID", "1.3.6.1.4.1.4203.1.11.3");
2358 /* Mark Wahl (Critical Angle) */
2359 oid_add_from_string("DYNAMIC_REFRESH","1.3.6.1.4.1.1466.101.119.1");
2360 oid_add_from_string("LDAP_START_TLS_OID","1.3.6.1.4.1.1466.20037");
2362 oid_add_from_string("inetOrgPerson", "2.16.840.1.113730.3.2.2");
2364 oid_add_from_string("US company arc", "2.16.840.1");
2366 /* http://www.alvestrand.no/objectid/2.16.840.1.113730.3.4.html */
2367 oid_add_from_string("Manage DSA IT LDAPv3 control", "2.16.840.1.113730.3.4.2");
2368 oid_add_from_string("Persistent Search LDAPv3 control", "2.16.840.1.113730.3.4.3");
2369 oid_add_from_string("Netscape Password Expired LDAPv3 control", "2.16.840.1.113730.3.4.4");
2370 oid_add_from_string("Netscape Password Expiring LDAPv3 control", "2.16.840.1.113730.3.4.5");
2371 oid_add_from_string("Netscape NT Synchronization Client LDAPv3 control", "2.16.840.1.113730.3.4.6");
2372 oid_add_from_string("Entry Change Notification LDAPv3 control", "2.16.840.1.113730.3.4.7");
2373 oid_add_from_string("Transaction ID Request Control", "2.16.840.1.113730.3.4.8");
2374 oid_add_from_string("VLV Request LDAPv3 control", "2.16.840.1.113730.3.4.9");
2375 oid_add_from_string("VLV Response LDAPv3 control", "2.16.840.1.113730.3.4.10");
2376 oid_add_from_string("Transaction ID Response Control", "2.16.840.1.113730.3.4.11");
2377 oid_add_from_string("Proxied Authorization (version 1) control", "2.16.840.1.113730.3.4.12");
2378 oid_add_from_string("iPlanet Directory Server Replication Update Information Control", "2.16.840.1.113730.3.4.13");
2379 oid_add_from_string("iPlanet Directory Server search on specific backend control", "2.16.840.1.113730.3.4.14");
2380 oid_add_from_string("Authentication Response Control", "2.16.840.1.113730.3.4.15");
2381 oid_add_from_string("Authentication Request Control", "2.16.840.1.113730.3.4.16");
2382 oid_add_from_string("Real Attributes Only Request Control", "2.16.840.1.113730.3.4.17");
2383 oid_add_from_string("Proxied Authorization (version 2) Control", "2.16.840.1.113730.3.4.18");
2384 oid_add_from_string("Chaining loop detection", "2.16.840.1.113730.3.4.19");
2385 oid_add_from_string("iPlanet Replication Modrdn Extra Mods Control", "2.16.840.1.113730.3.4.999");
2388 dissector_add_string("ldap.name", "netlogon", create_dissector_handle(dissect_NetLogon_PDU
, proto_cldap
));
2389 dissector_add_string("ldap.name", "objectGUID", create_dissector_handle(dissect_ldap_guid
, proto_ldap
));
2390 dissector_add_string("ldap.name", "supportedControl", create_dissector_handle(dissect_ldap_oid
, proto_ldap
));
2391 dissector_add_string("ldap.name", "supportedCapabilities", create_dissector_handle(dissect_ldap_oid
, proto_ldap
));
2392 dissector_add_string("ldap.name", "objectSid", create_dissector_handle(dissect_ldap_sid
, proto_ldap
));
2393 dissector_add_string("ldap.name", "nTSecurityDescriptor", create_dissector_handle(dissect_ldap_nt_sec_desc
, proto_ldap
));
2395 #include "packet-ldap-dis-tab.c"
2397 dissector_add_uint_range_with_preference("tcp.port", TCP_PORT_RANGE_LDAP
, ldap_handle
);
2399 dissector_add_uint("acdr.tls_application_port", 636, ldap_handle
);
2400 dissector_add_uint("acdr.tls_application", TLS_APP_LDAP
, ldap_handle
);
2404 prefs_register_ldap(void)
2406 if(ssl_port
!= global_ldaps_tcp_port
) {
2408 ssl_dissector_delete(ssl_port
, ldap_handle
);
2410 /* Set our port number for future use */
2411 ssl_port
= global_ldaps_tcp_port
;
2414 ssl_dissector_add(ssl_port
, ldap_handle
);
2420 * Editor modelines - https://www.wireshark.org/tools/modelines.html
2425 * indent-tabs-mode: nil
2428 * vi: set shiftwidth=2 tabstop=8 expandtab:
2429 * :indentSize=2:tabSize=8:noTabs=true: