1
0
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:
Jeremy Allison 2022-01-05 11:40:46 -08:00
parent 29d69c22a0
commit 23fbf0bad0
4 changed files with 56 additions and 5 deletions

View File

@ -1,2 +0,0 @@
^samba3.smb2.fileid_unique.fileid_unique\(fileserver\)
^samba3.smb2.fileid_unique.fileid_unique-dir\(fileserver\)

View File

@ -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,

View File

@ -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.
********************************************************************/

View File

@ -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)