#include "smbd/globals.h"
#include "../libcli/auth/libcli_auth.h"
-extern enum protocol_types Protocol;
-
#define DIR_ENTRY_SAFETY_MARGIN 4096
static char *store_file_unix_basic(connection_struct *conn,
static const char * const prohibited_ea_names[] = {
SAMBA_POSIX_INHERITANCE_EA_NAME,
SAMBA_XATTR_DOS_ATTRIB,
+ SAMBA_XATTR_DOSTIMESTAMPS,
+ SAMBA_XATTR_MARKER,
NULL
};
ssize_t sizeret = -1;
if (!lp_ea_support(SNUM(conn))) {
- *pnames = NULL;
+ if (pnames) {
+ *pnames = NULL;
+ }
*pnum_names = 0;
return NT_STATUS_OK;
}
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;
}
fname, mask);
state->got_exact_match = got_match;
if (!got_match) {
- got_match = mask_match(fname, mask,
+ got_match = mask_match(fname, mask, get_Protocol(),
state->conn->case_sensitive);
}
state->got_exact_match = got_match;
if (!got_match) {
got_match = mask_match(mangled_name, mask,
+ get_Protocol(),
state->conn->case_sensitive);
}
}
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,
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;
mdate_ts = smb_fname->st.st_ex_mtime;
adate_ts = smb_fname->st.st_ex_atime;
- create_date_ts = get_create_timespec(NULL, smb_fname);
- cdate_ts = get_change_timespec(NULL, smb_fname);
+ 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);
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 */
+ if (pad) {
+ 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) {
case SMB_FIND_INFO_STANDARD:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_INFO_STANDARD\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_INFO_STANDARD\n"));
if(requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
break;
case SMB_FIND_EA_SIZE:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_SIZE\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_SIZE\n"));
if (requires_resume_key) {
SIVAL(p,0,reskey);
p += 4;
struct ea_list *file_list = NULL;
size_t ea_len = 0;
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_EA_LIST\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_EA_LIST\n"));
if (!name_list) {
return false;
}
/* Max string size is 255 bytes. */
if (PTR_DIFF(p + 255 + ea_len,pdata) > space_remaining) {
*out_of_space = true;
- DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
+ DEBUG(9,("smbd_marshall_dir_entry: out of space\n"));
return False; /* Not finished - just out of space */
}
}
case SMB_FIND_FILE_BOTH_DIRECTORY_INFO:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_BOTH_DIRECTORY_INFO\n"));
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,cdate_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"));
+ DEBUG(10,("smbd_marshall_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,cdate_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"));
+ DEBUG(10,("smbd_marshall_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,cdate_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:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_NAMES_INFO\n"));
p += 4;
SIVAL(p,0,reskey); p += 4;
p += 4;
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"));
+ DEBUG(10,("smbd_marshall_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,cdate_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:
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_ID_BOTH_DIRECTORY_INFO\n"));
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,cdate_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. */
/* Begin of SMB_QUERY_FILE_UNIX_BASIC */
if (info_level == SMB_FIND_FILE_UNIX) {
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX\n"));
p = store_file_unix_basic(conn, p,
NULL, &smb_fname->st);
len = srvstr_push(base_data, flags2, p,
fname, PTR_DIFF(end_data, p),
STR_TERMINATE);
} else {
- DEBUG(10,("get_lanman2_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
+ DEBUG(10,("smbd_marshall_dir_entry: SMB_FIND_FILE_UNIX_INFO2\n"));
p = store_file_unix_basic_info2(conn, p,
NULL, &smb_fname->st);
nameptr = p;
}
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;
if (PTR_DIFF(p,pdata) > space_remaining) {
*out_of_space = true;
- DEBUG(9,("get_lanman2_dir_entry: out of space\n"));
+ DEBUG(9,("smbd_marshall_dir_entry: out of space\n"));
return false; /* Not finished - just out of space */
}
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,
+ bool 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)
+{
+ uint8_t align = 4;
+ const bool do_pad = true;
+
+ if (info_level >= 1 && info_level <= 3) {
+ /* No alignment on earlier info levels. */
+ align = 1;
+ }
+
+ return smbd_dirptr_lanman2_entry(ctx, conn, dirptr, flags2,
+ path_mask, dirtype, info_level,
+ requires_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.
****************************************************************************/
if(numentries == 0) {
dptr_close(sconn, &dptr_num);
- if (Protocol < PROTOCOL_NT1) {
+ if (get_Protocol() < PROTOCOL_NT1) {
reply_doserror(req, ERRDOS, ERRnofiles);
goto out;
} else {
requires_resume_key = (findnext_flags & FLAG_TRANS2_FIND_REQUIRE_RESUME);
continue_bit = (findnext_flags & FLAG_TRANS2_FIND_CONTINUE);
- srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
+ if (!continue_bit) {
+ /* We only need resume_name if continue_bit is zero. */
+ srvstr_get_path_wcard(ctx, params, req->flags2, &resume_name,
params+12,
total_params - 12, STR_TERMINATE, &ntstatus,
&mask_contains_wcard);
- if (!NT_STATUS_IS_OK(ntstatus)) {
- /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
- complain (it thinks we're asking for the directory above the shared
- path or an invalid name). Catch this as the resume name is only compared, never used in
- a file access. JRA. */
- srvstr_pull_talloc(ctx, params, req->flags2,
+ if (!NT_STATUS_IS_OK(ntstatus)) {
+ /* Win9x or OS/2 can send a resume name of ".." or ".". This will cause the parser to
+ complain (it thinks we're asking for the directory above the shared
+ path or an invalid name). Catch this as the resume name is only compared, never used in
+ a file access. JRA. */
+ srvstr_pull_talloc(ctx, params, req->flags2,
&resume_name, params+12,
total_params - 12,
STR_TERMINATE);
- if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
- reply_nterror(req, ntstatus);
- return;
+ if (!resume_name || !(ISDOT(resume_name) || ISDOTDOT(resume_name))) {
+ reply_nterror(req, ntstatus);
+ return;
+ }
}
}
close_after_request=%d, close_if_end = %d requires_resume_key = %d \
resume_key = %d resume name = %s continue=%d level = %d\n",
dptr_num, max_data_bytes, maxentries, close_after_request, close_if_end,
- requires_resume_key, resume_key, resume_name, continue_bit, info_level));
+ requires_resume_key, resume_key,
+ resume_name ? resume_name : "(NULL)", continue_bit, info_level));
if (!maxentries) {
/* W2K3 seems to treat zero as 1. */
* depend on the last file name instead.
*/
- if(*resume_name && !continue_bit) {
+ if(!continue_bit && resume_name && *resume_name) {
SMB_STRUCT_STAT st;
long current_pos = 0;
int snum = SNUM(conn);
char *fstype = lp_fstype(SNUM(conn));
uint32 additional_flags = 0;
- struct smb_filename *smb_fname_dot = NULL;
+ struct smb_filename smb_fname_dot;
SMB_STRUCT_STAT st;
- NTSTATUS status;
if (IS_IPC(conn)) {
if (info_level != SMB_QUERY_CIFS_UNIX_INFO) {
DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level));
- status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL,
- &smb_fname_dot);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ ZERO_STRUCT(smb_fname_dot);
+ smb_fname_dot.base_name = discard_const_p(char, ".");
- if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) {
+ if(SMB_VFS_STAT(conn, &smb_fname_dot) != 0) {
DEBUG(2,("stat of . failed (%s)\n", strerror(errno)));
- TALLOC_FREE(smb_fname_dot);
return map_nt_error_from_unix(errno);
}
- st = smb_fname_dot->st;
- TALLOC_FREE(smb_fname_dot);
+ st = smb_fname_dot.st;
*ppdata = (char *)SMB_REALLOC(
*ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN);
/* 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,
unsigned int data_size;
struct timespec create_time_ts, mtime_ts, atime_ts, ctime_ts;
time_t create_time, mtime, atime, c_time;
- SMB_STRUCT_STAT sbuf;
+ 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 = 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);
+ 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);
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,ctime_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 - "));
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,ctime_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,ctime_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,ctime_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_file_time *ft,
bool setting_write_time)
{
- struct smb_filename *smb_fname_base = NULL;
+ struct smb_filename smb_fname_base;
uint32 action =
FILE_NOTIFY_CHANGE_LAST_ACCESS
|FILE_NOTIFY_CHANGE_LAST_WRITE
|FILE_NOTIFY_CHANGE_CREATION;
- NTSTATUS status;
if (!VALID_STAT(smb_fname->st)) {
return NT_STATUS_OBJECT_NAME_NOT_FOUND;
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(10,("smb_set_file_time: setting utimes to modified values.\n"));
/* Always call ntimes on the base, even if a stream was passed in. */
- status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name,
- NULL, &smb_fname->st,
- &smb_fname_base);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ smb_fname_base = *smb_fname;
+ smb_fname_base.stream_name = NULL;
- if(file_ntimes(conn, smb_fname_base, ft)!=0) {
- TALLOC_FREE(smb_fname_base);
+ if(file_ntimes(conn, &smb_fname_base, ft)!=0) {
return map_nt_error_from_unix(errno);
}
- TALLOC_FREE(smb_fname_base);
notify_fname(conn, NOTIFY_ACTION_MODIFIED, action,
smb_fname->base_name);
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.
****************************************************************************/
const char *pdata,
int total_data,
files_struct *fsp,
- const struct smb_filename *smb_fname)
+ struct smb_filename *smb_fname)
{
NTSTATUS status = NT_STATUS_OK;
bool delete_on_close;
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,
static void handle_trans2(connection_struct *conn, struct smb_request *req,
struct trans_state *state)
{
- if (Protocol >= PROTOCOL_NT1) {
+ if (get_Protocol() >= PROTOCOL_NT1) {
req->flags2 |= 0x40; /* IS_LONG_NAME */
SSVAL(req->inbuf,smb_flg2,req->flags2);
}