#include <epan/oid_resolv.h>
#include <epan/strutil.h>
#include <epan/dissectors/packet-tcp.h>
+#include <epan/dissectors/packet-windows-common.h>
+#include <epan/dissectors/packet-dcerpc.h>
#include "packet-frame.h"
#include "packet-ldap.h"
+#include "packet-ntlmssp.h"
#include "packet-ber.h"
#include "packet-per.h"
static int hf_ldap_response_in = -1;
static int hf_ldap_response_to = -1;
static int hf_ldap_time = -1;
+static int hf_ldap_guid = -1;
static int hf_mscldap_netlogon_type = -1;
static int hf_mscldap_netlogon_flags = -1;
static int hf_mscldap_netlogon_version = -1;
static int hf_mscldap_netlogon_lm_token = -1;
static int hf_mscldap_netlogon_nt_token = -1;
+static int hf_ldap_sid = -1;
+static int hf_ldap_AccessMask_ADS_CREATE_CHILD = -1;
+static int hf_ldap_AccessMask_ADS_DELETE_CHILD = -1;
+static int hf_ldap_AccessMask_ADS_LIST = -1;
+static int hf_ldap_AccessMask_ADS_SELF_WRITE = -1;
+static int hf_ldap_AccessMask_ADS_READ_PROP = -1;
+static int hf_ldap_AccessMask_ADS_WRITE_PROP = -1;
+static int hf_ldap_AccessMask_ADS_DELETE_TREE = -1;
+static int hf_ldap_AccessMask_ADS_LIST_OBJECT = -1;
+static int hf_ldap_AccessMask_ADS_CONTROL_ACCESS = -1;
#include "packet-ldap-hf.c"
#include "packet-ldap-ett.c"
static dissector_table_t ldap_name_dissector_table=NULL;
+static const char *object_identifier_id = NULL; /* LDAP OID */
/* desegmentation of LDAP */
static gboolean ldap_desegment = TRUE;
static guint ldap_tcp_port = 389;
+
static gboolean do_protocolop = FALSE;
static gchar *attr_type = NULL;
static gboolean is_binary_attr_type = FALSE;
static dissector_handle_t gssapi_handle;
static dissector_handle_t gssapi_wrap_handle;
+static dissector_handle_t ntlmssp_handle = NULL;
/* different types of rpc calls ontop of ms cldap */
GHashTable *unmatched;
GHashTable *matched;
gboolean is_mscldap;
- gboolean first_time;
guint32 num_results;
} ldap_conv_info_t;
static ldap_conv_info_t *ldap_info_items;
return key1->messageId==key2->messageId;
}
+/* This string contains the last LDAPString that was decoded */
+static char *attributedesc_string=NULL;
+
/* This string contains the last AssertionValue that was decoded */
-static char *assertionvalue_string=NULL;
+static char *ldapvalue_string=NULL;
+
/* if the octet string contain all printable ASCII characters, then
* display it as a string, othervise just display it in hex.
*/
return offset;
}
+
/*
- * Check whether the string is printable ASCII or binary.
+ * Some special/wellknown attributes in common LDAP (read AD)
+ * are neither ascii strings nor blobs of hex data.
+ * Special case these attributes and decode them more nicely.
+ *
+ * Add more special cases as required to prettify further
+ * (there cant be that many ones that are truly interesting)
+ */
+ if(attributedesc_string && !strncmp("DomainSid", attributedesc_string, 9)){
+ tvbuff_t *sid_tvb;
+ char *tmpstr;
+
+ /* this octet string contains an NT SID */
+ sid_tvb=tvb_new_subset(tvb, offset, len, len);
+ dissect_nt_sid(sid_tvb, 0, tree, "SID", &tmpstr, hf_index);
+ ldapvalue_string=tmpstr;
+
+ goto finished;
+ } else if ( (len==16) /* GUIDs are always 16 bytes */
+ && (attributedesc_string && !strncmp("DomainGuid", attributedesc_string, 10))) {
+ guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ e_uuid_t uuid;
+
+ /* This octet string contained a GUID */
+ dissect_dcerpc_uuid_t(tvb, offset, pinfo, tree, drep, hf_ldap_guid, &uuid);
+
+ ldapvalue_string=ep_alloc(1024);
+ g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.Data1, uuid.Data2, uuid.Data3,
+ uuid.Data4[0], uuid.Data4[1],
+ uuid.Data4[2], uuid.Data4[3],
+ uuid.Data4[4], uuid.Data4[5],
+ uuid.Data4[6], uuid.Data4[7]);
+
+ goto finished;
+ }
+
+ /*
+ * It was not one of our "wellknown" attributes so make the best
+ * we can and just try to see if it is an ascii string or if it
+ * is a binary blob.
*
* XXX - should we support reading RFC 2252-style schemas
* for LDAP, and using that to determine how to display
* attribute values and assertion values?
+ *
+ * -- I dont think there are full schemas available that describe the
+ * interesting cases i.e. AD -- ronnie
*/
str=tvb_get_ptr(tvb, offset, len);
is_ascii=TRUE;
/* convert the string into a printable string */
if(is_ascii){
- assertionvalue_string=ep_alloc(len+1);
- memcpy(assertionvalue_string,str,len);
- assertionvalue_string[i]=0;
+ ldapvalue_string=ep_alloc(len+1);
+ memcpy(ldapvalue_string,str,len);
+ ldapvalue_string[i]=0;
} else {
- assertionvalue_string=ep_alloc(3*len);
+ ldapvalue_string=ep_alloc(3*len);
for(i=0;i<len;i++){
- g_snprintf(assertionvalue_string+i*3,3,"%02x",str[i]&0xff);
- assertionvalue_string[3*i+2]=':';
+ g_snprintf(ldapvalue_string+i*3,3,"%02x",str[i]&0xff);
+ ldapvalue_string[3*i+2]=':';
}
- assertionvalue_string[3*len-1]=0;
+ ldapvalue_string[3*len-1]=0;
}
- proto_tree_add_string(tree, hf_index, tvb, offset, len, assertionvalue_string);
- offset+=len;
+ proto_tree_add_string(tree, hf_index, tvb, offset, len, ldapvalue_string);
+
+finished:
+ offset+=len;
return offset;
}
-/* This string contains the last LDAPString that was decoded */
-static char *attributedesc_string=NULL;
-
/* This string contains the last Filter item that was decoded */
static char *Filter_string=NULL;
static char *and_filter_string=NULL;
/* we have found a match */
if(lcrp){
+ proto_item *it;
+
if(lcrp->is_request){
- proto_tree_add_uint(tree, hf_ldap_response_in, tvb, 0, 0, lcrp->rep_frame);
+ it=proto_tree_add_uint(tree, hf_ldap_response_in, tvb, 0, 0, lcrp->rep_frame);
+ PROTO_ITEM_SET_GENERATED(it);
} else {
nstime_t ns;
- proto_tree_add_uint(tree, hf_ldap_response_to, tvb, 0, 0, lcrp->req_frame);
+ it=proto_tree_add_uint(tree, hf_ldap_response_to, tvb, 0, 0, lcrp->req_frame);
+ PROTO_ITEM_SET_GENERATED(it);
nstime_delta(&ns, &pinfo->fd->abs_ts, &lcrp->req_time);
- proto_tree_add_time(tree, hf_ldap_time, tvb, 0, 0, &ns);
+ it=proto_tree_add_time(tree, hf_ldap_time, tvb, 0, 0, &ns);
+ PROTO_ITEM_SET_GENERATED(it);
}
}
gboolean rest_is_pad, gboolean is_mscldap)
{
int offset = 0;
- gboolean first_time = TRUE;
guint length_remaining;
guint msg_len = 0;
int messageOffset = 0;
gboolean pc, ind = 0;
gint32 ber_tag;
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
- /*
- * This will throw an exception if we don't have any data left.
- * That's what we want. (See "tcp_dissect_pdus()", which is
- * similar)
- */
length_remaining = tvb_ensure_length_remaining(tvb, offset);
if (rest_is_pad && length_remaining < 6) return;
* Now dissect the LDAP message.
*/
- /*dissect_ldap_message(msg_tvb, 0, pinfo, msg_tree, msg_item, first_time, ldap_info, is_mscldap);*/
- ldap_info->first_time= first_time;
ldap_info->is_mscldap = is_mscldap;
pinfo->private_data = ldap_info;
dissect_LDAPMessage_PDU(msg_tvb, pinfo, tree);
offset += msg_len;
- first_time = FALSE;
- }
}
static void
}
}
- while (tvb_reported_length_remaining(tvb, offset) > 0) {
-
- /*
- * This will throw an exception if we don't have any data left.
- * That's what we want. (See "tcp_dissect_pdus()", which is
- * similar, but doesn't have to deal with the SASL issues.
- * XXX - can we make "tcp_dissect_pdus()" provide enough information
- * to the "get_pdu_len" routine so that we could have one dealing
- * with the SASL issues, have that routine deal with SASL and
- * ASN.1, and just use "tcp_dissect_pdus()"?)
- */
length_remaining = tvb_ensure_length_remaining(tvb, offset);
/* It might still be a packet containing a SASL security layer
} else {
/* plain LDAP, so dissect the payload */
dissect_ldap_payload(tvb, pinfo, ldap_tree, ldap_info, FALSE, is_mscldap);
- /* dissect_ldap_payload() has it's own loop so go out here */
- break;
}
- }
}
static int dissect_mscldap_string(tvbuff_t *tvb, int offset, char *str, int maxlen, gboolean prepend_dot)
static guint
-get_sasl_ldap_pdu_len(tvbuff_t *tvb, int offset)
+get_sasl_ldap_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
/* sasl encapsulated ldap is 4 bytes plus the length in size */
return tvb_get_ntohl(tvb, offset)+4;
}
static guint
-get_normal_ldap_pdu_len(tvbuff_t *tvb, int offset)
+get_normal_ldap_pdu_len(packet_info *pinfo _U_, tvbuff_t *tvb, int offset)
{
guint32 len;
gboolean ind;
int data_offset;
/* normal ldap is tag+len bytes plus the length
- * offset==0 is where the tag is
- * offset==1 is where length starts
+ * offset is where the tag is
+ * offset+1 is where length starts
*/
- data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
- return len+data_offset;
+ data_offset=get_ber_length(NULL, tvb, offset+1, &len, &ind);
+ return len+data_offset-offset;
}
static void
return;
}
+static void
+dissect_ldap_oid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ char *oid;
+ const char *oidname;
+
+ /* tvb here contains an ascii string that is really an oid */
+/* XXX we should convert the string oid into a real oid so we can use
+ * proto_tree_add_oid() instead.
+ */
+
+ oid=tvb_get_ephemeral_string(tvb, 0, tvb_length(tvb));
+ if(!oid){
+ return;
+ }
+
+ oidname=get_oid_str_name(oid);
+
+ if(oidname){
+ proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s (%s)",oid,oidname);
+ } else {
+ proto_tree_add_text(tree, tvb, 0, tvb_length(tvb), "OID: %s",oid);
+ }
+}
+
+#define LDAP_ACCESSMASK_ADS_CREATE_CHILD 0x00000001
+static const true_false_string ldap_AccessMask_ADS_CREATE_CHILD_tfs = {
+ "ADS CREATE CHILD is SET",
+ "Ads create child is NOT set",
+};
+
+#define LDAP_ACCESSMASK_ADS_DELETE_CHILD 0x00000002
+static const true_false_string ldap_AccessMask_ADS_DELETE_CHILD_tfs = {
+ "ADS DELETE CHILD is SET",
+ "Ads delete child is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_LIST 0x00000004
+static const true_false_string ldap_AccessMask_ADS_LIST_tfs = {
+ "ADS LIST is SET",
+ "Ads list is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_SELF_WRITE 0x00000008
+static const true_false_string ldap_AccessMask_ADS_SELF_WRITE_tfs = {
+ "ADS SELF WRITE is SET",
+ "Ads self write is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_READ_PROP 0x00000010
+static const true_false_string ldap_AccessMask_ADS_READ_PROP_tfs = {
+ "ADS READ PROP is SET",
+ "Ads read prop is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_WRITE_PROP 0x00000020
+static const true_false_string ldap_AccessMask_ADS_WRITE_PROP_tfs = {
+ "ADS WRITE PROP is SET",
+ "Ads write prop is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_DELETE_TREE 0x00000040
+static const true_false_string ldap_AccessMask_ADS_DELETE_TREE_tfs = {
+ "ADS DELETE TREE is SET",
+ "Ads delete tree is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_LIST_OBJECT 0x00000080
+static const true_false_string ldap_AccessMask_ADS_LIST_OBJECT_tfs = {
+ "ADS LIST OBJECT is SET",
+ "Ads list object is NOT set",
+};
+#define LDAP_ACCESSMASK_ADS_CONTROL_ACCESS 0x00000100
+static const true_false_string ldap_AccessMask_ADS_CONTROL_ACCESS_tfs = {
+ "ADS CONTROL ACCESS is SET",
+ "Ads control access is NOT set",
+};
static void
-dissect_ldap(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+ldap_specific_rights(tvbuff_t *tvb, gint offset, proto_tree *tree, guint32 access)
{
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_CONTROL_ACCESS, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_LIST_OBJECT, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_DELETE_TREE, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_WRITE_PROP, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_READ_PROP, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_SELF_WRITE, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_LIST, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_DELETE_CHILD, tvb, offset, 4, access);
+
+ proto_tree_add_boolean(tree, hf_ldap_AccessMask_ADS_CREATE_CHILD, tvb, offset, 4, access);
+}
+struct access_mask_info ldap_access_mask_info = {
+ "LDAP", /* Name of specific rights */
+ ldap_specific_rights, /* Dissection function */
+ NULL, /* Generic mapping table */
+ NULL /* Standard mapping table */
+};
+
+static void
+dissect_ldap_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_nt_sec_desc(tvb, 0, pinfo, tree, NULL, TRUE, tvb_length(tvb), &ldap_access_mask_info);
+}
+
+static void
+dissect_ldap_sid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ char *tmpstr;
+
+ /* this octet string contains an NT SID */
+ dissect_nt_sid(tvb, 0, tree, "SID", &tmpstr, hf_ldap_sid);
+ ldapvalue_string=tmpstr;
+}
+
+static void
+dissect_ldap_guid(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint8 drep[4] = { 0x10, 0x00, 0x00, 0x00}; /* fake DREP struct */
+ e_uuid_t uuid;
+
+ /* This octet string contained a GUID */
+ dissect_dcerpc_uuid_t(tvb, 0, pinfo, tree, drep, hf_ldap_guid, &uuid);
+
+ ldapvalue_string=ep_alloc(1024);
+ g_snprintf(ldapvalue_string, 1023, "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
+ uuid.Data1, uuid.Data2, uuid.Data3,
+ uuid.Data4[0], uuid.Data4[1],
+ uuid.Data4[2], uuid.Data4[3],
+ uuid.Data4[4], uuid.Data4[5],
+ uuid.Data4[6], uuid.Data4[7]);
+}
+
+static void
+dissect_ldap_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ guint32 sasl_len;
+ guint32 gss_len;
+ guint32 ldap_len;
+ int offset;
+ gboolean ind;
+
ldm_tree = NULL;
- /* Here we must take care of reassembly but this is tricky since
- * depending on whether SASL is present or not, the heuristics
- * will be very different.
+ /* This is a bit tricky. We have to find out whether SASL is used
+ * so that we know how big a header we are supposed to pass
+ * to tcp_dissect_pdus()
*/
- if(ldap_desegment && (tvb_length(tvb)==tvb_reported_length(tvb))){
- guint32 len;
-
- /* check for a SASL header, i.e. four byte integer where the
- * first two bytes are 0x00 and the value is <64k and >2
- * (>2 to fight false positives, 0x00000000 is a common
- * "random" tcp payload)
- * (no SASL ldap PDUs are ever going to be >64k in size?)
- *
- * Following the SASL header is a GSSAPI blob so the next byte
- * is always 0x60. (only true for MS SASL LDAP, there are other
- * blobs that may follow in real-world)
- */
- len=tvb_get_ntohl(tvb, 0);
- if( (len<65535)
- && (len>2)
- && (tvb_get_guint8(tvb, 4)==0x60)){
- if(len<=tvb_length_remaining(tvb, 4)){
- /* we have a full ldap pdu */
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
- return;
- } else {
- /* we have to do reassembly */
- tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
- return;
- }
- }
- /* check if it is a normal BER encoded LDAP packet
- * i.e. first byte is 0x30 followed by a length that is
- * <64k
- * (no ldap PDUs are ever >64kb? )
- */
- if(tvb_get_guint8(tvb, 0)==0x30){
- gboolean ind;
- int data_offset;
-
- /* check that length makes sense */
- data_offset=get_ber_length(NULL, tvb, 1, &len, &ind);
-
- /* dont check ind since indefinite length is never used for ldap (famous last words)*/
- if(len<2 || len>65535){
- return;
- }
-
- if(len<=tvb_length_remaining(tvb, data_offset)){
- /* we have a full ldap pdu */
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
- return;
- } else {
- /* we have to do reassembly */
- tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
- return;
- }
- }
+ /* check for a SASL header, i.e. assume it is SASL if
+ * 1, first four bytes (SASL length) is an integer
+ * with a value that must be <64k and >2
+ * (>2 to fight false positives, 0x00000000 is a common
+ * "random" tcp payload)
+ * (no SASL ldap PDUs are ever going to be >64k in size?)
+ *
+ * Following the SASL header is a GSSAPI blob so the next byte
+ * is always 0x60. (only true for MS SASL LDAP, there are other
+ * blobs that may follow in real-world)
+ *
+ * 2, Then one byte with the value 0x60 indicating the GSSAPI blob
+ *
+ * 3, Then X bytes describing the BER encoded lengtyh of the blob.
+ * This length should point to the same end-of-pdu as 1,
+ *
+ * 4, finally a byte 0x06 indicating that the next object is an OID
+ */
+ sasl_len=tvb_get_ntohl(tvb, 0);
+
+ if( sasl_len<2 ){
+ goto this_was_not_sasl;
}
- dissect_ldap_pdu(tvb, pinfo, tree, FALSE);
+ if(tvb_get_guint8(tvb, 4)!=0x60){
+ goto this_was_not_sasl;
+ }
+
+ offset=get_ber_length(NULL, tvb, 5, &gss_len, &ind);
+ if(sasl_len!=(gss_len+offset-4)){
+ goto this_was_not_sasl;
+ }
+
+ if(tvb_get_guint8(tvb, offset)!=0x06){
+ goto this_was_not_sasl;
+ }
+
+ tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_sasl_ldap_pdu_len, dissect_sasl_ldap_pdu);
+
+
+this_was_not_sasl:
+ /* check if it is a normal BER encoded LDAP packet
+ * i.e. first byte is 0x30 followed by a length that is
+ * <64k
+ * (no ldap PDUs are ever >64kb? )
+ */
+ if(tvb_get_guint8(tvb, 0)!=0x30){
+ goto this_was_not_normal_ldap;
+ }
+
+ /* check that length makes sense */
+ offset=get_ber_length(NULL, tvb, 1, &ldap_len, &ind);
+
+ /* dont check ind since indefinite length is never used for ldap (famous last words)*/
+ if(ldap_len<2){
+ goto this_was_not_normal_ldap;
+ }
+
+ tcp_dissect_pdus(tvb, pinfo, tree, ldap_desegment, 4, get_normal_ldap_pdu_len, dissect_normal_ldap_pdu);
+
+
+this_was_not_normal_ldap:
+
return;
}
FT_STRING, BASE_NONE, NULL, 0x0,
"Client Site name", HFILL }},
+ { &hf_ldap_sid,
+ { "Sid", "ldap.sid",
+ FT_STRING, BASE_NONE, NULL, 0x0,
+ "Sid", HFILL }},
+
{ &hf_mscldap_netlogon_flags_pdc,
{ "PDC", "mscldap.netlogon.flags.pdc", FT_BOOLEAN, 32,
TFS(&tfs_ads_pdc), 0x00000001, "Is this DC a PDC or not?", HFILL }},
{ "NDNC", "mscldap.netlogon.flags.ndnc", FT_BOOLEAN, 32,
TFS(&tfs_ads_ndnc), 0x00000400, "Is this an NDNC dc?", HFILL }},
+ { &hf_ldap_guid,
+ { "GUID", "ldap.guid", FT_GUID, BASE_NONE,
+ NULL, 0, "GUID", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_CREATE_CHILD,
+ { "Create Child", "ldap.AccessMask.ADS_CREATE_CHILD", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_CREATE_CHILD_tfs), LDAP_ACCESSMASK_ADS_CREATE_CHILD, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_DELETE_CHILD,
+ { "Delete Child", "ldap.AccessMask.ADS_DELETE_CHILD", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_DELETE_CHILD_tfs), LDAP_ACCESSMASK_ADS_DELETE_CHILD, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_LIST,
+ { "List", "ldap.AccessMask.ADS_LIST", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_LIST_tfs), LDAP_ACCESSMASK_ADS_LIST, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_SELF_WRITE,
+ { "Self Write", "ldap.AccessMask.ADS_SELF_WRITE", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_SELF_WRITE_tfs), LDAP_ACCESSMASK_ADS_SELF_WRITE, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_READ_PROP,
+ { "Read Prop", "ldap.AccessMask.ADS_READ_PROP", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_READ_PROP_tfs), LDAP_ACCESSMASK_ADS_READ_PROP, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_WRITE_PROP,
+ { "Write Prop", "ldap.AccessMask.ADS_WRITE_PROP", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_WRITE_PROP_tfs), LDAP_ACCESSMASK_ADS_WRITE_PROP, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_DELETE_TREE,
+ { "Delete Tree", "ldap.AccessMask.ADS_DELETE_TREE", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_DELETE_TREE_tfs), LDAP_ACCESSMASK_ADS_DELETE_TREE, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_LIST_OBJECT,
+ { "List Object", "ldap.AccessMask.ADS_LIST_OBJECT", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_LIST_OBJECT_tfs), LDAP_ACCESSMASK_ADS_LIST_OBJECT, "", HFILL }},
+
+ { &hf_ldap_AccessMask_ADS_CONTROL_ACCESS,
+ { "Control Access", "ldap.AccessMask.ADS_CONTROL_ACCESS", FT_BOOLEAN, 32, TFS(&ldap_AccessMask_ADS_CONTROL_ACCESS_tfs), LDAP_ACCESSMASK_ADS_CONTROL_ACCESS, "", HFILL }},
+
#include "packet-ldap-hfarr.c"
};
proto_register_subtree_array(ett, array_length(ett));
- register_dissector("ldap", dissect_ldap, proto_ldap);
+ register_dissector("ldap", dissect_ldap_tcp, proto_ldap);
ldap_module = prefs_register_protocol(proto_ldap, NULL);
prefs_register_bool_preference(ldap_module, "desegment_ldap_messages",
"Reassemble LDAP messages spanning multiple TCP segments",
"Whether the LDAP dissector should reassemble messages spanning multiple TCP segments."
- " To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings, and disable \"Verify length\" in the BER protocol settings",
+ "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
&ldap_desegment);
prefs_register_uint_preference(ldap_module, "tcp.port", "LDAP TCP Port",
"Set the port for LDAP operations",
10, &ldap_tcp_port);
+ prefs_register_obsolete_preference(ldap_module, "max_pdu");
+
proto_cldap = proto_register_protocol(
"Connectionless Lightweight Directory Access Protocol",
"CLDAP", "cldap");
ldap_name_dissector_table = register_dissector_table("ldap.name", "LDAP Attribute Type Dissectors", FT_STRING, BASE_NONE);
-
}
proto_reg_handoff_ldap(void)
{
dissector_handle_t ldap_handle, cldap_handle;
- ldap_handle = create_dissector_handle(dissect_ldap, proto_ldap);
+ ldap_handle = create_dissector_handle(dissect_ldap_tcp, proto_ldap);
dissector_add("tcp.port", ldap_tcp_port, ldap_handle);
dissector_add("tcp.port", TCP_PORT_GLOBALCAT_LDAP, ldap_handle);
gssapi_handle = find_dissector("gssapi");
gssapi_wrap_handle = find_dissector("gssapi_verf");
+ ntlmssp_handle = find_dissector("ntlmssp");
+
/* http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dsml/dsml/ldap_controls_and_session_support.asp */
add_oid_str_name("1.2.840.113556.1.4.319","LDAP_PAGED_RESULT_OID_STRING");
add_oid_str_name("1.2.840.113556.1.4.417","LDAP_SERVER_SHOW_DELETED_OID");
add_oid_str_name("1.2.840.113556.1.4.473","LDAP_SERVER_SORT_OID");
+ add_oid_str_name("1.2.840.113556.1.4.474","LDAP_CONTROL_SORT_RESP_OID");
add_oid_str_name("1.2.840.113556.1.4.521","LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID");
add_oid_str_name("1.2.840.113556.1.4.528","LDAP_SERVER_NOTIFICATION_OID");
add_oid_str_name("1.2.840.113556.1.4.529","LDAP_SERVER_EXTENDED_DN_OID");
add_oid_str_name("1.2.840.113556.1.4.619","LDAP_SERVER_LAZY_COMMIT_OID");
+ add_oid_str_name("1.2.840.113556.1.4.800","LDAP_CAP_ACTIVE_DIRECTORY_OID");
add_oid_str_name("1.2.840.113556.1.4.801","LDAP_SERVER_SD_FLAGS_OID");
+ add_oid_str_name("1.2.840.113556.1.4.804","LDAP_OID_COMPARATOR_OR");
add_oid_str_name("1.2.840.113556.1.4.805","LDAP_SERVER_TREE_DELETE_OID");
add_oid_str_name("1.2.840.113556.1.4.841","LDAP_SERVER_DIRSYNC_OID");
add_oid_str_name("1.2.840.113556.1.4.970 ","None");
add_oid_str_name("1.2.840.113556.1.4.1340","LDAP_SERVER_SEARCH_OPTIONS_OID");
add_oid_str_name("1.2.840.113556.1.4.1413","LDAP_SERVER_PERMISSIVE_MODIFY_OID");
add_oid_str_name("1.2.840.113556.1.4.1504","LDAP_SERVER_ASQ_OID");
+ add_oid_str_name("1.2.840.113556.1.4.1670","LDAP_CAP_ACTIVE_DIRECTORY_V51_OID");
add_oid_str_name("1.2.840.113556.1.4.1781","LDAP_SERVER_FAST_BIND_OID");
+ add_oid_str_name("1.2.840.113556.1.4.1791","LDAP_CAP_ACTIVE_DIRECTORY_LDAP_INTEG_OID");
+ add_oid_str_name("1.2.840.113556.1.4.1851","LDAP_CAP_ACTIVE_DIRECTORY_ADAM_OID");
add_oid_str_name("1.3.6.1.4.1.1466.101.119.1","None");
add_oid_str_name("1.3.6.1.4.1.1466.20037","LDAP_START_TLS_OID");
add_oid_str_name("2.16.840.1.113730.3.4.9","LDAP_CONTROL_VLVREQUEST VLV");
+ add_oid_str_name("2.16.840.1.113730.3.4.10","LDAP_CONTROL_VLVRESPONSE VLV");
register_ldap_name_dissector("netlogon", dissect_NetLogon_PDU, proto_cldap);
+ register_ldap_name_dissector("objectGUID", dissect_ldap_guid, proto_ldap);
+ register_ldap_name_dissector("supportedControl", dissect_ldap_oid, proto_ldap);
+ register_ldap_name_dissector("supportedCapabilities", dissect_ldap_oid, proto_ldap);
+ register_ldap_name_dissector("objectSid", dissect_ldap_sid, proto_ldap);
+ register_ldap_name_dissector("nTSecurityDescriptor", dissect_ldap_nt_sec_desc, proto_ldap);
+
+#include "packet-ldap-dis-tab.c"
+
}