summaryrefslogtreecommitdiffstats
path: root/source/smbd/reply.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/smbd/reply.c')
-rw-r--r--source/smbd/reply.c678
1 files changed, 454 insertions, 224 deletions
diff --git a/source/smbd/reply.c b/source/smbd/reply.c
index c48bebb0c6c..14b16e1ae23 100644
--- a/source/smbd/reply.c
+++ b/source/smbd/reply.c
@@ -44,9 +44,12 @@ extern BOOL global_encrypted_passwords_negotiated;
set.
****************************************************************************/
+/* Custom version for processing POSIX paths. */
+#define IS_PATH_SEP(c,posix_only) ((c) == '/' || (!(posix_only) && (c) == '\\'))
+
NTSTATUS check_path_syntax_internal(pstring destname,
const pstring srcname,
- BOOL windows_path,
+ BOOL posix_path,
BOOL *p_last_component_contains_wcard)
{
char *d = destname;
@@ -57,12 +60,12 @@ NTSTATUS check_path_syntax_internal(pstring destname,
*p_last_component_contains_wcard = False;
while (*s) {
- if (IS_DIRECTORY_SEP(*s)) {
+ if (IS_PATH_SEP(*s,posix_path)) {
/*
* Safe to assume is not the second part of a mb char as this is handled below.
*/
/* Eat multiple '/' or '\\' */
- while (IS_DIRECTORY_SEP(*s)) {
+ while (IS_PATH_SEP(*s,posix_path)) {
s++;
}
if ((d != destname) && (*s != '\0')) {
@@ -77,7 +80,7 @@ NTSTATUS check_path_syntax_internal(pstring destname,
}
if (start_of_name_component) {
- if ((s[0] == '.') && (s[1] == '.') && (IS_DIRECTORY_SEP(s[2]) || s[2] == '\0')) {
+ if ((s[0] == '.') && (s[1] == '.') && (IS_PATH_SEP(s[2],posix_path) || s[2] == '\0')) {
/* Uh oh - "/../" or "\\..\\" or "/..\0" or "\\..\0" ! */
/*
@@ -107,8 +110,8 @@ NTSTATUS check_path_syntax_internal(pstring destname,
/* We're still at the start of a name component, just the previous one. */
continue;
- } else if ((s[0] == '.') && ((s[1] == '\0') || IS_DIRECTORY_SEP(s[1]))) {
- if (!windows_path) {
+ } else if ((s[0] == '.') && ((s[1] == '\0') || IS_PATH_SEP(s[1],posix_path))) {
+ if (posix_path) {
/* Eat the '.' */
s++;
continue;
@@ -118,7 +121,7 @@ NTSTATUS check_path_syntax_internal(pstring destname,
}
if (!(*s & 0x80)) {
- if (windows_path) {
+ if (!posix_path) {
if (*s <= 0x1f) {
return NT_STATUS_OBJECT_NAME_INVALID;
}
@@ -176,7 +179,7 @@ NTSTATUS check_path_syntax_internal(pstring destname,
NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
{
BOOL ignore;
- return check_path_syntax_internal(destname, srcname, True, &ignore);
+ return check_path_syntax_internal(destname, srcname, False, &ignore);
}
/****************************************************************************
@@ -187,7 +190,7 @@ NTSTATUS check_path_syntax(pstring destname, const pstring srcname)
NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname, BOOL *p_contains_wcard)
{
- return check_path_syntax_internal(destname, srcname, True, p_contains_wcard);
+ return check_path_syntax_internal(destname, srcname, False, p_contains_wcard);
}
/****************************************************************************
@@ -196,10 +199,10 @@ NTSTATUS check_path_syntax_wcard(pstring destname, const pstring srcname, BOOL *
set (a safe assumption).
****************************************************************************/
-static NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname)
+NTSTATUS check_path_syntax_posix(pstring destname, const pstring srcname)
{
BOOL ignore;
- return check_path_syntax_internal(destname, srcname, False, &ignore);
+ return check_path_syntax_internal(destname, srcname, True, &ignore);
}
/****************************************************************************
@@ -224,6 +227,16 @@ size_t srvstr_get_path_wcard(char *inbuf, char *dest, const char *src, size_t de
*contains_wcard = False;
+ if (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) {
+ /*
+ * For a DFS path the function parse_dfs_path()
+ * will do the path processing, just make a copy.
+ */
+ pstrcpy(dest, tmppath);
+ *err = NT_STATUS_OK;
+ return ret;
+ }
+
if (lp_posix_pathnames()) {
*err = check_path_syntax_posix(dest, tmppath);
} else {
@@ -251,6 +264,17 @@ size_t srvstr_get_path(char *inbuf, char *dest, const char *src, size_t dest_len
} else {
ret = srvstr_pull( inbuf, tmppath_ptr, src, dest_len, src_len, flags);
}
+
+ if (SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES) {
+ /*
+ * For a DFS path the function parse_dfs_path()
+ * will do the path processing, just make a copy.
+ */
+ pstrcpy(dest, tmppath);
+ *err = NT_STATUS_OK;
+ return ret;
+ }
+
if (lp_posix_pathnames()) {
*err = check_path_syntax_posix(dest, tmppath);
} else {
@@ -631,7 +655,14 @@ int reply_checkpath(connection_struct *conn, char *inbuf,char *outbuf, int dum_s
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(name, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name);
+ if (!NT_STATUS_IS_OK(status)) {
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ END_PROFILE(SMBcheckpath);
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ goto path_err;
+ }
DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(inbuf,smb_vwv0)));
@@ -710,7 +741,14 @@ int reply_getatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBgetatr);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
/* dos smetimes asks for a stat of "" - it returns a "hidden directory"
under WfWg - weird! */
@@ -789,7 +827,14 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBsetatr);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -797,6 +842,12 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBsetatr);
+ return ERROR_NT(status);
+ }
+
if (fname[0] == '.' && fname[1] == '\0') {
/*
* Not sure here is the right place to catch this
@@ -806,12 +857,6 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(NT_STATUS_ACCESS_DENIED);
}
- status = check_name(conn, fname);
- if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBsetatr);
- return ERROR_NT(status);
- }
-
mode = SVAL(inbuf,smb_vwv0);
mtime = srv_make_unix_date3(inbuf+smb_vwv1);
@@ -827,7 +872,7 @@ int reply_setatr(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
}
}
- if (!set_filetime(conn,fname,mtime)) {
+ if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
END_PROFILE(SMBsetatr);
return UNIXERROR(ERRDOS, ERRnoaccess);
}
@@ -944,7 +989,14 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(nt_status);
}
- RESOLVE_DFSPATH_WCARD(path, conn, inbuf, outbuf);
+ nt_status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, path, &mask_contains_wcard);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ END_PROFILE(SMBsearch);
+ if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(nt_status);
+ }
p++;
status_len = SVAL(p, 0);
@@ -954,16 +1006,13 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
if (status_len == 0) {
SMB_STRUCT_STAT sbuf;
- pstring dir2;
pstrcpy(directory,path);
- pstrcpy(dir2,path);
nt_status = unix_convert(conn, directory, True, NULL, &sbuf);
if (!NT_STATUS_IS_OK(nt_status)) {
END_PROFILE(SMBsearch);
return ERROR_NT(nt_status);
}
- unix_format(dir2);
nt_status = check_name(conn, directory);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -971,23 +1020,16 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(nt_status);
}
- p = strrchr_m(dir2,'/');
- if (p == NULL) {
- pstrcpy(mask,dir2);
- *dir2 = 0;
- } else {
- *p = 0;
- pstrcpy(mask,p+1);
- }
-
p = strrchr_m(directory,'/');
if (!p) {
- *directory = 0;
+ pstrcpy(mask,directory);
+ pstrcpy(directory,".");
} else {
*p = 0;
+ pstrcpy(mask,p+1);
}
- if (strlen(directory) == 0) {
+ if (*directory == '\0') {
pstrcpy(directory,".");
}
memset((char *)status,'\0',21);
@@ -1007,6 +1049,11 @@ int reply_search(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
}
string_set(&conn->dirpath,dptr_path(dptr_num));
pstrcpy(mask, dptr_wcard(dptr_num));
+ /*
+ * For a 'continue' search we have no string. So
+ * check from the initial saved string.
+ */
+ mask_contains_wcard = ms_has_wild(mask);
}
p = smb_buf(outbuf) + 3;
@@ -1202,7 +1249,14 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBopen);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1210,6 +1264,12 @@ int reply_open(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBopen);
+ return ERROR_NT(status);
+ }
+
if (!map_open_params_to_ntcreate(fname, deny_mode, OPENX_FILE_EXISTS_OPEN,
&access_mask, &share_mode, &create_disposition, &create_options)) {
END_PROFILE(SMBopen);
@@ -1320,7 +1380,14 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBopenX);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1328,6 +1395,12 @@ int reply_open_and_X(connection_struct *conn, char *inbuf,char *outbuf,int lengt
return ERROR_NT(status);
}
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBopenX);
+ return ERROR_NT(status);
+ }
+
if (!map_open_params_to_ntcreate(fname, deny_mode, smb_ofun,
&access_mask,
&share_mode,
@@ -1470,7 +1543,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int com;
int outsize = 0;
uint32 fattr = SVAL(inbuf,smb_vwv0);
- struct utimbuf times;
+ struct timespec ts[2];
files_struct *fsp;
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
SMB_STRUCT_STAT sbuf;
@@ -1484,7 +1557,7 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
com = SVAL(inbuf,smb_com);
- times.modtime = srv_make_unix_date3(inbuf + smb_vwv1);
+ ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf + smb_vwv1)); /* mtime. */
srvstr_get_path(inbuf, fname, smb_buf(inbuf) + 1, sizeof(fname), 0, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
@@ -1492,7 +1565,14 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcreate);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -1500,6 +1580,12 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcreate);
+ return ERROR_NT(status);
+ }
+
if (fattr & aVOLID) {
DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
}
@@ -1531,8 +1617,8 @@ int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- times.actime = sbuf.st_atime;
- file_utime(conn, fname, &times);
+ ts[0] = get_atimespec(&sbuf); /* atime. */
+ file_ntimes(conn, fname, ts);
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,fsp->fnum);
@@ -1582,13 +1668,26 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
pstrcat(fname,"TMXXXXXX");
}
- RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBctemp);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBctemp);
return ERROR_NT(status);
}
+
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBctemp);
+ return ERROR_NT(status);
+ }
tmpfd = smb_mkstemp(fname);
if (tmpfd == -1) {
@@ -1858,6 +1957,12 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
if (dirtype == 0) {
dirtype = FILE_ATTRIBUTE_NORMAL;
}
+
+ status = check_name(conn, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
status = can_delete(conn,directory,dirtype,can_defer);
if (!NT_STATUS_IS_OK(status)) {
return status;
@@ -1920,6 +2025,13 @@ NTSTATUS unlink_internals(connection_struct *conn, uint32 dirtype,
}
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
+
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ CloseDir(dir_hnd);
+ return status;
+ }
+
status = can_delete(conn, fname, dirtype, can_defer);
if (!NT_STATUS_IS_OK(status)) {
continue;
@@ -1966,8 +2078,15 @@ int reply_unlink(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
END_PROFILE(SMBunlink);
return ERROR_NT(status);
}
-
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
+
+ status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &path_contains_wcard);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBunlink);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
DEBUG(3,("reply_unlink : %s\n",name));
@@ -3109,7 +3228,6 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
{
NTSTATUS status = NT_STATUS_OK;
int outsize = 0;
- time_t mtime;
files_struct *fsp = NULL;
START_PROFILE(SMBclose);
@@ -3151,8 +3269,8 @@ int reply_close(connection_struct *conn, char *inbuf,char *outbuf, int size,
* Take care of any time sent in the close.
*/
- mtime = srv_make_unix_date3(inbuf+smb_vwv1);
- fsp_set_pending_modtime(fsp, mtime);
+ fsp_set_pending_modtime(fsp,
+ convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv1)));
/*
* close_file() returns the unix errno if an error
@@ -3185,7 +3303,7 @@ int reply_writeclose(connection_struct *conn,
NTSTATUS close_status = NT_STATUS_OK;
SMB_OFF_T startpos;
char *data;
- time_t mtime;
+ struct timespec mtime;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBwriteclose);
@@ -3196,7 +3314,7 @@ int reply_writeclose(connection_struct *conn,
numtowrite = SVAL(inbuf,smb_vwv1);
startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv2);
- mtime = srv_make_unix_date3(inbuf+smb_vwv4);
+ mtime = convert_time_t_to_timespec(srv_make_unix_date3(inbuf+smb_vwv4));
data = smb_buf(inbuf) + 1;
if (numtowrite && is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
@@ -3206,7 +3324,7 @@ int reply_writeclose(connection_struct *conn,
nwritten = write_file(fsp,data,startpos,numtowrite);
- set_filetime(conn, fsp->fsp_name,mtime);
+ set_filetime(conn, fsp->fsp_name, mtime);
/*
* More insanity. W2K only closes the file if writelen > 0.
@@ -3598,7 +3716,14 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBmkdir);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, directory, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -3606,6 +3731,12 @@ int reply_mkdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
+ status = check_name(conn, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBmkdir);
+ return ERROR_NT(status);
+ }
+
status = create_directory(conn, directory);
DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
@@ -3810,7 +3941,14 @@ int reply_rmdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(directory, conn, inbuf, outbuf)
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBrmdir);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
status = unix_convert(conn, directory, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -3854,7 +3992,6 @@ static BOOL resolve_wildcards(const char *name1, char *name2)
char *p,*p2, *pname1, *pname2;
int available_space, actual_space;
-
pname1 = strrchr_m(name1,'/');
pname2 = strrchr_m(name2,'/');
@@ -4008,6 +4145,11 @@ NTSTATUS rename_internals_fsp(connection_struct *conn, files_struct *fsp, pstrin
return status;
}
+ status = check_name(conn, newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/* Ensure newname contains a '/' */
if(strrchr_m(newname,'/') == 0) {
pstring tmpstr;
@@ -4152,9 +4294,13 @@ static void notify_rename(connection_struct *conn, BOOL is_dir,
code.
****************************************************************************/
-NTSTATUS rename_internals(connection_struct *conn, pstring name,
- pstring newname, uint32 attrs,
- BOOL replace_if_exists, BOOL has_wild)
+NTSTATUS rename_internals(connection_struct *conn,
+ pstring name,
+ pstring newname,
+ uint32 attrs,
+ BOOL replace_if_exists,
+ BOOL src_has_wild,
+ BOOL dest_has_wild)
{
pstring directory;
pstring mask;
@@ -4165,20 +4311,22 @@ NTSTATUS rename_internals(connection_struct *conn, pstring name,
NTSTATUS status = NT_STATUS_OK;
SMB_STRUCT_STAT sbuf1, sbuf2;
struct share_mode_lock *lck = NULL;
+ struct smb_Dir *dir_hnd = NULL;
+ const char *dname;
+ long offset = 0;
+ pstring destname;
*directory = *mask = 0;
ZERO_STRUCT(sbuf1);
ZERO_STRUCT(sbuf2);
- status = unix_convert(conn, name, has_wild, last_component_src,
- &sbuf1);
+ status = unix_convert(conn, name, src_has_wild, last_component_src, &sbuf1);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
- status = unix_convert(conn, newname, True, last_component_dest,
- &sbuf2);
+ status = unix_convert(conn, newname, dest_has_wild, last_component_dest, &sbuf2);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
@@ -4212,10 +4360,11 @@ NTSTATUS rename_internals(connection_struct *conn, pstring name,
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
- if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params))
+ if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+ }
- if (!has_wild) {
+ if (!src_has_wild) {
/*
* No wildcards - just process the one file.
*/
@@ -4242,6 +4391,21 @@ NTSTATUS rename_internals(connection_struct *conn, pstring name,
conn->short_case_preserve, directory,
newname, last_component_dest, is_short_name));
+ /* Ensure the source name is valid for us to access. */
+ status = check_name(conn, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ /* The dest name still may have wildcards. */
+ if (dest_has_wild) {
+ if (!resolve_wildcards(directory,newname)) {
+ DEBUG(6, ("rename_internals: resolve_wildcards %s %s failed\n",
+ directory,newname));
+ return NT_STATUS_NO_MEMORY;
+ }
+ }
+
/*
* Check for special case with case preserving and not
* case sensitive, if directory and newname are identical,
@@ -4276,8 +4440,12 @@ NTSTATUS rename_internals(connection_struct *conn, pstring name,
}
}
- resolve_wildcards(directory,newname);
-
+ /* Ensure the dest name is valid for us to access. */
+ status = check_name(conn, newname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
/*
* The source object must exist.
*/
@@ -4369,136 +4537,130 @@ NTSTATUS rename_internals(connection_struct *conn, pstring name,
nt_errstr(status), directory,newname));
return status;
- } else {
- /*
- * Wildcards - process each file that matches.
- */
- struct smb_Dir *dir_hnd = NULL;
- const char *dname;
- long offset = 0;
- pstring destname;
-
- if (strequal(mask,"????????.???"))
- pstrcpy(mask,"*");
+ }
+
+ /*
+ * Wildcards - process each file that matches.
+ */
+ if (strequal(mask,"????????.???")) {
+ pstrcpy(mask,"*");
+ }
- status = check_name(conn, directory);
- if (!NT_STATUS_IS_OK(status)) {
- return status;
- }
+ status = check_name(conn, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- dir_hnd = OpenDir(conn, directory, mask, attrs);
- if (dir_hnd == NULL) {
- return map_nt_error_from_unix(errno);
- }
+ dir_hnd = OpenDir(conn, directory, mask, attrs);
+ if (dir_hnd == NULL) {
+ return map_nt_error_from_unix(errno);
+ }
- status = NT_STATUS_NO_SUCH_FILE;
- /*
- * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- * - gentest fix. JRA
- */
+ status = NT_STATUS_NO_SUCH_FILE;
+ /*
+ * Was status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ * - gentest fix. JRA
+ */
- while ((dname = ReadDirName(dir_hnd, &offset))) {
- pstring fname;
- BOOL sysdir_entry = False;
+ while ((dname = ReadDirName(dir_hnd, &offset))) {
+ pstring fname;
+ BOOL sysdir_entry = False;
- pstrcpy(fname,dname);
+ pstrcpy(fname,dname);
- /* Quick check for "." and ".." */
- if (fname[0] == '.') {
- if (!fname[1]
- || (fname[1] == '.' && !fname[2])) {
- if (attrs & aDIR) {
- sysdir_entry = True;
- } else {
- continue;
- }
+ /* Quick check for "." and ".." */
+ if (fname[0] == '.') {
+ if (!fname[1] || (fname[1] == '.' && !fname[2])) {
+ if (attrs & aDIR) {
+ sysdir_entry = True;
+ } else {
+ continue;
}
}
+ }
- if (!is_visible_file(conn, directory, dname, &sbuf1,
- False)) {
- continue;
- }
+ if (!is_visible_file(conn, directory, dname, &sbuf1, False)) {
+ continue;
+ }
- if(!mask_match(fname, mask, conn->case_sensitive)) {
- continue;
- }
+ if(!mask_match(fname, mask, conn->case_sensitive)) {
+ continue;
+ }
- if (sysdir_entry) {
- status = NT_STATUS_OBJECT_NAME_INVALID;
- break;
- }
+ if (sysdir_entry) {
+ status = NT_STATUS_OBJECT_NAME_INVALID;
+ break;
+ }
- status = NT_STATUS_ACCESS_DENIED;
- slprintf(fname, sizeof(fname)-1, "%s/%s", directory,
- dname);
- if (!vfs_object_exist(conn, fname, &sbuf1)) {
- status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
- DEBUG(6, ("rename %s failed. Error %s\n",
- fname, nt_errstr(status)));
- continue;
- }
- status = can_rename(conn,fname,attrs,&sbuf1);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(6, ("rename %s refused\n", fname));
- continue;
- }
- pstrcpy(destname,newname);
+ status = NT_STATUS_ACCESS_DENIED;
+ slprintf(fname, sizeof(fname)-1, "%s/%s", directory, dname);
+
+ /* Ensure the source name is valid for us to access. */
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ if (!vfs_object_exist(conn, fname, &sbuf1)) {
+ status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
+ DEBUG(6, ("rename %s failed. Error %s\n",
+ fname, nt_errstr(status)));
+ continue;
+ }
+ status = can_rename(conn,fname,attrs,&sbuf1);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(6, ("rename %s refused\n", fname));
+ continue;
+ }
+ pstrcpy(destname,newname);
- if (!resolve_wildcards(fname,destname)) {
- DEBUG(6, ("resolve_wildcards %s %s failed\n",
- fname, destname));
- continue;
- }
+ if (!resolve_wildcards(fname,destname)) {
+ DEBUG(6, ("resolve_wildcards %s %s failed\n",
+ fname, destname));
+ continue;
+ }
- if (strcsequal(fname,destname)) {
- rename_open_files(conn, NULL, sbuf1.st_dev,
- sbuf1.st_ino, newname);
- DEBUG(3,("rename_internals: identical names "
- "in wildcard rename %s - success\n",
- fname));
- count++;
- status = NT_STATUS_OK;
- continue;
- }
+ /* Ensure the dest name is valid for us to access. */
+ status = check_name(conn, destname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
- if (!replace_if_exists
- && vfs_file_exist(conn,destname, NULL)) {
- DEBUG(6,("file_exist %s\n", destname));
- status = NT_STATUS_OBJECT_NAME_COLLISION;
- continue;
- }
+ if (strcsequal(fname,destname)) {
+ rename_open_files(conn, NULL, sbuf1.st_dev,
+ sbuf1.st_ino, newname);
+ DEBUG(3,("rename_internals: identical names "
+ "in wildcard rename %s - success\n",
+ fname));
+ count++;
+ status = NT_STATUS_OK;
+ continue;
+ }
+
+ if (!replace_if_exists && vfs_file_exist(conn,destname, NULL)) {
+ DEBUG(6,("file_exist %s\n", destname));
+ status = NT_STATUS_OBJECT_NAME_COLLISION;
+ continue;
+ }
- if (rename_path_prefix_equal(fname, destname)) {
- return NT_STATUS_SHARING_VIOLATION;
- }
+ if (rename_path_prefix_equal(fname, destname)) {
+ return NT_STATUS_SHARING_VIOLATION;
+ }
- lck = get_share_mode_lock(NULL, sbuf1.st_dev,
- sbuf1.st_ino, NULL, NULL);
+ lck = get_share_mode_lock(NULL, sbuf1.st_dev,
+ sbuf1.st_ino, NULL, NULL);
- if (!SMB_VFS_RENAME(conn,fname,destname)) {
- rename_open_files(conn, lck, sbuf1.st_dev,
- sbuf1.st_ino, newname);
- count++;
- status = NT_STATUS_OK;
- }
- TALLOC_FREE(lck);
- DEBUG(3,("rename_internals: doing rename on %s -> "
- "%s\n",fname,destname));
+ if (!SMB_VFS_RENAME(conn,fname,destname)) {
+ rename_open_files(conn, lck, sbuf1.st_dev,
+ sbuf1.st_ino, newname);
+ count++;
+ status = NT_STATUS_OK;
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(lck);
+ DEBUG(3,("rename_internals: doing rename on %s -> "
+ "%s\n",fname,destname));
}
-
-#if 0
- /* Don't think needed any more - JRA. */
- if (!NT_STATUS_EQUAL(error,NT_STATUS_NO_SUCH_FILE)) {
- if (!rcdest && bad_path_dest) {
- if (ms_has_wild(last_component_dest))
- return NT_STATUS_OBJECT_NAME_INVALID;
- return NT_STATUS_OBJECT_PATH_NOT_FOUND;
- }
- }
-#endif
+ CloseDir(dir_hnd);
if (count == 0 && NT_STATUS_IS_OK(status)) {
status = map_nt_error_from_unix(errno);
@@ -4520,30 +4682,45 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
char *p;
uint32 attrs = SVAL(inbuf,smb_vwv0);
NTSTATUS status;
- BOOL path1_contains_wcard = False;
- BOOL path2_contains_wcard = False;
+ BOOL src_has_wcard = False;
+ BOOL dest_has_wcard = False;
START_PROFILE(SMBmv);
p = smb_buf(inbuf) + 1;
- p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path1_contains_wcard);
+ p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
return ERROR_NT(status);
}
p++;
- p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &path2_contains_wcard);
+ p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
return ERROR_NT(status);
}
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
+ status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &src_has_wcard);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBmv);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
+
+ status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wcard);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBmv);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
- status = rename_internals(conn, name, newname, attrs, False, path1_contains_wcard);
+ status = rename_internals(conn, name, newname, attrs, False, src_has_wcard, dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBmv);
if (open_was_deferred(SVAL(inbuf,smb_mid))) {
@@ -4567,8 +4744,12 @@ int reply_mv(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
* TODO: check error codes on all callers
*/
-NTSTATUS copy_file(char *src, char *dest1,connection_struct *conn, int ofun,
- int count, BOOL target_is_directory)
+NTSTATUS copy_file(connection_struct *conn,
+ char *src,
+ char *dest1,
+ int ofun,
+ int count,
+ BOOL target_is_directory)
{
SMB_STRUCT_STAT src_sbuf, sbuf2;
SMB_OFF_T ret=-1;
@@ -4653,7 +4834,7 @@ NTSTATUS copy_file(char *src, char *dest1,connection_struct *conn, int ofun,
close_file(fsp1,NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- fsp_set_pending_modtime( fsp2, src_sbuf.st_mtime);
+ fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf));
/*
* As we are opening fsp1 read-only we only expect
@@ -4688,14 +4869,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int count=0;
int error = ERRnoaccess;
int err = 0;
- BOOL has_wild;
- BOOL exists=False;
int tid2 = SVAL(inbuf,smb_vwv0);
int ofun = SVAL(inbuf,smb_vwv1);
int flags = SVAL(inbuf,smb_vwv2);
BOOL target_is_directory=False;
- BOOL path_contains_wcard1 = False;
- BOOL path_contains_wcard2 = False;
+ BOOL source_has_wild = False;
+ BOOL dest_has_wild = False;
SMB_STRUCT_STAT sbuf1, sbuf2;
NTSTATUS status;
START_PROFILE(SMBcopy);
@@ -4703,12 +4882,12 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
*directory = *mask = 0;
p = smb_buf(inbuf);
- p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &path_contains_wcard1);
+ p += srvstr_get_path_wcard(inbuf, name, p, sizeof(name), 0, STR_TERMINATE, &status, &source_has_wild);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
return ERROR_NT(status);
}
- p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &path_contains_wcard2);
+ p += srvstr_get_path_wcard(inbuf, newname, p, sizeof(newname), 0, STR_TERMINATE, &status, &dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
return ERROR_NT(status);
@@ -4723,16 +4902,31 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
return ERROR_DOS(ERRSRV,ERRinvdevice);
}
- RESOLVE_DFSPATH_WCARD(name, conn, inbuf, outbuf);
- RESOLVE_DFSPATH_WCARD(newname, conn, inbuf, outbuf);
+ status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, name, &source_has_wild);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcopy);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
- status = unix_convert(conn, name, path_contains_wcard1, NULL, &sbuf1);
+ status = resolve_dfspath_wcard(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newname, &dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
return ERROR_NT(status);
}
- status = unix_convert(conn, newname, path_contains_wcard2, NULL, &sbuf2);
+ status = unix_convert(conn, name, source_has_wild, NULL, &sbuf1);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcopy);
+ return ERROR_NT(status);
+ }
+
+ status = unix_convert(conn, newname, dest_has_wild, NULL, &sbuf2);
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcopy);
return ERROR_NT(status);
@@ -4776,25 +4970,38 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
* Tine Smukavec <valentin.smukavec@hermes.si>.
*/
- if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params))
+ if (!VALID_STAT(sbuf1) && mangle_is_mangled(mask, conn->params)) {
mangle_check_cache( mask, sizeof(pstring)-1, conn->params );
+ }
- has_wild = path_contains_wcard1;
-
- if (!has_wild) {
+ if (!source_has_wild) {
pstrcat(directory,"/");
pstrcat(directory,mask);
- if (resolve_wildcards(directory,newname)
- && NT_STATUS_IS_OK(status = copy_file(
- directory,newname,conn,ofun,
- count,target_is_directory)))
- count++;
- if(!count && !NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBcopy);
+ if (dest_has_wild) {
+ if (!resolve_wildcards(directory,newname)) {
+ END_PROFILE(SMBcopy);
+ return ERROR_NT(NT_STATUS_NO_MEMORY);
+ }
+ }
+
+ status = check_name(conn, directory);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+
+ status = check_name(conn, newname);
+ if (!NT_STATUS_IS_OK(status)) {
return ERROR_NT(status);
}
- if (!count) {
- exists = vfs_file_exist(conn,directory,NULL);
+
+ status = copy_file(conn,directory,newname,ofun,
+ count,target_is_directory);
+
+ if(!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcopy);
+ return ERROR_NT(status);
+ } else {
+ count++;
}
} else {
struct smb_Dir *dir_hnd = NULL;
@@ -4833,13 +5040,27 @@ int reply_copy(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
error = ERRnoaccess;
slprintf(fname,sizeof(fname)-1, "%s/%s",directory,dname);
pstrcpy(destname,newname);
- if (resolve_wildcards(fname,destname) &&
- NT_STATUS_IS_OK(status = copy_file(
- fname,destname,conn,ofun,
- count,target_is_directory))) {
+ if (!resolve_wildcards(fname,destname)) {
+ continue;
+ }
+
+ status = check_name(conn, fname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+
+ status = check_name(conn, destname);
+ if (!NT_STATUS_IS_OK(status)) {
+ return ERROR_NT(status);
+ }
+
+ DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname, destname));
+
+ status = copy_file(conn,fname,destname,ofun,
+ count,target_is_directory);
+ if (NT_STATUS_IS_OK(status)) {
count++;
}
- DEBUG(3,("reply_copy : doing copy on %s -> %s\n",fname,destname));
}
CloseDir(dir_hnd);
}
@@ -4888,7 +5109,14 @@ int reply_setdir(connection_struct *conn, char *inbuf,char *outbuf, int dum_size
return ERROR_NT(status);
}
- RESOLVE_DFSPATH(newdir, conn, inbuf, outbuf);
+ status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, newdir);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(pathworks_setdir);
+ if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+ return ERROR_BOTH(NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
+ }
+ return ERROR_NT(status);
+ }
if (strlen(newdir) != 0) {
if (!vfs_directory_exist(conn,newdir,NULL)) {
@@ -5440,7 +5668,7 @@ int reply_readbmpx(connection_struct *conn, char *inbuf,char *outbuf,int length,
int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
{
- struct utimbuf unix_times;
+ struct timespec ts[2];
int outsize = 0;
files_struct *fsp = file_fsp(inbuf,smb_vwv0);
START_PROFILE(SMBsetattrE);
@@ -5457,15 +5685,15 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
* time as UNIX can't set this.
*/
- unix_times.actime = srv_make_unix_date2(inbuf+smb_vwv3);
- unix_times.modtime = srv_make_unix_date2(inbuf+smb_vwv5);
+ ts[0] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv3)); /* atime. */
+ ts[1] = convert_time_t_to_timespec(srv_make_unix_date2(inbuf+smb_vwv5)); /* mtime. */
/*
* Patch from Ray Frush <frush@engr.colostate.edu>
* Sometimes times are sent as zero - ignore them.
*/
- if (null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
+ if (null_timespec(ts[0]) && null_timespec(ts[1])) {
/* Ignore request */
if( DEBUGLVL( 3 ) ) {
dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
@@ -5473,20 +5701,22 @@ int reply_setattrE(connection_struct *conn, char *inbuf,char *outbuf, int size,
}
END_PROFILE(SMBsetattrE);
return(outsize);
- } else if (!null_mtime(unix_times.actime) && null_mtime(unix_times.modtime)) {
+ } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
/* set modify time = to access time if modify time was unset */
- unix_times.modtime = unix_times.actime;
+ ts[1] = ts[0];
}
/* Set the date on this file */
/* Should we set pending modtime here ? JRA */
- if(file_utime(conn, fsp->fsp_name, &unix_times)) {
+ if(file_ntimes(conn, fsp->fsp_name, ts)) {
END_PROFILE(SMBsetattrE);
return ERROR_DOS(ERRDOS,ERRnoaccess);
}
- DEBUG( 3, ( "reply_setattrE fnum=%d actime=%d modtime=%d\n",
- fsp->fnum, (int)unix_times.actime, (int)unix_times.modtime ) );
+ DEBUG( 3, ( "reply_setattrE fnum=%d actime=%u modtime=%u\n",
+ fsp->fnum,
+ (unsigned int)ts[0].tv_sec,
+ (unsigned int)ts[1].tv_sec));
END_PROFILE(SMBsetattrE);
return(outsize);