Copyright (C) Andrew Tridgell 1992-1998
Copyright (C) Andrew Bartlett 2001
Copyright (C) Jeremy Allison 1992-2007.
+ Copyright (C) Volker Lendecke 2007
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
return ret;
}
+/****************************************************************************
+ Check if we have a correct fsp pointing to a file. Replacement for the
+ CHECK_FSP macro.
+****************************************************************************/
+
+BOOL check_fsp(connection_struct *conn, struct smb_request *req,
+ files_struct *fsp, struct current_user *user)
+{
+ if (!(fsp) || !(conn)) {
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return False;
+ }
+ if (((conn) != (fsp)->conn) || user->vuid != (fsp)->vuid) {
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return False;
+ }
+ if ((fsp)->is_directory) {
+ reply_nterror(req, NT_STATUS_INVALID_DEVICE_REQUEST);
+ return False;
+ }
+ if ((fsp)->fh->fd == -1) {
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return False;
+ }
+ (fsp)->num_smb_operations++;
+ 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)
+{
+ if ((fsp) && (conn) && ((conn)==(fsp)->conn)
+ && (current_user.vuid==(fsp)->vuid)) {
+ return True;
+ }
+
+ reply_nterror(req, NT_STATUS_INVALID_HANDLE);
+ return False;
+}
+
/****************************************************************************
Reply to a (netbios-level) special message.
****************************************************************************/
Reply to a mknew or a create.
****************************************************************************/
-int reply_mknew(connection_struct *conn, char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_mknew(connection_struct *conn, struct smb_request *req)
{
pstring fname;
int com;
- int outsize = 0;
- uint32 fattr = SVAL(inbuf,smb_vwv0);
+ uint32 fattr = 0;
struct timespec ts[2];
files_struct *fsp;
- int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
+ int oplock_request = 0;
SMB_STRUCT_STAT sbuf;
NTSTATUS status;
uint32 access_mask = FILE_GENERIC_READ | FILE_GENERIC_WRITE;
uint32 share_mode = FILE_SHARE_READ|FILE_SHARE_WRITE;
uint32 create_disposition;
uint32 create_options = 0;
- struct smb_request req;
START_PROFILE(SMBcreate);
- init_smb_request(&req, (uint8 *)inbuf);
-
- com = SVAL(inbuf,smb_com);
+ if (req->wct < 3) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBcreate);
+ return;
+ }
- ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(inbuf + smb_vwv1)); /* mtime. */
+ fattr = SVAL(req->inbuf,smb_vwv0);
+ oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
+ com = SVAL(req->inbuf,smb_com);
- srvstr_get_path(inbuf, SVAL(inbuf,smb_flg2), fname, smb_buf(inbuf) + 1,
- sizeof(fname), 0, STR_TERMINATE, &status);
+ ts[1] =convert_time_t_to_timespec(
+ srv_make_unix_date3(req->inbuf + smb_vwv1));
+ /* mtime. */
+
+ srvstr_get_path((char *)req->inbuf, req->flags2, fname,
+ smb_buf(req->inbuf) + 1, sizeof(fname), 0,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
END_PROFILE(SMBcreate);
- return ERROR_NT(status);
+ return;
}
- status = resolve_dfspath(conn, SVAL(inbuf,smb_flg2) & FLAGS2_DFS_PATHNAMES, fname);
+ status = resolve_dfspath(conn, req->flags2 & 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);
+ reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
+ ERRSRV, ERRbadpath);
+ return;
}
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
status = unix_convert(conn, fname, False, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
END_PROFILE(SMBcreate);
- return ERROR_NT(status);
+ return;
}
status = check_name(conn, fname);
if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
END_PROFILE(SMBcreate);
- return ERROR_NT(status);
+ return;
}
if (fattr & aVOLID) {
- DEBUG(0,("Attempt to create file (%s) with volid set - please report this\n",fname));
+ DEBUG(0,("Attempt to create file (%s) with volid set - "
+ "please report this\n", fname));
}
if(com == SMBmknew) {
}
/* Open file using ntcreate. */
- status = open_file_ntcreate(conn, &req, fname, &sbuf,
+ status = open_file_ntcreate(conn, req, fname, &sbuf,
access_mask,
share_mode,
create_disposition,
fattr,
oplock_request,
NULL, &fsp);
-
+
if (!NT_STATUS_IS_OK(status)) {
END_PROFILE(SMBcreate);
- if (open_was_deferred(SVAL(inbuf,smb_mid))) {
+ if (open_was_deferred(req->mid)) {
/* We have re-scheduled this call. */
- return -1;
+ return;
}
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
-
+
ts[0] = get_atimespec(&sbuf); /* atime. */
file_ntimes(conn, fname, ts);
- outsize = set_message(inbuf,outbuf,1,0,True);
- SSVAL(outbuf,smb_vwv0,fsp->fnum);
+ reply_outbuf(req, 1, 0);
+
+ SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ SCVAL(req->outbuf,smb_flg,
+ CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
-
+
if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) {
- SCVAL(outbuf,smb_flg,CVAL(outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
+ SCVAL(req->outbuf,smb_flg,
+ CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
}
-
+
DEBUG( 2, ( "reply_mknew: file %s\n", fname ) );
- DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n", fname, fsp->fh->fd, (unsigned int)fattr ) );
+ DEBUG( 3, ( "reply_mknew %s fd=%d dmode=0x%x\n",
+ fname, fsp->fh->fd, (unsigned int)fattr ) );
END_PROFILE(SMBcreate);
- return(outsize);
+ return;
}
/****************************************************************************
Fake (read/write) sendfile. Returns -1 on read or write fail.
****************************************************************************/
-static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos, size_t nread, char *buf, size_t bufsize)
+static ssize_t fake_sendfile(files_struct *fsp, SMB_OFF_T startpos,
+ size_t nread)
{
+ size_t bufsize;
size_t tosend = nread;
+ char *buf;
+
+ if (nread == 0) {
+ return 0;
+ }
+
+ bufsize = MIN(nread, 65536);
+
+ if (!(buf = SMB_MALLOC_ARRAY(char, bufsize))) {
+ return -1;
+ }
while (tosend > 0) {
ssize_t ret;
}
ret = read_file(fsp,buf,startpos,cur_read);
if (ret == -1) {
+ SAFE_FREE(buf);
return -1;
}
}
if (write_data(smbd_server_fd(),buf,cur_read) != cur_read) {
+ SAFE_FREE(buf);
return -1;
}
tosend -= cur_read;
startpos += cur_read;
}
+ SAFE_FREE(buf);
return (ssize_t)nread;
}
+/****************************************************************************
+ Return a readbraw error (4 bytes of zero).
+****************************************************************************/
+
+static void reply_readbraw_error(void)
+{
+ char header[4];
+ SIVAL(header,0,0);
+ if (write_data(smbd_server_fd(),header,4) != 4) {
+ fail_readraw();
+ }
+}
+
/****************************************************************************
Use sendfile in readbraw.
****************************************************************************/
-void send_file_readbraw(connection_struct *conn, files_struct *fsp, SMB_OFF_T startpos, size_t nread,
- ssize_t mincount, char *outbuf, int out_buffsize)
+void send_file_readbraw(connection_struct *conn,
+ files_struct *fsp,
+ SMB_OFF_T startpos,
+ size_t nread,
+ ssize_t mincount)
{
+ char *outbuf = NULL;
ssize_t ret=0;
#if defined(WITH_SENDFILE)
if ( (chain_size == 0) && (nread > 0) &&
(fsp->wcp == NULL) && lp_use_sendfile(SNUM(conn)) ) {
- DATA_BLOB header;
+ char header[4];
+ DATA_BLOB header_blob;
- _smb_setlen(outbuf,nread);
- header.data = (uint8 *)outbuf;
- header.length = 4;
- header.free = NULL;
+ _smb_setlen(header,nread);
+ header_blob = data_blob_const(header, 4);
- if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd, &header, startpos, nread) == -1) {
- /* Returning ENOSYS means no data at all was sent. Do this as a normal read. */
+ if ( SMB_VFS_SENDFILE( smbd_server_fd(), fsp, fsp->fh->fd,
+ &header_blob, startpos, nread) == -1) {
+ /* Returning ENOSYS means no data at all was sent.
+ * Do this as a normal read. */
if (errno == ENOSYS) {
goto normal_readbraw;
}
set_use_sendfile(SNUM(conn), False);
DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
- if (fake_sendfile(fsp, startpos, nread, outbuf + 4, out_buffsize - 4) == -1) {
+ if (fake_sendfile(fsp, startpos, nread) == -1) {
DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readbraw fake_sendfile failed");
normal_readbraw:
+ outbuf = TALLOC_ARRAY(NULL, char, nread+4);
+ if (!outbuf) {
+ DEBUG(0,("send_file_readbraw: TALLOC_ARRAY failed for size %u.\n",
+ (unsigned)(nread+4)));
+ reply_readbraw_error();
+ return;
+ }
+
if (nread > 0) {
ret = read_file(fsp,outbuf+4,startpos,nread);
#if 0 /* mincount appears to be ignored in a W2K server. JRA. */
_smb_setlen(outbuf,ret);
if (write_data(smbd_server_fd(),outbuf,4+ret) != 4+ret)
fail_readraw();
+
+ TALLOC_FREE(outbuf);
}
/****************************************************************************
Reply to a readbraw (core+ protocol).
****************************************************************************/
-int reply_readbraw(connection_struct *conn, char *inbuf, char *outbuf, int dum_size, int out_buffsize)
+void reply_readbraw(connection_struct *conn, struct smb_request *req)
{
ssize_t maxcount,mincount;
size_t nread = 0;
SMB_OFF_T startpos;
- char *header = outbuf;
files_struct *fsp;
+ SMB_STRUCT_STAT st;
+ SMB_OFF_T size = 0;
+
START_PROFILE(SMBreadbraw);
if (srv_is_signing_active()) {
- exit_server_cleanly("reply_readbraw: SMB signing is active - raw reads/writes are disallowed.");
+ exit_server_cleanly("reply_readbraw: SMB signing is active - "
+ "raw reads/writes are disallowed.");
+ }
+
+ if (req->wct < 8) {
+ reply_readbraw_error();
+ END_PROFILE(SMBreadbraw);
+ return;
}
/*
* return a zero length response here.
*/
- fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+ fsp = file_fsp(SVAL(req->inbuf,smb_vwv0));
- if (!FNUM_OK(fsp,conn) || !fsp->can_read) {
+ /*
+ * We have to do a check_fsp by hand here, as
+ * we must always return 4 zero bytes on error,
+ * not a NTSTATUS.
+ */
+
+ if (!fsp || !conn || conn != fsp->conn ||
+ current_user.vuid != fsp->vuid ||
+ fsp->is_directory || fsp->fh->fd == -1) {
/*
* fsp could be NULL here so use the value from the packet. JRA.
*/
- DEBUG(3,("fnum %d not open in readbraw - cache prime?\n",(int)SVAL(inbuf,smb_vwv0)));
- _smb_setlen(header,0);
- if (write_data(smbd_server_fd(),header,4) != 4)
- fail_readraw();
+ DEBUG(3,("reply_readbraw: fnum %d not valid "
+ "- cache prime?\n",
+ (int)SVAL(req->inbuf,smb_vwv0)));
+ reply_readbraw_error();
END_PROFILE(SMBreadbraw);
- return(-1);
+ return;
}
- CHECK_FSP(fsp,conn);
+ /* Do a "by hand" version of CHECK_READ. */
+ if (!(fsp->can_read ||
+ ((req->flags2 & FLAGS2_READ_PERMIT_EXECUTE) &&
+ (fsp->access_mask & FILE_EXECUTE)))) {
+ DEBUG(3,("reply_readbraw: fnum %d not readable.\n",
+ (int)SVAL(req->inbuf,smb_vwv0)));
+ reply_readbraw_error();
+ END_PROFILE(SMBreadbraw);
+ return;
+ }
flush_write_cache(fsp, READRAW_FLUSH);
- startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv1);
- if(CVAL(inbuf,smb_wct) == 10) {
+ startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
+ if(req->wct == 10) {
/*
* This is a large offset (64 bit) read.
*/
#ifdef LARGE_SMB_OFF_T
- startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv8)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(inbuf,smb_vwv8) != 0) {
- DEBUG(0,("readbraw - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv8) ));
- _smb_setlen(header,0);
- if (write_data(smbd_server_fd(),header,4) != 4)
- fail_readraw();
+ if(IVAL(req->inbuf,smb_vwv8) != 0) {
+ DEBUG(0,("reply_readbraw: large offset "
+ "(%x << 32) used and we don't support "
+ "64 bit offsets.\n",
+ (unsigned int)IVAL(req->inbuf,smb_vwv8) ));
+ reply_readbraw_error();
END_PROFILE(SMBreadbraw);
- return(-1);
+ return;
}
#endif /* LARGE_SMB_OFF_T */
if(startpos < 0) {
- DEBUG(0,("readbraw - negative 64 bit readraw offset (%.0f) !\n", (double)startpos ));
- _smb_setlen(header,0);
- if (write_data(smbd_server_fd(),header,4) != 4)
- fail_readraw();
+ DEBUG(0,("reply_readbraw: negative 64 bit "
+ "readraw offset (%.0f) !\n",
+ (double)startpos ));
+ reply_readbraw_error();
END_PROFILE(SMBreadbraw);
- return(-1);
+ return;
}
}
- maxcount = (SVAL(inbuf,smb_vwv3) & 0xFFFF);
- mincount = (SVAL(inbuf,smb_vwv4) & 0xFFFF);
+
+ maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
+ mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
- if (!is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)maxcount,(SMB_BIG_UINT)startpos, READ_LOCK)) {
- SMB_STRUCT_STAT st;
- SMB_OFF_T size = 0;
-
- if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
- size = st.st_size;
- }
+ if (is_locked(fsp,(uint32)req->smbpid,
+ (SMB_BIG_UINT)maxcount,
+ (SMB_BIG_UINT)startpos,
+ READ_LOCK)) {
+ reply_readbraw_error();
+ END_PROFILE(SMBreadbraw);
+ return;
+ }
- if (startpos >= size) {
- nread = 0;
- } else {
- nread = MIN(maxcount,(size - startpos));
- }
+ if (SMB_VFS_FSTAT(fsp,fsp->fh->fd,&st) == 0) {
+ size = st.st_size;
+ }
+
+ if (startpos >= size) {
+ nread = 0;
+ } else {
+ nread = MIN(maxcount,(size - startpos));
}
#if 0 /* mincount appears to be ignored in a W2K server. JRA. */
nread = 0;
#endif
- DEBUG( 3, ( "readbraw fnum=%d start=%.0f max=%lu min=%lu nread=%lu\n", fsp->fnum, (double)startpos,
- (unsigned long)maxcount, (unsigned long)mincount, (unsigned long)nread ) );
+ DEBUG( 3, ( "reply_readbraw: fnum=%d start=%.0f max=%lu "
+ "min=%lu nread=%lu\n",
+ fsp->fnum, (double)startpos,
+ (unsigned long)maxcount,
+ (unsigned long)mincount,
+ (unsigned long)nread ) );
- send_file_readbraw(conn, fsp, startpos, nread, mincount, outbuf, out_buffsize);
+ send_file_readbraw(conn, fsp, startpos, nread, mincount);
- DEBUG(5,("readbraw finished\n"));
+ DEBUG(5,("reply_readbraw finished\n"));
END_PROFILE(SMBreadbraw);
- return -1;
}
#undef DBGC_CLASS
Setup readX header.
****************************************************************************/
-static int setup_readX_header(char *inbuf, char *outbuf, size_t smb_maxcnt)
+static int setup_readX_header(const uint8 *inbuf, uint8 *outbuf,
+ size_t smb_maxcnt)
{
int outsize;
- char *data = smb_buf(outbuf);
+ char *data;
+
+ outsize = set_message((char *)inbuf, (char *)outbuf,12,smb_maxcnt,
+ False);
+ data = smb_buf(outbuf);
SSVAL(outbuf,smb_vwv2,0xFFFF); /* Remaining - must be -1. */
SSVAL(outbuf,smb_vwv5,smb_maxcnt);
SSVAL(outbuf,smb_vwv7,(smb_maxcnt >> 16));
SSVAL(smb_buf(outbuf),-2,smb_maxcnt);
SCVAL(outbuf,smb_vwv0,0xFF);
- outsize = set_message(inbuf, outbuf,12,smb_maxcnt,False);
/* Reset the outgoing length, set_message truncates at 0x1FFFF. */
_smb_setlen_large(outbuf,(smb_size + 12*2 + smb_maxcnt - 4));
return outsize;
Reply to a read and X - possibly using sendfile.
****************************************************************************/
-int send_file_readX(connection_struct *conn, char *inbuf,char *outbuf,int length, int len_outbuf,
- files_struct *fsp, SMB_OFF_T startpos, size_t smb_maxcnt)
+static void send_file_readX(connection_struct *conn, struct smb_request *req,
+ files_struct *fsp, SMB_OFF_T startpos,
+ size_t smb_maxcnt)
{
SMB_STRUCT_STAT sbuf;
- int outsize = 0;
ssize_t nread = -1;
- char *data = smb_buf(outbuf);
if(SMB_VFS_FSTAT(fsp,fsp->fh->fd, &sbuf) == -1) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
+ return;
}
if (startpos > sbuf.st_size) {
* on a train in Germany :-). JRA.
*/
- if ((chain_size == 0) && (CVAL(inbuf,smb_vwv0) == 0xFF) &&
+ if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
+ uint8 headerbuf[smb_size + 12 * 2];
DATA_BLOB header;
/*
* correct amount of data).
*/
- setup_readX_header(inbuf,outbuf,smb_maxcnt);
- set_message(inbuf,outbuf,12,smb_maxcnt,False);
- header.data = (uint8 *)outbuf;
- header.length = data - outbuf;
- header.free = NULL;
+ header = data_blob_const(headerbuf, sizeof(headerbuf));
+
+ construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ setup_readX_header(req->inbuf, 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. */
/* Ensure we don't do this again. */
set_use_sendfile(SNUM(conn), False);
DEBUG(0,("send_file_readX: sendfile not available. Faking..\n"));
-
- if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
- len_outbuf - (data-outbuf))) == -1) {
+ nread = fake_sendfile(fsp, startpos,
+ smb_maxcnt);
+ if (nread == -1) {
DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning -1 here means successful sendfile. */
- return -1;
+ /* No outbuf here means successful sendfile. */
+ TALLOC_FREE(req->outbuf);
+ return;
}
DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
DEBUG( 3, ( "send_file_readX: sendfile fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning -1 here means successful sendfile. */
- return -1;
+ /* No outbuf here means successful sendfile. */
+ TALLOC_FREE(req->outbuf);
+ return;
}
#endif
normal_read:
if ((smb_maxcnt & 0xFF0000) > 0x10000) {
- int sendlen = setup_readX_header(inbuf,outbuf,smb_maxcnt) - smb_maxcnt;
+ uint8 headerbuf[smb_size + 2*12];
+
+ construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ setup_readX_header(req->inbuf, headerbuf, smb_maxcnt);
+
/* Send out the header. */
- if (write_data(smbd_server_fd(),outbuf,sendlen) != sendlen) {
+ if (write_data(smbd_server_fd(), (char *)headerbuf,
+ sizeof(headerbuf)) != sizeof(headerbuf)) {
DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readX sendfile failed");
}
- if ((nread = fake_sendfile(fsp, startpos, smb_maxcnt, data,
- len_outbuf - (data-outbuf))) == -1) {
+ nread = fake_sendfile(fsp, startpos, smb_maxcnt);
+ if (nread == -1) {
DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
fsp->fsp_name, strerror(errno) ));
exit_server_cleanly("send_file_readX: fake_sendfile failed");
}
- return -1;
+ TALLOC_FREE(req->outbuf);
+ return;
} else {
- nread = read_file(fsp,data,startpos,smb_maxcnt);
+ reply_outbuf(req, 12, smb_maxcnt);
+ nread = read_file(fsp, smb_buf(req->outbuf), startpos,
+ smb_maxcnt);
if (nread < 0) {
- return(UNIXERROR(ERRDOS,ERRnoaccess));
+ reply_unixerror(req, ERRDOS, ERRnoaccess);
+ return;
}
- outsize = setup_readX_header(inbuf, outbuf,nread);
+ setup_readX_header(req->inbuf, req->outbuf, nread);
DEBUG( 3, ( "send_file_readX fnum=%d max=%d nread=%d\n",
fsp->fnum, (int)smb_maxcnt, (int)nread ) );
- /* Returning the number of bytes we want to send back - including header. */
- return outsize;
+ chain_reply_new(req);
+
+ return;
}
}
Reply to a read and X.
****************************************************************************/
-int reply_read_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+void reply_read_and_X(connection_struct *conn, struct smb_request *req)
{
- files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv2));
- SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
- ssize_t nread = -1;
- size_t smb_maxcnt = SVAL(inbuf,smb_vwv5);
+ files_struct *fsp;
+ SMB_OFF_T startpos;
+ size_t smb_maxcnt;
BOOL big_readX = False;
#if 0
- size_t smb_mincnt = SVAL(inbuf,smb_vwv6);
+ size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
#endif
START_PROFILE(SMBreadX);
+ if ((req->wct != 10) && (req->wct != 12)) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
+ startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
+ smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
+
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
+ reply_pipe_read_and_X(req);
END_PROFILE(SMBreadX);
- return reply_pipe_read_and_X(inbuf,outbuf,length,bufsize);
+ return;
}
- CHECK_FSP(fsp,conn);
- if (!CHECK_READ(fsp,inbuf)) {
- return(ERROR_DOS(ERRDOS,ERRbadaccess));
+ if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ END_PROFILE(SMBreadX);
+ return;
}
- set_message(inbuf,outbuf,12,0,True);
+ if (!CHECK_READ(fsp,req->inbuf)) {
+ reply_doserror(req, ERRDOS,ERRbadaccess);
+ END_PROFILE(SMBreadX);
+ return;
+ }
if (global_client_caps & CAP_LARGE_READX) {
- size_t upper_size = SVAL(inbuf,smb_vwv7);
+ size_t upper_size = SVAL(req->inbuf,smb_vwv7);
smb_maxcnt |= (upper_size<<16);
if (upper_size > 1) {
/* Can't do this on a chained packet. */
- if ((CVAL(inbuf,smb_vwv0) != 0xFF)) {
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
+ reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ END_PROFILE(SMBreadX);
+ return;
}
/* We currently don't do this on signed or sealed data. */
if (srv_is_signing_active() || srv_encryption_on()) {
- return ERROR_NT(NT_STATUS_NOT_SUPPORTED);
+ reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
+ END_PROFILE(SMBreadX);
+ return;
}
/* Is there room in the reply for this data ? */
if (smb_maxcnt > (0xFFFFFF - (smb_size -4 + 12*2))) {
- return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
+ reply_nterror(req,
+ NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBreadX);
+ return;
}
big_readX = True;
}
}
- if(CVAL(inbuf,smb_wct) == 12) {
+ if (req->wct == 12) {
#ifdef LARGE_SMB_OFF_T
/*
* This is a large offset (64 bit) read.
*/
- startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv10)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(inbuf,smb_vwv10) != 0) {
- DEBUG(0,("reply_read_and_X - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv10) ));
+ if(IVAL(req->inbuf,smb_vwv10) != 0) {
+ DEBUG(0,("reply_read_and_X - large offset (%x << 32) "
+ "used and we don't support 64 bit offsets.\n",
+ (unsigned int)IVAL(req->inbuf,smb_vwv10) ));
END_PROFILE(SMBreadX);
- return ERROR_DOS(ERRDOS,ERRbadaccess);
+ reply_doserror(req, ERRDOS, ERRbadaccess);
+ return;
}
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)smb_maxcnt,(SMB_BIG_UINT)startpos, READ_LOCK)) {
+ if (is_locked(fsp, (uint32)req->smbpid, (SMB_BIG_UINT)smb_maxcnt,
+ (SMB_BIG_UINT)startpos, READ_LOCK)) {
END_PROFILE(SMBreadX);
- return ERROR_DOS(ERRDOS,ERRlock);
+ reply_doserror(req, ERRDOS, ERRlock);
+ return;
}
- if (!big_readX && schedule_aio_read_and_X(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt)) {
+ if (!big_readX
+ && schedule_aio_read_and_X(conn, req, fsp, startpos, smb_maxcnt)) {
END_PROFILE(SMBreadX);
- return -1;
+ reply_post_legacy(req, -1);
+ return;
}
- nread = send_file_readX(conn, inbuf, outbuf, length, bufsize, fsp, startpos, smb_maxcnt);
- /* Only call chain_reply if not an error. */
- if (nread != -1 && SVAL(outbuf,smb_rcls) == 0) {
- nread = chain_reply(inbuf,&outbuf,length,bufsize);
- }
+ send_file_readX(conn, req, fsp, startpos, smb_maxcnt);
END_PROFILE(SMBreadX);
- return nread;
+ return;
}
/****************************************************************************
Reply to a write and X.
****************************************************************************/
-int reply_write_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize)
+void reply_write_and_X(connection_struct *conn, struct smb_request *req)
{
- files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv2));
- SMB_OFF_T startpos = IVAL_TO_SMB_OFF_T(inbuf,smb_vwv3);
- size_t numtowrite = SVAL(inbuf,smb_vwv10);
- BOOL write_through = BITSETW(inbuf+smb_vwv7,0);
- ssize_t nwritten = -1;
- unsigned int smb_doff = SVAL(inbuf,smb_vwv11);
- unsigned int smblen = smb_len(inbuf);
+ files_struct *fsp;
+ SMB_OFF_T startpos;
+ size_t numtowrite;
+ BOOL write_through;
+ ssize_t nwritten;
+ unsigned int smb_doff;
+ unsigned int smblen;
char *data;
- BOOL large_writeX = ((CVAL(inbuf,smb_wct) == 14) && (smblen > 0xFFFF));
+ BOOL large_writeX;
NTSTATUS status;
+
START_PROFILE(SMBwriteX);
- /* If it's an IPC, pass off the pipe handler. */
- if (IS_IPC(conn)) {
+ if ((req->wct != 12) && (req->wct != 14)) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBwriteX);
- return reply_pipe_write_and_X(inbuf,outbuf,length,bufsize);
+ return;
}
- CHECK_FSP(fsp,conn);
- if (!CHECK_WRITE(fsp)) {
- return(ERROR_DOS(ERRDOS,ERRbadaccess));
- }
+ numtowrite = SVAL(req->inbuf,smb_vwv10);
+ smb_doff = SVAL(req->inbuf,smb_vwv11);
+ smblen = smb_len(req->inbuf);
+ large_writeX = ((req->wct == 14) && (smblen > 0xFFFF));
- set_message(inbuf,outbuf,6,0,True);
-
/* Deal with possible LARGE_WRITEX */
if (large_writeX) {
- numtowrite |= ((((size_t)SVAL(inbuf,smb_vwv9)) & 1 )<<16);
+ numtowrite |= ((((size_t)SVAL(req->inbuf,smb_vwv9)) & 1 )<<16);
}
if(smb_doff > smblen || (smb_doff + numtowrite > smblen)) {
+ reply_doserror(req, ERRDOS, ERRbadmem);
END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRbadmem);
+ return;
}
- data = smb_base(inbuf) + smb_doff;
+ /* If it's an IPC, pass off the pipe handler. */
+ if (IS_IPC(conn)) {
+ reply_pipe_write_and_X(req);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
+
+ fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
+ startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
+ write_through = BITSETW(req->inbuf+smb_vwv7,0);
- if(CVAL(inbuf,smb_wct) == 14) {
+ if (!check_fsp(conn, req, fsp, ¤t_user)) {
+ END_PROFILE(SMBwriteX);
+ return;
+ }
+
+ if (!CHECK_WRITE(fsp)) {
+ reply_doserror(req, ERRDOS, ERRbadaccess);
+ END_PROFILE(SMBwriteX);
+ return;
+ }
+
+ data = smb_base(req->inbuf) + smb_doff;
+
+ if(req->wct == 14) {
#ifdef LARGE_SMB_OFF_T
/*
* This is a large offset (64 bit) write.
*/
- startpos |= (((SMB_OFF_T)IVAL(inbuf,smb_vwv12)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
#else /* !LARGE_SMB_OFF_T */
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(inbuf,smb_vwv12) != 0) {
- DEBUG(0,("reply_write_and_X - large offset (%x << 32) used and we don't support \
-64 bit offsets.\n", (unsigned int)IVAL(inbuf,smb_vwv12) ));
+ if(IVAL(req->inbuf,smb_vwv12) != 0) {
+ DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
+ "used and we don't support 64 bit offsets.\n",
+ (unsigned int)IVAL(inbuf,smb_vwv12) ));
+ reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRbadaccess);
+ return;
}
#endif /* LARGE_SMB_OFF_T */
}
- if (is_locked(fsp,(uint32)SVAL(inbuf,smb_pid),(SMB_BIG_UINT)numtowrite,(SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ if (is_locked(fsp,(uint32)req->smbpid,
+ (SMB_BIG_UINT)numtowrite,
+ (SMB_BIG_UINT)startpos, WRITE_LOCK)) {
+ reply_doserror(req, ERRDOS, ERRlock);
END_PROFILE(SMBwriteX);
- return ERROR_DOS(ERRDOS,ERRlock);
+ return;
}
/* X/Open SMB protocol says that, unlike SMBwrite
nwritten = 0;
} else {
- if (schedule_aio_write_and_X(conn, inbuf, outbuf, length, bufsize,
- fsp,data,startpos,numtowrite)) {
+ if (schedule_aio_write_and_X(conn, req, fsp, data, startpos,
+ numtowrite)) {
END_PROFILE(SMBwriteX);
- return -1;
+ return;
}
nwritten = write_file(fsp,data,startpos,numtowrite);
}
if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
+ reply_unixerror(req, ERRHRD, ERRdiskfull);
END_PROFILE(SMBwriteX);
- return(UNIXERROR(ERRHRD,ERRdiskfull));
+ return;
}
- SSVAL(outbuf,smb_vwv2,nwritten);
+ reply_outbuf(req, 6, 0);
+ SSVAL(req->outbuf,smb_vwv2,nwritten);
if (large_writeX)
- SSVAL(outbuf,smb_vwv4,(nwritten>>16)&1);
+ SSVAL(req->outbuf,smb_vwv4,(nwritten>>16)&1);
if (nwritten < (ssize_t)numtowrite) {
- SCVAL(outbuf,smb_rcls,ERRHRD);
- SSVAL(outbuf,smb_err,ERRdiskfull);
+ SCVAL(req->outbuf,smb_rcls,ERRHRD);
+ SSVAL(req->outbuf,smb_err,ERRdiskfull);
}
DEBUG(3,("writeX fnum=%d num=%d wrote=%d\n",
status = sync_file(conn, fsp, write_through);
if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBwriteX);
DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ END_PROFILE(SMBwriteX);
+ return;
}
END_PROFILE(SMBwriteX);
- return chain_reply(inbuf,&outbuf,length,bufsize);
+ chain_reply_new(req);
+ return;
}
/****************************************************************************
Reply to a flush.
****************************************************************************/
-int reply_flush(connection_struct *conn, char *inbuf,char *outbuf, int size, int dum_buffsize)
+void reply_flush(connection_struct *conn, struct smb_request *req)
{
- int outsize = set_message(inbuf,outbuf,0,0,False);
- uint16 fnum = SVAL(inbuf,smb_vwv0);
- files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv0));
+ uint16 fnum;
+ files_struct *fsp;
+
START_PROFILE(SMBflush);
- if (fnum != 0xFFFF)
- CHECK_FSP(fsp,conn);
+ if (req->wct < 1) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ return;
+ }
+
+ fnum = SVAL(req->inbuf,smb_vwv0);
+ fsp = file_fsp(fnum);
+
+ if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp, ¤t_user)) {
+ return;
+ }
if (!fsp) {
file_sync_all(conn);
} else {
NTSTATUS status = sync_file(conn, fsp, True);
if (!NT_STATUS_IS_OK(status)) {
- END_PROFILE(SMBflush);
DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
fsp->fsp_name, nt_errstr(status) ));
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ END_PROFILE(SMBflush);
+ return;
}
}
+ reply_outbuf(req, 0, 0);
+
DEBUG(3,("flush\n"));
END_PROFILE(SMBflush);
- return(outsize);
+ return;
}
/****************************************************************************
conn POINTER CAN BE NULL HERE !
****************************************************************************/
-int reply_echo(connection_struct *conn,
- char *inbuf,char *outbuf, int dum_size, int dum_buffsize)
+void reply_echo(connection_struct *conn, struct smb_request *req)
{
- int smb_reverb = SVAL(inbuf,smb_vwv0);
+ int smb_reverb;
int seq_num;
- unsigned int data_len = smb_buflen(inbuf);
- int outsize = set_message(inbuf,outbuf,1,data_len,True);
+ unsigned int data_len = smb_buflen(req->inbuf);
+
START_PROFILE(SMBecho);
+ if (req->wct < 1) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBecho);
+ return;
+ }
+
if (data_len > BUFFER_SIZE) {
DEBUG(0,("reply_echo: data_len too large.\n"));
+ reply_nterror(req, NT_STATUS_INSUFFICIENT_RESOURCES);
END_PROFILE(SMBecho);
- return -1;
+ return;
}
+ smb_reverb = SVAL(req->inbuf,smb_vwv0);
+
+ reply_outbuf(req, 1, data_len);
+
/* copy any incoming data back out */
- if (data_len > 0)
- memcpy(smb_buf(outbuf),smb_buf(inbuf),data_len);
+ if (data_len > 0) {
+ memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
+ }
if (smb_reverb > 100) {
DEBUG(0,("large reverb (%d)?? Setting to 100\n",smb_reverb));
}
for (seq_num =1 ; seq_num <= smb_reverb ; seq_num++) {
- SSVAL(outbuf,smb_vwv0,seq_num);
-
- smb_setlen(inbuf,outbuf,outsize - 4);
+ SSVAL(req->outbuf,smb_vwv0,seq_num);
- show_msg(outbuf);
- if (!send_smb(smbd_server_fd(),outbuf))
+ show_msg((char *)req->outbuf);
+ if (!send_smb(smbd_server_fd(),(char *)req->outbuf))
exit_server_cleanly("reply_echo: send_smb failed.");
}
DEBUG(3,("echo %d times\n", smb_reverb));
+ TALLOC_FREE(req->outbuf);
+
smb_echo_count++;
END_PROFILE(SMBecho);
- return -1;
+ return;
}
/****************************************************************************
Reply to a lockingX request.
****************************************************************************/
-int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
- int length, int bufsize)
+void reply_lockingX(connection_struct *conn, struct smb_request *req)
{
- files_struct *fsp = file_fsp(SVAL(inbuf,smb_vwv2));
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
- unsigned char oplocklevel = CVAL(inbuf,smb_vwv3+1);
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- uint16 num_locks = SVAL(inbuf,smb_vwv7);
+ files_struct *fsp;
+ unsigned char locktype;
+ unsigned char oplocklevel;
+ uint16 num_ulocks;
+ uint16 num_locks;
SMB_BIG_UINT count = 0, offset = 0;
uint32 lock_pid;
- int32 lock_timeout = IVAL(inbuf,smb_vwv4);
+ int32 lock_timeout;
int i;
char *data;
- BOOL large_file_format =
- (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
+ BOOL large_file_format;
BOOL err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
START_PROFILE(SMBlockingX);
+
+ if (req->wct < 8) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
- CHECK_FSP(fsp,conn);
+ fsp = file_fsp(SVAL(req->inbuf,smb_vwv2));
+ locktype = CVAL(req->inbuf,smb_vwv3);
+ oplocklevel = CVAL(req->inbuf,smb_vwv3+1);
+ num_ulocks = SVAL(req->inbuf,smb_vwv6);
+ num_locks = SVAL(req->inbuf,smb_vwv7);
+ 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)) {
+ END_PROFILE(SMBlockingX);
+ return;
+ }
- data = smb_buf(inbuf);
+ data = smb_buf(req->inbuf);
if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
/* we don't support these - and CANCEL_LOCK makes w2k
and XP reboot so I don't really want to be
compatible! (tridge) */
- return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
+ reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRnoatomiclocks));
+ END_PROFILE(SMBlockingX);
+ return;
}
/* Check if this is an oplock break on a file
* send a reply */
if (num_locks == 0 && num_ulocks == 0) {
END_PROFILE(SMBlockingX);
- return -1;
+ reply_post_legacy(req, -1);
+ return;
} else {
END_PROFILE(SMBlockingX);
- return ERROR_DOS(ERRDOS,ERRlock);
+ reply_doserror(req, ERRDOS, ERRlock);
+ return;
}
}
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
- if(CVAL(inbuf,smb_vwv0) != 0xff)
+ if(CVAL(req->inbuf,smb_vwv0) != 0xff)
DEBUG(0,("reply_lockingX: Error : pure oplock "
"break is a chained %d request !\n",
- (unsigned int)CVAL(inbuf,smb_vwv0) ));
+ (unsigned int)CVAL(req->inbuf,
+ smb_vwv0) ));
END_PROFILE(SMBlockingX);
- return -1;
+ return;
}
}
*/
release_level_2_oplocks_on_change(fsp);
+
+ if (smb_buflen(req->inbuf) <
+ (num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBlockingX);
+ return;
+ }
/* Data now points at the beginning of the list
of smb_unlkrng structs */
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
+ reply_doserror(req, ERRDOS, ERRnoaccess);
+ return;
}
DEBUG(10,("reply_lockingX: unlock start=%.0f, len=%.0f for "
if (NT_STATUS_V(status)) {
END_PROFILE(SMBlockingX);
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
}
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
+ reply_doserror(req, ERRDOS, ERRnoaccess);
+ return;
}
DEBUG(10,("reply_lockingX: lock start=%.0f, len=%.0f for pid "
locktype,
NT_STATUS_FILE_LOCK_CONFLICT)) {
END_PROFILE(SMBlockingX);
- return ERROR_NT(NT_STATUS_DOS(ERRDOS, ERRcancelviolation));
+ reply_nterror(
+ req,
+ NT_STATUS_DOS(
+ ERRDOS,
+ ERRcancelviolation));
+ return;
}
}
/* Remove a matching pending lock. */
* onto the blocking lock queue.
*/
if(push_blocking_lock_request(br_lck,
- inbuf, length,
+ (char *)req->inbuf,
+ smb_len(req->inbuf)+4,
fsp,
lock_timeout,
i,
block_smbpid)) {
TALLOC_FREE(br_lck);
END_PROFILE(SMBlockingX);
- return -1;
+ reply_post_legacy(req, -1);
+ return;
}
}
if (NT_STATUS_V(status)) {
END_PROFILE(SMBlockingX);
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
}
*/
if(err) {
END_PROFILE(SMBlockingX);
- return ERROR_DOS(ERRDOS,ERRnoaccess);
+ reply_doserror(req, ERRDOS, ERRnoaccess);
+ return;
}
do_unlock(smbd_messaging_context(),
WINDOWS_LOCK);
}
END_PROFILE(SMBlockingX);
- return ERROR_NT(status);
+ reply_nterror(req, status);
+ return;
}
- set_message(inbuf,outbuf,2,0,True);
+ reply_outbuf(req, 2, 0);
DEBUG(3, ("lockingX fnum=%d type=%d num_locks=%d num_ulocks=%d\n",
fsp->fnum, (unsigned int)locktype, num_locks, num_ulocks));
END_PROFILE(SMBlockingX);
- return chain_reply(inbuf,&outbuf,length,bufsize);
+ chain_reply_new(req);
}
#undef DBGC_CLASS