diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 1 | ||||
-rw-r--r-- | source3/include/smb.h | 3 | ||||
-rw-r--r-- | source3/smbd/service.c | 1 | ||||
-rw-r--r-- | source3/smbd/smb2_create.c | 11 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 33 |
5 files changed, 39 insertions, 10 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index f30939a8857..04065b0c5a2 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 bc7a90d5492..202f9d77db6 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 25e0eb10f8e..bc2cdaf2d85 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 3cf8b185b08..3e0d180bf34 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 963103c85b8..fb4d46b76bf 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: |