static const char * const prohibited_ea_names[] = {
SAMBA_POSIX_INHERITANCE_EA_NAME,
SAMBA_XATTR_DOS_ATTRIB,
+ SAMBA_XATTR_DOSTIMESTAMPS,
NULL
};
if (sizeret == 0) {
TALLOC_FREE(names);
- *pnames = NULL;
+ if (pnames) {
+ *pnames = NULL;
+ }
*pnum_names = 0;
return NT_STATUS_OK;
}
names[num_names++] = p;
}
- *pnames = names;
+ if (pnames) {
+ *pnames = names;
+ } else {
+ TALLOC_FREE(names);
+ }
*pnum_names = num_names;
return NT_STATUS_OK;
}
const char *fname,
const struct smb_filename *smb_fname,
uint64_t space_remaining,
+ uint8_t align,
+ bool do_pad,
char *base_data,
char **ppdata,
char *end_data,
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;
uint32_t nt_extmode; /* Used for NT connections instead of mode */
+ off_t off;
+ off_t pad = 0;
*out_of_space = false;
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);
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(conn, NULL, smb_fname);
+ cdate_ts = get_change_timespec(conn, 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);
+
+ /* align the record */
+ off = PTR_DIFF(pdata, base_data);
+ pad = (off + (align-1)) & ~(align-1);
+ pad -= off;
+ off += pad;
+ /* initialize padding to 0 */
+ memset(pdata, 0, pad);
+ space_remaining -= pad;
+
+ pdata += pad;
p = pdata;
last_entry_ptr = p;
+ pad = 0;
+ off = 0;
+
nt_extmode = mode ? mode : FILE_ATTRIBUTE_NORMAL;
switch (info_level) {
was_8_3 = mangle_is_8_3(fname, True, conn->params);
p += 4;
SIVAL(p,0,reskey); p += 4;
- 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(conn->ts_res,p,create_date_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,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;
STR_TERMINATE_ASCII);
SIVAL(q,0,len);
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
+
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
case SMB_FIND_FILE_DIRECTORY_INFO:
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- 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(conn->ts_res,p,create_date_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,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;
STR_TERMINATE_ASCII);
SIVAL(p,0,len);
p += 4 + len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
+
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
case SMB_FIND_FILE_FULL_DIRECTORY_INFO:
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_FULL_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- 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(conn->ts_res,p,create_date_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,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;
SIVAL(q, 0, len);
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
case SMB_FIND_FILE_NAMES_INFO:
STR_TERMINATE_ASCII);
SIVAL(p, -4, len);
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
+
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
case SMB_FIND_ID_FULL_DIRECTORY_INFO:
DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_FULL_DIRECTORY_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
- 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(conn->ts_res,p,create_date_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,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;
STR_TERMINATE_ASCII);
SIVAL(q, 0, len);
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
+
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
case SMB_FIND_ID_BOTH_DIRECTORY_INFO:
was_8_3 = mangle_is_8_3(fname, True, conn->params);
p += 4;
SIVAL(p,0,reskey); p += 4;
- 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(conn->ts_res,p,create_date_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,adate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,p,mdate_ts); p += 8;
+ put_long_date_timespec(conn->ts_res,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;
STR_TERMINATE_ASCII);
SIVAL(q,0,len);
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
+
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len);
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
break;
/* CIFS UNIX Extension. */
}
p += len;
- SIVAL(p,0,0); /* Ensure any padding is null. */
len = PTR_DIFF(p, pdata);
- len = (len + 3) & ~3;
- SIVAL(pdata,0,len); /* Offset from this structure to the beginning of the next one */
- p = pdata + len;
+ pad = (len + (align-1)) & ~(align-1);
+ /*
+ * offset to the next entry, the caller
+ * will overwrite it for the last entry
+ * that's why we always include the padding
+ */
+ SIVAL(pdata,0,pad);
+ /*
+ * set padding to zero
+ */
+ if (do_pad) {
+ memset(p, 0, pad - len);
+ p = pdata + pad;
+ } else {
+ p = pdata + len;
+ }
/* End of SMB_QUERY_FILE_UNIX_BASIC */
break;
return true;
}
-static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
- connection_struct *conn,
- struct dptr_struct *dirptr,
- uint16 flags2,
- const char *path_mask,
- uint32 dirtype,
- int info_level,
- int requires_resume_key,
- bool dont_descend,
- bool ask_sharemode,
- char **ppdata,
- char *base_data,
- char *end_data,
- int space_remaining,
- bool *out_of_space,
- bool *got_exact_match,
- int *_last_entry_off,
- struct ea_list *name_list)
+bool smbd_dirptr_lanman2_entry(TALLOC_CTX *ctx,
+ connection_struct *conn,
+ struct dptr_struct *dirptr,
+ uint16 flags2,
+ const char *path_mask,
+ uint32 dirtype,
+ int info_level,
+ int requires_resume_key,
+ bool dont_descend,
+ bool ask_sharemode,
+ uint8_t align,
+ bool do_pad,
+ char **ppdata,
+ char *base_data,
+ char *end_data,
+ int space_remaining,
+ bool *out_of_space,
+ bool *got_exact_match,
+ int *_last_entry_off,
+ struct ea_list *name_list)
{
const char *p;
const char *mask = NULL;
fname,
smb_fname,
space_remaining,
+ align,
+ do_pad,
base_data,
ppdata,
end_data,
return true;
}
+static bool get_lanman2_dir_entry(TALLOC_CTX *ctx,
+ connection_struct *conn,
+ struct dptr_struct *dirptr,
+ uint16 flags2,
+ const char *path_mask,
+ uint32 dirtype,
+ int info_level,
+ int requires_resume_key,
+ bool dont_descend,
+ bool ask_sharemode,
+ char **ppdata,
+ char *base_data,
+ char *end_data,
+ int space_remaining,
+ bool *out_of_space,
+ bool *got_exact_match,
+ int *last_entry_off,
+ struct ea_list *name_list)
+{
+ bool resume_key = false;
+ const uint8_t align = 4;
+ const bool do_pad = true;
+
+ if (requires_resume_key) {
+ resume_key = true;
+ }
+
+ return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
+ path_mask, dirtype, info_level,
+ resume_key, dont_descend, ask_sharemode,
+ align, do_pad,
+ ppdata, base_data, end_data,
+ space_remaining,
+ out_of_space, got_exact_match,
+ last_entry_off, name_list);
+}
+
/****************************************************************************
Reply to a TRANS2_FINDFIRST.
****************************************************************************/
/* Capabilities are filled in at connection time through STATVFS call */
additional_flags |= conn->fs_capabilities;
+ additional_flags |= lp_parm_int(conn->params->service,
+ "share", "fake_fscaps",
+ 0);
SIVAL(pdata,0,FILE_CASE_PRESERVED_NAMES|FILE_CASE_SENSITIVE_SEARCH|
FILE_SUPPORTS_OBJECT_IDS|FILE_UNICODE_ON_DISK|
SOFF_T(pdata,0,SMB_VFS_GET_ALLOC_SIZE(conn,fsp,psbuf)); /* Number of bytes used on disk - 64 Bit */
pdata += 8;
- put_long_date_timespec(pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
- put_long_date_timespec(pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
- put_long_date_timespec(pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata, psbuf->st_ex_ctime); /* Change Time 64 Bit */
+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER ,pdata+8, psbuf->st_ex_atime); /* Last access time 64 Bit */
+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER, pdata+16, psbuf->st_ex_mtime); /* Last modification time 64 Bit */
pdata += 24;
SIVAL(pdata,0,psbuf->st_ex_uid); /* user id for the owner */
pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
/* Create (birth) time 64 bit */
- put_long_date_timespec(pdata, psbuf->st_ex_btime);
+ put_long_date_timespec(TIMESTAMP_SET_NT_OR_BETTER,pdata, psbuf->st_ex_btime);
pdata += 8;
map_info2_flags_from_sbuf(psbuf, &file_flags, &flags_mask);
TALLOC_CTX *mem_ctx,
uint16_t info_level,
files_struct *fsp,
- const struct smb_filename *smb_fname,
+ struct smb_filename *smb_fname,
bool delete_pending,
struct timespec write_time_ts,
bool ms_dfs_link,
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;
- SMB_STRUCT_STAT sbuf;
+ struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
+ time_t create_time, mtime, atime, c_time;
+ SMB_STRUCT_STAT *psbuf = &smb_fname->st;
char *p;
char *base_name;
char *dos_fname;
uint64_t file_index = 0;
uint32_t access_mask = 0;
- sbuf = smb_fname->st;
-
if (INFO_LEVEL_IS_UNIX(info_level) && !lp_unix_extensions()) {
return NT_STATUS_INVALID_LEVEL;
}
if (!mode)
mode = FILE_ATTRIBUTE_NORMAL;
- nlink = sbuf.st_ex_nlink;
+ nlink = psbuf->st_ex_nlink;
if (nlink && (mode&aDIR)) {
nlink = 1;
dend = dstart + data_size - 1;
if (!null_timespec(write_time_ts) && !INFO_LEVEL_IS_UNIX(info_level)) {
- update_stat_ex_mtime(&sbuf, write_time_ts);
+ update_stat_ex_mtime(psbuf, write_time_ts);
}
- create_time_ts = sbuf.st_ex_btime;
- mtime_ts = sbuf.st_ex_mtime;
- atime_ts = sbuf.st_ex_atime;
+ create_time_ts = get_create_timespec(conn, fsp, smb_fname);
+ mtime_ts = psbuf->st_ex_mtime;
+ atime_ts = psbuf->st_ex_atime;
+ ctime_ts = get_change_timespec(conn, 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)
string_replace(dos_fname, '/', '\\');
}
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, &sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp, psbuf);
if (!fsp) {
/* Do we have this path open ? */
files_struct *fsp1;
- struct file_id fileid = vfs_file_id_from_sbuf(conn, &sbuf);
+ struct file_id fileid = vfs_file_id_from_sbuf(conn, psbuf);
fsp1 = file_find_di_first(fileid);
if (fsp1 && fsp1->initial_allocation_size) {
- allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, &sbuf);
+ allocation_size = SMB_VFS_GET_ALLOC_SIZE(conn, fsp1, psbuf);
}
}
if (!(mode & aDIR)) {
- file_size = get_file_size_stat(&sbuf);
+ file_size = get_file_size_stat(psbuf);
}
if (fsp) {
I think this causes us to fail the IFSKIT
BasicFileInformationTest. -tpot */
- file_index = ((sbuf.st_ex_ino) & UINT32_MAX); /* FileIndexLow */
- file_index |= ((uint64_t)((sbuf.st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
+ file_index = ((psbuf->st_ex_ino) & UINT32_MAX); /* FileIndexLow */
+ file_index |= ((uint64_t)((psbuf->st_ex_dev) & UINT32_MAX)) << 32; /* FileIndexHigh */
switch (info_level) {
case SMB_INFO_STANDARD:
case 0xFF0F:/*SMB2_INFO_QUERY_ALL_EAS*/
{
+ /* This is FileFullEaInformation - 0xF which maps to
+ * 1015 (decimal) in smbd_do_setfilepathinfo. */
+
/* We have data_size bytes to put EA's into. */
size_t total_ea_len = 0;
struct ea_list *ea_file_list = NULL;
data_size = 40;
SIVAL(pdata,36,0);
}
- 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(conn->ts_res,pdata,create_time_ts);
+ put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
+ put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(conn->ts_res,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;
unsigned int ea_size =
estimate_ea_size(conn, fsp, smb_fname->base_name);
DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_ALL_INFORMATION\n"));
- 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(conn->ts_res,pdata,create_time_ts);
+ put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
+ put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
SIVAL(pdata,32,mode);
SIVAL(pdata,36,0); /* padding. */
pdata += 40;
unsigned int ea_size =
estimate_ea_size(conn, fsp, smb_fname->base_name);
DEBUG(10,("smbd_do_qfilepathinfo: SMB2_FILE_ALL_INFORMATION\n"));
- 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(conn->ts_res,pdata+0x00,create_time_ts);
+ put_long_date_timespec(conn->ts_res,pdata+0x08,atime_ts);
+ put_long_date_timespec(conn->ts_res,pdata+0x10,mtime_ts); /* write time */
+ put_long_date_timespec(conn->ts_res,pdata+0x18,ctime_ts); /* change time */
SIVAL(pdata, 0x20, mode);
SIVAL(pdata, 0x24, 0); /* padding. */
SBVAL(pdata, 0x28, allocation_size);
case SMB_FILE_NETWORK_OPEN_INFORMATION:
DEBUG(10,("smbd_do_qfilepathinfo: SMB_FILE_NETWORK_OPEN_INFORMATION\n"));
- 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(conn->ts_res,pdata,create_time_ts);
+ put_long_date_timespec(conn->ts_res,pdata+8,atime_ts);
+ put_long_date_timespec(conn->ts_res,pdata+16,mtime_ts); /* write time */
+ put_long_date_timespec(conn->ts_res,pdata+24,ctime_ts); /* change time */
SOFF_T(pdata,32,allocation_size);
SOFF_T(pdata,40,file_size);
SIVAL(pdata,48,mode);
case SMB_QUERY_FILE_UNIX_BASIC:
- pdata = store_file_unix_basic(conn, pdata, fsp, &sbuf);
+ pdata = store_file_unix_basic(conn, pdata, fsp, psbuf);
data_size = PTR_DIFF(pdata,(*ppdata));
{
case SMB_QUERY_FILE_UNIX_INFO2:
- pdata = store_file_unix_basic_info2(conn, pdata, fsp, &sbuf);
+ pdata = store_file_unix_basic_info2(conn, pdata, fsp, psbuf);
data_size = PTR_DIFF(pdata,(*ppdata));
{
DEBUG(10,("smbd_do_qfilepathinfo: SMB_QUERY_FILE_UNIX_LINK\n"));
#ifdef S_ISLNK
- if(!S_ISLNK(sbuf.st_ex_mode)) {
+ if(!S_ISLNK(psbuf->st_ex_mode)) {
return NT_STATUS_DOS(ERRSRV, ERRbadlink);
}
#else
return NT_STATUS_NOT_IMPLEMENTED;
}
- if (S_ISDIR(sbuf.st_ex_mode)) {
+ if (S_ISDIR(psbuf->st_ex_mode)) {
if (fsp && fsp->is_directory) {
def_acl =
SMB_VFS_SYS_ACL_GET_FILE(
SSVAL(pdata,0,SMB_POSIX_ACL_VERSION);
SSVAL(pdata,2,num_file_acls);
SSVAL(pdata,4,num_def_acls);
- if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, &sbuf, file_acl)) {
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE, psbuf, file_acl)) {
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
}
return NT_STATUS_INTERNAL_ERROR;
}
- if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), &sbuf, def_acl)) {
+ if (!marshall_posix_acl(conn, pdata + SMB_POSIX_ACL_HEADER_SIZE + (num_file_acls*SMB_POSIX_ACL_ENTRY_SIZE), psbuf, def_acl)) {
if (file_acl) {
SMB_VFS_SYS_ACL_FREE_ACL(conn, file_acl);
}
struct smb_filename *smb_fname_base = NULL;
uint32 action =
FILE_NOTIFY_CHANGE_LAST_ACCESS
- |FILE_NOTIFY_CHANGE_LAST_WRITE;
- bool set_createtime = false;
+ |FILE_NOTIFY_CHANGE_LAST_WRITE
+ |FILE_NOTIFY_CHANGE_CREATION;
NTSTATUS status;
if (!VALID_STAT(smb_fname->st)) {
/* get some defaults (no modifications) if any info is zero or -1. */
if (null_timespec(ft->create_time)) {
- ft->create_time = smb_fname->st.st_ex_btime;
- } else {
- set_createtime = true;
- }
-
- if (null_timespec(ft->ctime)) {
- ft->ctime = smb_fname->st.st_ex_ctime;
+ action &= ~FILE_NOTIFY_CHANGE_CREATION;
}
if (null_timespec(ft->atime)) {
- ft->atime= smb_fname->st.st_ex_atime;
action &= ~FILE_NOTIFY_CHANGE_LAST_ACCESS;
}
if (null_timespec(ft->mtime)) {
- ft->mtime = smb_fname->st.st_ex_mtime;
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
action &= ~FILE_NOTIFY_CHANGE_LAST_WRITE;
}
+ /* Ensure the resolution is the correct for
+ * what we can store on this filesystem. */
+
+ round_timespec(conn->ts_res, &ft->create_time);
+ round_timespec(conn->ts_res, &ft->ctime);
+ round_timespec(conn->ts_res, &ft->atime);
+ round_timespec(conn->ts_res, &ft->mtime);
+
DEBUG(5,("smb_set_filetime: actime: %s\n ",
time_to_asc(convert_timespec_to_time_t(ft->atime))));
DEBUG(5,("smb_set_filetime: modtime: %s\n ",
DEBUG(5,("smb_set_file_time: createtime: %s\n ",
time_to_asc(convert_timespec_to_time_t(ft->create_time))));
- /*
- * Try and set the times of this file if
- * they are different from the current values.
- */
-
- {
- struct timespec mts = smb_fname->st.st_ex_mtime;
- struct timespec ats = smb_fname->st.st_ex_atime;
- if ((timespec_compare(&ft->atime, &ats) == 0) &&
- (timespec_compare(&ft->mtime, &mts) == 0)) {
- if (set_createtime) {
- notify_fname(conn, NOTIFY_ACTION_MODIFIED,
- FILE_NOTIFY_CHANGE_CREATION,
- smb_fname->base_name);
- }
- return NT_STATUS_OK;
- }
- }
-
if (setting_write_time) {
/*
* This was a Windows setfileinfo on an open file.
return status;
}
+/****************************************************************************
+ Deal with SMB_FILE_FULL_EA_INFORMATION set.
+****************************************************************************/
+
+static NTSTATUS smb_set_file_full_ea_info(connection_struct *conn,
+ const char *pdata,
+ int total_data,
+ files_struct *fsp)
+{
+ struct ea_list *ea_list = NULL;
+ NTSTATUS status;
+
+ if (!fsp) {
+ return NT_STATUS_INVALID_HANDLE;
+ }
+
+ if (!lp_ea_support(SNUM(conn))) {
+ DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u but "
+ "EA's not supported.\n",
+ (unsigned int)total_data));
+ return NT_STATUS_EAS_NOT_SUPPORTED;
+ }
+
+ if (total_data < 10) {
+ DEBUG(10, ("smb_set_file_full_ea_info - ea_len = %u "
+ "too small.\n",
+ (unsigned int)total_data));
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+
+ ea_list = read_nttrans_ea_list(talloc_tos(),
+ pdata,
+ total_data);
+
+ if (!ea_list) {
+ return NT_STATUS_INVALID_PARAMETER;
+ }
+ status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
+
+ DEBUG(10, ("smb_set_file_full_ea_info on file %s returned %s\n",
+ smb_fname_str_dbg(fsp->fsp_name),
+ nt_errstr(status) ));
+
+ return status;
+}
+
+
/****************************************************************************
Deal with SMB_SET_FILE_DISPOSITION_INFO.
****************************************************************************/
break;
}
+ case SMB_FILE_FULL_EA_INFORMATION:
+ {
+ status = smb_set_file_full_ea_info(conn,
+ pdata,
+ total_data,
+ fsp);
+ break;
+ }
+
/* From tridge Samba4 :
* MODE_INFORMATION in setfileinfo (I have no
* idea what "mode information" on a file is - it takes a value of 0,