The branch, v3-5-test has been updated
       via  920ffe4... Fix bug #7410 - samba sends "raw" inode number as 
uniqueid with unix extensions.
      from  167c082... s3: Fix a typo found by ITPFS oota <[email protected]>

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 920ffe49290cacd30d9bc582c1c3fee38308c260
Author: Jeremy Allison <[email protected]>
Date:   Thu May 20 11:36:47 2010 -0700

    Fix bug #7410 - samba sends "raw" inode number as uniqueid with unix 
extensions.
    
    Move to a consistent get_FileIndex() function for all inode returns,
    that checks if st_dev on the file is identical to the top directory
    dev_t of the exported share, and if so uses the raw 64-bit inode
    number. If it isn't (we've traversed a mount point) - return what
    we used to do for Windows which is the concatination of the bottom
    32-bits of the inode with the 32-bit device number. We can get more
    creative with this over time (hashing?) if we want as now all inode returns 
go
    through this single function.
    
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 source3/include/proto.h    |    1 +
 source3/include/smb.h      |    3 +++
 source3/smbd/service.c     |    1 +
 source3/smbd/smb2_create.c |   11 ++++++++---
 source3/smbd/trans2.c      |   33 ++++++++++++++++++++++++++-------
 5 files changed, 39 insertions(+), 10 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index f30939a..04065b0 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -7050,6 +7050,7 @@ int sys_statvfs(const char *path, vfs_statvfs_struct 
*statbuf);
 /* The following definitions come from smbd/trans2.c  */
 
 uint64_t smb_roundup(connection_struct *conn, uint64_t val);
+uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf);
 NTSTATUS get_ea_value(TALLOC_CTX *mem_ctx, connection_struct *conn,
                      files_struct *fsp, const char *fname,
                      const char *ea_name, struct ea_struct *pea);
diff --git a/source3/include/smb.h b/source3/include/smb.h
index bc7a90d..202f9d7 100644
--- a/source3/include/smb.h
+++ b/source3/include/smb.h
@@ -607,6 +607,9 @@ typedef struct connection_struct {
 
        /* Semantics provided by the underlying filesystem. */
        int fs_capabilities;
+       /* Device number of the directory of the share mount.
+          Used to ensure unique FileIndex returns. */
+       SMB_DEV_T base_share_dev;
 
        name_compare_entry *hide_list; /* Per-share list of files to return as 
hidden. */
        name_compare_entry *veto_list; /* Per-share list of files to veto 
(never show). */
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 25e0eb1..bc2cdaf 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -1033,6 +1033,7 @@ connection_struct *make_connection_snum(struct 
smbd_server_connection *sconn,
                *pstatus = NT_STATUS_BAD_NETWORK_NAME;
                goto err_root_exit;
        }
+       conn->base_share_dev = smb_fname_cpath->st.st_ex_dev;
 
        string_set(&conn->origpath,conn->connectpath);
 
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 3cf8b18..3e0d180 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -651,13 +651,18 @@ static struct tevent_req 
*smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
 
                if (qfid) {
                        uint8_t p[32];
+                       uint64_t file_index = get_FileIndex(result->conn,
+                                                       &result->fsp_name->st);
                        DATA_BLOB blob = data_blob_const(p, sizeof(p));
 
                        ZERO_STRUCT(p);
 
-                       /* TODO: maybe use result->file_id */
-                       SIVAL(p, 0, result->fsp_name->st.st_ex_ino);/* 
FileIndexLow */
-                       SIVAL(p, 4, result->fsp_name->st.st_ex_dev);/* 
FileIndexHigh */
+                       /* From conversations with Microsoft engineers at
+                          the MS plugfest. The first 8 bytes are the "volume 
index"
+                          == inode, the second 8 bytes are the "volume id",
+                          == dev. This will be updated in the SMB2 doc. */
+                       SBVAL(p, 0, file_index);
+                       SIVAL(p, 8, result->fsp_name->st.st_ex_dev);/* 
FileIndexHigh */
 
                        status = smb2_create_blob_add(state, &out_context_blobs,
                                                      SMB2_CREATE_TAG_QFID,
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 963103c..fb4d46b 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -57,6 +57,23 @@ uint64_t smb_roundup(connection_struct *conn, uint64_t val)
        return val;
 }
 
+/********************************************************************
+ Create a 64 bit FileIndex. If the file is on the same device as
+ the root of the share, just return the 64-bit inode. If it isn't,
+ mangle as we used to do.
+********************************************************************/
+
+uint64_t get_FileIndex(connection_struct *conn, const SMB_STRUCT_STAT *psbuf)
+{
+       uint64_t file_index;
+       if (conn->base_share_dev == psbuf->st_ex_dev) {
+               return (uint64_t)psbuf->st_ex_ino;
+       }
+       file_index = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
+       file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* 
FileIndexHigh */
+       return file_index;
+}
+
 /****************************************************************************
  Utility functions for dealing with extended attributes.
 ****************************************************************************/
@@ -1474,6 +1491,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        uint32_t reskey=0;
        uint64_t file_size = 0;
        uint64_t allocation_size = 0;
+       uint64_t file_index = 0;
        uint32_t len;
        struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
        time_t mdate = (time_t)0, adate = (time_t)0, create_date = (time_t)0;
@@ -1496,6 +1514,8 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
        }
        allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, NULL, &smb_fname->st);
 
+       file_index = get_FileIndex(conn, &smb_fname->st);
+
        mdate_ts = smb_fname->st.st_ex_mtime;
        adate_ts = smb_fname->st.st_ex_atime;
        create_date_ts = get_create_timespec(conn, NULL, smb_fname);
@@ -1864,8 +1884,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                        p +=4;
                }
                SIVAL(p,0,0); p += 4; /* Unknown - reserved ? */
-               SIVAL(p,0,smb_fname->st.st_ex_ino); p += 4; /* FileIndexLow */
-               SIVAL(p,0,smb_fname->st.st_ex_dev); p += 4; /* FileIndexHigh */
+               SBVAL(p,0,file_index); p += 8;
                len = srvstr_push(base_data, flags2, p,
                                  fname, PTR_DIFF(end_data, p),
                                  STR_TERMINATE_ASCII);
@@ -1935,8 +1954,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,
                }
                p += 26;
                SSVAL(p,0,0); p += 2; /* Reserved ? */
-               SIVAL(p,0,smb_fname->st.st_ex_ino); p += 4; /* FileIndexLow */
-               SIVAL(p,0,smb_fname->st.st_ex_dev); p += 4; /* FileIndexHigh */
+               SBVAL(p,0,file_index); p += 8;
                len = srvstr_push(base_data, flags2, p,
                                  fname, PTR_DIFF(end_data, p),
                                  STR_TERMINATE_ASCII);
@@ -3850,6 +3868,8 @@ static char *store_file_unix_basic(connection_struct 
*conn,
                                files_struct *fsp,
                                const SMB_STRUCT_STAT *psbuf)
 {
+       uint64_t file_index = get_FileIndex(conn, psbuf);
+
        DEBUG(10,("store_file_unix_basic: SMB_QUERY_FILE_UNIX_BASIC\n"));
        DEBUG(4,("store_file_unix_basic: st_mode=%o\n",(int)psbuf->st_ex_mode));
 
@@ -3883,7 +3903,7 @@ static char *store_file_unix_basic(connection_struct 
*conn,
        SIVAL(pdata,4,0);
        pdata += 8;
 
-       SINO_T_VAL(pdata,0,(SMB_INO_T)psbuf->st_ex_ino);   /* inode number */
+       SINO_T_VAL(pdata,0,(SMB_INO_T)file_index);   /* inode number */
        pdata += 8;
 
        SIVAL(pdata,0, unix_perms_to_wire(psbuf->st_ex_mode));     /* Standard 
UNIX file permissions */
@@ -4285,8 +4305,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,
 
           I think this causes us to fail the IFSKIT
           BasicFileInformationTest. -tpot */
-       file_index =  ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
-       file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* 
FileIndexHigh */
+       file_index = get_FileIndex(conn, psbuf);
 
        switch (info_level) {
                case SMB_INFO_STANDARD:


-- 
Samba Shared Repository

Reply via email to