s3:smbd: add a generic smbd_dirptr_lanman2_entry() function
authorStefan Metzmacher <metze@samba.org>
Fri, 14 Aug 2009 11:23:19 +0000 (13:23 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 19 Aug 2009 20:12:42 +0000 (22:12 +0200)
This can we used by SMB2, the key difference between
SMB1 and SMB2 is that with SMB2 entries are aligned
to 8 bytes and there's no padding at the end of the last entry.

metze

source3/smbd/globals.h
source3/smbd/trans2.c

index fd92c22e7299fe27049322b6c7a1bb50025bbb10..0db61f87a3d5ad1eedcab6591553f31eabf4d51c 100644 (file)
@@ -234,6 +234,27 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                           uint32_t *_mode,
                           long *_prev_offset);
 
+bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+                              connection_struct *conn,
+                              struct dptr_struct *dirptr,
+                              uint16 flags2,
+                              const char *path_mask,
+                              uint32 dirtype,
+                              int info_level,
+                              int requires_resume_key,
+                              bool dont_descend,
+                              bool ask_sharemode,
+                              uint8_t align,
+                              bool do_pad,
+                              char **ppdata,
+                              char *base_data,
+                              char *end_data,
+                              int space_remaining,
+                              bool *out_of_space,
+                              bool *got_exact_match,
+                              int *_last_entry_off,
+                              struct ea_list *name_list);
+
 NTSTATUS smbd_check_open_rights(struct connection_struct *conn,
                                const struct smb_filename *smb_fname,
                                uint32_t access_mask,
index ae4b8b0d314bcf2ac79d07aa10757dfd60ea6676..56651b44ec5687057d837cfd10aabc2a267ab2aa 100644 (file)
@@ -1458,6 +1458,8 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                    const char *fname,
                                    const struct smb_filename *smb_fname,
                                    uint64_t space_remaining,
+                                   uint8_t align,
+                                   bool do_pad,
                                    char *base_data,
                                    char **ppdata,
                                    char *end_data,
@@ -1476,6 +1478,8 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        char *last_entry_ptr;
        bool was_8_3;
        uint32_t nt_extmode; /* Used for NT connections instead of mode */
+       off_t off;
+       off_t pad = 0;
 
        *out_of_space = false;
 
@@ -1506,9 +1510,22 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        adate = convert_timespec_to_time_t(adate_ts);
        c_date = convert_timespec_to_time_t(cdate_ts);
 
+       /* align the record */
+       off = PTR_DIFF(pdata, base_data);
+       pad = (off + (align-1)) & ~(align-1);
+       pad -= off;
+       off += pad;
+       /* initialize padding to 0 */
+       memset(pdata, 0, pad);
+       space_remaining -= pad;
+
+       pdata += pad;
        p = pdata;
        last_entry_ptr = p;
 
+       pad = 0;
+       off = 0;
+
        nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
 
        switch (info_level) {
@@ -1694,11 +1711,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                  STR_TERMINATE_ASCII);
                SIVAL(q,0,len);
                p += len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
+
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        case SMB_FIND_FILE_DIRECTORY_INFO:
@@ -1717,11 +1747,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                  STR_TERMINATE_ASCII);
                SIVAL(p,0,len);
                p += 4 + len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
+
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
@@ -1748,11 +1791,23 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                SIVAL(q, 0, len);
                p += len;
 
-               SIVAL(p,0,0); /* Ensure any padding is null. */
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        case SMB_FIND_FILE_NAMES_INFO:
@@ -1767,11 +1822,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                  STR_TERMINATE_ASCII);
                SIVAL(p, -4, len);
                p += len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
+
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        case SMB_FIND_ID_FULL_DIRECTORY_INFO:
@@ -1800,11 +1868,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                  STR_TERMINATE_ASCII);
                SIVAL(q, 0, len);
                p += len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
+
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
@@ -1858,11 +1939,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                                  STR_TERMINATE_ASCII);
                SIVAL(q,0,len);
                p += len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
+
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                break;
 
        /* CIFS UNIX Extension. */
@@ -1893,12 +1987,24 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                }
 
                p += len;
-               SIVAL(p,0,0); /* Ensure any padding is null. */
 
                len = PTR_DIFF(p, pdata);
-               len = (len + 3) & ~3;
-               SIVAL(pdata,0,len);     /* Offset from this structure to the beginning of the next one */
-               p = pdata + len;
+               pad = (len + (align-1)) & ~(align-1);
+               /*
+                * offset to the next entry, the caller
+                * will overwrite it for the last entry
+                * that's why we always include the padding
+                */
+               SIVAL(pdata,0,pad);
+               /*
+                * set padding to zero
+                */
+               if (do_pad) {
+                       memset(p, 0, pad - len);
+                       p = pdata + pad;
+               } else {
+                       p = pdata + len;
+               }
                /* End of SMB_QUERY_FILE_UNIX_BASIC */
 
                break;
@@ -1921,24 +2027,26 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        return true;
 }
 
-static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
-                               connection_struct *conn,
-                               struct dptr_struct *dirptr,
-                               uint16 flags2,
-                               const char *path_mask,
-                               uint32 dirtype,
-                               int info_level,
-                               int requires_resume_key,
-                               bool dont_descend,
-                               bool ask_sharemode,
-                               char **ppdata,
-                               char *base_data,
-                               char *end_data,
-                               int space_remaining,
-                               bool *out_of_space,
-                               bool *got_exact_match,
-                               int *_last_entry_off,
-                               struct ea_list *name_list)
+bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+                              connection_struct *conn,
+                              struct dptr_struct *dirptr,
+                              uint16 flags2,
+                              const char *path_mask,
+                              uint32 dirtype,
+                              int info_level,
+                              int requires_resume_key,
+                              bool dont_descend,
+                              bool ask_sharemode,
+                              uint8_t align,
+                              bool do_pad,
+                              char **ppdata,
+                              char *base_data,
+                              char *end_data,
+                              int space_remaining,
+                              bool *out_of_space,
+                              bool *got_exact_match,
+                              int *_last_entry_off,
+                              struct ea_list *name_list)
 {
        const char *p;
        const char *mask = NULL;
@@ -2001,6 +2109,8 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
                                     fname,
                                     smb_fname,
                                     space_remaining,
+                                    align,
+                                    do_pad,
                                     base_data,
                                     ppdata,
                                     end_data,
@@ -2020,6 +2130,43 @@ static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
        return true;
 }
 
+static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
+                               connection_struct *conn,
+                               struct dptr_struct *dirptr,
+                               uint16 flags2,
+                               const char *path_mask,
+                               uint32 dirtype,
+                               int info_level,
+                               int requires_resume_key,
+                               bool dont_descend,
+                               bool ask_sharemode,
+                               char **ppdata,
+                               char *base_data,
+                               char *end_data,
+                               int space_remaining,
+                               bool *out_of_space,
+                               bool *got_exact_match,
+                               int *last_entry_off,
+                               struct ea_list *name_list)
+{
+       bool resume_key = false;
+       const uint8_t align = 4;
+       const bool do_pad = true;
+
+       if (requires_resume_key) {
+               resume_key = true;
+       }
+
+       return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
+                                        path_mask, dirtype, info_level,
+                                        resume_key, dont_descend, ask_sharemode,
+                                        align, do_pad,
+                                        ppdata, base_data, end_data,
+                                        space_remaining,
+                                        out_of_space, got_exact_match,
+                                        last_entry_off, name_list);
+}
+
 /****************************************************************************
  Reply to a TRANS2_FINDFIRST.
 ****************************************************************************/