Pretty up the SID dissector ...
[obnox/wireshark/wip.git] / packet-smb.c
index 563cdb3625c66b8ff8f46c54a6fd41eb43c02b85..5f12961e10dae4ef9b025dbea4fb745c639c7d46 100644 (file)
@@ -3,7 +3,7 @@
  * Copyright 1999, Richard Sharpe <rsharpe@ns.aus.com>
  * 2001  Rewrite by Ronnie Sahlberg and Guy Harris
  *
- * $Id: packet-smb.c,v 1.196 2002/01/20 22:12:28 guy Exp $
+ * $Id: packet-smb.c,v 1.219 2002/03/15 19:47:03 sharpe Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@ethereal.com>
 #include <string.h>
 #include <glib.h>
 #include <ctype.h>
-#include "packet.h"
-#include "conversation.h"
+#include <epan/packet.h>
+#include <epan/conversation.h>
 #include "smb.h"
 #include "alignment.h"
-#include "strutil.h"
+#include <epan/strutil.h>
 #include "prefs.h"
 #include "reassemble.h"
 
@@ -538,6 +538,9 @@ static int hf_smb_fs_attr_fc = -1;
 static int hf_smb_fs_attr_vq = -1;
 static int hf_smb_fs_attr_dim = -1;
 static int hf_smb_fs_attr_vic = -1;
+static int hf_smb_quota_flags_deny_disk = -1;
+static int hf_smb_quota_flags_log_limit = -1;
+static int hf_smb_quota_flags_log_warning = -1;
 
 static gint ett_smb = -1;
 static gint ett_smb_hdr = -1;
@@ -562,7 +565,6 @@ static gint ett_smb_lock_type = -1;
 static gint ett_smb_ssetupandxaction = -1;
 static gint ett_smb_optionsup = -1;
 static gint ett_smb_time_date = -1;
-static gint ett_smb_64bit_time = -1;
 static gint ett_smb_move_flags = -1;
 static gint ett_smb_file_attributes = -1;
 static gint ett_smb_search_resume_key = -1;
@@ -606,6 +608,7 @@ static gint ett_smb_acl = -1;
 static gint ett_smb_ace = -1;
 static gint ett_smb_ace_flags = -1;
 static gint ett_smb_sec_desc_type = -1;
+static gint ett_smb_quotaflags = -1;
 
 proto_tree *top_tree=NULL;     /* ugly */
 
@@ -1097,23 +1100,98 @@ dissect_smb_UTIME(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offse
        return offset;
 }
 
-static int
-dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset, char *str, int hf_date)
+#define TIME_FIXUP_CONSTANT (369.0*365.25*24*60*60-(3.0*24*60*60+6.0*60*60))
+
+/*
+ * Translate an 8-byte FILETIME value, given as the upper and lower 32 bits,
+ * to an "nstime_t".
+ * A FILETIME is a 64-bit integer, giving the time since Jan 1, 1601,
+ * midnight "UTC", in 100ns units.
+ * Return TRUE if the conversion succeeds, FALSE otherwise.
+ *
+ * According to the Samba code, it appears to be kludge-GMT (at least for
+ * file listings). This means it's the GMT you get by taking a local time
+ * and adding the server time zone offset.  This is NOT the same as GMT in
+ * some cases.   However, we don't know the server time zone, so we don't
+ * do that adjustment.
+ *
+ * This code is based on the Samba code:
+ *
+ *     Unix SMB/Netbios implementation.
+ *     Version 1.9.
+ *     time handling functions
+ *     Copyright (C) Andrew Tridgell 1992-1998
+ */
+static gboolean
+nt_time_to_nstime(guint32 filetime_high, guint32 filetime_low, nstime_t *tv)
 {
-       proto_item *item = NULL;
-       proto_tree *tree = NULL;
-       nstime_t tv;
+       double d;
+       /* The next two lines are a fix needed for the 
+           broken SCO compiler. JRA. */
+       time_t l_time_min = TIME_T_MIN;
+       time_t l_time_max = TIME_T_MAX;
 
-       /* XXXX we need some way to represent this as a time
-          properly. For now we display everything as 8 bytes*/
+       if (filetime_high == 0)
+               return FALSE;
 
-       if(parent_tree){
-               item = proto_tree_add_text(parent_tree, tvb, offset, 8,
-                       str);
-               tree = proto_item_add_subtree(item, ett_smb_64bit_time);
-       }
+       /*
+        * Get the time as a double, in seconds and fractional seconds.
+        */
+       d = ((double)filetime_high)*4.0*(double)(1<<30);
+       d += filetime_low;
+       d *= 1.0e-7;
+       /* Now adjust by 369 years, to make the seconds since 1970. */
+       d -= TIME_FIXUP_CONSTANT;
+
+       if (!(l_time_min <= d && d <= l_time_max))
+               return FALSE;
+
+       /*
+        * Get the time as seconds and nanoseconds.
+        */
+       tv->secs = d;
+       tv->nsecs = (d - tv->secs)*1000000000;
+
+       return TRUE;
+}
 
-       proto_tree_add_bytes_format(tree, hf_smb_unknown, tvb, offset, 8, tvb_get_ptr(tvb, offset, 8), "%s: can't decode this yet", str);
+int
+dissect_smb_64bit_time(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int hf_date)
+{
+       guint32 filetime_high, filetime_low;
+       nstime_t ts;
+
+       /* XXX there seems also to be another special time value which is fairly common :
+          0x40000000 00000000  
+          the meaning of this one is yet unknown 
+       */
+       if (tree) {
+               filetime_low = tvb_get_letohl(tvb, offset);
+               filetime_high = tvb_get_letohl(tvb, offset + 4);
+               if (filetime_low == 0 && filetime_high == 0) {
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: No time specified (0)",
+                           proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0 && filetime_high==0x80000000){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (relative time)",
+                           proto_registrar_get_name(hf_date));
+               } else if(filetime_low==0xffffffff && filetime_high==0x7fffffff){
+                       proto_tree_add_text(tree, tvb, offset, 8,
+                           "%s: Infinity (absolute time)",
+                           proto_registrar_get_name(hf_date));
+               } else {                        
+                       if (nt_time_to_nstime(filetime_high, filetime_low, &ts)) {
+                               proto_tree_add_time(tree, hf_date, tvb,
+                                   offset, 8, &ts);
+                       } else {
+                               proto_tree_add_text(tree, tvb, offset, 8,
+                                   "%s: Time can't be converted",
+                                   proto_registrar_get_name(hf_date));
+                       }
+               }
+       }
 
        offset += 8;
        return offset;
@@ -2073,7 +2151,7 @@ dissect_negprot_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, in
 
                /* system time */
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                               "System Time", hf_smb_system_time);
+                               hf_smb_system_time);
 
                /* time zone */
                tz = tvb_get_letohs(tvb, offset);
@@ -2679,12 +2757,13 @@ static int
 dissect_close_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* last write time */
@@ -2904,12 +2983,13 @@ static int
 dissect_read_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* read count */
@@ -3033,13 +3113,15 @@ dissect_lock_and_read_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
 static int
 dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
-       guint16 cnt=0, bc;
+       guint32 ofs=0;
+       guint16 cnt=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3048,9 +3130,15 @@ dissect_write_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        offset += 2;
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %d byte%s at offset %d", cnt, 
+                               (cnt == 1) ? "" : "s", ofs);
+
        /* remaining */
        proto_tree_add_item(tree, hf_smb_remaining, tvb, offset, 2, TRUE);
        offset += 2;
@@ -3082,14 +3170,19 @@ static int
 dissect_write_file_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, cnt;
 
        WORD_COUNT;
 
        /* write count */
+       cnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %d byte%s", cnt, (cnt == 1) ? "" : "s");
+
        BYTE_COUNT;
 
        END_OF_SMB
@@ -3101,12 +3194,13 @@ static int
 dissect_lock_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock count */
@@ -3172,8 +3266,7 @@ dissect_create_temporary_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        int fn_len;
        const char *fn;
        guint8 wc;
-       guint16 bc;
-       guint16 fid;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
@@ -3214,12 +3307,13 @@ static int
 dissect_seek_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* Seek Mode */
@@ -3260,12 +3354,13 @@ static int
 dissect_set_information2_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* create time */
@@ -3336,12 +3431,13 @@ dissect_write_and_close_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 {
        guint8 wc;
        guint16 cnt=0;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* write count */
@@ -3400,13 +3496,14 @@ static int
 dissect_read_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
        guint32 to;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3482,12 +3579,13 @@ static int
 dissect_read_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* offset */
@@ -3626,13 +3724,14 @@ static int
 dissect_write_raw_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -3703,13 +3802,14 @@ static int
 dissect_write_mpx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint32 to;
-       guint16 datalen=0, bc;
+       guint16 datalen=0, bc, fid;
        guint8 wc;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* total data length */
@@ -4030,7 +4130,7 @@ static int
 dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff, lt=0;
-       guint16 andxoffset=0, un=0, ln=0, bc;
+       guint16 andxoffset=0, un=0, ln=0, bc, fid;
        guint32 to;
        proto_item *litem = NULL;
        proto_tree *ltree = NULL;
@@ -4059,7 +4159,8 @@ dissect_locking_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
        offset += 2;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        /* lock type */
@@ -4590,7 +4691,8 @@ static int
 dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *smb_tree)
 {
        guint8  wc, cmd=0xff;
-       guint16 andxoffset=0, bc;
+       guint16 andxoffset=0, bc, maxcnt = 0;
+       guint32 ofs = 0;
        smb_info_t *si;
        unsigned int fid;
 
@@ -4625,13 +4727,20 @@ dissect_read_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i
        }
 
        /* offset */
+       ofs = tvb_get_letohl(tvb, offset);
        proto_tree_add_item(tree, hf_smb_offset, tvb, offset, 4, TRUE);
        offset += 4;
 
        /* max count */
+       maxcnt = tvb_get_letohs(tvb, offset);
        proto_tree_add_item(tree, hf_smb_max_count, tvb, offset, 2, TRUE);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %d byte%s at offset %d", maxcnt, 
+                               (maxcnt == 1) ? "" : "s", ofs);
+
        /* min count */
        proto_tree_add_item(tree, hf_smb_min_count, tvb, offset, 2, TRUE);
        offset += 2;
@@ -4710,6 +4819,11 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_len, tvb, offset, 2, datalen);
        offset += 2;
 
+       if (check_col(pinfo->cinfo, COL_INFO))
+               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                               ", %d byte%s", datalen, 
+                               (datalen == 1) ? "" : "s");
+
        /* data offset */
        dataoffset=tvb_get_letohs(tvb, offset);
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
@@ -4725,11 +4839,13 @@ dissect_read_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited
            && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               if (si->sip != NULL && (frame=(guint32)g_hash_table_lookup(
+               gpointer hash_value;
+               if (si->sip != NULL && (hash_value = g_hash_table_lookup(
                                                si->ct->dcerpc_fid_to_frame,
                                                si->sip->extra_info)) != NULL) {
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -4838,6 +4954,8 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        proto_tree_add_uint(tree, hf_smb_data_offset, tvb, offset, 2, dataoffset);
        offset += 2;
 
+       /* FIXME: add byte/offset to COL_INFO */
+
        if(wc==14){
                /* high offset */
                proto_tree_add_item(tree, hf_smb_high_offset, tvb, offset, 4, TRUE);
@@ -4848,11 +4966,13 @@ dissect_write_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
        /* is this part of DCERPC over SMB reassembly?*/
        if(smb_dcerpc_reassembly && !pinfo->fd->flags.visited && (bc<=tvb_length_remaining(tvb, offset)) ){
-               guint32 frame;
-               frame=(guint32)g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
+               gpointer hash_value;
+               hash_value = g_hash_table_lookup(si->ct->dcerpc_fid_to_frame,
                        si->sip->extra_info);
-               if(frame){
+               if(hash_value){
                        fragment_data *fd_head;
+                       guint32 frame = GPOINTER_TO_UINT(hash_value);
+
                        /* first fragment is always from a SMB Trans command and
                           offset 0 of the following read/write SMB commands start
                           BEYOND the first Trans SMB payload. Look for offset
@@ -5191,8 +5311,14 @@ dissect_session_setup_andx_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree
                COUNT_BYTES(dn_len);
 
                if (check_col(pinfo->cinfo, COL_INFO)) {
-                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s@%s",
-                       an,dn);
+                       col_append_fstr(pinfo->cinfo, COL_INFO, ", User: ");
+
+                       if (!dn[0] && !an[0])
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                               "anonymous");
+                       else
+                               col_append_fstr(pinfo->cinfo, COL_INFO, 
+                                               "%s\\%s", dn,an);
                }
 
                /* OS */
@@ -6318,16 +6444,26 @@ dissect_security_information_mask(tvbuff_t *tvb, packet_info *pinfo, proto_tree
        return offset;
 }
 
-static int
+static void
+free_g_string(void *arg)
+{
+       GString *gstring = arg;
+
+       g_string_free(arg, TRUE);
+}
+
+int
 dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, char *name)
 {
        proto_item *item = NULL;
        proto_tree *tree = NULL;
-       int old_offset = offset;
+       int old_offset = offset, sa_offset = offset;
+        guint *s_auths = NULL;
        guint8 revision;
        guint8 num_auth;
+        guint auth = 0;   /* FIXME: What if it is larger than 32-bits */
        int i;
-       char str[256], *strp;
+       GString *gstr;
 
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, -1,
@@ -6341,7 +6477,8 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
        offset += 1;
 
        switch(revision){
-       case 1:  /*only revision of SOD we will se ?*/
+       case 1:  
+       case 2:  /* Not sure what the different revision numbers mean */
          /* number of authorities*/
          num_auth = tvb_get_guint8(tvb, offset);
          proto_tree_add_item(tree, hf_smb_sid_num_auth, tvb, offset, 1, TRUE);
@@ -6350,27 +6487,47 @@ dissect_nt_sid(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
          /* XXX perhaps we should have these thing searchable?
             a new FT_xxx thingie? SMB is quite common!*/
          /* identifier authorities */
-         strp=str;
-         *strp=0;
+
+          /* FIXME: We should dynamically allocate the authorities array,
+             which is only one thing. Then we don't have to allocate two
+             strings below etc ...
+          */
+
          for(i=0;i<6;i++){
-           sprintf(strp,"%s%d-",strp,tvb_get_guint8(tvb, offset));
+           auth = (auth << 8) + tvb_get_guint8(tvb, offset);
+
            offset++;
          }
+
+         proto_tree_add_text(tree, tvb, offset - 6, 6, "Authority: %u", auth);
+
+          sa_offset = offset;
+
+         CLEANUP_PUSH(free, s_auths);
+
+          s_auths = g_malloc(sizeof(guint) * num_auth);
+
          /* sub authorities */
          for(i=0;i<num_auth;i++){
            /* XXX should not be letohl but native byteorder according to
               samba header files. considering that all non-x86 NT ports
               are dead we can (?) assume that non le byte encodings
               will be "uncommon"?*/
-           sprintf(strp,"%s%d-",strp,tvb_get_letohl(tvb, offset));
-           offset+=4;
+              s_auths[i] = tvb_get_letohl(tvb, offset);
+              offset+=4;
          }
-         /* strip trailing '-'*/
-         str[strlen(str)-1]=0;
 
-         proto_tree_add_text(tree, tvb, offset-6-num_auth*4, 6+num_auth*4, "SID: %s", str);
-         proto_item_append_text(item, ": %s", str);
-  
+         CLEANUP_CALL_AND_POP;
+
+          gstr = g_string_new("");
+          
+          for (i = 0; i < num_auth; i++)
+              g_string_sprintfa(gstr, (i>0 ? "-%u" : "%u"), s_auths[i]);
+
+          proto_tree_add_text(tree, tvb, sa_offset, num_auth * 4, "Sub-authorities: %s", gstr->str);
+
+         proto_item_append_text(item, ": S-1-%u-%s", auth, gstr->str);  
+
        }
 
        proto_item_set_len(item, offset-old_offset);
@@ -6415,9 +6572,11 @@ static const true_false_string tfs_ace_flags_failed_access = {
 };
 
 #define APPEND_ACE_TEXT(flag, item, string) \
-        if(item && flag){                                     \
-                  proto_item_append_text(item, string);       \
-        }
+       if(flag){                                                       \
+               if(item)                                                \
+                       proto_item_append_text(item, string, sep);      \
+               sep = ", ";                                             \
+       }
 
 static int
 dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree)
@@ -6425,41 +6584,42 @@ dissect_nt_v2_ace_flags(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tre
        proto_item *item = NULL;
        proto_tree *tree = NULL;
        guint8 mask;
+       char *sep = " ";
 
        mask = tvb_get_guint8(tvb, offset);
        if(parent_tree){
                item = proto_tree_add_text(parent_tree, tvb, offset, 1,
-                                          "NT ACE Flags:0x%02x", mask);
+                                          "NT ACE Flags: 0x%02x", mask);
                tree = proto_item_add_subtree(item, ett_smb_ace_flags);
        }
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_failed_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x80, item, "  Failed Access,");
+       APPEND_ACE_TEXT(mask&0x80, item, "%sFailed Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_successful_access,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x40, item, "  Successful Access,");
+       APPEND_ACE_TEXT(mask&0x40, item, "%sSuccessful Access");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherited_ace,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x10, item, "  Inherited ACE,");
+       APPEND_ACE_TEXT(mask&0x10, item, "%sInherited ACE");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_inherit_only,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x08, item, "  Inherit Only,");
+       APPEND_ACE_TEXT(mask&0x08, item, "%sInherit Only");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_non_propagate_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x04, item, "  No Propagate Inherit,");
+       APPEND_ACE_TEXT(mask&0x04, item, "%sNo Propagate Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_container_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x02, item, "  Container Inherit,");
+       APPEND_ACE_TEXT(mask&0x02, item, "%sContainer Inherit");
 
        proto_tree_add_boolean(tree, hf_smb_ace_flags_object_inherit,
                       tvb, offset, 1, mask);
-       APPEND_ACE_TEXT(mask&0x01, item, "  Object Inherit,");
+       APPEND_ACE_TEXT(mask&0x01, item, "%sObject Inherit");
 
 
        offset += 1;
@@ -6497,7 +6657,7 @@ dissect_nt_v2_ace(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *par
        offset = dissect_nt_access_mask(tvb, pinfo, tree, offset);
 
        /* SID */
-       offset = dissect_nt_sid(tvb, pinfo, offset, tree, "SID");
+       offset = dissect_nt_sid(tvb, pinfo, offset, tree, "ACE");
 
        proto_item_set_len(item, offset-old_offset);
        return offset;
@@ -6526,6 +6686,7 @@ dissect_nt_acl(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent
 
        switch(revision){
        case 2:  /* only version we will ever see of this structure?*/
+       case 3:
          /* size */
          proto_tree_add_item(tree, hf_smb_acl_size, tvb, offset, 2, TRUE);
          offset += 2;
@@ -6646,7 +6807,7 @@ dissect_nt_sec_desc_type(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tr
 }
 
 
-static int
+int
 dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *parent_tree, int len)
 {
        proto_item *item = NULL;
@@ -6677,22 +6838,22 @@ dissect_nt_sec_desc(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *p
 
          /* offset to owner sid */
          owner_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID : %d", owner_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to owner SID: %d", owner_sid_offset);
          offset += 4;
 
          /* offset to group sid */
          group_sid_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID : %d", group_sid_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to group SID: %d", group_sid_offset);
          offset += 4;
 
          /* offset to sacl */
          sacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL : %d", sacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to SACL: %d", sacl_offset);
          offset += 4;
 
          /* offset to dacl */
          dacl_offset = tvb_get_letohl(tvb, offset);
-         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL : %d", dacl_offset);
+         proto_tree_add_text(tree, tvb, offset, 4, "Offset to DACL: %d", dacl_offset);
          offset += 4;
 
          /*owner SID*/
@@ -6857,9 +7018,12 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                break;
        case NT_TRANS_IOCTL:
                break;
-       case NT_TRANS_SSD:
+       case NT_TRANS_SSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6869,14 +7033,18 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                /* security information */
                offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
                break;
+       }
        case NT_TRANS_NOTIFY:
                break;
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
-       case NT_TRANS_QSD:
+       case NT_TRANS_QSD: {
+               guint16 fid;
+
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* 2 reserved bytes */
@@ -6887,6 +7055,7 @@ dissect_nt_trans_param_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset = dissect_security_information_mask(tvb, pinfo, tree, offset);
                break;
        }
+       }
 
        return offset;
 }
@@ -6911,13 +7080,16 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
        switch(ntd->subcmd){
        case NT_TRANS_CREATE:
                break;
-       case NT_TRANS_IOCTL:
+       case NT_TRANS_IOCTL: {
+               guint16 fid;
+
                /* function code */
                proto_tree_add_item(tree, hf_smb_nt_ioctl_function_code, tvb, offset, 4, TRUE);
                offset += 4;
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* isfsctl */
@@ -6928,14 +7100,18 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset = dissect_nt_ioctl_flags(tvb, pinfo, tree, offset);
 
                break;
+       }
        case NT_TRANS_SSD:
                break;
-       case NT_TRANS_NOTIFY:
+       case NT_TRANS_NOTIFY: {
+               guint16 fid;
+
                /* completion filter */
                offset = dissect_nt_notify_completion_filter(tvb, pinfo, tree, offset);
 
                /* fid */
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                offset += 2;
 
                /* watch tree */
@@ -6947,6 +7123,7 @@ dissect_nt_trans_setup_request(tvbuff_t *tvb, packet_info *pinfo, int offset, pr
                offset += 1;
 
                break;
+       }
        case NT_TRANS_RENAME:
                /* XXX not documented */
                break;
@@ -7273,19 +7450,19 @@ dissect_nt_trans_param_response(tvbuff_t *tvb, packet_info *pinfo, int offset, p
 
                /* create time */
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Create Time", hf_smb_create_time);
+                       hf_smb_create_time);
        
                /* access time */
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Access Time", hf_smb_access_time);
+                       hf_smb_access_time);
        
                /* last write time */
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Write Time", hf_smb_last_write_time);
+                       hf_smb_last_write_time);
        
                /* last change time */
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Change Time", hf_smb_change_time);
+                       hf_smb_change_time);
        
                /* Extended File Attributes */
                offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
@@ -7560,9 +7737,9 @@ dissect_nt_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                }
                
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
+               add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
                pinfo->fragmented = FALSE;
        }
 
@@ -7668,12 +7845,13 @@ dissect_write_print_file_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
 {
        int cnt;
        guint8 wc;
-       guint16 bc;
+       guint16 bc, fid;
 
        WORD_COUNT;
 
        /* fid */
-       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+       fid = tvb_get_letohs(tvb, offset);
+       add_fid(tvb, pinfo, tree, offset, 2, fid);
        offset += 2;
 
        BYTE_COUNT;
@@ -7970,19 +8148,19 @@ dissect_nt_create_andx_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
 
        /* create time */
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+               hf_smb_create_time);
        
        /* access time */
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+               hf_smb_access_time);
        
        /* last write time */
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
-       
+               hf_smb_last_write_time);
+
        /* last change time */
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+               hf_smb_change_time);
        
        /* Extended File Attributes */
        offset = dissect_file_ext_attr(tvb, pinfo, tree, offset);
@@ -8042,6 +8220,7 @@ static const value_string trans2_cmd_vals[] = {
        { 0x01,         "FIND_FIRST2" },
        { 0x02,         "FIND_NEXT2" },
        { 0x03,         "QUERY_FS_INFORMATION" },
+       { 0x04,         "QUOTAS" },
        { 0x05,         "QUERY_PATH_INFORMATION" },
        { 0x06,         "SET_PATH_INFORMATION" },
        { 0x07,         "QUERY_FILE_INFORMATION" },
@@ -8133,6 +8312,7 @@ static const value_string qfsi_vals[] = {
        { 0x0103,       "Query FS Size Info"},
        { 0x0104,       "Query FS Device Info"},
        { 0x0105,       "Query FS Attribute Info"},
+       { 1006,         "Query FS Quota Info"},
        {0, NULL}
 };
 
@@ -8507,10 +8687,13 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                }
 
                break;
-       case 0x07:      /*TRANS2_QUERY_FILE_INFORMATION*/
+       case 0x07: {    /*TRANS2_QUERY_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8522,10 +8705,14 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(2);
                
                break;
-       case 0x08:      /*TRANS2_SET_FILE_INFORMATION*/
+       }
+       case 0x08: {    /*TRANS2_SET_FILE_INFORMATION*/
+               guint16 fid;
+
                /* fid */
                CHECK_BYTE_COUNT_TRANS(2);
-               proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+               fid = tvb_get_letohs(tvb, offset);
+               add_fid(tvb, pinfo, tree, offset, 2, fid);
                COUNT_BYTES_TRANS(2);
 
                /* level of interest */
@@ -8542,6 +8729,7 @@ dissect_transaction2_request_parameters(tvbuff_t *tvb, packet_info *pinfo,
                COUNT_BYTES_TRANS(2);
 
                break;
+       }
        case 0x09:      /*TRANS2_FSCTL*/
        case 0x0a:      /*TRANS2_IOCTL2*/
                /* these calls have no parameter block in the request */
@@ -9068,25 +9256,25 @@ dissect_4_2_14_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create", hf_smb_create_time);
+               hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+               hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+               hf_smb_change_time);
        *bcp -= 8;
        
        /* File Attributes */
@@ -9628,8 +9816,12 @@ dissect_transaction_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                offset += 2;
 
                if(si->cmd==SMB_COM_TRANSACTION2){
+                       guint16 fid;
+
                        /* fid */
-                       proto_tree_add_item(tree, hf_smb_fid, tvb, offset, 2, TRUE);
+                       fid = tvb_get_letohs(tvb, offset);
+                       add_fid(tvb, pinfo, tree, offset, 2, fid);
+
                        offset += 2;
                }
 
@@ -10162,25 +10354,25 @@ dissect_4_3_4_4(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+               hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+               hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+               hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10273,25 +10465,25 @@ dissect_4_3_4_5(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+               hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+               hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+               hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10389,25 +10581,25 @@ dissect_4_3_4_6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
        /* create time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Create Time", hf_smb_create_time);
+               hf_smb_create_time);
        *bcp -= 8;
        
        /* access time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Access Time", hf_smb_access_time);
+               hf_smb_access_time);
        *bcp -= 8;
        
        /* last write time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Write Time", hf_smb_last_write_time);
+               hf_smb_last_write_time);
        *bcp -= 8;
        
        /* last change time */
        CHECK_BYTE_COUNT_SUBR(8);
        offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-               "Change Time", hf_smb_change_time);
+               hf_smb_change_time);
        *bcp -= 8;
        
        /* end of file */
@@ -10694,6 +10886,66 @@ dissect_device_characteristics(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pa
        return offset;
 }
 
+/* dissect 4 bytes specifying the number of 256 byte blocks for a quota limit */
+static void
+dissect_quota_32bit(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset,
+               char *str)
+{ 
+       guint32 quota;
+       int i;
+       char *prefix = "KMGTPE";
+
+       quota = tvb_get_letohl(tvb, offset);
+
+       /* divide by four to get number of KB*/
+       quota >>= 2;
+
+       /* divide by 1024 until the result is less than 1024 */
+       i=0;
+       while( quota>1023 ){
+               i++;
+               quota >>= 10;
+       }
+
+       proto_tree_add_text(tree, tvb, offset, 4,
+                       "%s is %d%cB",str, quota, prefix[i]);
+}
+
+
+static const true_false_string tfs_quota_flags_deny_disk = {
+       "DENY DISK SPACE for users exceeding quota limit",
+       "Do NOT deny disk space for users exceeding quota limit"
+};
+static const true_false_string tfs_quota_flags_log_limit = {
+       "LOG EVENT when a user exceeds their QUOTA LIMIT",
+       "Do NOT log event when a user exceeds their quota limit"
+};
+static const true_false_string tfs_quota_flags_log_warning = {
+       "LOG EVENT when a user exceeds their WARNING LEVEL",
+       "Do NOT log event when a user exceeds their warning level"
+};
+static void
+dissect_quota_flags(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, int offset)
+{
+       guint8 mask;
+       proto_item *item = NULL;
+       proto_tree *tree = NULL;
+
+       mask = tvb_get_guint8(tvb, offset);
+
+       if(parent_tree){
+               item = proto_tree_add_text(parent_tree, tvb, offset, 1,
+                       "Quota Flags: 0x%02x", mask);
+               tree = proto_item_add_subtree(item, ett_smb_quotaflags);
+       }
+
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_limit,
+               tvb, offset, 1, mask);
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_log_warning,
+               tvb, offset, 1, mask);
+       proto_tree_add_boolean(tree, hf_smb_quota_flags_deny_disk,
+               tvb, offset, 1, mask);
+}
 
 /*dissect the data block for TRANS2_QUERY_FS_INFORMATION*/
 static int
@@ -10760,7 +11012,7 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                /* create time */
                CHECK_BYTE_COUNT_TRANS_SUBR(8);
                offset = dissect_smb_64bit_time(tvb, pinfo, tree, offset,
-                       "Create Time", hf_smb_create_time);
+                       hf_smb_create_time);
                *bcp -= 8;
        
                /* volume serial number */
@@ -10848,6 +11100,46 @@ dissect_qfsi_vals(tvbuff_t * tvb, packet_info * pinfo, proto_tree * tree,
                COUNT_BYTES_TRANS_SUBR(fn_len);
 
                break;
+       case 1006:      /* QUERY_FS_QUOTA_INFO */
+               /* first 25 bytes are unknown */
+               CHECK_BYTE_COUNT_TRANS_SUBR(25);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 25, TRUE);
+               COUNT_BYTES_TRANS_SUBR(25);
+
+               /* This really calls for a separate routing, but this will do for testing */
+               /* number of 256byte blocks for WARNING LEVEL, 32bit integer */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               dissect_quota_32bit(tvb, pinfo, tree, offset, "Default (Soft) Quota Warning Level");
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* these 4 bytes are unknown */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 4, TRUE);
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* number of 256byte blocks for QUOTA LIMIT, 64bit integer */
+               CHECK_BYTE_COUNT_TRANS_SUBR(4);
+               dissect_quota_32bit(tvb, pinfo, tree, offset, "Default (Hard) Quota Limit");
+               COUNT_BYTES_TRANS_SUBR(4);
+
+               /* these 3 bytes are unknown */
+               CHECK_BYTE_COUNT_TRANS_SUBR(3);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 3, TRUE);
+               COUNT_BYTES_TRANS_SUBR(3);
+
+               /* one byte of quota flags */
+               CHECK_BYTE_COUNT_TRANS_SUBR(1);
+               dissect_quota_flags(tvb, pinfo, tree, offset);
+               COUNT_BYTES_TRANS_SUBR(1);
+
+               /* these 7 bytes are unknown */
+               CHECK_BYTE_COUNT_TRANS_SUBR(7);
+               proto_tree_add_item(tree, hf_smb_unknown, tvb,
+                           offset, 7, TRUE);
+               COUNT_BYTES_TRANS_SUBR(7);
        }
  
        return offset;
@@ -11352,9 +11644,9 @@ dissect_transaction_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree
                }
                
                pd_tvb = tvb_new_real_data(r_fd->data, r_fd->datalen,
-                                            r_fd->datalen, "Reassembled SMB");
+                                            r_fd->datalen);
                tvb_set_child_real_data_tvbuff(tvb, pd_tvb);
-               pinfo->fd->data_src = g_slist_append(pinfo->fd->data_src, pd_tvb);
+               add_new_data_source(pinfo->fd, pd_tvb, "Reassembled SMB");
                pinfo->fragmented = FALSE;
        }
 
@@ -12387,7 +12679,8 @@ const value_string DOS_errors[] = {
   {SMBE_nosuchshare, "Requested share does not exist"},
   {SMBE_filexists, "File in operation already exists"},
   {SMBE_cannotopen, "Cannot open the file specified"},
-  {SMBE_unknownlevel, "Unknown level??"},
+  {SMBE_unknownlevel, "Unknown info level"},
+  {SMBE_invalidname, "Invalid name"},
   {SMBE_badpipe, "Named pipe invalid"},
   {SMBE_pipebusy, "All instances of pipe are busy"},
   {SMBE_pipeclosing, "Named pipe close in progress"},
@@ -12407,6 +12700,7 @@ const value_string DOS_errors[] = {
   {SMBE_invalidenvironment, "Invalid environment"},
   {SMBE_printerdriverinuse, "Printer driver in use"},
   {SMBE_invalidparam, "Invalid parameter"},
+  {SMBE_invalidformsize, "Invalid form size"},
   {0, NULL}
   };
 
@@ -12506,6 +12800,117 @@ static char *decode_smb_error(guint8 errcls, guint16 errcode)
 
 }
 
+
+/* These are the MS country codes from www.unicode.org/unicode/onlinedat/countries.html
+   For countries that share teh same number I choose to use only the name of the largest
+   country. Appologies for this. If this offends you, here is the table to change that.
+
+  There might be more info in winnls.h for those that have wincompilers
+*/
+const value_string ms_country_codes[] = {
+       {  1,   "USA"},
+       {  2,   "Canada"},
+       {  7,   "Russia"},
+       { 20,   "Egypt"},
+       { 27,   "South Africa"},
+       { 30,   "Greece"},
+       { 31,   "Netherlands"},
+       { 32,   "Belgium"},
+       { 33,   "France"},
+       { 34,   "Spain"},
+       { 36,   "Hungary"},
+       { 39,   "Italy"},
+       { 40,   "Romania"},
+       { 41,   "Switzerland"},
+       { 43,   "Austria"},
+       { 44,   "United Kingdom"},
+       { 45,   "Denmark"},
+       { 46,   "Sweden"},
+       { 47,   "Norway"},
+       { 48,   "Poland"},
+       { 49,   "Germany"},
+       { 51,   "Peru"},
+       { 52,   "Mexico"},
+       { 54,   "Argentina"},
+       { 55,   "Brazil"},
+       { 56,   "Chile"},
+       { 57,   "Colombia"},
+       { 58,   "Venezuela"},
+       { 60,   "Malaysia"},
+       { 62,   "Australia"},
+       { 63,   "Philippines"},
+       { 64,   "New Zealand"},
+       { 65,   "Singapore"},
+       { 66,   "Thailand"},
+       { 81,   "Japan"},
+       { 82,   "South Korea"},
+       { 84,   "Viet Nam"},
+       { 86,   "China"},
+       { 90,   "Turkey"},
+       { 91,   "India"},
+       { 92,   "Pakistan"},
+       {212,   "Morocco"},
+       {213,   "Algeria"},
+       {216,   "Tunisia"},
+       {218,   "Libya"},
+       {254,   "Kenya"},
+       {263,   "Zimbabwe"},
+       {298,   "Faroe Islands"},
+       {351,   "Portugal"},
+       {352,   "Luxembourg"},
+       {353,   "Ireland"},
+       {354,   "Iceland"},
+       {355,   "Albania"},
+       {358,   "Finland"},
+       {359,   "Bulgaria"},
+       {370,   "Lithuania"},
+       {371,   "Latvia"},
+       {372,   "Estonia"},
+       {374,   "Armenia"},
+       {375,   "Belarus"},
+       {380,   "Ukraine"},
+       {381,   "Serbia"},
+       {385,   "Croatia"},
+       {386,   "Slovenia"},
+       {389,   "Macedonia"},
+       {420,   "Czech Republic"},
+       {421,   "Slovak Republic"},
+       {501,   "Belize"},
+       {502,   "Guatemala"},
+       {503,   "El Salvador"},
+       {504,   "Honduras"},
+       {505,   "Nicaragua"},
+       {506,   "Costa Rica"},
+       {507,   "Panama"},
+       {591,   "Bolivia"},
+       {593,   "Ecuador"},
+       {595,   "Paraguay"},
+       {598,   "Uruguay"},
+       {673,   "Brunei Darussalam"},
+       {852,   "Hong Kong"},
+       {853,   "Macau"},
+       {886,   "Taiwan"},
+       {960,   "Maldives"},
+       {961,   "Lebanon"},
+       {962,   "Jordan"},
+       {963,   "Syria"},
+       {964,   "Iraq"},
+       {965,   "Kuwait"},
+       {966,   "Saudi Arabia"},
+       {967,   "Yemen"},
+       {968,   "Oman"},
+       {972,   "Israel"},
+       {973,   "Bahrain/United Arab Emirates"},
+       {974,   "Qatar"},
+       {976,   "Mongolia"},
+       {981,   "Iran"},
+       {994,   "Azerbaijan"},
+       {995,   "Georgia"},
+       {996,   "Kyrgyzstan"},
+
+       {0,     NULL}
+};
+
 /*
  * NT error codes.
  *
@@ -13712,22 +14117,50 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                        */
                        sip=g_hash_table_lookup(si.ct->unmatched, (void *)pid_mid);
                        if(sip!=NULL){
-                               if(si.request){
-                                       /* ok, we are processing an SMB
-                                          request but there was already
-                                          another "identical" smb resuest
-                                          we had not matched yet.
-                                          This must mean that either we have
-                                          a retransmission or that the
-                                          response to the previous one was
-                                          lost and the client has reused
-                                          the MID for this conversation.
-                                          In either case it's not much more
-                                          we can do than forget the old
-                                          request and concentrate on the 
+                               gboolean cmd_match=FALSE;
+
+                               /*
+                                * Make sure the SMB we found was the
+                                * same command, or a different command
+                                * that's another valid type of reply
+                                * to that command.
+                                */
+                               if(si.cmd==sip->cmd){
+                                       cmd_match=TRUE;
+                               }
+                               else if(si.cmd==SMB_COM_NT_CANCEL){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_TRANSACTION)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_TRANSACTION2_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_TRANSACTION2)){
+                                       cmd_match=TRUE;
+                               }
+                               else if((si.cmd==SMB_COM_NT_TRANSACT_SECONDARY) 
+                                    && (sip->cmd==SMB_COM_NT_TRANSACT)){
+                                       cmd_match=TRUE;
+                               }
+
+                               if( (si.request) || (!cmd_match) ) {
+                                       /* If we are processing an SMB request but there was already
+                                          another "identical" smb resuest we had not matched yet.
+                                          This must mean that either we have a retransmission or that the
+                                          response to the previous one was lost and the client has reused
+                                          the MID for this conversation. In either case it's not much more
+                                          we can do than forget the old request and concentrate on the 
                                           present one instead.
+
+                                          We also do this cleanup if we see that the cmd in the original
+                                          request in sip->cmd is not compatible with the current cmd.
+                                          This is to prevent matching errors such as if there were two
+                                          SMBs of different cmds but with identical MID and PID values and
+                                          if ethereal lost the first reply and the second request.
                                        */
                                        g_hash_table_remove(si.ct->unmatched, (void *)pid_mid);
+                                       sip=NULL; /* XXX should free it as well */
                                } else {
                                        /* we have found a response to some request we have seen earlier.
                                           What we do now depends on whether this is the first response
@@ -13759,6 +14192,7 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                sip = g_mem_chunk_alloc(smb_saved_info_chunk);
                                sip->frame_req = pinfo->fd->num;
                                sip->frame_res = 0;
+                               sip->cmd = si.cmd;
                                sip->extra_info = NULL;
                                g_hash_table_insert(si.ct->unmatched, (void *)pid_mid, sip);
                        }
@@ -13904,7 +14338,8 @@ dissect_smb(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree)
                                 */
                                col_append_fstr(
                                        pinfo->cinfo, COL_INFO, ", Error: %s",
-                                       val_to_str(nt_status, NT_errors, "%s"));
+                                       val_to_str(nt_status, NT_errors,
+                                           "Unknown (0x%08X)"));
                        }
                } else {
                        /*
@@ -14078,7 +14513,7 @@ proto_register_smb(void)
                NULL, 0, "Unique token identifying this session", HFILL }},
 
        { &hf_smb_server_timezone,
-               { "Time Zone", "smb.server.timezone", FT_INT16, BASE_DEC,
+               { "Time Zone", "smb.server_timezone", FT_INT16, BASE_DEC,
                NULL, 0, "Current timezone at server.", HFILL }},
 
        { &hf_smb_encryption_key_length,
@@ -14098,7 +14533,7 @@ proto_register_smb(void)
                NULL, 0, "Maximum raw buffer size", HFILL }},
 
        { &hf_smb_server_guid,
-               { "Server GUID", "smb.server.guid", FT_BYTES, BASE_HEX,
+               { "Server GUID", "smb.server_guid", FT_BYTES, BASE_HEX,
                NULL, 0, "Globally unique identifier for this server", HFILL }},
 
        { &hf_smb_security_blob_len,
@@ -14154,79 +14589,79 @@ proto_register_smb(void)
                NULL, 0, "Current time at server, SMB_TIME format", HFILL }},
 
        { &hf_smb_server_cap_raw_mode,
-               { "Raw Mode", "smb.server.cap.raw_mode", FT_BOOLEAN, 32,
+               { "Raw Mode", "smb.server_cap.raw_mode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_raw_mode), SERVER_CAP_RAW_MODE, "Are Raw Read and Raw Write supported?", HFILL }},
 
        { &hf_smb_server_cap_mpx_mode,
-               { "MPX Mode", "smb.server.cap.mpx_mode", FT_BOOLEAN, 32,
+               { "MPX Mode", "smb.server_cap.mpx_mode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_mpx_mode), SERVER_CAP_MPX_MODE, "Are Read Mpx and Write Mpx supported?", HFILL }},
 
        { &hf_smb_server_cap_unicode,
-               { "Unicode", "smb.server.cap.unicode", FT_BOOLEAN, 32,
+               { "Unicode", "smb.server_cap.unicode", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_unicode), SERVER_CAP_UNICODE, "Are Unicode strings supported?", HFILL }},
 
        { &hf_smb_server_cap_large_files,
-               { "Large Files", "smb.server.cap.large_files", FT_BOOLEAN, 32,
+               { "Large Files", "smb.server_cap.large_files", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_files), SERVER_CAP_LARGE_FILES, "Are large files (>4GB) supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_smbs,
-               { "NT SMBs", "smb.server.cap.nt_smbs", FT_BOOLEAN, 32,
+               { "NT SMBs", "smb.server_cap.nt_smbs", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_smbs), SERVER_CAP_NT_SMBS, "Are NT SMBs supported?", HFILL }},
 
        { &hf_smb_server_cap_rpc_remote_apis,
-               { "RPC Remote APIs", "smb.server.cap.rpc_remote_apis", FT_BOOLEAN, 32,
+               { "RPC Remote APIs", "smb.server_cap.rpc_remote_apis", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_rpc_remote_apis), SERVER_CAP_RPC_REMOTE_APIS, "Are RPC Remote APIs supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_status,
-               { "NT Status Codes", "smb.server.cap.nt_status", FT_BOOLEAN, 32,
+               { "NT Status Codes", "smb.server_cap.nt_status", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_status), SERVER_CAP_STATUS32, "Are NT Status Codes supported?", HFILL }},
 
        { &hf_smb_server_cap_level_ii_oplocks,
-               { "Level 2 Oplocks", "smb.server.cap.level_2_oplocks", FT_BOOLEAN, 32,
+               { "Level 2 Oplocks", "smb.server_cap.level_2_oplocks", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_level_ii_oplocks), SERVER_CAP_LEVEL_II_OPLOCKS, "Are Level 2 oplocks supported?", HFILL }},
 
        { &hf_smb_server_cap_lock_and_read,
-               { "Lock and Read", "smb.server.cap.lock_and_read", FT_BOOLEAN, 32,
+               { "Lock and Read", "smb.server_cap.lock_and_read", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_lock_and_read), SERVER_CAP_LOCK_AND_READ, "Is Lock and Read supported?", HFILL }},
 
        { &hf_smb_server_cap_nt_find,
-               { "NT Find", "smb.server.cap.nt_find", FT_BOOLEAN, 32,
+               { "NT Find", "smb.server_cap.nt_find", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_nt_find), SERVER_CAP_NT_FIND, "Is NT Find supported?", HFILL }},
 
        { &hf_smb_server_cap_dfs,
-               { "Dfs", "smb.server.cap.dfs", FT_BOOLEAN, 32,
+               { "Dfs", "smb.server_cap.dfs", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_dfs), SERVER_CAP_DFS, "Is Dfs supported?", HFILL }},
 
        { &hf_smb_server_cap_infolevel_passthru,
-               { "Infolevel Passthru", "smb.server.cap.infolevel_passthru", FT_BOOLEAN, 32,
+               { "Infolevel Passthru", "smb.server_cap.infolevel_passthru", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_infolevel_passthru), SERVER_CAP_INFOLEVEL_PASSTHRU, "Is NT information level request passthrough supported?", HFILL }},
 
        { &hf_smb_server_cap_large_readx,
-               { "Large ReadX", "smb.server.cap.large_readx", FT_BOOLEAN, 32,
+               { "Large ReadX", "smb.server_cap.large_readx", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_readx), SERVER_CAP_LARGE_READX, "Is Large Read andX supported?", HFILL }},
 
        { &hf_smb_server_cap_large_writex,
-               { "Large WriteX", "smb.server.cap.large_writex", FT_BOOLEAN, 32,
+               { "Large WriteX", "smb.server_cap.large_writex", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_large_writex), SERVER_CAP_LARGE_WRITEX, "Is Large Write andX supported?", HFILL }},
 
        { &hf_smb_server_cap_unix,
-               { "UNIX", "smb.server.cap.unix", FT_BOOLEAN, 32,
+               { "UNIX", "smb.server_cap.unix", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_unix), SERVER_CAP_UNIX , "Are UNIX extensions supported?", HFILL }},
 
        { &hf_smb_server_cap_reserved,
-               { "Reserved", "smb.server.cap.reserved", FT_BOOLEAN, 32,
+               { "Reserved", "smb.server_cap.reserved", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_reserved), SERVER_CAP_RESERVED, "RESERVED", HFILL }},
 
        { &hf_smb_server_cap_bulk_transfer,
-               { "Bulk Transfer", "smb.server.cap.bulk_transfer", FT_BOOLEAN, 32,
+               { "Bulk Transfer", "smb.server_cap.bulk_transfer", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_bulk_transfer), SERVER_CAP_BULK_TRANSFER, "Are Bulk Read and Bulk Write supported?", HFILL }},
 
        { &hf_smb_server_cap_compressed_data,
-               { "Compressed Data", "smb.server.cap.compressed_data", FT_BOOLEAN, 32,
+               { "Compressed Data", "smb.server_cap.compressed_data", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_compressed_data), SERVER_CAP_COMPRESSED_DATA, "Is compressed data transfer supported?", HFILL }},
 
        { &hf_smb_server_cap_extended_security,
-               { "Extended Security", "smb.server.cap.extended_security", FT_BOOLEAN, 32,
+               { "Extended Security", "smb.server_cap.extended_security", FT_BOOLEAN, 32,
                TFS(&tfs_server_cap_extended_security), SERVER_CAP_EXTENDED_SECURITY, "Are Extended security exchanges supported?", HFILL }},
 
        { &hf_smb_system_time,
@@ -14314,91 +14749,91 @@ proto_register_smb(void)
                NULL, 0, "FID: File ID", HFILL }},
 
        { &hf_smb_file_attr_read_only_16bit,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 16,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_read_only_8bit,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 8,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_16bit,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 16,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_hidden_8bit,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 8,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_16bit,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 16,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_system_8bit,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 8,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_16bit,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 16,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_attr_volume_8bit,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 8,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME ID file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_16bit,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 16,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_directory_8bit,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 8,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_16bit,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 16,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_archive_8bit,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 8,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 8,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_attr_device,
-               { "Device", "smb.file.attribute.device", FT_BOOLEAN, 16,
+               { "Device", "smb.file_attribute.device", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_attr_normal,
-               { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 16,
+               { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_attr_temporary,
-               { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 16,
+               { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_attr_sparse,
-               { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 16,
+               { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_attr_reparse,
-               { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 16,
+               { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_attr_compressed,
-               { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 16,
+               { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_attr_offline,
-               { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 16,
+               { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_attr_not_content_indexed,
-               { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 16,
+               { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_attr_encrypted,
-               { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 16,
+               { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 16,
                TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_file_size,
-               { "File Size", "smb.file.size", FT_UINT32, BASE_DEC,
+               { "File Size", "smb.file_size", FT_UINT32, BASE_DEC,
                NULL, 0, "File Size", HFILL }},
 
        { &hf_smb_search_attribute_read_only,
@@ -14486,7 +14921,7 @@ proto_register_smb(void)
                NULL, 0, "Padding or unknown data", HFILL }},
 
        { &hf_smb_file_data,
-               { "File Data", "smb.file.data", FT_BYTES, BASE_HEX,
+               { "File Data", "smb.file_data", FT_BYTES, BASE_HEX,
                NULL, 0, "Data read/written to the file", HFILL }},
 
        { &hf_smb_total_data_len,
@@ -15109,91 +15544,91 @@ proto_register_smb(void)
                TFS(&tfs_nt_share_access_delete), 0x00000004, "", HFILL }},
 
        { &hf_smb_file_eattr_read_only,
-               { "Read Only", "smb.file.attribute.read_only", FT_BOOLEAN, 32,
+               { "Read Only", "smb.file_attribute.read_only", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_read_only), FILE_ATTRIBUTE_READ_ONLY, "READ ONLY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_hidden,
-               { "Hidden", "smb.file.attribute.hidden", FT_BOOLEAN, 32,
+               { "Hidden", "smb.file_attribute.hidden", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_hidden), FILE_ATTRIBUTE_HIDDEN, "HIDDEN file attribute", HFILL }},
 
        { &hf_smb_file_eattr_system,
-               { "System", "smb.file.attribute.system", FT_BOOLEAN, 32,
+               { "System", "smb.file_attribute.system", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_system), FILE_ATTRIBUTE_SYSTEM, "SYSTEM file attribute", HFILL }},
 
        { &hf_smb_file_eattr_volume,
-               { "Volume ID", "smb.file.attribute.volume", FT_BOOLEAN, 32,
+               { "Volume ID", "smb.file_attribute.volume", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_volume), FILE_ATTRIBUTE_VOLUME, "VOLUME file attribute", HFILL }},
 
        { &hf_smb_file_eattr_directory,
-               { "Directory", "smb.file.attribute.directory", FT_BOOLEAN, 32,
+               { "Directory", "smb.file_attribute.directory", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_directory), FILE_ATTRIBUTE_DIRECTORY, "DIRECTORY file attribute", HFILL }},
 
        { &hf_smb_file_eattr_archive,
-               { "Archive", "smb.file.attribute.archive", FT_BOOLEAN, 32,
+               { "Archive", "smb.file_attribute.archive", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_archive), FILE_ATTRIBUTE_ARCHIVE, "ARCHIVE file attribute", HFILL }},
 
        { &hf_smb_file_eattr_device,
-               { "Device", "smb.file.attribute.device", FT_BOOLEAN, 32,
+               { "Device", "smb.file_attribute.device", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_device), FILE_ATTRIBUTE_DEVICE, "Is this file a device?", HFILL }},
 
        { &hf_smb_file_eattr_normal,
-               { "Normal", "smb.file.attribute.normal", FT_BOOLEAN, 32,
+               { "Normal", "smb.file_attribute.normal", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_normal), FILE_ATTRIBUTE_NORMAL, "Is this a normal file?", HFILL }},
 
        { &hf_smb_file_eattr_temporary,
-               { "Temporary", "smb.file.attribute.temporary", FT_BOOLEAN, 32,
+               { "Temporary", "smb.file_attribute.temporary", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_temporary), FILE_ATTRIBUTE_TEMPORARY, "Is this a temporary file?", HFILL }},
 
        { &hf_smb_file_eattr_sparse,
-               { "Sparse", "smb.file.attribute.sparse", FT_BOOLEAN, 32,
+               { "Sparse", "smb.file_attribute.sparse", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_sparse), FILE_ATTRIBUTE_SPARSE, "Is this a sparse file?", HFILL }},
 
        { &hf_smb_file_eattr_reparse,
-               { "Reparse Point", "smb.file.attribute.reparse", FT_BOOLEAN, 32,
+               { "Reparse Point", "smb.file_attribute.reparse", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_reparse), FILE_ATTRIBUTE_REPARSE, "Does this file have an associated reparse point?", HFILL }},
 
        { &hf_smb_file_eattr_compressed,
-               { "Compressed", "smb.file.attribute.compressed", FT_BOOLEAN, 32,
+               { "Compressed", "smb.file_attribute.compressed", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_compressed), FILE_ATTRIBUTE_COMPRESSED, "Is this file compressed?", HFILL }},
 
        { &hf_smb_file_eattr_offline,
-               { "Offline", "smb.file.attribute.offline", FT_BOOLEAN, 32,
+               { "Offline", "smb.file_attribute.offline", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_offline), FILE_ATTRIBUTE_OFFLINE, "Is this file offline?", HFILL }},
 
        { &hf_smb_file_eattr_not_content_indexed,
-               { "Content Indexed", "smb.file.attribute.not_content_indexed", FT_BOOLEAN, 32,
+               { "Content Indexed", "smb.file_attribute.not_content_indexed", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_not_content_indexed), FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, "May this file be indexed by the content indexing service", HFILL }},
 
        { &hf_smb_file_eattr_encrypted,
-               { "Encrypted", "smb.file.attribute.encrypted", FT_BOOLEAN, 32,
+               { "Encrypted", "smb.file_attribute.encrypted", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_encrypted), FILE_ATTRIBUTE_ENCRYPTED, "Is this file encrypted?", HFILL }},
 
        { &hf_smb_file_eattr_write_through,
-               { "Write Through", "smb.file.attribute.write_through", FT_BOOLEAN, 32,
+               { "Write Through", "smb.file_attribute.write_through", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_write_through), FILE_ATTRIBUTE_WRITE_THROUGH, "Does this object need write through?", HFILL }},
 
        { &hf_smb_file_eattr_no_buffering,
-               { "No Buffering", "smb.file.attribute.no_buffering", FT_BOOLEAN, 32,
+               { "No Buffering", "smb.file_attribute.no_buffering", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_no_buffering), FILE_ATTRIBUTE_NO_BUFFERING, "May the server buffer this object?", HFILL }},
 
        { &hf_smb_file_eattr_random_access,
-               { "Random Access", "smb.file.attribute.random_access", FT_BOOLEAN, 32,
+               { "Random Access", "smb.file_attribute.random_access", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_random_access), FILE_ATTRIBUTE_RANDOM_ACCESS, "Optimize for random access", HFILL }},
 
        { &hf_smb_file_eattr_sequential_scan,
-               { "Sequential Scan", "smb.file.attribute.sequential_scan", FT_BOOLEAN, 32,
+               { "Sequential Scan", "smb.file_attribute.sequential_scan", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_sequential_scan), FILE_ATTRIBUTE_SEQUENTIAL_SCAN, "Optimize for sequential scan", HFILL }},
 
        { &hf_smb_file_eattr_delete_on_close,
-               { "Delete on Close", "smb.file.attribute.delete_on_close", FT_BOOLEAN, 32,
+               { "Delete on Close", "smb.file_attribute.delete_on_close", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_delete_on_close), FILE_ATTRIBUTE_DELETE_ON_CLOSE, "Should this object be deleted on close?", HFILL }},
 
        { &hf_smb_file_eattr_backup_semantics,
-               { "Backup", "smb.file.attribute.backup_semantics", FT_BOOLEAN, 32,
+               { "Backup", "smb.file_attribute.backup_semantics", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_backup_semantics), FILE_ATTRIBUTE_BACKUP_SEMANTICS, "Does this object need/support backup semantics", HFILL }},
 
        { &hf_smb_file_eattr_posix_semantics,
-               { "Posix", "smb.file.attribute.posix_semantics", FT_BOOLEAN, 32,
+               { "Posix", "smb.file_attribute.posix_semantics", FT_BOOLEAN, 32,
                TFS(&tfs_file_attribute_posix_semantics), FILE_ATTRIBUTE_POSIX_SEMANTICS, "Does this object need/support POSIX semantics?", HFILL }},
 
        { &hf_smb_sec_desc_len,
@@ -15517,19 +15952,19 @@ proto_register_smb(void)
                NULL, 0, "Length of Short (8.3) File Name", HFILL }},
 
        { &hf_smb_fs_id,
-               { "FS Id", "smb.fs.id", FT_UINT32, BASE_DEC,
+               { "FS Id", "smb.fs_id", FT_UINT32, BASE_DEC,
                NULL, 0, "File System ID (NT Server always returns 0)", HFILL }},
 
        { &hf_smb_sector_unit,
-               { "Sectors/Unit", "smb.fs.sector_per_unit", FT_UINT32, BASE_DEC,
+               { "Sectors/Unit", "smb.fs_sector_per_unit", FT_UINT32, BASE_DEC,
                NULL, 0, "Sectors per allocation unit", HFILL }},
 
        { &hf_smb_fs_units,
-               { "Total Units", "smb.fs.units", FT_UINT32, BASE_DEC,
+               { "Total Units", "smb.fs_units", FT_UINT32, BASE_DEC,
                NULL, 0, "Total number of units on this filesystem", HFILL }},
 
        { &hf_smb_fs_sector,
-               { "Bytes per Sector", "smb.fs.bytes_per_sector", FT_UINT32, BASE_DEC,
+               { "Bytes per Sector", "smb.fs_bytes_per_sector", FT_UINT32, BASE_DEC,
                NULL, 0, "Bytes per sector", HFILL }},
 
        { &hf_smb_avail_units,
@@ -15553,15 +15988,15 @@ proto_register_smb(void)
                NULL, 0, "Number of free allocation units", HFILL }},
 
        { &hf_smb_max_name_len,
-               { "Max name length", "smb.fs.max_name_len", FT_UINT32, BASE_DEC,
+               { "Max name length", "smb.fs_max_name_len", FT_UINT32, BASE_DEC,
                NULL, 0, "Maximum length of each file name component in number of bytes", HFILL }},
 
        { &hf_smb_fs_name_len,
-               { "Label Length", "smb.fs.name.len", FT_UINT32, BASE_DEC,
+               { "Label Length", "smb.fs_name.len", FT_UINT32, BASE_DEC,
                NULL, 0, "Length of filesystem name in bytes", HFILL }},
 
        { &hf_smb_fs_name,
-               { "FS Name", "smb.fs.name", FT_STRING, BASE_DEC,
+               { "FS Name", "smb.fs_name", FT_STRING, BASE_DEC,
                NULL, 0, "Name of filesystem", HFILL }},
 
        { &hf_smb_device_char_removable,
@@ -15593,31 +16028,31 @@ proto_register_smb(void)
                TFS(&tfs_device_char_virtual), 0x00000040, "Is this a virtual device", HFILL }},
 
        { &hf_smb_fs_attr_css,
-               { "Case Sensitive Search", "smb.fs.attr.css", FT_BOOLEAN, 32,
+               { "Case Sensitive Search", "smb.fs_attr.css", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_css), 0x00000001, "Does this FS support Case Sensitive Search?", HFILL }},
 
        { &hf_smb_fs_attr_cpn,
-               { "Case Preserving", "smb.fs.attr.cpn", FT_BOOLEAN, 32,
+               { "Case Preserving", "smb.fs_attr.cpn", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_cpn), 0x00000002, "Will this FS Preserve Name Case?", HFILL }},
 
        { &hf_smb_fs_attr_pacls,
-               { "Persistent ACLs", "smb.fs.attr.pacls", FT_BOOLEAN, 32,
+               { "Persistent ACLs", "smb.fs_attr.pacls", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_pacls), 0x00000004, "Does this FS support Persistent ACLs?", HFILL }},
 
        { &hf_smb_fs_attr_fc,
-               { "Compression", "smb.fs.attr.fc", FT_BOOLEAN, 32,
+               { "Compression", "smb.fs_attr.fc", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_fc), 0x00000008, "Does this FS support File Compression?", HFILL }},
 
        { &hf_smb_fs_attr_vq,
-               { "Volume Quotas", "smb.fs.attr.vq", FT_BOOLEAN, 32,
+               { "Volume Quotas", "smb.fs_attr.vq", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_vq), 0x00000010, "Does this FS support Volume Quotas?", HFILL }},
 
        { &hf_smb_fs_attr_dim,
-               { "Mounted", "smb.fs.attr.dim", FT_BOOLEAN, 32,
+               { "Mounted", "smb.fs_attr.dim", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_dim), 0x00000020, "Is this FS a Mounted Device?", HFILL }},
 
        { &hf_smb_fs_attr_vic,
-               { "Compressed", "smb.fs.attr.vic", FT_BOOLEAN, 32,
+               { "Compressed", "smb.fs_attr.vic", FT_BOOLEAN, 32,
                TFS(&tfs_fs_attr_vic), 0x00008000, "Is this FS Compressed?", HFILL }},
 
        { &hf_smb_sec_desc_revision,
@@ -15681,7 +16116,7 @@ proto_register_smb(void)
                TFS(&tfs_ace_flags_failed_access), 0x80, "Should failed accesses be audited?", HFILL }},
 
        { &hf_smb_sec_desc_type_owner_defaulted,
-               { "Onwer Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
+               { "Owner Defaulted", "smb.sec_desc.type.owner_defaulted", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_owner_defaulted), 0x0001, "Is Owner Defaulted set?", HFILL }},
 
        { &hf_smb_sec_desc_type_group_defaulted,
@@ -15732,6 +16167,18 @@ proto_register_smb(void)
                { "Self Relative", "smb.sec_desc.type.self_relative", FT_BOOLEAN, 16,
                TFS(&tfs_sec_desc_type_self_relative), 0x8000, "Is this SecDesc self relative?", HFILL }},
 
+       { &hf_smb_quota_flags_deny_disk,
+               { "Deny Disk", "smb.quota.flags.deny_disk", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_deny_disk), 0x02, "Is the default quota limit enforced?", HFILL }},
+
+       { &hf_smb_quota_flags_log_limit,
+               { "Log Limit", "smb.quota.flags.log_limit", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_limit), 0x20, "Should the server log an event when the limit is exceeded?", HFILL }},
+
+       { &hf_smb_quota_flags_log_warning,
+               { "Log Warning", "smb.quota.flags.log_warning", FT_BOOLEAN, 8,
+               TFS(&tfs_quota_flags_log_warning), 0x10, "Should the server log an event when the warning level is exceeded?", HFILL }},
+
        };
        static gint *ett[] = {
                &ett_smb,
@@ -15757,7 +16204,6 @@ proto_register_smb(void)
                &ett_smb_ssetupandxaction,
                &ett_smb_optionsup,
                &ett_smb_time_date,
-               &ett_smb_64bit_time,
                &ett_smb_move_flags,
                &ett_smb_file_attributes,
                &ett_smb_search_resume_key,
@@ -15801,6 +16247,7 @@ proto_register_smb(void)
                &ett_smb_ace,
                &ett_smb_ace_flags,
                &ett_smb_sec_desc_type,
+               &ett_smb_quotaflags,
        };
        module_t *smb_module;