unsigned int smb_echo_count = 0;
extern uint32 global_client_caps;
-extern struct current_user current_user;
extern bool global_encrypted_passwords_negotiated;
/****************************************************************************
}
*d = '\0';
+
return ret;
}
****************************************************************************/
bool check_fsp_open(connection_struct *conn, struct smb_request *req,
- files_struct *fsp, struct current_user *user)
+ files_struct *fsp)
{
if (!(fsp) || !(conn)) {
reply_nterror(req, NT_STATUS_INVALID_HANDLE);
return False;
}
- if (((conn) != (fsp)->conn) || user->vuid != (fsp)->vuid) {
+ if (((conn) != (fsp)->conn) || req->vuid != (fsp)->vuid) {
reply_nterror(req, NT_STATUS_INVALID_HANDLE);
return False;
}
****************************************************************************/
bool check_fsp(connection_struct *conn, struct smb_request *req,
- files_struct *fsp, struct current_user *user)
+ files_struct *fsp)
{
- if (!check_fsp_open(conn, req, fsp, user)) {
+ if (!check_fsp_open(conn, req, fsp)) {
return False;
}
if ((fsp)->is_directory) {
return True;
}
+/****************************************************************************
+ Check if we have a correct fsp pointing to a quota fake file. Replacement for
+ the CHECK_NTQUOTA_HANDLE_OK macro.
+****************************************************************************/
+
+bool check_fsp_ntquota_handle(connection_struct *conn, struct smb_request *req,
+ files_struct *fsp)
+{
+ if (!check_fsp_open(conn, req, fsp)) {
+ return false;
+ }
+
+ if (fsp->is_directory) {
+ return false;
+ }
+
+ if (fsp->fake_file_handle == NULL) {
+ return false;
+ }
+
+ if (fsp->fake_file_handle->type != FAKE_FILE_TYPE_QUOTA) {
+ return false;
+ }
+
+ if (fsp->fake_file_handle->private_data == NULL) {
+ return false;
+ }
+
+ return true;
+}
+
/****************************************************************************
Check if we have a correct fsp. Replacement for the FSP_BELONGS_CONN macro
****************************************************************************/
bool fsp_belongs_conn(connection_struct *conn, struct smb_request *req,
- files_struct *fsp, struct current_user *user)
+ files_struct *fsp)
{
if ((fsp) && (conn) && ((conn)==(fsp)->conn)
- && (current_user.vuid==(fsp)->vuid)) {
+ && (req->vuid == (fsp)->vuid)) {
return True;
}
void reply_setatr(struct smb_request *req)
{
+ struct timespec ts[2];
connection_struct *conn = req->conn;
char *fname = NULL;
int mode;
START_PROFILE(SMBsetatr);
+ ZERO_STRUCT(ts);
+
if (req->wct < 2) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
return;
mode = SVAL(req->inbuf,smb_vwv0);
mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ ts[1] = convert_time_t_to_timespec(mtime);
+ status = smb_set_file_time(conn, NULL, fname,
+ &sbuf, ts, true);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
+ END_PROFILE(SMBsetatr);
+ return;
+ }
+
if (mode != FILE_ATTRIBUTE_NORMAL) {
if (VALID_STAT_OF_DIR(sbuf))
mode |= aDIR;
}
}
- if (!set_filetime(conn,fname,convert_time_t_to_timespec(mtime))) {
- reply_unixerror(req, ERRDOS, ERRnoaccess);
- END_PROFILE(SMBsetatr);
- return;
- }
-
reply_outbuf(req, 0, 0);
DEBUG( 3, ( "setatr name=%s mode=%d\n", fname, mode ) );
bool mask_contains_wcard = False;
bool allow_long_path_components = (req->flags2 & FLAGS2_LONG_PATH_COMPONENTS) ? True : False;
TALLOC_CTX *ctx = talloc_tos();
+ bool ask_sharemode = lp_parm_bool(SNUM(conn), "smbd", "search ask sharemode", true);
START_PROFILE(SMBsearch);
}
for (i=numentries;(i<maxentries) && !finished;i++) {
- finished = !get_dir_entry(ctx,conn,mask,dirtype,&fname,
- &size,&mode,&date,check_descend);
+ finished = !get_dir_entry(ctx,
+ conn,
+ mask,
+ dirtype,
+ &fname,
+ &size,
+ &mode,
+ &date,
+ check_descend,
+ ask_sharemode);
if (!finished) {
char buf[DIR_STRUCT_SIZE];
memcpy(buf,status,21);
}
size = sbuf.st_size;
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
if (fattr & aDIR) {
- DEBUG(3,("attempt to open a directory %s\n",fname));
+ DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
close_file(fsp,ERROR_CLOSE);
reply_doserror(req, ERRDOS,ERRnoaccess);
END_PROFILE(SMBopen);
sbuf.st_size = get_allocation_size(conn,fsp,&sbuf);
}
- fattr = dos_mode(conn,fname,&sbuf);
+ fattr = dos_mode(conn,fsp->fsp_name,&sbuf);
mtime = sbuf.st_mtime;
if (fattr & aDIR) {
close_file(fsp,ERROR_CLOSE);
}
ts[0] = get_atimespec(&sbuf); /* atime. */
- file_ntimes(conn, fname, ts);
+ status = smb_set_file_time(conn, fsp, fsp->fsp_name, &sbuf, ts, true);
+ if (!NT_STATUS_IS_OK(status)) {
+ END_PROFILE(SMBcreate);
+ reply_openerror(req, status);
+ return;
+ }
reply_outbuf(req, 1, 0);
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
+ DEBUG( 2, ( "reply_mknew: file %s\n", fsp->fsp_name ) );
DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
- fname, fsp->fh->fd, (unsigned int)fattr ) );
+ fsp->fsp_name, fsp->fh->fd, (unsigned int)fattr ) );
END_PROFILE(SMBcreate);
return;
return;
}
- status = check_name(conn, CONST_DISCARD(char *,fname));
+ status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBctemp);
SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
/* the returned filename is relative to the directory */
- s = strrchr_m(fname, '/');
+ s = strrchr_m(fsp->fsp_name, '/');
if (!s) {
- s = fname;
+ s = fsp->fsp_name;
} else {
s++;
}
CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
- DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fname ) );
- DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fname, fsp->fh->fd,
- (unsigned int)sbuf.st_mode ) );
+ DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
+ DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+ fsp->fh->fd, (unsigned int)sbuf.st_mode ) );
END_PROFILE(SMBctemp);
return;
return NT_STATUS_OK;
}
- if (fsp->access_mask & DELETE_ACCESS) {
+ if (fsp->access_mask & (DELETE_ACCESS|FILE_WRITE_ATTRIBUTES)) {
return NT_STATUS_OK;
}
/* On open checks the open itself will check the share mode, so
don't do it here as we'll get it wrong. */
- status = open_file_ntcreate(conn, req, fname, &sbuf,
- DELETE_ACCESS,
- FILE_SHARE_NONE,
- FILE_OPEN,
- 0,
- FILE_ATTRIBUTE_NORMAL,
- req != NULL ? 0 : INTERNAL_OPEN_ONLY,
- NULL, &fsp);
+ status = create_file_unixpath
+ (conn, /* conn */
+ req, /* req */
+ fname, /* fname */
+ DELETE_ACCESS, /* access_mask */
+ FILE_SHARE_NONE, /* share_access */
+ FILE_OPEN, /* create_disposition*/
+ FILE_NON_DIRECTORY_FILE, /* create_options */
+ FILE_ATTRIBUTE_NORMAL, /* file_attributes */
+ 0, /* oplock_request */
+ 0, /* allocation_size */
+ NULL, /* sd */
+ NULL, /* ea_list */
+ &fsp, /* result */
+ NULL, /* pinfo */
+ &sbuf); /* psbuf */
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(10, ("open_file_ntcreate failed: %s\n",
+ DEBUG(10, ("create_file_unixpath failed: %s\n",
nt_errstr(status)));
return status;
}
/* The set is across all open files on this dev/inode pair. */
- if (!set_delete_on_close(fsp, True, ¤t_user.ut)) {
+ if (!set_delete_on_close(fsp, True, &conn->server_info->utok)) {
close_file(fsp, NORMAL_CLOSE);
return NT_STATUS_ACCESS_DENIED;
}
return status;
}
- dir_hnd = OpenDir(conn, directory, mask, dirtype);
+ dir_hnd = OpenDir(talloc_tos(), conn, directory, mask,
+ dirtype);
if (dir_hnd == NULL) {
return map_nt_error_from_unix(errno);
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
return status;
}
}
count++;
- DEBUG(3,("unlink_internals: succesful unlink [%s]\n",
+ DEBUG(3,("unlink_internals: successful unlink [%s]\n",
fname));
TALLOC_FREE(fname);
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
}
- if (count == 0 && NT_STATUS_IS_OK(status)) {
+ if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
status = map_nt_error_from_unix(errno);
}
* reply_readbraw has already checked the length.
*/
- if ( (chain_size == 0) && (nread > 0) &&
+ if ( (chain_size == 0) && (nread > 0) && (fsp->base_fsp == NULL) &&
(fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
char header[4];
DATA_BLOB header_blob;
_smb_setlen(header,nread);
header_blob = data_blob_const(header, 4);
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd,
+ if (SMB_VFS_SENDFILE(smbd_server_fd(), fsp,
&header_blob, startpos, nread) == -1) {
/* Returning ENOSYS means no data at all was sent.
* Do this as a normal read. */
*/
if (!fsp || !conn || conn != fsp->conn ||
- current_user.vuid != fsp->vuid ||
+ req->vuid != fsp->vuid ||
fsp->is_directory || fsp->fh->fd == -1) {
/*
* fsp could be NULL here so use the value from the packet. JRA.
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlockread);
return;
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBread);
return;
}
*/
if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
- !is_encrypted_packet(req->inbuf) &&
+ !is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
construct_reply_common((char *)req->inbuf, (char *)headerbuf);
setup_readX_header((char *)headerbuf, smb_maxcnt);
- if ((nread = SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, smb_maxcnt)) == -1) {
- /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
- if (errno == ENOSYS) {
+ if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
+ /* Returning ENOSYS or EINVAL means no data at all was sent.
+ Do this as a normal read. */
+ if (errno == ENOSYS || errno == EINVAL) {
goto normal_read;
}
return;
}
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBreadX);
return;
}
return;
}
- if (!big_readX
- && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
+ if (!big_readX &&
+ schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
END_PROFILE(SMBreadX);
return;
}
void reply_writebraw(struct smb_request *req)
{
connection_struct *conn = req->conn;
- int outsize = 0;
char *buf = NULL;
ssize_t nwritten=0;
ssize_t total_written=0;
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
error_to_writebrawerr(req);
END_PROFILE(SMBwritebraw);
return;
* it to send more bytes */
memcpy(buf, req->inbuf, smb_size);
- outsize = srv_set_message(buf,
- Protocol>PROTOCOL_COREPLUS?1:0,0,True);
+ srv_set_message(buf,Protocol>PROTOCOL_COREPLUS?1:0,0,True);
SCVAL(buf,smb_com,SMBwritebraw);
SSVALS(buf,smb_vwv0,0xFFFF);
show_msg(buf);
}
/* Now read the raw data into the buffer and write it */
- if (read_smb_length(smbd_server_fd(),buf,
- SMB_SECONDARY_WAIT, get_srv_read_error()) == -1) {
+ status = read_smb_length(smbd_server_fd(), buf, SMB_SECONDARY_WAIT,
+ &numtowrite);
+ if (!NT_STATUS_IS_OK(status)) {
exit_server_cleanly("secondary writebraw failed");
}
- /*
- * Even though this is not an smb message,
- * smb_len returns the generic length of a packet.
- */
-
- numtowrite = smb_len(buf);
-
/* Set up outbuf to return the correct size */
reply_outbuf(req, 1, 0);
(int)tcount,(int)nwritten,(int)numtowrite));
}
- if (read_data(smbd_server_fd(), buf+4, numtowrite,get_srv_read_error())
- != numtowrite ) {
+ status = read_data(smbd_server_fd(), buf+4, numtowrite);
+
+ if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("reply_writebraw: Oversize secondary write "
- "raw read failed (%s). Terminating\n",
- strerror(errno) ));
+ "raw read failed (%s). Terminating\n",
+ nt_errstr(status)));
exit_server_cleanly("secondary writebraw failed");
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteunlock);
return;
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwrite);
return;
}
startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
write_through = BITSETW(req->inbuf+smb_vwv7,0);
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteX);
return;
}
nwritten = 0;
} else {
- if (req->unread_bytes == 0 &&
- schedule_aio_write_and_X(conn, req, fsp, data,
- startpos, numtowrite)) {
+ if ((req->unread_bytes == 0) &&
+ schedule_aio_write_and_X(conn, req, fsp, data, startpos,
+ numtowrite)) {
END_PROFILE(SMBwriteX);
return;
}
-
+
nwritten = write_file(req,fsp,data,startpos,numtowrite);
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
return;
}
fnum = SVAL(req->inbuf,smb_vwv0);
fsp = file_fsp(fnum);
- if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp, ¤t_user)) {
+ if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
return;
}
* We can only use CHECK_FSP if we know it's not a directory.
*/
- if(!fsp || (fsp->conn != conn) || (fsp->vuid != current_user.vuid)) {
+ if(!fsp || (fsp->conn != conn) || (fsp->vuid != req->vuid)) {
reply_doserror(req, ERRDOS, ERRbadfid);
END_PROFILE(SMBclose);
return;
DEBUG(3,("close directory fnum=%d\n", fsp->fnum));
status = close_file(fsp,NORMAL_CLOSE);
} else {
+ time_t t;
/*
* Close ordinary file.
*/
* Take care of any time sent in the close.
*/
- fsp_set_pending_modtime(fsp, convert_time_t_to_timespec(
- srv_make_unix_date3(
- req->inbuf+smb_vwv1)));
+ t = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ set_close_write_time(fsp, convert_time_t_to_timespec(t));
/*
* close_file() returns the unix errno if an error
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteclose);
return;
}
nwritten = write_file(req,fsp,data,startpos,numtowrite);
- set_filetime(conn, fsp->fsp_name, mtime);
-
+ set_close_write_time(fsp, mtime);
+
/*
* More insanity. W2K only closes the file if writelen > 0.
* JRA.
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlock);
return;
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBunlock);
return;
}
}
/* Open for exclusive use, write only. */
- status = print_fsp_open(conn, NULL, &fsp);
+ status = print_fsp_open(conn, NULL, req->vuid, &fsp);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
START_PROFILE(SMBsplclose);
- if (req->wct < 3) {
+ if (req->wct < 1) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBsplclose);
return;
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplclose);
return;
}
return;
}
+ reply_outbuf(req, 0, 0);
+
END_PROFILE(SMBsplclose);
return;
}
fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplwr);
return;
}
const char *dname = NULL;
bool ret = True;
long offset = 0;
- struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
+ struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn, directory,
+ NULL, 0);
if(dir_hnd == NULL)
return False;
}
TALLOC_FREE(fullname);
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
return ret;
}
*/
const char *dname;
long dirpos = 0;
- struct smb_Dir *dir_hnd = OpenDir(conn, directory, NULL, 0);
+ struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
+ directory, NULL, 0);
if(dir_hnd == NULL) {
errno = ENOTEMPTY;
if (!is_visible_file(conn, directory, dname, &st, False))
continue;
if(!IS_VETO_PATH(conn, dname)) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
errno = ENOTEMPTY;
goto err;
}
}
TALLOC_FREE(fullname);
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
/* Retry the rmdir */
ret = SMB_VFS_RMDIR(conn,directory);
}
sharepaths we need to manipulate relative paths. */
/* TODO - create the absolute path and manipulate the newname
relative to the sharepath. */
- if (fsp->conn != conn) {
+ if (!strequal(fsp->conn->connectpath, conn->connectpath)) {
continue;
}
DEBUG(10,("rename_open_files: renaming file fnum %d (file_id %s) from %s -> %s\n",
return NT_STATUS_ACCESS_DENIED;
}
- lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL);
+ lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
+ NULL);
/*
* We have the file open ourselves, so not being able to get the
uint32 attrs,
bool replace_if_exists,
bool src_has_wild,
- bool dest_has_wild)
+ bool dest_has_wild,
+ uint32_t access_mask)
{
char *directory = NULL;
char *mask = NULL;
status = S_ISDIR(sbuf1.st_mode) ?
open_directory(conn, req, directory, &sbuf1,
- DELETE_ACCESS,
+ access_mask,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, NULL,
&fsp)
: open_file_ntcreate(conn, req, directory, &sbuf1,
- DELETE_ACCESS,
+ access_mask,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, 0, NULL,
&fsp);
return status;
}
- dir_hnd = OpenDir(conn, directory, mask, attrs);
+ dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, attrs);
if (dir_hnd == NULL) {
return map_nt_error_from_unix(errno);
}
status = S_ISDIR(sbuf1.st_mode) ?
open_directory(conn, req, fname, &sbuf1,
- DELETE_ACCESS,
+ access_mask,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, NULL,
&fsp)
: open_file_ntcreate(conn, req, fname, &sbuf1,
- DELETE_ACCESS,
+ access_mask,
FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, 0, 0, 0, NULL,
&fsp);
TALLOC_FREE(fname);
TALLOC_FREE(destname);
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
- if (count == 0 && NT_STATUS_IS_OK(status)) {
+ if (count == 0 && NT_STATUS_IS_OK(status) && errno != 0) {
status = map_nt_error_from_unix(errno);
}
DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
status = rename_internals(ctx, conn, req, name, newname, attrs, False,
- src_has_wcard, dest_has_wcard);
+ src_has_wcard, dest_has_wcard, DELETE_ACCESS);
if (!NT_STATUS_IS_OK(status)) {
if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
close_file(fsp1,NORMAL_CLOSE);
/* Ensure the modtime is set correctly on the destination file. */
- fsp_set_pending_modtime( fsp2, get_mtimespec(&src_sbuf));
+ set_close_write_time(fsp2, get_mtimespec(&src_sbuf));
/*
* As we are opening fsp1 read-only we only expect
return;
}
- dir_hnd = OpenDir(conn, directory, mask, 0);
+ dir_hnd = OpenDir(talloc_tos(), conn, directory, mask, 0);
if (dir_hnd == NULL) {
status = map_nt_error_from_unix(errno);
reply_nterror(req, status);
directory,
dname);
if (!fname) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBcopy);
return;
continue;
}
if (!destname) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
reply_nterror(req, NT_STATUS_NO_MEMORY);
END_PROFILE(SMBcopy);
return;
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
END_PROFILE(SMBcopy);
return;
status = check_name(conn, destname);
if (!NT_STATUS_IS_OK(status)) {
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
reply_nterror(req, status);
END_PROFILE(SMBcopy);
return;
TALLOC_FREE(fname);
TALLOC_FREE(destname);
}
- CloseDir(dir_hnd);
+ TALLOC_FREE(dir_hnd);
}
if (count == 0) {
lock_timeout = IVAL(req->inbuf,smb_vwv4);
large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
- if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlockingX);
return;
}
connection_struct *conn = req->conn;
struct timespec ts[2];
files_struct *fsp;
+ SMB_STRUCT_STAT sbuf;
+ NTSTATUS status;
START_PROFILE(SMBsetattrE);
* Sometimes times are sent as zero - ignore them.
*/
- if (null_timespec(ts[0]) && null_timespec(ts[1])) {
- /* Ignore request */
- if( DEBUGLVL( 3 ) ) {
- dbgtext( "reply_setattrE fnum=%d ", fsp->fnum);
- dbgtext( "ignoring zero request - not setting timestamps of 0\n" );
+ /* Ensure we have a valid stat struct for the source. */
+ if (fsp->fh->fd != -1) {
+ if (SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
+ status = map_nt_error_from_unix(errno);
+ reply_nterror(req, status);
+ END_PROFILE(SMBsetattrE);
+ return;
+ }
+ } else {
+ if (SMB_VFS_STAT(conn, fsp->fsp_name, &sbuf) == -1) {
+ status = map_nt_error_from_unix(errno);
+ reply_nterror(req, status);
+ END_PROFILE(SMBsetattrE);
+ return;
}
- END_PROFILE(SMBsetattrE);
- return;
- } else if (!null_timespec(ts[0]) && null_timespec(ts[1])) {
- /* set modify time = to access time if modify time was unset */
- ts[1] = ts[0];
}
- /* Set the date on this file */
- /* Should we set pending modtime here ? JRA */
- if(file_ntimes(conn, fsp->fsp_name, ts)) {
+ status = smb_set_file_time(conn, fsp, fsp->fsp_name,
+ &sbuf, ts, true);
+ if (!NT_STATUS_IS_OK(status)) {
reply_doserror(req, ERRDOS, ERRnoaccess);
END_PROFILE(SMBsetattrE);
return;