mirror of
https://github.com/samba-team/samba.git
synced 2025-01-10 01:18:15 +03:00
s3: smbd: Create and use a common function for generating a fileid - create_clock_itime().
This first gets the clock_gettime_mono() value, converts to an NTTIME (as this is what is stored in the dos attribute EA), then mixes in 8 bits of randomness shifted up by 55 bits to cope with poor resolution clocks to avoid duplicate inodes. Using 8 bits of randomness on top of an NTTIME gives us around 114 years headroom. We can now guarentee returning a itime-based fileid in a normal share (storing dos attributes in an EA). Remove knownfail.d/fileid-unique BUG: https://bugzilla.samba.org/show_bug.cgi?id=14928 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Christof Schmitt <cs@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Sat Jan 8 06:35:22 UTC 2022 on sn-devel-184
This commit is contained in:
parent
29d69c22a0
commit
23fbf0bad0
@ -1,2 +0,0 @@
|
||||
^samba3.smb2.fileid_unique.fileid_unique\(fileserver\)
|
||||
^samba3.smb2.fileid_unique.fileid_unique-dir\(fileserver\)
|
@ -175,6 +175,7 @@ void update_stat_ex_create_time(struct stat_ex *dst, struct timespec create_time
|
||||
void update_stat_ex_file_id(struct stat_ex *dst, uint64_t file_id);
|
||||
void update_stat_ex_from_saved_stat(struct stat_ex *dst,
|
||||
const struct stat_ex *src);
|
||||
void create_clock_itime(struct stat_ex *dst);
|
||||
int sys_stat(const char *fname, SMB_STRUCT_STAT *sbuf,
|
||||
bool fake_dir_create_times);
|
||||
int sys_fstat(int fd, SMB_STRUCT_STAT *sbuf,
|
||||
|
@ -310,6 +310,58 @@ void init_stat_ex_from_stat (struct stat_ex *dst,
|
||||
dst->st_ex_iflags |= ST_EX_IFLAG_CALCULATED_FILE_ID;
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
Create a clock-derived itime (imaginary) time. Used to generate
|
||||
the fileid.
|
||||
********************************************************************/
|
||||
|
||||
void create_clock_itime(struct stat_ex *dst)
|
||||
{
|
||||
NTTIME tval;
|
||||
struct timespec itime;
|
||||
uint64_t mixin;
|
||||
uint8_t rval;
|
||||
|
||||
/* Start with the system clock. */
|
||||
clock_gettime_mono(&itime);
|
||||
|
||||
/* Convert to NTTIME. */
|
||||
tval = unix_timespec_to_nt_time(itime);
|
||||
|
||||
/*
|
||||
* In case the system clock is poor granularity
|
||||
* (happens on VM or docker images) then mix in
|
||||
* 8 bits of randomness.
|
||||
*/
|
||||
generate_random_buffer((unsigned char *)&rval, 1);
|
||||
mixin = rval;
|
||||
|
||||
/*
|
||||
* Shift up by 55 bits. This gives us approx 114 years
|
||||
* of headroom.
|
||||
*/
|
||||
mixin <<= 55;
|
||||
|
||||
/* And OR into the nttime. */
|
||||
tval |= mixin;
|
||||
|
||||
/*
|
||||
* Convert to a unix timespec, ignoring any
|
||||
* constraints on seconds being higher than
|
||||
* TIME_T_MAX or lower than TIME_T_MIN. These
|
||||
* are only needed to allow unix display time functions
|
||||
* to work correctly, and this is being used to
|
||||
* generate a fileid. All we care about is the
|
||||
* NTTIME being valid across all NTTIME ranges
|
||||
* (which we carefully ensured above).
|
||||
*/
|
||||
|
||||
itime = nt_time_to_unix_timespec_raw(tval);
|
||||
|
||||
/* And set as a generated itime. */
|
||||
update_stat_ex_itime(dst, itime);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
A stat() wrapper.
|
||||
********************************************************************/
|
||||
|
@ -4129,13 +4129,13 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
|
||||
* If we created a file and it's not a stream, this is the point where
|
||||
* we set the itime (aka invented time) that get's stored in the DOS
|
||||
* attribute xattr. The value is going to be either what the filesystem
|
||||
* provided or a copy of the creation date.
|
||||
* provided or a generated itime value.
|
||||
*
|
||||
* Either way, we turn the itime into a File-ID, unless the filesystem
|
||||
* provided one (unlikely).
|
||||
*/
|
||||
if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) {
|
||||
smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
|
||||
create_clock_itime(&smb_fname->st);
|
||||
|
||||
if (lp_store_dos_attributes(SNUM(conn)) &&
|
||||
smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
|
||||
@ -4317,7 +4317,7 @@ static NTSTATUS mkdir_internal(connection_struct *conn,
|
||||
return NT_STATUS_NOT_A_DIRECTORY;
|
||||
}
|
||||
|
||||
smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
|
||||
create_clock_itime(&smb_dname->st);
|
||||
|
||||
if (lp_store_dos_attributes(SNUM(conn))) {
|
||||
if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
|
||||
|
Loading…
Reference in New Issue
Block a user