diff options
| -rw-r--r-- | source3/include/proto.h | 6 | ||||
| -rw-r--r-- | source3/lib/system.c | 4 | ||||
| -rw-r--r-- | source3/smbd/dosmode.c | 20 | ||||
| -rw-r--r-- | source3/smbd/nttrans.c | 32 | ||||
| -rw-r--r-- | source3/smbd/reply.c | 2 | ||||
| -rw-r--r-- | source3/smbd/trans2.c | 38 | 
6 files changed, 74 insertions, 28 deletions
| diff --git a/source3/include/proto.h b/source3/include/proto.h index e8bfe8efae..8b3e029d3f 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -6266,6 +6266,12 @@ bool set_sticky_write_time_fsp(struct files_struct *fsp,  			       struct timespec mtime);  bool update_write_time(struct files_struct *fsp); +struct timespec get_create_timespec(struct files_struct *fsp, +				const struct smb_filename *smb_fname); + +struct timespec get_change_timespec(struct files_struct *fsp, +				const struct smb_filename *smb_fname); +  /* The following definitions come from smbd/error.c  */  bool use_nt_status(void); diff --git a/source3/lib/system.c b/source3/lib/system.c index 6a4f5d5413..2c6894ff94 100644 --- a/source3/lib/system.c +++ b/source3/lib/system.c @@ -456,7 +456,7 @@ static struct timespec calc_create_time_stat_ex(const struct stat_ex *st)   use the best approximation.  ****************************************************************************/ -static void get_create_timespec(const struct stat *pst, struct stat_ex *dst) +static void make_create_timespec(const struct stat *pst, struct stat_ex *dst)  {  	if (S_ISDIR(pst->st_mode) && lp_fake_dir_create_times()) {  		dst->st_ex_btime.tv_sec = 315493200L;          /* 1/1/1980 */ @@ -518,7 +518,7 @@ static void init_stat_ex_from_stat (struct stat_ex *dst,  	dst->st_ex_atime = get_atimespec(src);  	dst->st_ex_mtime = get_mtimespec(src);  	dst->st_ex_ctime = get_ctimespec(src); -	get_create_timespec(src, dst); +	make_create_timespec(src, dst);  	dst->st_ex_blksize = src->st_blksize;  	dst->st_ex_blocks = src->st_blocks; diff --git a/source3/smbd/dosmode.c b/source3/smbd/dosmode.c index 535532d07a..f4803cb68d 100644 --- a/source3/smbd/dosmode.c +++ b/source3/smbd/dosmode.c @@ -851,3 +851,23 @@ bool update_write_time(struct files_struct *fsp)  	return true;  } + +/****************************************************************** + Return a create time (may look at EA in future). +******************************************************************/ + +struct timespec get_create_timespec(struct files_struct *fsp, +				const struct smb_filename *smb_fname) +{ +	return smb_fname->st.st_ex_btime; +} + +/****************************************************************** + Return a change time (may look at EA in future). +******************************************************************/ + +struct timespec get_change_timespec(struct files_struct *fsp, +				const struct smb_filename *smb_fname) +{ +	return smb_fname->st.st_ex_mtime; +} diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index b7b2634963..9f4074c865 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -399,6 +399,7 @@ void reply_ntcreate_and_X(struct smb_request *req)  	int info = 0;  	files_struct *fsp = NULL;  	char *p = NULL; +	struct timespec create_timespec;  	struct timespec c_timespec;  	struct timespec a_timespec;  	struct timespec m_timespec; @@ -524,6 +525,10 @@ void reply_ntcreate_and_X(struct smb_request *req)  		goto out;  	} +	/* Ensure we're pointing at the correct stat struct. */ +	TALLOC_FREE(smb_fname); +	smb_fname = fsp->fsp_name; +  	/*  	 * If the caller set the extended oplock request bit  	 * and we granted one (by whatever means) - set the @@ -591,23 +596,25 @@ void reply_ntcreate_and_X(struct smb_request *req)  	}  	/* Create time. */ -	c_timespec = smb_fname->st.st_ex_btime; +	create_timespec = get_create_timespec(fsp, smb_fname);  	a_timespec = smb_fname->st.st_ex_atime;  	m_timespec = smb_fname->st.st_ex_mtime; +	c_timespec = get_change_timespec(fsp, smb_fname);  	if (lp_dos_filetime_resolution(SNUM(conn))) { -		dos_filetime_timespec(&c_timespec); +		dos_filetime_timespec(&create_timespec);  		dos_filetime_timespec(&a_timespec);  		dos_filetime_timespec(&m_timespec); +		dos_filetime_timespec(&c_timespec);  	} -	put_long_date_timespec(p, c_timespec); /* create time. */ +	put_long_date_timespec(p, create_timespec); /* create time. */  	p += 8;  	put_long_date_timespec(p, a_timespec); /* access time */  	p += 8;  	put_long_date_timespec(p, m_timespec); /* write time */  	p += 8; -	put_long_date_timespec(p, m_timespec); /* change time */ +	put_long_date_timespec(p, c_timespec); /* change time */  	p += 8;  	SIVAL(p,0,fattr); /* File Attributes. */  	p += 4; @@ -638,7 +645,6 @@ void reply_ntcreate_and_X(struct smb_request *req)  	chain_reply(req);   out: -	TALLOC_FREE(smb_fname);  	END_PROFILE(SMBntcreateX);  	return;  } @@ -844,6 +850,7 @@ static void call_nt_transact_create(connection_struct *conn,  	struct security_descriptor *sd = NULL;  	uint32 ea_len;  	uint16 root_dir_fid; +	struct timespec create_timespec;  	struct timespec c_timespec;  	struct timespec a_timespec;  	struct timespec m_timespec; @@ -1016,6 +1023,10 @@ static void call_nt_transact_create(connection_struct *conn,  		goto out;  	} +	/* Ensure we're pointing at the correct stat struct. */ +	TALLOC_FREE(smb_fname); +	smb_fname = fsp->fsp_name; +  	/*  	 * If the caller set the extended oplock request bit  	 * and we granted one (by whatever means) - set the @@ -1083,23 +1094,25 @@ static void call_nt_transact_create(connection_struct *conn,  	}  	/* Create time. */ -	c_timespec = smb_fname->st.st_ex_btime; +	create_timespec = get_create_timespec(fsp, smb_fname);  	a_timespec = smb_fname->st.st_ex_atime;  	m_timespec = smb_fname->st.st_ex_mtime; +	c_timespec = get_change_timespec(fsp, smb_fname);  	if (lp_dos_filetime_resolution(SNUM(conn))) { -		dos_filetime_timespec(&c_timespec); +		dos_filetime_timespec(&create_timespec);  		dos_filetime_timespec(&a_timespec);  		dos_filetime_timespec(&m_timespec); +		dos_filetime_timespec(&c_timespec);  	} -	put_long_date_timespec(p, c_timespec); /* create time. */ +	put_long_date_timespec(p, create_timespec); /* create time. */  	p += 8;  	put_long_date_timespec(p, a_timespec); /* access time */  	p += 8;  	put_long_date_timespec(p, m_timespec); /* write time */  	p += 8; -	put_long_date_timespec(p, m_timespec); /* change time */ +	put_long_date_timespec(p, c_timespec); /* change time */  	p += 8;  	SIVAL(p,0,fattr); /* File Attributes. */  	p += 4; @@ -1131,7 +1144,6 @@ static void call_nt_transact_create(connection_struct *conn,  	/* Send the required number of replies */  	send_nt_replies(conn, req, NT_STATUS_OK, params, param_len, *ppdata, 0);   out: -	TALLOC_FREE(smb_fname);  	return;  } diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 3498109f12..de187e902b 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -7793,7 +7793,7 @@ void reply_getattrE(struct smb_request *req)  	reply_outbuf(req, 11, 0); -	create_ts = sbuf.st_ex_btime; +	create_ts = get_create_timespec(fsp, fsp->fsp_name);  	srv_put_dos_date2((char *)req->outbuf, smb_vwv0, create_ts.tv_sec);  	srv_put_dos_date2((char *)req->outbuf, smb_vwv2,  			  convert_timespec_to_time_t(sbuf.st_ex_atime)); diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index 2e47eab4f0..93b217558d 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -1468,8 +1468,9 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  	uint64_t file_size = 0;  	uint64_t allocation_size = 0;  	uint32_t len; -	struct timespec mdate_ts, adate_ts, create_date_ts; +	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; +	time_t c_date = (time_t)0;  	char *nameptr;  	char *last_entry_ptr;  	bool was_8_3; @@ -1480,6 +1481,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  	ZERO_STRUCT(mdate_ts);  	ZERO_STRUCT(adate_ts);  	ZERO_STRUCT(create_date_ts); +	ZERO_STRUCT(cdate_ts);  	if (!(mode & aDIR)) {  		file_size = get_file_size_stat(&smb_fname->st); @@ -1488,17 +1490,20 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  	mdate_ts = smb_fname->st.st_ex_mtime;  	adate_ts = smb_fname->st.st_ex_atime; -	create_date_ts = smb_fname->st.st_ex_btime; +	create_date_ts = get_create_timespec(NULL, smb_fname); +	cdate_ts = get_change_timespec(NULL, smb_fname);  	if (lp_dos_filetime_resolution(SNUM(conn))) {  		dos_filetime_timespec(&create_date_ts);  		dos_filetime_timespec(&mdate_ts);  		dos_filetime_timespec(&adate_ts); +		dos_filetime_timespec(&cdate_ts);  	}  	create_date = convert_timespec_to_time_t(create_date_ts);  	mdate = convert_timespec_to_time_t(mdate_ts);  	adate = convert_timespec_to_time_t(adate_ts); +	c_date = convert_timespec_to_time_t(cdate_ts);  	p = pdata;  	last_entry_ptr = p; @@ -1649,7 +1654,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  		put_long_date_timespec(p,create_date_ts); p += 8;  		put_long_date_timespec(p,adate_ts); p += 8;  		put_long_date_timespec(p,mdate_ts); p += 8; -		put_long_date_timespec(p,mdate_ts); p += 8; +		put_long_date_timespec(p,cdate_ts); p += 8;  		SOFF_T(p,0,file_size); p += 8;  		SOFF_T(p,0,allocation_size); p += 8;  		SIVAL(p,0,nt_extmode); p += 4; @@ -1702,7 +1707,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  		put_long_date_timespec(p,create_date_ts); p += 8;  		put_long_date_timespec(p,adate_ts); p += 8;  		put_long_date_timespec(p,mdate_ts); p += 8; -		put_long_date_timespec(p,mdate_ts); p += 8; +		put_long_date_timespec(p,cdate_ts); p += 8;  		SOFF_T(p,0,file_size); p += 8;  		SOFF_T(p,0,allocation_size); p += 8;  		SIVAL(p,0,nt_extmode); p += 4; @@ -1725,7 +1730,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  		put_long_date_timespec(p,create_date_ts); p += 8;  		put_long_date_timespec(p,adate_ts); p += 8;  		put_long_date_timespec(p,mdate_ts); p += 8; -		put_long_date_timespec(p,mdate_ts); p += 8; +		put_long_date_timespec(p,cdate_ts); p += 8;  		SOFF_T(p,0,file_size); p += 8;  		SOFF_T(p,0,allocation_size); p += 8;  		SIVAL(p,0,nt_extmode); p += 4; @@ -1775,7 +1780,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  		put_long_date_timespec(p,create_date_ts); p += 8;  		put_long_date_timespec(p,adate_ts); p += 8;  		put_long_date_timespec(p,mdate_ts); p += 8; -		put_long_date_timespec(p,mdate_ts); p += 8; +		put_long_date_timespec(p,cdate_ts); p += 8;  		SOFF_T(p,0,file_size); p += 8;  		SOFF_T(p,0,allocation_size); p += 8;  		SIVAL(p,0,nt_extmode); p += 4; @@ -1809,7 +1814,7 @@ static bool smbd_marshall_dir_entry(TALLOC_CTX *ctx,  		put_long_date_timespec(p,create_date_ts); p += 8;  		put_long_date_timespec(p,adate_ts); p += 8;  		put_long_date_timespec(p,mdate_ts); p += 8; -		put_long_date_timespec(p,mdate_ts); p += 8; +		put_long_date_timespec(p,cdate_ts); p += 8;  		SOFF_T(p,0,file_size); p += 8;  		SOFF_T(p,0,allocation_size); p += 8;  		SIVAL(p,0,nt_extmode); p += 4; @@ -3996,8 +4001,8 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  	char *pdata = *ppdata;  	char *dstart, *dend;  	unsigned int data_size; -	struct timespec create_time_ts, mtime_ts, atime_ts; -	time_t create_time, mtime, atime; +	struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts; +	time_t create_time, mtime, atime, c_time;  	SMB_STRUCT_STAT sbuf;  	char *p;  	char *base_name; @@ -4052,19 +4057,22 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  		update_stat_ex_mtime(&sbuf, write_time_ts);  	} -	create_time_ts = sbuf.st_ex_btime; +	create_time_ts = get_create_timespec(fsp, smb_fname);  	mtime_ts = sbuf.st_ex_mtime;  	atime_ts = sbuf.st_ex_atime; +	ctime_ts = get_change_timespec(fsp, smb_fname);  	if (lp_dos_filetime_resolution(SNUM(conn))) {  		dos_filetime_timespec(&create_time_ts);  		dos_filetime_timespec(&mtime_ts);  		dos_filetime_timespec(&atime_ts); +		dos_filetime_timespec(&ctime_ts);  	}  	create_time = convert_timespec_to_time_t(create_time_ts);  	mtime = convert_timespec_to_time_t(mtime_ts);  	atime = convert_timespec_to_time_t(atime_ts); +	c_time = convert_timespec_to_time_t(ctime_ts);  	p = strrchr_m(smb_fname->base_name,'/');  	if (!p) @@ -4257,14 +4265,14 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  			put_long_date_timespec(pdata,create_time_ts);  			put_long_date_timespec(pdata+8,atime_ts);  			put_long_date_timespec(pdata+16,mtime_ts); /* write time */ -			put_long_date_timespec(pdata+24,mtime_ts); /* change time */ +			put_long_date_timespec(pdata+24,ctime_ts); /* change time */  			SIVAL(pdata,32,mode);  			DEBUG(5,("SMB_QFBI - "));  			DEBUG(5,("create: %s ", ctime(&create_time)));  			DEBUG(5,("access: %s ", ctime(&atime)));  			DEBUG(5,("write: %s ", ctime(&mtime))); -			DEBUG(5,("change: %s ", ctime(&mtime))); +			DEBUG(5,("change: %s ", ctime(&c_time)));  			DEBUG(5,("mode: %x\n", mode));  			break; @@ -4352,7 +4360,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  			put_long_date_timespec(pdata,create_time_ts);  			put_long_date_timespec(pdata+8,atime_ts);  			put_long_date_timespec(pdata+16,mtime_ts); /* write time */ -			put_long_date_timespec(pdata+24,mtime_ts); /* change time */ +			put_long_date_timespec(pdata+24,ctime_ts); /* change time */  			SIVAL(pdata,32,mode);  			SIVAL(pdata,36,0); /* padding. */  			pdata += 40; @@ -4384,7 +4392,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  			put_long_date_timespec(pdata+0x00,create_time_ts);  			put_long_date_timespec(pdata+0x08,atime_ts);  			put_long_date_timespec(pdata+0x10,mtime_ts); /* write time */ -			put_long_date_timespec(pdata+0x18,mtime_ts); /* change time */ +			put_long_date_timespec(pdata+0x18,ctime_ts); /* change time */  			SIVAL(pdata,	0x20, mode);  			SIVAL(pdata,	0x24, 0); /* padding. */  			SBVAL(pdata,	0x28, allocation_size); @@ -4517,7 +4525,7 @@ NTSTATUS smbd_do_qfilepathinfo(connection_struct *conn,  			put_long_date_timespec(pdata,create_time_ts);  			put_long_date_timespec(pdata+8,atime_ts);  			put_long_date_timespec(pdata+16,mtime_ts); /* write time */ -			put_long_date_timespec(pdata+24,mtime_ts); /* change time */ +			put_long_date_timespec(pdata+24,ctime_ts); /* change time */  			SOFF_T(pdata,32,allocation_size);  			SOFF_T(pdata,40,file_size);  			SIVAL(pdata,48,mode); | 
