summaryrefslogtreecommitdiff
path: root/source3/smbd
diff options
context:
space:
mode:
Diffstat (limited to 'source3/smbd')
-rw-r--r--source3/smbd/aio.c177
-rw-r--r--source3/smbd/blocking.c372
-rw-r--r--source3/smbd/chgpasswd.c6
-rw-r--r--source3/smbd/ipc.c152
-rw-r--r--source3/smbd/lanman.c2
-rw-r--r--source3/smbd/mangle.c2
-rw-r--r--source3/smbd/map_username.c2
-rw-r--r--source3/smbd/message.c40
-rw-r--r--source3/smbd/negprot.c17
-rw-r--r--source3/smbd/notify.c82
-rw-r--r--source3/smbd/nttrans.c110
-rw-r--r--source3/smbd/open.c191
-rw-r--r--source3/smbd/password.c2
-rw-r--r--source3/smbd/pipes.c28
-rw-r--r--source3/smbd/posix_acls.c4
-rw-r--r--source3/smbd/process.c31
-rw-r--r--source3/smbd/reply.c592
-rw-r--r--source3/smbd/server.c8
-rw-r--r--source3/smbd/sesssetup.c128
-rw-r--r--source3/smbd/trans2.c81
-rw-r--r--source3/smbd/uid.c2
21 files changed, 975 insertions, 1054 deletions
diff --git a/source3/smbd/aio.c b/source3/smbd/aio.c
index c3fd0a2bc0..8beed0744c 100644
--- a/source3/smbd/aio.c
+++ b/source3/smbd/aio.c
@@ -45,94 +45,52 @@ struct aio_extra {
struct aio_extra *next, *prev;
SMB_STRUCT_AIOCB acb;
files_struct *fsp;
- bool read_req;
- uint16 mid;
- char *inbuf;
+ struct smb_request *req;
char *outbuf;
+ int (*handle_completion)(struct aio_extra *ex);
};
-static struct aio_extra *aio_list_head;
+static int handle_aio_read_complete(struct aio_extra *aio_ex);
+static int handle_aio_write_complete(struct aio_extra *aio_ex);
-/****************************************************************************
- Create the extended aio struct we must keep around for the lifetime
- of the aio_read call.
-*****************************************************************************/
+static struct aio_extra *aio_list_head;
-static struct aio_extra *create_aio_ex_read(files_struct *fsp, size_t buflen,
- uint16 mid)
+static int aio_extra_destructor(struct aio_extra *aio_ex)
{
- struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra);
-
- if (!aio_ex) {
- return NULL;
- }
- ZERO_STRUCTP(aio_ex);
- /* The output buffer stored in the aio_ex is the start of
- the smb return buffer. The buffer used in the acb
- is the start of the reply data portion of that buffer. */
- aio_ex->outbuf = SMB_MALLOC_ARRAY(char, buflen);
- if (!aio_ex->outbuf) {
- SAFE_FREE(aio_ex);
- return NULL;
- }
- DLIST_ADD(aio_list_head, aio_ex);
- aio_ex->fsp = fsp;
- aio_ex->read_req = True;
- aio_ex->mid = mid;
- return aio_ex;
+ DLIST_REMOVE(aio_list_head, aio_ex);
+ return 0;
}
/****************************************************************************
Create the extended aio struct we must keep around for the lifetime
- of the aio_write call.
+ of the aio call.
*****************************************************************************/
-static struct aio_extra *create_aio_ex_write(files_struct *fsp,
- size_t inbuflen,
- size_t outbuflen,
- uint16 mid)
+static struct aio_extra *create_aio_extra(files_struct *fsp, size_t buflen)
{
- struct aio_extra *aio_ex = SMB_MALLOC_P(struct aio_extra);
+ struct aio_extra *aio_ex = TALLOC_ZERO_P(NULL, struct aio_extra);
if (!aio_ex) {
return NULL;
}
- ZERO_STRUCTP(aio_ex);
- /* We need space for an output reply of outbuflen bytes. */
- aio_ex->outbuf = SMB_MALLOC_ARRAY(char, outbuflen);
- if (!aio_ex->outbuf) {
- SAFE_FREE(aio_ex);
- return NULL;
- }
+ /* The output buffer stored in the aio_ex is the start of
+ the smb return buffer. The buffer used in the acb
+ is the start of the reply data portion of that buffer. */
- if (!(aio_ex->inbuf = SMB_MALLOC_ARRAY(char, inbuflen))) {
- SAFE_FREE(aio_ex->outbuf);
- SAFE_FREE(aio_ex);
+ aio_ex->outbuf = TALLOC_ARRAY(aio_ex, char, buflen);
+ if (!aio_ex->outbuf) {
+ TALLOC_FREE(aio_ex);
return NULL;
}
-
DLIST_ADD(aio_list_head, aio_ex);
+ talloc_set_destructor(aio_ex, aio_extra_destructor);
aio_ex->fsp = fsp;
- aio_ex->read_req = False;
- aio_ex->mid = mid;
return aio_ex;
}
/****************************************************************************
- Delete the extended aio struct.
-*****************************************************************************/
-
-static void delete_aio_ex(struct aio_extra *aio_ex)
-{
- DLIST_REMOVE(aio_list_head, aio_ex);
- SAFE_FREE(aio_ex->inbuf);
- SAFE_FREE(aio_ex->outbuf);
- SAFE_FREE(aio_ex);
-}
-
-/****************************************************************************
- Given the aiocb struct find the extended aio struct containing it.
+ Given the mid find the extended aio struct containing it.
*****************************************************************************/
static struct aio_extra *find_aio_ex(uint16 mid)
@@ -140,7 +98,7 @@ static struct aio_extra *find_aio_ex(uint16 mid)
struct aio_extra *p;
for( p = aio_list_head; p; p = p->next) {
- if (mid == p->mid) {
+ if (mid == p->req->mid) {
return p;
}
}
@@ -221,6 +179,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
SMB_STRUCT_AIOCB *a;
size_t bufsize;
size_t min_aio_read_size = lp_aio_read_size(SNUM(conn));
+ int ret;
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
@@ -240,7 +199,7 @@ bool schedule_aio_read_and_X(connection_struct *conn,
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF)
+ if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF)
|| (lp_write_cache_size(SNUM(conn)) != 0) ) {
return False;
}
@@ -257,43 +216,47 @@ bool schedule_aio_read_and_X(connection_struct *conn,
bufsize = smb_size + 12 * 2 + smb_maxcnt;
- if ((aio_ex = create_aio_ex_read(fsp, bufsize, req->mid)) == NULL) {
+ if ((aio_ex = create_aio_extra(fsp, bufsize)) == NULL) {
DEBUG(10,("schedule_aio_read_and_X: malloc fail.\n"));
return False;
}
+ aio_ex->handle_completion = handle_aio_read_complete;
- construct_reply_common((char *)req->inbuf, aio_ex->outbuf);
+ construct_reply_common_req(req, aio_ex->outbuf);
srv_set_message(aio_ex->outbuf, 12, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
/* Now set up the aio record for the read call. */
-
+
a->aio_fildes = fsp->fh->fd;
a->aio_buf = smb_buf(aio_ex->outbuf);
a->aio_nbytes = smb_maxcnt;
a->aio_offset = startpos;
a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO;
- a->aio_sigevent.sigev_value.sival_int = aio_ex->mid;
+ a->aio_sigevent.sigev_value.sival_int = req->mid;
become_root();
- if (SMB_VFS_AIO_READ(fsp,a) == -1) {
+ ret = SMB_VFS_AIO_READ(fsp, a);
+ unbecome_root();
+
+ if (ret == -1) {
DEBUG(0,("schedule_aio_read_and_X: aio_read failed. "
"Error %s\n", strerror(errno) ));
- delete_aio_ex(aio_ex);
- unbecome_root();
+ TALLOC_FREE(aio_ex);
return False;
}
- unbecome_root();
+
+ aio_ex->req = talloc_move(aio_ex, &req);
DEBUG(10,("schedule_aio_read_and_X: scheduled aio_read for file %s, "
"offset %.0f, len = %u (mid = %u)\n",
fsp->fsp_name, (double)startpos, (unsigned int)smb_maxcnt,
- (unsigned int)aio_ex->mid ));
+ (unsigned int)aio_ex->req->mid ));
- srv_defer_sign_response(aio_ex->mid);
+ srv_defer_sign_response(aio_ex->req->mid);
outstanding_aio_calls++;
return True;
}
@@ -310,9 +273,10 @@ bool schedule_aio_write_and_X(connection_struct *conn,
{
struct aio_extra *aio_ex;
SMB_STRUCT_AIOCB *a;
- size_t inbufsize, outbufsize;
- bool write_through = BITSETW(req->inbuf+smb_vwv7,0);
+ size_t bufsize;
+ bool write_through = BITSETW(req->vwv+7,0);
size_t min_aio_write_size = lp_aio_write_size(SNUM(conn));
+ int ret;
if (fsp->base_fsp != NULL) {
/* No AIO on streams yet */
@@ -332,7 +296,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
/* Only do this on non-chained and non-chaining reads not using the
* write cache. */
- if (chain_size !=0 || (CVAL(req->inbuf,smb_vwv0) != 0xFF)
+ if (chain_size !=0 || (CVAL(req->vwv+0, 0) != 0xFF)
|| (lp_write_cache_size(SNUM(conn)) != 0) ) {
return False;
}
@@ -350,45 +314,43 @@ bool schedule_aio_write_and_X(connection_struct *conn,
return False;
}
- inbufsize = smb_len(req->inbuf) + 4;
- reply_outbuf(req, 6, 0);
- outbufsize = smb_len(req->outbuf) + 4;
- if (!(aio_ex = create_aio_ex_write(fsp, inbufsize, outbufsize,
- req->mid))) {
+ bufsize = smb_size + 6*2;
+
+ if (!(aio_ex = create_aio_extra(fsp, bufsize))) {
DEBUG(0,("schedule_aio_write_and_X: malloc fail.\n"));
return False;
}
+ aio_ex->handle_completion = handle_aio_write_complete;
- /* Copy the SMB header already setup in outbuf. */
- memcpy(aio_ex->inbuf, req->inbuf, inbufsize);
-
- /* Copy the SMB header already setup in outbuf. */
- memcpy(aio_ex->outbuf, req->outbuf, outbufsize);
- TALLOC_FREE(req->outbuf);
+ construct_reply_common_req(req, aio_ex->outbuf);
+ srv_set_message(aio_ex->outbuf, 6, 0, True);
SCVAL(aio_ex->outbuf,smb_vwv0,0xFF); /* Never a chained reply. */
a = &aio_ex->acb;
/* Now set up the aio record for the write call. */
-
+
a->aio_fildes = fsp->fh->fd;
- a->aio_buf = aio_ex->inbuf + (PTR_DIFF(data, req->inbuf));
+ a->aio_buf = data;
a->aio_nbytes = numtowrite;
a->aio_offset = startpos;
a->aio_sigevent.sigev_notify = SIGEV_SIGNAL;
a->aio_sigevent.sigev_signo = RT_SIGNAL_AIO;
- a->aio_sigevent.sigev_value.sival_int = aio_ex->mid;
+ a->aio_sigevent.sigev_value.sival_int = req->mid;
become_root();
- if (SMB_VFS_AIO_WRITE(fsp,a) == -1) {
+ ret = SMB_VFS_AIO_WRITE(fsp, a);
+ unbecome_root();
+
+ if (ret == -1) {
DEBUG(3,("schedule_aio_wrote_and_X: aio_write failed. "
"Error %s\n", strerror(errno) ));
- delete_aio_ex(aio_ex);
- unbecome_root();
+ TALLOC_FREE(aio_ex);
return False;
}
- unbecome_root();
-
+
+ aio_ex->req = talloc_move(aio_ex, &req);
+
release_level_2_oplocks_on_change(fsp);
if (!write_through && !lp_syncalways(SNUM(fsp->conn))
@@ -406,7 +368,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
DEBUG(10,("schedule_aio_write_and_X: scheduled aio_write "
"behind for file %s\n", fsp->fsp_name ));
} else {
- srv_defer_sign_response(aio_ex->mid);
+ srv_defer_sign_response(aio_ex->req->mid);
}
outstanding_aio_calls++;
@@ -414,7 +376,7 @@ bool schedule_aio_write_and_X(connection_struct *conn,
"%s, offset %.0f, len = %u (mid = %u) "
"outstanding_aio_calls = %d\n",
fsp->fsp_name, (double)startpos, (unsigned int)numtowrite,
- (unsigned int)aio_ex->mid, outstanding_aio_calls ));
+ (unsigned int)aio_ex->req->mid, outstanding_aio_calls ));
return True;
}
@@ -442,7 +404,7 @@ static int handle_aio_read_complete(struct aio_extra *aio_ex)
/* If errno is ECANCELED then don't return anything to the
* client. */
if (errno == ECANCELED) {
- srv_cancel_sign_response(aio_ex->mid);
+ srv_cancel_sign_response(aio_ex->req->mid);
return 0;
}
@@ -536,7 +498,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
/* If errno is ECANCELED then don't return anything to the
* client. */
if (errno == ECANCELED) {
- srv_cancel_sign_response(aio_ex->mid);
+ srv_cancel_sign_response(aio_ex->req->mid);
return 0;
}
@@ -544,7 +506,7 @@ static int handle_aio_write_complete(struct aio_extra *aio_ex)
ERROR_BOTH(map_nt_error_from_unix(ret), ERRHRD, ERRdiskfull);
srv_set_message(outbuf,0,0,true);
} else {
- bool write_through = BITSETW(aio_ex->inbuf+smb_vwv7,0);
+ bool write_through = BITSETW(aio_ex->req->vwv+7,0);
NTSTATUS status;
SSVAL(outbuf,smb_vwv2,nwritten);
@@ -600,16 +562,11 @@ static bool handle_aio_completed(struct aio_extra *aio_ex, int *perr)
if (SMB_VFS_AIO_ERROR(aio_ex->fsp, &aio_ex->acb) == EINPROGRESS) {
DEBUG(10,( "handle_aio_completed: operation mid %u still in "
"process for file %s\n",
- aio_ex->mid, aio_ex->fsp->fsp_name ));
+ aio_ex->req->mid, aio_ex->fsp->fsp_name ));
return False;
}
- if (aio_ex->read_req) {
- err = handle_aio_read_complete(aio_ex);
- } else {
- err = handle_aio_write_complete(aio_ex);
- }
-
+ err = aio_ex->handle_completion(aio_ex);
if (err) {
*perr = err; /* Only save non-zero errors. */
}
@@ -666,7 +623,7 @@ int process_aio_queue(void)
continue;
}
- delete_aio_ex(aio_ex);
+ TALLOC_FREE(aio_ex);
}
outstanding_aio_calls -= signals_received;
@@ -738,7 +695,7 @@ int wait_for_aio_completion(files_struct *fsp)
DEBUG(10,("wait_for_aio_completion: returned err = %d, "
"errno = %s\n", err, strerror(errno) ));
-
+
if (err == -1 && errno == EAGAIN) {
DEBUG(0,("wait_for_aio_completion: aio_suspend timed "
"out waiting for %d events after a wait of "
@@ -767,7 +724,7 @@ int wait_for_aio_completion(files_struct *fsp)
if (!handle_aio_completed(aio_ex, &err)) {
continue;
}
- delete_aio_ex(aio_ex);
+ TALLOC_FREE(aio_ex);
}
SAFE_FREE(aiocb_list);
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index 4374b50eac..2237a89ace 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -2,17 +2,17 @@
Unix SMB/CIFS implementation.
Blocking Locking functions
Copyright (C) Jeremy Allison 1998-2003
-
+
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
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
-
+
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
-
+
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -26,10 +26,9 @@
notify. It consists of the requesting SMB and the expiry time.
*****************************************************************************/
-typedef struct _blocking_lock_record {
- struct _blocking_lock_record *next;
- struct _blocking_lock_record *prev;
- int com_type;
+typedef struct blocking_lock_record {
+ struct blocking_lock_record *next;
+ struct blocking_lock_record *prev;
files_struct *fsp;
struct timeval expire_time;
int lock_num;
@@ -39,9 +38,7 @@ typedef struct _blocking_lock_record {
uint32_t blocking_pid; /* PID that blocks us. */
enum brl_flavour lock_flav;
enum brl_type lock_type;
- char *inbuf;
- int length;
- bool encrypted;
+ struct smb_request *req;
} blocking_lock_record;
/* dlink list we store pending lock records on. */
@@ -54,16 +51,6 @@ static blocking_lock_record *blocking_lock_cancelled_queue;
static struct timed_event *brl_timeout;
/****************************************************************************
- Destructor for the above structure.
-****************************************************************************/
-
-static void free_blocking_lock_record(blocking_lock_record *blr)
-{
- SAFE_FREE(blr->inbuf);
- SAFE_FREE(blr);
-}
-
-/****************************************************************************
Determine if this is a secondary element of a chained SMB.
**************************************************************************/
@@ -150,7 +137,7 @@ static bool recalc_brl_timeout(void)
****************************************************************************/
bool push_blocking_lock_request( struct byte_range_lock *br_lck,
- const struct smb_request *req,
+ struct smb_request *req,
files_struct *fsp,
int lock_timeout,
int lock_num,
@@ -162,7 +149,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32_t blocking_pid)
{
static bool set_lock_msg;
- size_t length = smb_len(req->inbuf)+4;
blocking_lock_record *blr;
NTSTATUS status;
@@ -176,7 +162,8 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
* the expiration time here.
*/
- if((blr = SMB_MALLOC_P(blocking_lock_record)) == NULL) {
+ blr = talloc(NULL, struct blocking_lock_record);
+ if (blr == NULL) {
DEBUG(0,("push_blocking_lock_request: Malloc fail !\n" ));
return False;
}
@@ -184,13 +171,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->next = NULL;
blr->prev = NULL;
- if((blr->inbuf = (char *)SMB_MALLOC(length)) == NULL) {
- DEBUG(0,("push_blocking_lock_request: Malloc fail (2)!\n" ));
- SAFE_FREE(blr);
- return False;
- }
-
- blr->com_type = CVAL(req->inbuf,smb_com);
blr->fsp = fsp;
if (lock_timeout == -1) {
blr->expire_time.tv_sec = 0;
@@ -206,9 +186,6 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
blr->lock_type = lock_type;
blr->offset = offset;
blr->count = count;
- memcpy(blr->inbuf, req->inbuf, length);
- blr->length = length;
- blr->encrypted = req->encrypted;
/* Add a pending lock record for this. */
status = brl_lock(smbd_messaging_context(), br_lck,
@@ -224,10 +201,12 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
+ TALLOC_FREE(blr);
return False;
}
+ blr->req = talloc_move(blr, &req);
+
DLIST_ADD_END(blocking_lock_queue, blr, blocking_lock_record *);
recalc_brl_timeout();
@@ -238,14 +217,14 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
set_lock_msg = True;
}
- DEBUG(3,("push_blocking_lock_request: lock request length=%u blocked with "
+ DEBUG(3,("push_blocking_lock_request: lock request blocked with "
"expiry time (%u sec. %u usec) (+%d msec) for fnum = %d, name = %s\n",
- (unsigned int)length, (unsigned int)blr->expire_time.tv_sec,
+ (unsigned int)blr->expire_time.tv_sec,
(unsigned int)blr->expire_time.tv_usec, lock_timeout,
blr->fsp->fnum, blr->fsp->fsp_name ));
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
+ srv_defer_sign_response(blr->req->mid);
return True;
}
@@ -256,14 +235,7 @@ bool push_blocking_lock_request( struct byte_range_lock *br_lck,
static void reply_lockingX_success(blocking_lock_record *blr)
{
- struct smb_request *req;
-
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- smb_panic("Could not allocate smb_request");
- }
-
- init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
- reply_outbuf(req, 2, 0);
+ reply_outbuf(blr->req, 2, 0);
/*
* As this message is a lockingX call we must handle
@@ -273,13 +245,14 @@ static void reply_lockingX_success(blocking_lock_record *blr)
* that here and must set up the chain info manually.
*/
- chain_reply(req);
+ chain_reply(blr->req);
- if (!srv_send_smb(smbd_server_fd(),
- (char *)req->outbuf,
+ if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
IS_CONN_ENCRYPTED(blr->fsp->conn))) {
exit_server_cleanly("send_blocking_reply: srv_send_smb failed.");
}
+
+ TALLOC_FREE(blr->req->outbuf);
}
/****************************************************************************
@@ -288,11 +261,6 @@ static void reply_lockingX_success(blocking_lock_record *blr)
static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS status)
{
- char outbuf[smb_size];
- char *inbuf = blr->inbuf;
-
- construct_reply_common(inbuf, outbuf);
-
/* whenever a timeout is given w2k maps LOCK_NOT_GRANTED to
FILE_LOCK_CONFLICT! (tridge) */
if (NT_STATUS_EQUAL(status, NT_STATUS_LOCK_NOT_GRANTED)) {
@@ -315,10 +283,12 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
}
}
- ERROR_NT(status);
- if (!srv_send_smb(smbd_server_fd(),outbuf, blr->encrypted)) {
+ reply_nterror(blr->req, status);
+ if (!srv_send_smb(smbd_server_fd(), (char *)blr->req->outbuf,
+ blr->req->encrypted)) {
exit_server_cleanly("generic_blocking_lock_error: srv_send_smb failed.");
}
+ TALLOC_FREE(blr->req->outbuf);
}
/****************************************************************************
@@ -328,18 +298,18 @@ static void generic_blocking_lock_error(blocking_lock_record *blr, NTSTATUS stat
static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
{
- char *inbuf = blr->inbuf;
files_struct *fsp = blr->fsp;
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
+ uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
uint64_t count = (uint64_t)0, offset = (uint64_t) 0;
uint32 lock_pid;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ unsigned char locktype = CVAL(blr->req->vwv+3, 0);
bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- char *data;
+ uint8_t *data;
int i;
- data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
-
+ data = (uint8_t *)blr->req->buf
+ + ((large_file_format ? 20 : 10)*num_ulocks);
+
/*
* Data now points at the beginning of the list
* of smb_lkrng structs.
@@ -350,19 +320,19 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
* as under POSIX rules, if we have a lock already there, we
* will delete it (and we shouldn't) .....
*/
-
+
for(i = blr->lock_num - 1; i >= 0; i--) {
bool err;
-
+
lock_pid = get_lock_pid( data, i, large_file_format);
count = get_lock_count( data, i, large_file_format);
offset = get_lock_offset( data, i, large_file_format, &err);
-
+
/*
* We know err cannot be set as if it was the lock
* request would never have been queued. JRA.
*/
-
+
do_unlock(smbd_messaging_context(),
fsp,
lock_pid,
@@ -370,7 +340,7 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
offset,
WINDOWS_LOCK);
}
-
+
generic_blocking_lock_error(blr, status);
}
@@ -380,28 +350,28 @@ static void reply_lockingX_error(blocking_lock_record *blr, NTSTATUS status)
static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status)
{
- switch(blr->com_type) {
+ switch(blr->req->cmd) {
case SMBlockingX:
reply_lockingX_error(blr, status);
break;
case SMBtrans2:
case SMBtranss2:
- {
- char outbuf[smb_size];
- char *inbuf = blr->inbuf;
- construct_reply_common(inbuf, outbuf);
- /* construct_reply_common has done us the favor to pre-fill the
- * command field with SMBtranss2 which is wrong :-)
- */
- SCVAL(outbuf,smb_com,SMBtrans2);
- ERROR_NT(status);
- if (!srv_send_smb(smbd_server_fd(),
- outbuf,
- IS_CONN_ENCRYPTED(blr->fsp->conn))) {
- exit_server_cleanly("blocking_lock_reply_error: srv_send_smb failed.");
- }
- break;
+ reply_nterror(blr->req, status);
+
+ /*
+ * construct_reply_common has done us the favor to pre-fill
+ * the command field with SMBtranss2 which is wrong :-)
+ */
+ SCVAL(blr->req->outbuf,smb_com,SMBtrans2);
+
+ if (!srv_send_smb(smbd_server_fd(),
+ (char *)blr->req->outbuf,
+ IS_CONN_ENCRYPTED(blr->fsp->conn))) {
+ exit_server_cleanly("blocking_lock_reply_error: "
+ "srv_send_smb failed.");
}
+ TALLOC_FREE(blr->req->outbuf);
+ break;
default:
DEBUG(0,("blocking_lock_reply_error: PANIC - unknown type on blocking lock queue - exiting.!\n"));
exit_server("PANIC - unknown type on blocking lock queue");
@@ -415,18 +385,18 @@ static void blocking_lock_reply_error(blocking_lock_record *blr, NTSTATUS status
static bool process_lockingX(blocking_lock_record *blr)
{
- char *inbuf = blr->inbuf;
- unsigned char locktype = CVAL(inbuf,smb_vwv3);
+ unsigned char locktype = CVAL(blr->req->vwv+3, 0);
files_struct *fsp = blr->fsp;
- uint16 num_ulocks = SVAL(inbuf,smb_vwv6);
- uint16 num_locks = SVAL(inbuf,smb_vwv7);
+ uint16 num_ulocks = SVAL(blr->req->vwv+6, 0);
+ uint16 num_locks = SVAL(blr->req->vwv+7, 0);
uint64_t count = (uint64_t)0, offset = (uint64_t)0;
uint32 lock_pid;
bool large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES);
- char *data;
+ uint8_t *data;
NTSTATUS status = NT_STATUS_OK;
- data = smb_buf(inbuf) + ((large_file_format ? 20 : 10)*num_ulocks);
+ data = (uint8_t *)blr->req->buf
+ + ((large_file_format ? 20 : 10)*num_ulocks);
/*
* Data now points at the beginning of the list
@@ -440,7 +410,7 @@ static bool process_lockingX(blocking_lock_record *blr)
lock_pid = get_lock_pid( data, blr->lock_num, large_file_format);
count = get_lock_count( data, blr->lock_num, large_file_format);
offset = get_lock_offset( data, blr->lock_num, large_file_format, &err);
-
+
/*
* We know err cannot be set as if it was the lock
* request would never have been queued. JRA.
@@ -469,20 +439,21 @@ static bool process_lockingX(blocking_lock_record *blr)
/*
* Success - we got all the locks.
*/
-
+
DEBUG(3,("process_lockingX file = %s, fnum=%d type=%d num_locks=%d\n",
fsp->fsp_name, fsp->fnum, (unsigned int)locktype, num_locks) );
reply_lockingX_success(blr);
return True;
- } else if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
- !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
- /*
- * We have other than a "can't get lock"
- * error. Free any locks we had and return an error.
- * Return True so we get dequeued.
- */
-
+ }
+
+ if (!NT_STATUS_EQUAL(status,NT_STATUS_LOCK_NOT_GRANTED) &&
+ !NT_STATUS_EQUAL(status,NT_STATUS_FILE_LOCK_CONFLICT)) {
+ /*
+ * We have other than a "can't get lock"
+ * error. Free any locks we had and return an error.
+ * Return True so we get dequeued.
+ */
blocking_lock_reply_error(blr, status);
return True;
}
@@ -490,11 +461,11 @@ static bool process_lockingX(blocking_lock_record *blr)
/*
* Still can't get all the locks - keep waiting.
*/
-
+
DEBUG(10,("process_lockingX: only got %d locks of %d needed for file %s, fnum = %d. \
Waiting....\n",
blr->lock_num, num_locks, fsp->fsp_name, fsp->fnum));
-
+
return False;
}
@@ -505,7 +476,6 @@ Waiting....\n",
static bool process_trans2(blocking_lock_record *blr)
{
- struct smb_request *req;
char params[2];
NTSTATUS status;
struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
@@ -535,17 +505,9 @@ static bool process_trans2(blocking_lock_record *blr)
/* We finally got the lock, return success. */
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- blocking_lock_reply_error(blr, NT_STATUS_NO_MEMORY);
- return True;
- }
-
- init_smb_request(req, (uint8 *)blr->inbuf, 0, blr->encrypted);
-
- SCVAL(req->inbuf, smb_com, SMBtrans2);
SSVAL(params,0,0);
/* Fake up max_data_bytes here - we know it fits. */
- send_trans2_replies(blr->fsp->conn, req, params, 2, NULL, 0, 0xffff);
+ send_trans2_replies(blr->fsp->conn, blr->req, params, 2, NULL, 0, 0xffff);
return True;
}
@@ -557,7 +519,7 @@ static bool process_trans2(blocking_lock_record *blr)
static bool blocking_lock_record_process(blocking_lock_record *blr)
{
- switch(blr->com_type) {
+ switch(blr->req->cmd) {
case SMBlockingX:
return process_lockingX(blr);
case SMBtrans2:
@@ -579,37 +541,39 @@ void cancel_pending_lock_requests_by_fid(files_struct *fsp, struct byte_range_lo
blocking_lock_record *blr, *next = NULL;
for(blr = blocking_lock_queue; blr; blr = next) {
- next = blr->next;
- if(blr->fsp->fnum == fsp->fnum) {
- unsigned char locktype = 0;
-
- if (blr->com_type == SMBlockingX) {
- locktype = CVAL(blr->inbuf,smb_vwv3);
- }
-
- if (br_lck) {
- DEBUG(10,("remove_pending_lock_requests_by_fid - removing request type %d for \
-file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
+ unsigned char locktype = 0;
- brl_lock_cancel(br_lck,
- blr->lock_pid,
- procid_self(),
- blr->offset,
- blr->count,
- blr->lock_flav);
+ next = blr->next;
+ if (blr->fsp->fnum != fsp->fnum) {
+ continue;
+ }
- blocking_lock_cancel(fsp,
- blr->lock_pid,
- blr->offset,
- blr->count,
- blr->lock_flav,
- locktype,
- NT_STATUS_RANGE_NOT_LOCKED);
- }
- /* We're closing the file fsp here, so ensure
- * we don't have a dangling pointer. */
- blr->fsp = NULL;
+ if (blr->req->cmd == SMBlockingX) {
+ locktype = CVAL(blr->req->vwv+3, 0);
}
+
+ DEBUG(10, ("remove_pending_lock_requests_by_fid - removing "
+ "request type %d for file %s fnum = %d\n",
+ blr->req->cmd, fsp->fsp_name, fsp->fnum));
+
+ brl_lock_cancel(br_lck,
+ blr->lock_pid,
+ procid_self(),
+ blr->offset,
+ blr->count,
+ blr->lock_flav);
+
+ blocking_lock_cancel(fsp,
+ blr->lock_pid,
+ blr->offset,
+ blr->count,
+ blr->lock_flav,
+ locktype,
+ NT_STATUS_RANGE_NOT_LOCKED);
+
+ /* We're closing the file fsp here, so ensure
+ * we don't have a dangling pointer. */
+ blr->fsp = NULL;
}
}
@@ -622,28 +586,36 @@ void remove_pending_lock_requests_by_mid(int mid)
blocking_lock_record *blr, *next = NULL;
for(blr = blocking_lock_queue; blr; blr = next) {
+ files_struct *fsp;
+ struct byte_range_lock *br_lck;
+
next = blr->next;
- if(SVAL(blr->inbuf,smb_mid) == mid) {
- files_struct *fsp = blr->fsp;
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
- if (br_lck) {
- DEBUG(10,("remove_pending_lock_requests_by_mid - removing request type %d for \
-file %s fnum = %d\n", blr->com_type, fsp->fsp_name, fsp->fnum ));
+ if (blr->req->mid != mid) {
+ continue;
+ }
- brl_lock_cancel(br_lck,
+ fsp = blr->fsp;
+ br_lck = brl_get_locks(talloc_tos(), fsp);
+
+ if (br_lck) {
+ DEBUG(10, ("remove_pending_lock_requests_by_mid - "
+ "removing request type %d for file %s fnum "
+ "= %d\n", blr->req->cmd, fsp->fsp_name,
+ fsp->fnum ));
+
+ brl_lock_cancel(br_lck,
blr->lock_pid,
procid_self(),
blr->offset,
blr->count,
blr->lock_flav);
- TALLOC_FREE(br_lck);
- }
-
- blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
- DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
+ TALLOC_FREE(br_lck);
}
+
+ blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
+ DLIST_REMOVE(blocking_lock_queue, blr);
+ TALLOC_FREE(blr);
}
}
@@ -657,7 +629,7 @@ bool blocking_lock_was_deferred(int mid)
for(blr = blocking_lock_queue; blr; blr = next) {
next = blr->next;
- if(SVAL(blr->inbuf,smb_mid) == mid) {
+ if(blr->req->mid == mid) {
return True;
}
}
@@ -693,86 +665,18 @@ static void process_blocking_lock_queue(void)
*/
for (blr = blocking_lock_queue; blr; blr = next) {
- connection_struct *conn = NULL;
- uint16 vuid;
- files_struct *fsp = NULL;
next = blr->next;
/*
- * Ensure we don't have any old chain_fsp values
- * sitting around....
- */
- chain_size = 0;
- fsp = blr->fsp;
-
- conn = conn_find(SVAL(blr->inbuf,smb_tid));
- vuid = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID :
- SVAL(blr->inbuf,smb_uid);
-
- DEBUG(5,("process_blocking_lock_queue: examining pending lock fnum = %d for file %s\n",
- fsp->fnum, fsp->fsp_name ));
-
- if(!change_to_user(conn,vuid)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
-
- /*
- * Remove the entry and return an error to the client.
- */
-
- if (br_lck) {
- brl_lock_cancel(br_lck,
- blr->lock_pid,
- procid_self(),
- blr->offset,
- blr->count,
- blr->lock_flav);
- TALLOC_FREE(br_lck);
- }
-
- DEBUG(0,("process_blocking_lock_queue: Unable to become user vuid=%d.\n",
- vuid ));
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
- DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
- recalc_timeout = True;
- continue;
- }
-
- if(!set_current_service(conn,SVAL(blr->inbuf,smb_flg),True)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
-
- /*
- * Remove the entry and return an error to the client.
- */
-
- if (br_lck) {
- brl_lock_cancel(br_lck,
- blr->lock_pid,
- procid_self(),
- blr->offset,
- blr->count,
- blr->lock_flav);
- TALLOC_FREE(br_lck);
- }
-
- DEBUG(0,("process_blocking_lock_queue: Unable to become service Error was %s.\n", strerror(errno) ));
- blocking_lock_reply_error(blr,NT_STATUS_ACCESS_DENIED);
- DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
- recalc_timeout = True;
- change_to_root_user();
- continue;
- }
-
- /*
* Go through the remaining locks and try and obtain them.
* The call returns True if all locks were obtained successfully
* and False if we still need to wait.
*/
if(blocking_lock_record_process(blr)) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(
+ talloc_tos(), blr->fsp);
if (br_lck) {
brl_lock_cancel(br_lck,
@@ -785,21 +689,19 @@ static void process_blocking_lock_queue(void)
}
DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
+ TALLOC_FREE(blr);
recalc_timeout = True;
- change_to_root_user();
continue;
}
- change_to_root_user();
-
/*
* We couldn't get the locks for this record on the list.
* If the time has expired, return a lock error.
*/
if (!timeval_is_zero(&blr->expire_time) && timeval_compare(&blr->expire_time, &tv_curr) <= 0) {
- struct byte_range_lock *br_lck = brl_get_locks(talloc_tos(), fsp);
+ struct byte_range_lock *br_lck = brl_get_locks(
+ talloc_tos(), blr->fsp);
/*
* Lock expired - throw away all previously
@@ -807,8 +709,10 @@ static void process_blocking_lock_queue(void)
*/
if (br_lck) {
- DEBUG(5,("process_blocking_lock_queue: pending lock fnum = %d for file %s timed out.\n",
- fsp->fnum, fsp->fsp_name ));
+ DEBUG(5,("process_blocking_lock_queue: "
+ "pending lock fnum = %d for file %s "
+ "timed out.\n", blr->fsp->fnum,
+ blr->fsp->fsp_name ));
brl_lock_cancel(br_lck,
blr->lock_pid,
@@ -821,7 +725,7 @@ static void process_blocking_lock_queue(void)
blocking_lock_reply_error(blr,NT_STATUS_FILE_LOCK_CONFLICT);
DLIST_REMOVE(blocking_lock_queue, blr);
- free_blocking_lock_record(blr);
+ TALLOC_FREE(blr);
recalc_timeout = True;
}
}
@@ -865,7 +769,7 @@ static void process_blocking_lock_cancel_message(struct messaging_context *ctx,
blocking_lock_reply_error(blr, err);
DLIST_REMOVE(blocking_lock_cancelled_queue, blr);
- free_blocking_lock_record(blr);
+ TALLOC_FREE(blr);
}
/****************************************************************************
@@ -908,9 +812,9 @@ bool blocking_lock_cancel(files_struct *fsp,
}
/* Check the flags are right. */
- if (blr->com_type == SMBlockingX &&
+ if (blr->req->cmd == SMBlockingX &&
(locktype & LOCKING_ANDX_LARGE_FILES) !=
- (CVAL(blr->inbuf,smb_vwv3) & LOCKING_ANDX_LARGE_FILES)) {
+ (CVAL(blr->req->vwv+3, 0) & LOCKING_ANDX_LARGE_FILES)) {
return False;
}
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c
index 64a4311256..e6d2bbf59f 100644
--- a/source3/smbd/chgpasswd.c
+++ b/source3/smbd/chgpasswd.c
@@ -184,17 +184,17 @@ static int dochild(int master, const char *slavedev, const struct passwd *pass,
/* Make slave stdin/out/err of child. */
- if (sys_dup2(slave, STDIN_FILENO) != STDIN_FILENO)
+ if (dup2(slave, STDIN_FILENO) != STDIN_FILENO)
{
DEBUG(3, ("Could not re-direct stdin\n"));
return (False);
}
- if (sys_dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
+ if (dup2(slave, STDOUT_FILENO) != STDOUT_FILENO)
{
DEBUG(3, ("Could not re-direct stdout\n"));
return (False);
}
- if (sys_dup2(slave, STDERR_FILENO) != STDERR_FILENO)
+ if (dup2(slave, STDERR_FILENO) != STDERR_FILENO)
{
DEBUG(3, ("Could not re-direct stderr\n"));
return (False);
diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c
index 0ce226809e..26a4212ec9 100644
--- a/source3/smbd/ipc.c
+++ b/source3/smbd/ipc.c
@@ -81,7 +81,8 @@ static void copy_trans_params_and_data(char *outbuf, int align,
Send a trans reply.
****************************************************************************/
-void send_trans_reply(connection_struct *conn, const uint8_t *inbuf,
+void send_trans_reply(connection_struct *conn,
+ struct smb_request *req,
char *rparam, int rparam_len,
char *rdata, int rdata_len,
bool buffer_too_large)
@@ -90,7 +91,6 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf,
int tot_data_sent = 0;
int tot_param_sent = 0;
int align;
- char *outbuf;
int ldata = rdata ? rdata_len : 0;
int lparam = rparam ? rparam_len : 0;
@@ -103,38 +103,43 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf,
align = ((this_lparam)%4);
- if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf,
- 10, 1+align+this_ldata+this_lparam)) {
- smb_panic("could not allocate outbuf");
- }
+ reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);
+
+ /*
+ * We might have SMBtranss in req which was transferred to the outbuf,
+ * fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans);
- copy_trans_params_and_data(outbuf, align,
+ copy_trans_params_and_data((char *)req->outbuf, align,
rparam, tot_param_sent, this_lparam,
rdata, tot_data_sent, this_ldata);
- SSVAL(outbuf,smb_vwv0,lparam);
- SSVAL(outbuf,smb_vwv1,ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,0);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,smb_offset(smb_buf(outbuf)+1+this_lparam+align,
- outbuf));
- SSVAL(outbuf,smb_vwv8,0);
- SSVAL(outbuf,smb_vwv9,0);
+ SSVAL(req->outbuf,smb_vwv0,lparam);
+ SSVAL(req->outbuf,smb_vwv1,ldata);
+ SSVAL(req->outbuf,smb_vwv3,this_lparam);
+ SSVAL(req->outbuf,smb_vwv4,
+ smb_offset(smb_buf(req->outbuf)+1, req->outbuf));
+ SSVAL(req->outbuf,smb_vwv5,0);
+ SSVAL(req->outbuf,smb_vwv6,this_ldata);
+ SSVAL(req->outbuf,smb_vwv7,
+ smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
+ req->outbuf));
+ SSVAL(req->outbuf,smb_vwv8,0);
+ SSVAL(req->outbuf,smb_vwv9,0);
if (buffer_too_large) {
- error_packet_set((char *)outbuf, ERRDOS, ERRmoredata,
+ error_packet_set((char *)req->outbuf, ERRDOS, ERRmoredata,
STATUS_BUFFER_OVERFLOW, __LINE__, __FILE__);
}
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(), (char *)outbuf,
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
IS_CONN_ENCRYPTED(conn))) {
exit_server_cleanly("send_trans_reply: srv_send_smb failed.");
}
- TALLOC_FREE(outbuf);
+ TALLOC_FREE(req->outbuf);
tot_data_sent = this_ldata;
tot_param_sent = this_lparam;
@@ -154,39 +159,45 @@ void send_trans_reply(connection_struct *conn, const uint8_t *inbuf,
align = (this_lparam%4);
- if (!create_outbuf(talloc_tos(), (char *)inbuf, &outbuf,
- 10, 1+align+this_ldata+this_lparam)) {
- smb_panic("could not allocate outbuf");
- }
+ reply_outbuf(req, 10, 1+align+this_ldata+this_lparam);
+
+ /*
+ * We might have SMBtranss in req which was transferred to the
+ * outbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans);
- copy_trans_params_and_data(outbuf, align,
+ copy_trans_params_and_data((char *)req->outbuf, align,
rparam, tot_param_sent, this_lparam,
rdata, tot_data_sent, this_ldata);
- SSVAL(outbuf,smb_vwv3,this_lparam);
- SSVAL(outbuf,smb_vwv4,smb_offset(smb_buf(outbuf)+1,outbuf));
- SSVAL(outbuf,smb_vwv5,tot_param_sent);
- SSVAL(outbuf,smb_vwv6,this_ldata);
- SSVAL(outbuf,smb_vwv7,
- smb_offset(smb_buf(outbuf)+1+this_lparam+align, outbuf));
- SSVAL(outbuf,smb_vwv8,tot_data_sent);
- SSVAL(outbuf,smb_vwv9,0);
+ SSVAL(req->outbuf,smb_vwv3,this_lparam);
+ SSVAL(req->outbuf,smb_vwv4,
+ smb_offset(smb_buf(req->outbuf)+1,req->outbuf));
+ SSVAL(req->outbuf,smb_vwv5,tot_param_sent);
+ SSVAL(req->outbuf,smb_vwv6,this_ldata);
+ SSVAL(req->outbuf,smb_vwv7,
+ smb_offset(smb_buf(req->outbuf)+1+this_lparam+align,
+ req->outbuf));
+ SSVAL(req->outbuf,smb_vwv8,tot_data_sent);
+ SSVAL(req->outbuf,smb_vwv9,0);
if (buffer_too_large) {
- error_packet_set(outbuf, ERRDOS, ERRmoredata,
+ error_packet_set((char *)req->outbuf,
+ ERRDOS, ERRmoredata,
STATUS_BUFFER_OVERFLOW,
__LINE__, __FILE__);
}
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(), outbuf,
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
IS_CONN_ENCRYPTED(conn)))
exit_server_cleanly("send_trans_reply: srv_send_smb "
"failed.");
tot_data_sent += this_ldata;
tot_param_sent += this_lparam;
- TALLOC_FREE(outbuf);
+ TALLOC_FREE(req->outbuf);
}
}
@@ -218,7 +229,7 @@ static void api_rpc_trans_reply(connection_struct *conn,
return;
}
- send_trans_reply(conn, req->inbuf, NULL, 0, (char *)rdata, data_len,
+ send_trans_reply(conn, req, NULL, 0, (char *)rdata, data_len,
is_data_outstanding);
SAFE_FREE(rdata);
return;
@@ -239,7 +250,7 @@ static void api_WNPHS(connection_struct *conn, struct smb_request *req,
DEBUG(4,("WaitNamedPipeHandleState priority %x\n",
(int)SVAL(param,0)));
- send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
}
@@ -257,7 +268,7 @@ static void api_SNPHS(connection_struct *conn, struct smb_request *req,
DEBUG(4,("SetNamedPipeHandleState to code %x\n", (int)SVAL(param,0)));
- send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0, False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
}
@@ -276,7 +287,7 @@ static void api_no_reply(connection_struct *conn, struct smb_request *req)
DEBUG(3,("Unsupported API fd command\n"));
/* now send the reply */
- send_trans_reply(conn, req->inbuf, rparam, 4, NULL, 0, False);
+ send_trans_reply(conn, req, rparam, 4, NULL, 0, False);
return;
}
@@ -320,8 +331,7 @@ static void api_fd_reply(connection_struct *conn, uint16 vuid,
/* Win9x does this call with a unicode pipe name, not a pnum. */
/* Just return success for now... */
DEBUG(3,("Got TRANSACT_WAITNAMEDPIPEHANDLESTATE on text pipe name\n"));
- send_trans_reply(conn, req->inbuf, NULL, 0, NULL, 0,
- False);
+ send_trans_reply(conn, req, NULL, 0, NULL, 0, False);
return;
}
@@ -506,10 +516,10 @@ void reply_trans(struct smb_request *req)
size = smb_len(req->inbuf) + 4;
av_size = smb_len(req->inbuf);
- dsoff = SVAL(req->inbuf, smb_dsoff);
- dscnt = SVAL(req->inbuf, smb_dscnt);
- psoff = SVAL(req->inbuf, smb_psoff);
- pscnt = SVAL(req->inbuf, smb_pscnt);
+ dsoff = SVAL(req->vwv+12, 0);
+ dscnt = SVAL(req->vwv+11, 0);
+ psoff = SVAL(req->vwv+10, 0);
+ pscnt = SVAL(req->vwv+9, 0);
result = allow_new_trans(conn->pending_trans, req->mid);
if (!NT_STATUS_IS_OK(result)) {
@@ -531,20 +541,20 @@ void reply_trans(struct smb_request *req)
state->mid = req->mid;
state->vuid = req->vuid;
- state->setup_count = CVAL(req->inbuf, smb_suwcnt);
+ state->setup_count = CVAL(req->vwv+13, 0);
state->setup = NULL;
- state->total_param = SVAL(req->inbuf, smb_tpscnt);
+ state->total_param = SVAL(req->vwv+0, 0);
state->param = NULL;
- state->total_data = SVAL(req->inbuf, smb_tdscnt);
+ state->total_data = SVAL(req->vwv+1, 0);
state->data = NULL;
- state->max_param_return = SVAL(req->inbuf, smb_mprcnt);
- state->max_data_return = SVAL(req->inbuf, smb_mdrcnt);
- state->max_setup_return = CVAL(req->inbuf, smb_msrcnt);
- state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0);
- state->one_way = BITSETW(req->inbuf+smb_vwv5,1);
+ state->max_param_return = SVAL(req->vwv+2, 0);
+ state->max_data_return = SVAL(req->vwv+3, 0);
+ state->max_setup_return = CVAL(req->vwv+4, 0);
+ state->close_on_completion = BITSETW(req->vwv+5, 0);
+ state->one_way = BITSETW(req->vwv+5, 1);
- srvstr_pull_buf_talloc(state, req->inbuf, req->flags2, &state->name,
- smb_buf(req->inbuf), STR_TERMINATE);
+ srvstr_pull_req_talloc(state, req, &state->name, req->buf,
+ STR_TERMINATE);
if ((dscnt > state->total_data) || (pscnt > state->total_param) ||
!state->name)
@@ -710,20 +720,20 @@ void reply_transs(struct smb_request *req)
/* Revise total_params and total_data in case they have changed
* downwards */
- if (SVAL(req->inbuf, smb_vwv0) < state->total_param)
- state->total_param = SVAL(req->inbuf,smb_vwv0);
- if (SVAL(req->inbuf, smb_vwv1) < state->total_data)
- state->total_data = SVAL(req->inbuf,smb_vwv1);
+ if (SVAL(req->vwv+0, 0) < state->total_param)
+ state->total_param = SVAL(req->vwv+0, 0);
+ if (SVAL(req->vwv+1, 0) < state->total_data)
+ state->total_data = SVAL(req->vwv+1, 0);
av_size = smb_len(req->inbuf);
- pcnt = SVAL(req->inbuf, smb_spscnt);
- poff = SVAL(req->inbuf, smb_spsoff);
- pdisp = SVAL(req->inbuf, smb_spsdisp);
+ pcnt = SVAL(req->vwv+2, 0);
+ poff = SVAL(req->vwv+3, 0);
+ pdisp = SVAL(req->vwv+4, 0);
- dcnt = SVAL(req->inbuf, smb_sdscnt);
- doff = SVAL(req->inbuf, smb_sdsoff);
- ddisp = SVAL(req->inbuf, smb_sdsdisp);
+ dcnt = SVAL(req->vwv+5, 0);
+ doff = SVAL(req->vwv+6, 0);
+ ddisp = SVAL(req->vwv+7, 0);
state->received_param += pcnt;
state->received_data += dcnt;
@@ -776,12 +786,6 @@ void reply_transs(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBtranss is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBtrans);
-
handle_trans(conn, req, state);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c
index 0c866da706..6ed3ce2c87 100644
--- a/source3/smbd/lanman.c
+++ b/source3/smbd/lanman.c
@@ -4632,7 +4632,7 @@ void api_reply(connection_struct *conn, uint16 vuid,
/* If api_Unsupported returns false we can't return anything. */
if (reply) {
- send_trans_reply(conn, req->inbuf, rparam, rparam_len,
+ send_trans_reply(conn, req, rparam, rparam_len,
rdata, rdata_len, False);
}
diff --git a/source3/smbd/mangle.c b/source3/smbd/mangle.c
index 360692c546..4d4d0dc5af 100644
--- a/source3/smbd/mangle.c
+++ b/source3/smbd/mangle.c
@@ -140,7 +140,7 @@ bool name_to_8_3(const char *in,
/* name mangling can be disabled for speed, in which case
we just truncate the string */
if (!lp_manglednames(p)) {
- safe_strcpy(out,in,12);
+ strlcpy(out, in, 13);
return True;
}
diff --git a/source3/smbd/map_username.c b/source3/smbd/map_username.c
index a8899dd538..f549f0c9f3 100644
--- a/source3/smbd/map_username.c
+++ b/source3/smbd/map_username.c
@@ -178,7 +178,7 @@ bool map_username(fstring user)
/* skip lines like 'user = ' */
- dosuserlist = str_list_make(talloc_tos(), dosname, NULL);
+ dosuserlist = str_list_make_v3(talloc_tos(), dosname, NULL);
if (!dosuserlist) {
DEBUG(0,("Bad username map entry. Unable to build user list. Ignoring.\n"));
continue;
diff --git a/source3/smbd/message.c b/source3/smbd/message.c
index 62df5c37eb..65eaeca777 100644
--- a/source3/smbd/message.c
+++ b/source3/smbd/message.c
@@ -140,8 +140,8 @@ void reply_sends(struct smb_request *req)
{
struct msg_state *state;
int len;
- char *msg;
- char *p;
+ const char *msg;
+ const char *p;
START_PROFILE(SMBsends);
@@ -153,18 +153,16 @@ void reply_sends(struct smb_request *req)
state = talloc(talloc_tos(), struct msg_state);
- p = smb_buf(req->inbuf)+1;
- p += srvstr_pull_buf_talloc(
- state, (char *)req->inbuf, req->flags2, &state->from, p,
- STR_ASCII|STR_TERMINATE) + 1;
- p += srvstr_pull_buf_talloc(
- state, (char *)req->inbuf, req->flags2, &state->to, p,
- STR_ASCII|STR_TERMINATE) + 1;
+ p = (const char *)req->buf + 1;
+ p += srvstr_pull_req_talloc(
+ state, req, &state->from, p, STR_ASCII|STR_TERMINATE) + 1;
+ p += srvstr_pull_req_talloc(
+ state, req, &state->to, p, STR_ASCII|STR_TERMINATE) + 1;
msg = p;
len = SVAL(msg,0);
- len = MIN(len, smb_bufrem(req->inbuf, msg+2));
+ len = MIN(len, smbreq_bufrem(req, msg+2));
state->msg = talloc_array(state, char, len);
@@ -191,7 +189,7 @@ void reply_sends(struct smb_request *req)
void reply_sendstrt(struct smb_request *req)
{
- char *p;
+ const char *p;
START_PROFILE(SMBsendstrt);
@@ -211,13 +209,13 @@ void reply_sendstrt(struct smb_request *req)
return;
}
- p = smb_buf(req->inbuf)+1;
- p += srvstr_pull_buf_talloc(
- smbd_msg_state, (char *)req->inbuf, req->flags2,
- &smbd_msg_state->from, p, STR_ASCII|STR_TERMINATE) + 1;
- p += srvstr_pull_buf_talloc(
- smbd_msg_state, (char *)req->inbuf, req->flags2,
- &smbd_msg_state->to, p, STR_ASCII|STR_TERMINATE) + 1;
+ p = (const char *)req->buf+1;
+ p += srvstr_pull_req_talloc(
+ smbd_msg_state, req, &smbd_msg_state->from, p,
+ STR_ASCII|STR_TERMINATE) + 1;
+ p += srvstr_pull_req_talloc(
+ smbd_msg_state, req, &smbd_msg_state->to, p,
+ STR_ASCII|STR_TERMINATE) + 1;
DEBUG( 3, ( "SMBsendstrt (from %s to %s)\n", smbd_msg_state->from,
smbd_msg_state->to ) );
@@ -236,7 +234,7 @@ void reply_sendstrt(struct smb_request *req)
void reply_sendtxt(struct smb_request *req)
{
int len;
- char *msg;
+ const char *msg;
char *tmp;
size_t old_len;
@@ -254,11 +252,11 @@ void reply_sendtxt(struct smb_request *req)
return;
}
- msg = smb_buf(req->inbuf) + 1;
+ msg = (const char *)req->buf + 1;
old_len = talloc_get_size(smbd_msg_state->msg);
- len = MIN(SVAL(msg, 0), smb_bufrem(req->inbuf, msg+2));
+ len = MIN(SVAL(msg, 0), smbreq_bufrem(req, msg+2));
tmp = TALLOC_REALLOC_ARRAY(smbd_msg_state, smbd_msg_state->msg,
char, old_len + len);
diff --git a/source3/smbd/negprot.c b/source3/smbd/negprot.c
index 84f111fb02..43fdc1d608 100644
--- a/source3/smbd/negprot.c
+++ b/source3/smbd/negprot.c
@@ -507,11 +507,9 @@ static const struct {
void reply_negprot(struct smb_request *req)
{
- size_t size = smb_len(req->inbuf) + 4;
int choice= -1;
int protocol;
- char *p;
- int bcc = SVAL(smb_buf(req->inbuf),-2);
+ const char *p;
int arch = ARCH_ALL;
int num_cliprotos;
char **cliprotos;
@@ -528,19 +526,26 @@ void reply_negprot(struct smb_request *req)
}
done_negprot = True;
- if (req->inbuf[size-1] != '\0') {
+ if (req->buflen == 0) {
+ DEBUG(0, ("negprot got no protocols\n"));
+ reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+ END_PROFILE(SMBnegprot);
+ return;
+ }
+
+ if (req->buf[req->buflen-1] != '\0') {
DEBUG(0, ("negprot protocols not 0-terminated\n"));
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBnegprot);
return;
}
- p = smb_buf(req->inbuf) + 1;
+ p = (const char *)req->buf + 1;
num_cliprotos = 0;
cliprotos = NULL;
- while (p < (smb_buf(req->inbuf) + bcc)) {
+ while (smbreq_bufrem(req, p) > 0) {
char **tmp;
diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c
index 139dfe7d5b..5a517654bf 100644
--- a/source3/smbd/notify.c
+++ b/source3/smbd/notify.c
@@ -24,7 +24,7 @@
struct notify_change_request {
struct notify_change_request *prev, *next;
struct files_struct *fsp; /* backpointer for cancel by mid */
- uint8 request_buf[smb_size];
+ struct smb_request *req;
uint32 filter;
uint32 max_param;
struct notify_mid_map *mid_map;
@@ -133,40 +133,33 @@ static bool notify_marshall_changes(int num_changes,
*****************************************************************************/
static void change_notify_reply_packet(connection_struct *conn,
- const uint8 *request_buf,
+ struct smb_request *req,
NTSTATUS error_code)
{
- char outbuf[smb_size+38];
+ reply_outbuf(req, 18, 0);
- memset(outbuf, '\0', sizeof(outbuf));
- construct_reply_common((char *)request_buf, outbuf);
-
- ERROR_NT(error_code);
-
- /*
- * Seems NT needs a transact command with an error code
- * in it. This is a longer packet than a simple error.
- */
- srv_set_message(outbuf,18,0,False);
+ if (!NT_STATUS_IS_OK(error_code)) {
+ error_packet_set((char *)req->outbuf, 0, 0, error_code,
+ __LINE__,__FILE__);
+ }
- show_msg(outbuf);
- if (!srv_send_smb(smbd_server_fd(),
- outbuf,
- IS_CONN_ENCRYPTED(conn)))
+ show_msg((char *)req->outbuf);
+ if (!srv_send_smb(smbd_server_fd(), (char *)req->outbuf,
+ req->encrypted)) {
exit_server_cleanly("change_notify_reply_packet: srv_send_smb "
"failed.");
+ }
+ TALLOC_FREE(req->outbuf);
}
void change_notify_reply(connection_struct *conn,
- const uint8 *request_buf, uint32 max_param,
+ struct smb_request *req, uint32 max_param,
struct notify_change_buf *notify_buf)
{
prs_struct ps;
- struct smb_request *req = NULL;
- uint8 tmp_request[smb_size];
if (notify_buf->num_changes == -1) {
- change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
+ change_notify_reply_packet(conn, req, NT_STATUS_OK);
notify_buf->num_changes = 0;
return;
}
@@ -179,31 +172,14 @@ void change_notify_reply(connection_struct *conn,
* We exceed what the client is willing to accept. Send
* nothing.
*/
- change_notify_reply_packet(conn, request_buf, NT_STATUS_OK);
- goto done;
- }
-
- if (!(req = talloc(talloc_tos(), struct smb_request))) {
- change_notify_reply_packet(conn, request_buf, NT_STATUS_NO_MEMORY);
+ change_notify_reply_packet(conn, req, NT_STATUS_OK);
goto done;
}
- memcpy(tmp_request, request_buf, smb_size);
-
- /*
- * We're only interested in the header fields here
- */
-
- smb_setlen((char *)tmp_request, smb_size);
- SCVAL(tmp_request, smb_wct, 0);
-
- init_smb_request(req, tmp_request,0, conn->encrypted_tid);
-
send_nt_replies(conn, req, NT_STATUS_OK, prs_data_p(&ps),
prs_offset(&ps), NULL, 0);
done:
- TALLOC_FREE(req);
prs_mem_free(&ps);
TALLOC_FREE(notify_buf->changes);
@@ -251,7 +227,7 @@ NTSTATUS change_notify_create(struct files_struct *fsp, uint32 filter,
return status;
}
-NTSTATUS change_notify_add_request(const struct smb_request *req,
+NTSTATUS change_notify_add_request(struct smb_request *req,
uint32 max_param,
uint32 filter, bool recursive,
struct files_struct *fsp)
@@ -262,16 +238,16 @@ NTSTATUS change_notify_add_request(const struct smb_request *req,
DEBUG(10, ("change_notify_add_request: Adding request for %s: "
"max_param = %d\n", fsp->fsp_name, (int)max_param));
- if (!(request = SMB_MALLOC_P(struct notify_change_request))
- || !(map = SMB_MALLOC_P(struct notify_mid_map))) {
- SAFE_FREE(request);
+ if (!(request = talloc(NULL, struct notify_change_request))
+ || !(map = talloc(request, struct notify_mid_map))) {
+ TALLOC_FREE(request);
return NT_STATUS_NO_MEMORY;
}
request->mid_map = map;
map->req = request;
- memcpy(request->request_buf, req->inbuf, sizeof(request->request_buf));
+ request->req = talloc_move(request, &req);
request->max_param = max_param;
request->filter = filter;
request->fsp = fsp;
@@ -280,11 +256,11 @@ NTSTATUS change_notify_add_request(const struct smb_request *req,
DLIST_ADD_END(fsp->notify->requests, request,
struct notify_change_request *);
- map->mid = SVAL(req->inbuf, smb_mid);
+ map->mid = request->req->mid;
DLIST_ADD(notify_changes_by_mid, map);
/* Push the MID of this packet on the signing queue. */
- srv_defer_sign_response(SVAL(req->inbuf,smb_mid));
+ srv_defer_sign_response(request->req->mid);
return NT_STATUS_OK;
}
@@ -314,9 +290,7 @@ static void change_notify_remove_request(struct notify_change_request *remove_re
DLIST_REMOVE(fsp->notify->requests, req);
DLIST_REMOVE(notify_changes_by_mid, req->mid_map);
- SAFE_FREE(req->mid_map);
- TALLOC_FREE(req->backend_data);
- SAFE_FREE(req);
+ TALLOC_FREE(req);
}
/****************************************************************************
@@ -337,8 +311,8 @@ void remove_pending_change_notify_requests_by_mid(uint16 mid)
return;
}
- change_notify_reply_packet(map->req->fsp->conn,
- map->req->request_buf, NT_STATUS_CANCELLED);
+ change_notify_reply_packet(map->req->fsp->conn, map->req->req,
+ NT_STATUS_CANCELLED);
change_notify_remove_request(map->req);
}
@@ -354,8 +328,8 @@ void remove_pending_change_notify_requests_by_fid(files_struct *fsp,
}
while (fsp->notify->requests != NULL) {
- change_notify_reply_packet(fsp->conn,
- fsp->notify->requests->request_buf, status);
+ change_notify_reply_packet(
+ fsp->conn, fsp->notify->requests->req, status);
change_notify_remove_request(fsp->notify->requests);
}
}
@@ -449,7 +423,7 @@ static void notify_fsp(files_struct *fsp, uint32 action, const char *name)
*/
change_notify_reply(fsp->conn,
- fsp->notify->requests->request_buf,
+ fsp->notify->requests->req,
fsp->notify->requests->max_param,
fsp->notify);
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 30841686fb..1a13d962f0 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -120,6 +120,11 @@ void send_nt_replies(connection_struct *conn,
+ data_alignment_offset);
/*
+ * We might have had SMBnttranss in req->inbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBnttrans);
+
+ /*
* Set total params and data to be sent.
*/
@@ -304,11 +309,10 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
char *fname = NULL;
int pnum = -1;
char *p = NULL;
- uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags);
+ uint32 flags = IVAL(req->vwv+3, 1);
TALLOC_CTX *ctx = talloc_tos();
- srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf), STR_TERMINATE);
+ srvstr_pull_req_talloc(ctx, req, &fname, req->buf, STR_TERMINATE);
if (!fname) {
reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
@@ -408,24 +412,21 @@ void reply_ntcreate_and_X(struct smb_request *req)
return;
}
- flags = IVAL(req->inbuf,smb_ntcreate_Flags);
- access_mask = IVAL(req->inbuf,smb_ntcreate_DesiredAccess);
- file_attributes = IVAL(req->inbuf,smb_ntcreate_FileAttributes);
- share_access = IVAL(req->inbuf,smb_ntcreate_ShareAccess);
- create_disposition = IVAL(req->inbuf,smb_ntcreate_CreateDisposition);
- create_options = IVAL(req->inbuf,smb_ntcreate_CreateOptions);
- root_dir_fid = (uint16)IVAL(req->inbuf,smb_ntcreate_RootDirectoryFid);
+ flags = IVAL(req->vwv+3, 1);
+ access_mask = IVAL(req->vwv+7, 1);
+ file_attributes = IVAL(req->vwv+13, 1);
+ share_access = IVAL(req->vwv+15, 1);
+ create_disposition = IVAL(req->vwv+17, 1);
+ create_options = IVAL(req->vwv+19, 1);
+ root_dir_fid = (uint16)IVAL(req->vwv+5, 1);
- allocation_size = (uint64_t)IVAL(req->inbuf,
- smb_ntcreate_AllocationSize);
+ allocation_size = (uint64_t)IVAL(req->vwv+9, 1);
#ifdef LARGE_SMB_OFF_T
- allocation_size |= (((uint64_t)IVAL(
- req->inbuf,
- smb_ntcreate_AllocationSize + 4)) << 32);
+ allocation_size |= (((uint64_t)IVAL(req->vwv+11, 1)) << 32);
#endif
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf), 0, STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -729,6 +730,9 @@ static NTSTATUS set_sd(files_struct *fsp, uint8 *data, uint32 sd_len,
if (psd->sacl==0) {
security_info_sent &= ~SACL_SECURITY_INFORMATION;
}
+ if (security_info_sent & DACL_SECURITY_INFORMATION) {
+ psd->type |= SEC_DESC_DACL_PRESENT;
+ }
if (psd->dacl==0) {
security_info_sent &= ~DACL_SECURITY_INFORMATION;
}
@@ -1228,7 +1232,7 @@ void reply_ntrename(struct smb_request *req)
connection_struct *conn = req->conn;
char *oldname = NULL;
char *newname = NULL;
- char *p;
+ const char *p;
NTSTATUS status;
bool src_has_wcard = False;
bool dest_has_wcard = False;
@@ -1244,13 +1248,12 @@ void reply_ntrename(struct smb_request *req)
return;
}
- attrs = SVAL(req->inbuf,smb_vwv0);
- rename_type = SVAL(req->inbuf,smb_vwv1);
+ attrs = SVAL(req->vwv+0, 0);
+ rename_type = SVAL(req->vwv+1, 0);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p,
- 0, STR_TERMINATE, &status,
- &src_has_wcard);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &oldname, p, STR_TERMINATE,
+ &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBntrename);
@@ -1271,9 +1274,8 @@ void reply_ntrename(struct smb_request *req)
}
p++;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
- 0, STR_TERMINATE, &status,
- &dest_has_wcard);
+ p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
+ &status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBntrename);
@@ -1446,7 +1448,8 @@ static void call_nt_transact_notify_change(connection_struct *conn,
* here.
*/
- change_notify_reply(fsp->conn, req->inbuf, max_param_count, fsp->notify);
+ change_notify_reply(fsp->conn, req, max_param_count,
+ fsp->notify);
/*
* change_notify_reply() above has independently sent its
@@ -2538,11 +2541,11 @@ void reply_nttrans(struct smb_request *req)
size = smb_len(req->inbuf) + 4;
av_size = smb_len(req->inbuf);
- pscnt = IVAL(req->inbuf,smb_nt_ParameterCount);
- psoff = IVAL(req->inbuf,smb_nt_ParameterOffset);
- dscnt = IVAL(req->inbuf,smb_nt_DataCount);
- dsoff = IVAL(req->inbuf,smb_nt_DataOffset);
- function_code = SVAL(req->inbuf, smb_nt_Function);
+ pscnt = IVAL(req->vwv+9, 1);
+ psoff = IVAL(req->vwv+11, 1);
+ dscnt = IVAL(req->vwv+13, 1);
+ dsoff = IVAL(req->vwv+15, 1);
+ function_code = SVAL(req->vwv+18, 0);
if (IS_IPC(conn) && (function_code != NT_TRANSACT_CREATE)) {
reply_doserror(req, ERRSRV, ERRaccess);
@@ -2568,15 +2571,15 @@ void reply_nttrans(struct smb_request *req)
state->mid = req->mid;
state->vuid = req->vuid;
- state->total_data = IVAL(req->inbuf, smb_nt_TotalDataCount);
+ state->total_data = IVAL(req->vwv+3, 1);
state->data = NULL;
- state->total_param = IVAL(req->inbuf, smb_nt_TotalParameterCount);
+ state->total_param = IVAL(req->vwv+1, 1);
state->param = NULL;
- state->max_data_return = IVAL(req->inbuf,smb_nt_MaxDataCount);
- state->max_param_return = IVAL(req->inbuf,smb_nt_MaxParameterCount);
+ state->max_data_return = IVAL(req->vwv+7, 1);
+ state->max_param_return = IVAL(req->vwv+5, 1);
/* setup count is in *words* */
- state->setup_count = 2*CVAL(req->inbuf,smb_nt_SetupCount);
+ state->setup_count = 2*CVAL(req->vwv+17, 1);
state->setup = NULL;
state->call = function_code;
@@ -2691,8 +2694,7 @@ void reply_nttrans(struct smb_request *req)
goto bad_param;
}
- memcpy( state->setup, &req->inbuf[smb_nt_SetupStart],
- state->setup_count);
+ memcpy(state->setup, req->vwv+19, state->setup_count);
dump_data(10, (uint8 *)state->setup, state->setup_count);
}
@@ -2763,25 +2765,23 @@ void reply_nttranss(struct smb_request *req)
/* Revise state->total_param and state->total_data in case they have
changed downwards */
- if (IVAL(req->inbuf, smb_nts_TotalParameterCount)
- < state->total_param) {
- state->total_param = IVAL(req->inbuf,
- smb_nts_TotalParameterCount);
+ if (IVAL(req->vwv+1, 1) < state->total_param) {
+ state->total_param = IVAL(req->vwv+1, 1);
}
- if (IVAL(req->inbuf, smb_nts_TotalDataCount) < state->total_data) {
- state->total_data = IVAL(req->inbuf, smb_nts_TotalDataCount);
+ if (IVAL(req->vwv+3, 1) < state->total_data) {
+ state->total_data = IVAL(req->vwv+3, 1);
}
size = smb_len(req->inbuf) + 4;
av_size = smb_len(req->inbuf);
- pcnt = IVAL(req->inbuf,smb_nts_ParameterCount);
- poff = IVAL(req->inbuf, smb_nts_ParameterOffset);
- pdisp = IVAL(req->inbuf, smb_nts_ParameterDisplacement);
+ pcnt = IVAL(req->vwv+5, 1);
+ poff = IVAL(req->vwv+7, 1);
+ pdisp = IVAL(req->vwv+9, 1);
- dcnt = IVAL(req->inbuf, smb_nts_DataCount);
- ddisp = IVAL(req->inbuf, smb_nts_DataDisplacement);
- doff = IVAL(req->inbuf, smb_nts_DataOffset);
+ dcnt = IVAL(req->vwv+11, 1);
+ doff = IVAL(req->vwv+13, 1);
+ ddisp = IVAL(req->vwv+15, 1);
state->received_param += pcnt;
state->received_data += dcnt;
@@ -2834,12 +2834,6 @@ void reply_nttranss(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBnttranss is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBnttrans);
-
handle_nttrans(conn, state, req);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/open.c b/source3/smbd/open.c
index 1564525005..3fd0d1a03a 100644
--- a/source3/smbd/open.c
+++ b/source3/smbd/open.c
@@ -30,6 +30,56 @@ struct deferred_open_record {
};
/****************************************************************************
+ SMB1 file varient of se_access_check. Never test FILE_READ_ATTRIBUTES.
+****************************************************************************/
+
+NTSTATUS smb1_file_se_access_check(const struct security_descriptor *sd,
+ const NT_USER_TOKEN *token,
+ uint32_t access_desired,
+ uint32_t *access_granted)
+{
+ return se_access_check(sd,
+ token,
+ (access_desired & ~FILE_READ_ATTRIBUTES),
+ access_granted);
+}
+
+/****************************************************************************
+ Check if we have open rights.
+****************************************************************************/
+
+static NTSTATUS check_open_rights(struct connection_struct *conn,
+ const char *fname,
+ uint32_t access_mask)
+{
+ /* Check if we have rights to open. */
+ NTSTATUS status;
+ uint32_t access_granted = 0;
+ struct security_descriptor *sd;
+
+ status = SMB_VFS_GET_NT_ACL(conn, fname,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),&sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("check_open_rights: Could not get acl "
+ "on %s: %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
+ }
+
+ status = smb1_file_se_access_check(sd,
+ conn->server_info->ptok,
+ access_mask,
+ &access_granted);
+
+ TALLOC_FREE(sd);
+ return status;
+}
+
+/****************************************************************************
fd support routines - attempt to do a dos_open.
****************************************************************************/
@@ -337,6 +387,17 @@ static NTSTATUS open_file(files_struct *fsp,
} else {
fsp->fh->fd = -1; /* What we used to call a stat open. */
+ if (file_existed) {
+ status = check_open_rights(conn,
+ path,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_file: Access denied on "
+ "file %s\n",
+ path));
+ return status;
+ }
+ }
}
if (!file_existed) {
@@ -1126,6 +1187,68 @@ static void schedule_defer_open(struct share_mode_lock *lck,
}
/****************************************************************************
+ Work out what access_mask to use from what the client sent us.
+****************************************************************************/
+
+static NTSTATUS calculate_access_mask(connection_struct *conn,
+ const char *fname,
+ bool file_existed,
+ uint32_t access_mask,
+ uint32_t *access_mask_out)
+{
+ NTSTATUS status;
+
+ /*
+ * Convert GENERIC bits to specific bits.
+ */
+
+ se_map_generic(&access_mask, &file_generic_mapping);
+
+ /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
+ if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
+ if (file_existed) {
+
+ struct security_descriptor *sd;
+ uint32_t access_granted = 0;
+
+ status = SMB_VFS_GET_NT_ACL(conn, fname,
+ (OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION),&sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("calculate_access_mask: Could not get acl "
+ "on file %s: %s\n",
+ fname,
+ nt_errstr(status)));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ status = smb1_file_se_access_check(sd,
+ conn->server_info->ptok,
+ access_mask,
+ &access_granted);
+
+ TALLOC_FREE(sd);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("calculate_access_mask: Access denied on "
+ "file %s: when calculating maximum access\n",
+ fname));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ access_mask = access_granted;
+ } else {
+ access_mask = FILE_GENERIC_ALL;
+ }
+ }
+
+ *access_mask_out = access_mask;
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
Open a file with a share mode.
****************************************************************************/
@@ -1206,15 +1329,6 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
create_disposition, create_options, unx_mode,
oplock_request));
- if ((access_mask & FILE_READ_DATA)||(access_mask & FILE_WRITE_DATA)) {
- DEBUG(10, ("open_file_ntcreate: adding FILE_READ_ATTRIBUTES "
- "to requested access_mask 0x%x, new mask 0x%x",
- access_mask,
- access_mask | FILE_READ_ATTRIBUTES ));
-
- access_mask |= FILE_READ_ATTRIBUTES;
- }
-
if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
DEBUG(0, ("No smb request but not an internal only open!\n"));
return NT_STATUS_INTERNAL_ERROR;
@@ -1370,16 +1484,17 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
}
}
- /* This is a nasty hack - must fix... JRA. */
- if (access_mask == MAXIMUM_ALLOWED_ACCESS) {
- open_access_mask = access_mask = FILE_GENERIC_ALL;
+ status = calculate_access_mask(conn, fname, file_existed,
+ access_mask,
+ &access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_file_ntcreate: calculate_access_mask "
+ "on file %s returned %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
}
- /*
- * Convert GENERIC bits to specific bits.
- */
-
- se_map_generic(&access_mask, &file_generic_mapping);
open_access_mask = access_mask;
if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
@@ -1819,7 +1934,10 @@ NTSTATUS open_file_ntcreate(connection_struct *conn,
/* Record the options we were opened with. */
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
- fsp->access_mask = access_mask;
+ /*
+ * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
+ */
+ fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
if (file_existed) {
/* stat opens on existing files don't get oplocks. */
@@ -2135,6 +2253,17 @@ NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_NOT_A_DIRECTORY;
}
+ status = calculate_access_mask(conn, fname, dir_existed,
+ access_mask,
+ &access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_directory: calculate_access_mask "
+ "on file %s returned %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
+ }
+
switch( create_disposition ) {
case FILE_OPEN:
@@ -2209,6 +2338,19 @@ NTSTATUS open_directory(connection_struct *conn,
return NT_STATUS_NOT_A_DIRECTORY;
}
+ if (info == FILE_WAS_OPENED) {
+ status = check_open_rights(conn,
+ fname,
+ access_mask);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(10, ("open_directory: check_open_rights on "
+ "file %s failed with %s\n",
+ fname,
+ nt_errstr(status)));
+ return status;
+ }
+ }
+
status = file_new(req, conn, &fsp);
if(!NT_STATUS_IS_OK(status)) {
return status;
@@ -2228,8 +2370,10 @@ NTSTATUS open_directory(connection_struct *conn,
fsp->share_access = share_access;
fsp->fh->private_options = create_options;
- fsp->access_mask = access_mask;
-
+ /*
+ * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
+ */
+ fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
fsp->print_file = False;
fsp->modified = False;
fsp->oplock_type = NO_OPLOCK;
@@ -2779,7 +2923,12 @@ NTSTATUS create_file_unixpath(connection_struct *conn,
security_acl_map_generic(sd->dacl, &file_generic_mapping);
security_acl_map_generic(sd->sacl, &file_generic_mapping);
- status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
+ if (sec_info_sent & (OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION)) {
+ status = SMB_VFS_FSET_NT_ACL(fsp, sec_info_sent, sd);
+ }
fsp->access_mask = saved_access_mask;
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index 88e7b766be..84b40f28cc 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -576,7 +576,7 @@ static bool user_ok(const char *user, int snum)
TALLOC_FREE(valid);
if (ret && lp_onlyuser(snum)) {
- char **user_list = str_list_make(
+ char **user_list = str_list_make_v3(
talloc_tos(), lp_username(snum), NULL);
if (user_list &&
str_list_substitute(user_list, "%S",
diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c
index d971e9dc62..b52b1b02d0 100644
--- a/source3/smbd/pipes.c
+++ b/source3/smbd/pipes.c
@@ -48,8 +48,7 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
NTSTATUS status;
/* XXXX we need to handle passed times, sattr and flags */
- srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &pipe_name,
- smb_buf(req->inbuf), STR_TERMINATE);
+ srvstr_pull_req_talloc(ctx, req, &pipe_name, req->buf, STR_TERMINATE);
if (!pipe_name) {
reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
ERRDOS, ERRbadpipe);
@@ -119,10 +118,10 @@ void reply_open_pipe_and_X(connection_struct *conn, struct smb_request *req)
void reply_pipe_write(struct smb_request *req)
{
- files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
- size_t numtowrite = SVAL(req->inbuf,smb_vwv1);
+ files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
+ size_t numtowrite = SVAL(req->vwv+1, 0);
ssize_t nwritten;
- uint8_t *data;
+ const uint8_t *data;
if (!fsp_is_np(fsp)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -134,7 +133,7 @@ void reply_pipe_write(struct smb_request *req)
return;
}
- data = (uint8_t *)smb_buf(req->inbuf) + 3;
+ data = req->buf + 3;
if (numtowrite == 0) {
nwritten = 0;
@@ -171,13 +170,12 @@ void reply_pipe_write(struct smb_request *req)
void reply_pipe_write_and_X(struct smb_request *req)
{
- files_struct *fsp = file_fsp(req, SVAL(req->inbuf, smb_vwv2));
- size_t numtowrite = SVAL(req->inbuf,smb_vwv10);
+ files_struct *fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ size_t numtowrite = SVAL(req->vwv+10, 0);
ssize_t nwritten;
- int smb_doff = SVAL(req->inbuf, smb_vwv11);
+ int smb_doff = SVAL(req->vwv+11, 0);
bool pipe_start_message_raw =
- ((SVAL(req->inbuf, smb_vwv7)
- & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
+ ((SVAL(req->vwv+7, 0) & (PIPE_START_MESSAGE|PIPE_RAW_MODE))
== (PIPE_START_MESSAGE|PIPE_RAW_MODE));
uint8_t *data;
@@ -247,9 +245,9 @@ void reply_pipe_write_and_X(struct smb_request *req)
void reply_pipe_read_and_X(struct smb_request *req)
{
- files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
- int smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
- int smb_mincnt = SVAL(req->inbuf,smb_vwv6);
+ files_struct *fsp = file_fsp(req, SVAL(req->vwv+0, 0));
+ int smb_maxcnt = SVAL(req->vwv+5, 0);
+ int smb_mincnt = SVAL(req->vwv+6, 0);
ssize_t nread;
uint8_t *data;
bool unused;
@@ -259,7 +257,7 @@ void reply_pipe_read_and_X(struct smb_request *req)
is deliberate, instead we always return the next lump of
data on the pipe */
#if 0
- uint32 smb_offs = IVAL(req->inbuf,smb_vwv3);
+ uint32 smb_offs = IVAL(req->vwv+3, 0);
#endif
if (!fsp_is_np(fsp)) {
diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c
index cccf3087f7..7ca2ed787b 100644
--- a/source3/smbd/posix_acls.c
+++ b/source3/smbd/posix_acls.c
@@ -3511,7 +3511,7 @@ NTSTATUS set_nt_acl(files_struct *fsp, uint32 security_info_sent, const SEC_DESC
create_file_sids(&sbuf, &file_owner_sid, &file_grp_sid);
/* See here: http://www.codeproject.com/KB/winsdk/accessctrl2.aspx
- * for details. JRA.
+ * for details and also the log trace in bug #4308. JRA.
*/
if ((security_info_sent & DACL_SECURITY_INFORMATION) &&
@@ -4301,7 +4301,7 @@ SEC_DESC *get_nt_acl_no_snum( TALLOC_CTX *ctx, const char *fname)
finfo.fh->fd = -1;
finfo.fsp_name = CONST_DISCARD(char *,fname);
- if (!NT_STATUS_IS_OK(posix_fget_nt_acl( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
+ if (!NT_STATUS_IS_OK(SMB_VFS_FGET_NT_ACL( &finfo, DACL_SECURITY_INFORMATION, &psd))) {
DEBUG(0,("get_nt_acl_no_snum: get_nt_acl returned zero.\n"));
conn_free_internal( conn );
return NULL;
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index a8b93d8e1c..b3cd2f26c8 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -20,8 +20,6 @@
#include "includes.h"
-extern int smb_echo_count;
-
/*
* Size of data we can send to client. Set
* by the client for all protocols above CORE.
@@ -39,6 +37,8 @@ SIG_ATOMIC_T got_sig_term = 0;
extern bool global_machine_password_needs_changing;
extern int max_send;
+static void construct_reply_common(const char *inbuf, char *outbuf);
+
/* Accessor function for smb_read_error for smbd functions. */
/****************************************************************************
@@ -371,12 +371,16 @@ void init_smb_request(struct smb_request *req,
(unsigned int)req_size ));
exit_server_cleanly("Invalid SMB request");
}
+ req->cmd = CVAL(inbuf, smb_com);
req->flags2 = SVAL(inbuf, smb_flg2);
req->smbpid = SVAL(inbuf, smb_pid);
req->mid = SVAL(inbuf, smb_mid);
req->vuid = SVAL(inbuf, smb_uid);
req->tid = SVAL(inbuf, smb_tid);
req->wct = CVAL(inbuf, smb_wct);
+ req->vwv = (uint16_t *)(inbuf+smb_vwv);
+ req->buflen = smb_buflen(inbuf);
+ req->buf = (const uint8_t *)smb_buf(inbuf);
req->unread_bytes = unread_bytes;
req->encrypted = encrypted;
req->conn = conn_find(req->tid);
@@ -390,15 +394,14 @@ void init_smb_request(struct smb_request *req,
exit_server_cleanly("Invalid SMB request");
}
/* Ensure bcc is correct. */
- if (((uint8 *)smb_buf(inbuf)) + smb_buflen(inbuf) > inbuf + req_size) {
+ if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
DEBUG(0,("init_smb_request: invalid bcc number %u "
"(wct = %u, size %u)\n",
- (unsigned int)smb_buflen(inbuf),
+ (unsigned int)req->buflen,
(unsigned int)req->wct,
(unsigned int)req_size));
exit_server_cleanly("Invalid SMB request");
}
- req->inbuf = inbuf;
req->outbuf = NULL;
}
@@ -1422,6 +1425,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
if (!change_to_user(conn,session_tag)) {
reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
+ remove_deferred_open_smb_message(req->mid);
return conn;
}
@@ -1450,8 +1454,7 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
/* encrypted required from now on. */
conn->encrypt_level = Required;
} else if (ENCRYPTION_REQUIRED(conn)) {
- uint8 com = CVAL(req->inbuf,smb_com);
- if (com != SMBtrans2 && com != SMBtranss2) {
+ if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
exit_server_cleanly("encryption required "
"on connection");
return conn;
@@ -1486,7 +1489,6 @@ static connection_struct *switch_message(uint8 type, struct smb_request *req, in
static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
{
- uint8 type = CVAL(inbuf,smb_com);
connection_struct *conn;
struct smb_request *req;
@@ -1496,8 +1498,9 @@ static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool enc
smb_panic("could not allocate smb_request");
}
init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
+ req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
- conn = switch_message(type, req, size);
+ conn = switch_message(req->cmd, req, size);
if (req->unread_bytes) {
/* writeX failed. drain socket. */
@@ -1589,7 +1592,7 @@ void remove_from_common_flags2(uint32 v)
common_flags2 &= ~v;
}
-void construct_reply_common(const char *inbuf, char *outbuf)
+static void construct_reply_common(const char *inbuf, char *outbuf)
{
srv_set_message(outbuf,0,0,false);
@@ -1607,6 +1610,11 @@ void construct_reply_common(const char *inbuf, char *outbuf)
SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
}
+void construct_reply_common_req(struct smb_request *req, char *outbuf)
+{
+ construct_reply_common((char *)req->inbuf, outbuf);
+}
+
/****************************************************************************
Construct a chained reply and add it to the already made reply
****************************************************************************/
@@ -1717,6 +1725,7 @@ void chain_reply(struct smb_request *req)
smb_panic("could not allocate smb_request");
}
init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted);
+ req2->inbuf = (uint8_t *)inbuf2;
req2->chain_fsp = req->chain_fsp;
/* process the request */
@@ -1925,8 +1934,6 @@ void smbd_process(void)
process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
- TALLOC_FREE(inbuf);
-
num_smbs++;
/* The timeout_processing function isn't run nearly
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 25480c6e3b..be39fd464d 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -208,7 +208,7 @@ NTSTATUS check_path_syntax_posix(char *path)
****************************************************************************/
size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
- const char *inbuf,
+ const char *base_ptr,
uint16 smb_flags2,
char **pp_dest,
const char *src,
@@ -221,22 +221,8 @@ size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
*pp_dest = NULL;
- if (src_len == 0) {
- ret = srvstr_pull_buf_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- flags);
- } else {
- ret = srvstr_pull_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags);
- }
+ ret = srvstr_pull_talloc(ctx, base_ptr, smb_flags2, pp_dest, src,
+ src_len, flags);
if (!*pp_dest) {
*err = NT_STATUS_INVALID_PARAMETER;
@@ -268,7 +254,7 @@ size_t srvstr_get_path_wcard(TALLOC_CTX *ctx,
****************************************************************************/
size_t srvstr_get_path(TALLOC_CTX *ctx,
- const char *inbuf,
+ const char *base_ptr,
uint16 smb_flags2,
char **pp_dest,
const char *src,
@@ -276,48 +262,27 @@ size_t srvstr_get_path(TALLOC_CTX *ctx,
int flags,
NTSTATUS *err)
{
- size_t ret;
-
- *pp_dest = NULL;
-
- if (src_len == 0) {
- ret = srvstr_pull_buf_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- flags);
- } else {
- ret = srvstr_pull_talloc(ctx,
- inbuf,
- smb_flags2,
- pp_dest,
- src,
- src_len,
- flags);
- }
-
- if (!*pp_dest) {
- *err = NT_STATUS_INVALID_PARAMETER;
- return ret;
- }
-
- if (smb_flags2 & FLAGS2_DFS_PATHNAMES) {
- /*
- * For a DFS path the function parse_dfs_path()
- * will do the path processing, just make a copy.
- */
- *err = NT_STATUS_OK;
- return ret;
- }
+ bool ignore;
+ return srvstr_get_path_wcard(ctx, base_ptr, smb_flags2, pp_dest, src,
+ src_len, flags, err, &ignore);
+}
- if (lp_posix_pathnames()) {
- *err = check_path_syntax_posix(*pp_dest);
- } else {
- *err = check_path_syntax(*pp_dest);
- }
+size_t srvstr_get_path_req_wcard(TALLOC_CTX *mem_ctx, struct smb_request *req,
+ char **pp_dest, const char *src, int flags,
+ NTSTATUS *err, bool *contains_wcard)
+{
+ return srvstr_get_path_wcard(mem_ctx, (char *)req->inbuf, req->flags2,
+ pp_dest, src, smbreq_bufrem(req, src),
+ flags, err, contains_wcard);
+}
- return ret;
+size_t srvstr_get_path_req(TALLOC_CTX *mem_ctx, struct smb_request *req,
+ char **pp_dest, const char *src, int flags,
+ NTSTATUS *err)
+{
+ bool ignore;
+ return srvstr_get_path_req_wcard(mem_ctx, req, pp_dest, src,
+ flags, err, &ignore);
}
/****************************************************************************
@@ -517,26 +482,25 @@ void reply_tcon(struct smb_request *req)
char *dev = NULL;
int pwlen=0;
NTSTATUS nt_status;
- char *p;
+ const char *p;
DATA_BLOB password_blob;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBtcon);
- if (smb_buflen(req->inbuf) < 4) {
+ if (req->buflen < 4) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBtcon);
return;
}
- p = smb_buf(req->inbuf)+1;
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &service_buf, p, STR_TERMINATE) + 1;
- pwlen = srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &password, p, STR_TERMINATE) + 1;
- p += pwlen;
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2,
- &dev, p, STR_TERMINATE) + 1;
+ p = (const char *)req->buf + 1;
+ p += srvstr_pull_req_talloc(ctx, req, &service_buf, p, STR_TERMINATE);
+ p += 1;
+ pwlen = srvstr_pull_req_talloc(ctx, req, &password, p, STR_TERMINATE);
+ p += pwlen+1;
+ p += srvstr_pull_req_talloc(ctx, req, &dev, p, STR_TERMINATE);
+ p += 1;
if (service_buf == NULL || password == NULL || dev == NULL) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
@@ -583,7 +547,7 @@ void reply_tcon(struct smb_request *req)
void reply_tcon_and_X(struct smb_request *req)
{
connection_struct *conn = req->conn;
- char *service = NULL;
+ const char *service = NULL;
DATA_BLOB password;
TALLOC_CTX *ctx = talloc_tos();
/* what the cleint thinks the device is */
@@ -593,7 +557,7 @@ void reply_tcon_and_X(struct smb_request *req)
NTSTATUS nt_status;
int passlen;
char *path = NULL;
- char *p, *q;
+ const char *p, *q;
uint16 tcon_flags;
START_PROFILE(SMBtconX);
@@ -604,8 +568,8 @@ void reply_tcon_and_X(struct smb_request *req)
return;
}
- passlen = SVAL(req->inbuf,smb_vwv3);
- tcon_flags = SVAL(req->inbuf,smb_vwv2);
+ passlen = SVAL(req->vwv+3, 0);
+ tcon_flags = SVAL(req->vwv+2, 0);
/* we might have to close an old one */
if ((tcon_flags & 0x1) && conn) {
@@ -614,34 +578,31 @@ void reply_tcon_and_X(struct smb_request *req)
conn = NULL;
}
- if ((passlen > MAX_PASS_LEN) || (passlen >= smb_buflen(req->inbuf))) {
+ if ((passlen > MAX_PASS_LEN) || (passlen >= req->buflen)) {
reply_doserror(req, ERRDOS, ERRbuftoosmall);
END_PROFILE(SMBtconX);
return;
}
if (global_encrypted_passwords_negotiated) {
- password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
- passlen);
+ password = data_blob_talloc(talloc_tos(), req->buf, passlen);
if (lp_security() == SEC_SHARE) {
/*
* Security = share always has a pad byte
* after the password.
*/
- p = smb_buf(req->inbuf) + passlen + 1;
+ p = (const char *)req->buf + passlen + 1;
} else {
- p = smb_buf(req->inbuf) + passlen;
+ p = (const char *)req->buf + passlen;
}
} else {
- password = data_blob_talloc(talloc_tos(), smb_buf(req->inbuf),
- passlen+1);
+ password = data_blob_talloc(talloc_tos(), req->buf, passlen+1);
/* Ensure correct termination */
password.data[passlen]=0;
- p = smb_buf(req->inbuf) + passlen + 1;
+ p = (const char *)req->buf + passlen + 1;
}
- p += srvstr_pull_buf_talloc(ctx, req->inbuf, req->flags2, &path, p,
- STR_TERMINATE);
+ p += srvstr_pull_req_talloc(ctx, req, &path, p, STR_TERMINATE);
if (path == NULL) {
data_blob_clear_free(&password);
@@ -669,7 +630,7 @@ void reply_tcon_and_X(struct smb_request *req)
p += srvstr_pull_talloc(ctx, req->inbuf, req->flags2,
&client_devicetype, p,
- MIN(6,smb_bufrem(req->inbuf, p)), STR_ASCII);
+ MIN(6, smbreq_bufrem(req, p)), STR_ASCII);
if (client_devicetype == NULL) {
data_blob_clear_free(&password);
@@ -803,8 +764,8 @@ void reply_ioctl(struct smb_request *req)
return;
}
- device = SVAL(req->inbuf,smb_vwv1);
- function = SVAL(req->inbuf,smb_vwv2);
+ device = SVAL(req->vwv+1, 0);
+ function = SVAL(req->vwv+2, 0);
ioctl_code = (device << 16) + function;
DEBUG(4, ("Received IOCTL (code 0x%x)\n", ioctl_code));
@@ -831,7 +792,7 @@ void reply_ioctl(struct smb_request *req)
case IOCTL_QUERY_JOB_INFO:
{
files_struct *fsp = file_fsp(
- req, SVAL(req->inbuf, smb_vwv0));
+ req, SVAL(req->vwv+0, 0));
if (!fsp) {
reply_doserror(req, ERRDOS, ERRbadfid);
END_PROFILE(SMBioctl);
@@ -860,10 +821,10 @@ void reply_ioctl(struct smb_request *req)
Strange checkpath NTSTATUS mapping.
****************************************************************************/
-static NTSTATUS map_checkpath_error(const char *inbuf, NTSTATUS status)
+static NTSTATUS map_checkpath_error(uint16_t flags2, NTSTATUS status)
{
/* Strange DOS error code semantics only for checkpath... */
- if (!(SVAL(inbuf,smb_flg2) & FLAGS2_32_BIT_ERROR_CODES)) {
+ if (!(flags2 & FLAGS2_32_BIT_ERROR_CODES)) {
if (NT_STATUS_EQUAL(NT_STATUS_OBJECT_NAME_INVALID,status)) {
/* We need to map to ERRbadpath */
return NT_STATUS_OBJECT_PATH_NOT_FOUND;
@@ -886,11 +847,11 @@ void reply_checkpath(struct smb_request *req)
START_PROFILE(SMBcheckpath);
- srvstr_get_path(ctx,(char *)req->inbuf, req->flags2, &name,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &name, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
+
if (!NT_STATUS_IS_OK(status)) {
- status = map_checkpath_error((char *)req->inbuf, status);
+ status = map_checkpath_error(req->flags2, status);
reply_nterror(req, status);
END_PROFILE(SMBcheckpath);
return;
@@ -910,7 +871,7 @@ void reply_checkpath(struct smb_request *req)
goto path_err;
}
- DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->inbuf,smb_vwv0)));
+ DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
status = unix_convert(ctx, conn, name, False, &name, NULL, &sbuf);
if (!NT_STATUS_IS_OK(status)) {
@@ -950,7 +911,7 @@ void reply_checkpath(struct smb_request *req)
one at a time - if a component fails it expects
ERRbadpath, not ERRbadfile.
*/
- status = map_checkpath_error((char *)req->inbuf, status);
+ status = map_checkpath_error(req->flags2, status);
if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
/*
* Windows returns different error codes if
@@ -979,15 +940,14 @@ void reply_getatr(struct smb_request *req)
int mode=0;
SMB_OFF_T size=0;
time_t mtime=0;
- char *p;
+ const char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
START_PROFILE(SMBgetatr);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
- 0, STR_TERMINATE, &status);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBgetatr);
@@ -1081,7 +1041,7 @@ void reply_setatr(struct smb_request *req)
int mode;
time_t mtime;
SMB_STRUCT_STAT sbuf;
- char *p;
+ const char *p;
NTSTATUS status;
TALLOC_CTX *ctx = talloc_tos();
@@ -1094,9 +1054,8 @@ void reply_setatr(struct smb_request *req)
return;
}
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname, p,
- 0, STR_TERMINATE, &status);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req(ctx, req, &fname, p, STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBsetatr);
@@ -1143,8 +1102,8 @@ void reply_setatr(struct smb_request *req)
return;
}
- mode = SVAL(req->inbuf,smb_vwv0);
- mtime = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ mode = SVAL(req->vwv+0, 0);
+ mtime = srv_make_unix_date3(req->vwv+1);
ts[1] = convert_time_t_to_timespec(mtime);
status = smb_set_file_time(conn, NULL, fname,
@@ -1236,7 +1195,7 @@ void reply_dskattr(struct smb_request *req)
void reply_search(struct smb_request *req)
{
connection_struct *conn = req->conn;
- char *mask = NULL;
+ const char *mask = NULL;
char *directory = NULL;
char *fname = NULL;
SMB_OFF_T size;
@@ -1246,7 +1205,7 @@ void reply_search(struct smb_request *req)
unsigned int numentries = 0;
unsigned int maxentries = 0;
bool finished = False;
- char *p;
+ const char *p;
int status_len;
char *path = NULL;
char status[21];
@@ -1268,29 +1227,22 @@ void reply_search(struct smb_request *req)
}
if (lp_posix_pathnames()) {
- reply_unknown_new(req, CVAL(req->inbuf, smb_com));
+ reply_unknown_new(req, req->cmd);
END_PROFILE(SMBsearch);
return;
}
/* If we were called as SMBffirst then we must expect close. */
- if(CVAL(req->inbuf,smb_com) == SMBffirst) {
+ if(req->cmd == SMBffirst) {
expect_close = True;
}
reply_outbuf(req, 1, 3);
- maxentries = SVAL(req->inbuf,smb_vwv0);
- dirtype = SVAL(req->inbuf,smb_vwv1);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx,
- (char *)req->inbuf,
- req->flags2,
- &path,
- p,
- 0,
- STR_TERMINATE,
- &nt_status,
- &mask_contains_wcard);
+ maxentries = SVAL(req->vwv+0, 0);
+ dirtype = SVAL(req->vwv+1, 0);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
+ &nt_status, &mask_contains_wcard);
if (!NT_STATUS_IS_OK(nt_status)) {
reply_nterror(req, nt_status);
END_PROFILE(SMBsearch);
@@ -1339,27 +1291,21 @@ void reply_search(struct smb_request *req)
}
p = strrchr_m(directory,'/');
- if (!p) {
+ if ((p != NULL) && (*directory != '/')) {
+ mask = p + 1;
+ directory = talloc_strndup(ctx, directory,
+ PTR_DIFF(p, directory));
+ } else {
mask = directory;
directory = talloc_strdup(ctx,".");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
- }
- } else {
- *p = 0;
- mask = p+1;
}
- if (*directory == '\0') {
- directory = talloc_strdup(ctx,".");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBsearch);
- return;
- }
+ if (!directory) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBsearch);
+ return;
}
+
memset((char *)status,'\0',21);
SCVAL(status,0,(dirtype & 0x1F));
@@ -1497,7 +1443,7 @@ void reply_search(struct smb_request *req)
}
/* If we were called as SMBfunique, then we can close the dirptr now ! */
- if(dptr_num >= 0 && CVAL(req->inbuf,smb_com) == SMBfunique) {
+ if(dptr_num >= 0 && req->cmd == SMBfunique) {
dptr_close(&dptr_num);
}
@@ -1530,7 +1476,7 @@ void reply_search(struct smb_request *req)
}
DEBUG(4,("%s mask=%s path=%s dtype=%d nument=%u of %u\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)),
+ smb_fn_name(req->cmd),
mask,
directory ? directory : "./",
dirtype,
@@ -1550,7 +1496,7 @@ void reply_fclose(struct smb_request *req)
int status_len;
char status[21];
int dptr_num= -2;
- char *p;
+ const char *p;
char *path = NULL;
NTSTATUS err;
bool path_contains_wcard = False;
@@ -1559,21 +1505,14 @@ void reply_fclose(struct smb_request *req)
START_PROFILE(SMBfclose);
if (lp_posix_pathnames()) {
- reply_unknown_new(req, CVAL(req->inbuf, smb_com));
+ reply_unknown_new(req, req->cmd);
END_PROFILE(SMBfclose);
return;
}
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx,
- (char *)req->inbuf,
- req->flags2,
- &path,
- p,
- 0,
- STR_TERMINATE,
- &err,
- &path_contains_wcard);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &path, p, STR_TERMINATE,
+ &err, &path_contains_wcard);
if (!NT_STATUS_IS_OK(err)) {
reply_nterror(req, err);
END_PROFILE(SMBfclose);
@@ -1638,12 +1577,11 @@ void reply_open(struct smb_request *req)
}
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- deny_mode = SVAL(req->inbuf,smb_vwv0);
- dos_attr = SVAL(req->inbuf,smb_vwv1);
+ deny_mode = SVAL(req->vwv+0, 0);
+ dos_attr = SVAL(req->vwv+1, 0);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf)+1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopen);
@@ -1739,8 +1677,8 @@ void reply_open_and_X(struct smb_request *req)
int core_oplock_request;
int oplock_request;
#if 0
- int smb_sattr = SVAL(req->inbuf,smb_vwv4);
- uint32 smb_time = make_unix_date3(req->inbuf+smb_vwv6);
+ int smb_sattr = SVAL(req->vwv+4, 0);
+ uint32 smb_time = make_unix_date3(req->vwv+6);
#endif
int smb_ofun;
uint32 fattr=0;
@@ -1765,14 +1703,14 @@ void reply_open_and_X(struct smb_request *req)
return;
}
- open_flags = SVAL(req->inbuf,smb_vwv2);
- deny_mode = SVAL(req->inbuf,smb_vwv3);
- smb_attr = SVAL(req->inbuf,smb_vwv5);
+ open_flags = SVAL(req->vwv+2, 0);
+ deny_mode = SVAL(req->vwv+3, 0);
+ smb_attr = SVAL(req->vwv+5, 0);
ex_oplock_request = EXTENDED_OPLOCK_REQUEST(req->inbuf);
core_oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
oplock_request = ex_oplock_request | core_oplock_request;
- smb_ofun = SVAL(req->inbuf,smb_vwv8);
- allocation_size = (uint64_t)IVAL(req->inbuf,smb_vwv9);
+ smb_ofun = SVAL(req->vwv+8, 0);
+ allocation_size = (uint64_t)IVAL(req->vwv+9, 0);
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
@@ -1786,9 +1724,8 @@ void reply_open_and_X(struct smb_request *req)
}
/* XXXX we need to handle passed times, sattr and flags */
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf), 0, STR_TERMINATE,
- &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBopenX);
@@ -1954,7 +1891,6 @@ void reply_mknew(struct smb_request *req)
{
connection_struct *conn = req->conn;
char *fname = NULL;
- int com;
uint32 fattr = 0;
struct timespec ts[2];
files_struct *fsp;
@@ -1975,17 +1911,14 @@ void reply_mknew(struct smb_request *req)
return;
}
- fattr = SVAL(req->inbuf,smb_vwv0);
+ fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- com = SVAL(req->inbuf,smb_com);
- ts[1] =convert_time_t_to_timespec(
- srv_make_unix_date3(req->inbuf + smb_vwv1));
+ ts[1] = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+1));
/* mtime. */
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcreate);
@@ -1997,7 +1930,7 @@ void reply_mknew(struct smb_request *req)
"please report this\n", fname));
}
- if(com == SMBmknew) {
+ if(req->cmd == SMBmknew) {
/* We should fail if file exists. */
create_disposition = FILE_CREATE;
} else {
@@ -2086,12 +2019,11 @@ void reply_ctemp(struct smb_request *req)
return;
}
- fattr = SVAL(req->inbuf,smb_vwv0);
+ fattr = SVAL(req->vwv+0, 0);
oplock_request = CORE_OPLOCK_REQUEST(req->inbuf);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
- smb_buf(req->inbuf)+1, 0, STR_TERMINATE,
- &status);
+ srvstr_get_path_req(ctx, req, &fname, (const char *)req->buf+1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBctemp);
@@ -2558,11 +2490,11 @@ void reply_unlink(struct smb_request *req)
return;
}
- dirtype = SVAL(req->inbuf,smb_vwv0);
+ dirtype = SVAL(req->vwv+0, 0);
- srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status, &path_contains_wcard);
+ srvstr_get_path_req_wcard(ctx, req, &name, (const char *)req->buf + 1,
+ STR_TERMINATE, &status,
+ &path_contains_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBunlink);
@@ -2813,7 +2745,7 @@ void reply_readbraw(struct smb_request *req)
* return a zero length response here.
*/
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
/*
* We have to do a check_fsp by hand here, as
@@ -2829,7 +2761,7 @@ void reply_readbraw(struct smb_request *req)
*/
DEBUG(3,("reply_readbraw: fnum %d not valid "
"- cache prime?\n",
- (int)SVAL(req->inbuf,smb_vwv0)));
+ (int)SVAL(req->vwv+0, 0)));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
@@ -2840,7 +2772,7 @@ void reply_readbraw(struct smb_request *req)
((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)));
+ (int)SVAL(req->vwv+0, 0)));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
@@ -2848,14 +2780,14 @@ void reply_readbraw(struct smb_request *req)
flush_write_cache(fsp, READRAW_FLUSH);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv1);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+1, 0);
if(req->wct == 10) {
/*
* This is a large offset (64 bit) read.
*/
#ifdef LARGE_SMB_OFF_T
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv8)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+8, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
@@ -2863,11 +2795,11 @@ void reply_readbraw(struct smb_request *req)
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv8) != 0) {
+ if(IVAL(req->vwv+8, 0) != 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) ));
+ (unsigned int)IVAL(req->vwv+8, 0) ));
reply_readbraw_error();
END_PROFILE(SMBreadbraw);
return;
@@ -2885,8 +2817,8 @@ void reply_readbraw(struct smb_request *req)
}
}
- maxcount = (SVAL(req->inbuf,smb_vwv3) & 0xFFFF);
- mincount = (SVAL(req->inbuf,smb_vwv4) & 0xFFFF);
+ maxcount = (SVAL(req->vwv+3, 0) & 0xFFFF);
+ mincount = (SVAL(req->vwv+4, 0) & 0xFFFF);
/* ensure we don't overrun the packet size */
maxcount = MIN(65535,maxcount);
@@ -2955,14 +2887,14 @@ void reply_lockread(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlockread);
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBlockread);
return;
@@ -2970,8 +2902,8 @@ void reply_lockread(struct smb_request *req)
release_level_2_oplocks_on_change(fsp);
- numtoread = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+ numtoread = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
numtoread = MIN(BUFFER_SIZE - (smb_size + 3*2 + 3), numtoread);
@@ -3063,21 +2995,21 @@ void reply_read(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBread);
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBread);
return;
}
- numtoread = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
+ numtoread = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
numtoread = MIN(BUFFER_SIZE-outsize,numtoread);
@@ -3183,7 +3115,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
* on a train in Germany :-). JRA.
*/
- if ((chain_size == 0) && (CVAL(req->inbuf,smb_vwv0) == 0xFF) &&
+ if ((chain_size == 0) && (CVAL(req->vwv+0, 0) == 0xFF) &&
!is_encrypted_packet(req->inbuf) && (fsp->base_fsp == NULL) &&
lp_use_sendfile(SNUM(conn)) && (fsp->wcp == NULL) ) {
uint8 headerbuf[smb_size + 12 * 2];
@@ -3197,7 +3129,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
header = data_blob_const(headerbuf, sizeof(headerbuf));
- construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ construct_reply_common_req(req, (char *)headerbuf);
setup_readX_header((char *)headerbuf, smb_maxcnt);
if ((nread = SMB_VFS_SENDFILE(smbd_server_fd(), fsp, &header, startpos, smb_maxcnt)) == -1) {
@@ -3249,7 +3181,7 @@ normal_read:
if ((smb_maxcnt & 0xFF0000) > 0x10000) {
uint8 headerbuf[smb_size + 2*12];
- construct_reply_common((char *)req->inbuf, (char *)headerbuf);
+ construct_reply_common_req(req, (char *)headerbuf);
setup_readX_header((char *)headerbuf, smb_maxcnt);
/* Send out the header. */
@@ -3297,7 +3229,7 @@ void reply_read_and_X(struct smb_request *req)
size_t smb_maxcnt;
bool big_readX = False;
#if 0
- size_t smb_mincnt = SVAL(req->inbuf,smb_vwv6);
+ size_t smb_mincnt = SVAL(req->vwv+6, 0);
#endif
START_PROFILE(SMBreadX);
@@ -3307,9 +3239,9 @@ void reply_read_and_X(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- smb_maxcnt = SVAL(req->inbuf,smb_vwv5);
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ smb_maxcnt = SVAL(req->vwv+5, 0);
/* If it's an IPC, pass off the pipe handler. */
if (IS_IPC(conn)) {
@@ -3323,18 +3255,18 @@ void reply_read_and_X(struct smb_request *req)
return;
}
- if (!CHECK_READ(fsp,req->inbuf)) {
+ if (!CHECK_READ(fsp,req)) {
reply_doserror(req, ERRDOS,ERRbadaccess);
END_PROFILE(SMBreadX);
return;
}
if (global_client_caps & CAP_LARGE_READX) {
- size_t upper_size = SVAL(req->inbuf,smb_vwv7);
+ size_t upper_size = SVAL(req->vwv+7, 0);
smb_maxcnt |= (upper_size<<16);
if (upper_size > 1) {
/* Can't do this on a chained packet. */
- if ((CVAL(req->inbuf,smb_vwv0) != 0xFF)) {
+ if ((CVAL(req->vwv+0, 0) != 0xFF)) {
reply_nterror(req, NT_STATUS_NOT_SUPPORTED);
END_PROFILE(SMBreadX);
return;
@@ -3361,7 +3293,7 @@ void reply_read_and_X(struct smb_request *req)
/*
* This is a large offset (64 bit) read.
*/
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv10)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+10, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
@@ -3369,10 +3301,10 @@ void reply_read_and_X(struct smb_request *req)
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv10) != 0) {
+ if(IVAL(req->vwv+10, 0) != 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) ));
+ (unsigned int)IVAL(req->vwv+10, 0) ));
END_PROFILE(SMBreadX);
reply_doserror(req, ERRDOS, ERRbadaccess);
return;
@@ -3455,7 +3387,7 @@ void reply_writebraw(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
error_to_writebrawerr(req);
END_PROFILE(SMBwritebraw);
@@ -3469,9 +3401,9 @@ void reply_writebraw(struct smb_request *req)
return;
}
- tcount = IVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- write_through = BITSETW(req->inbuf+smb_vwv7,0);
+ tcount = IVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ write_through = BITSETW(req->vwv+7,0);
/* We have to deal with slightly different formats depending
on whether we are using the core+ or lanman1.0 protocol */
@@ -3480,8 +3412,8 @@ void reply_writebraw(struct smb_request *req)
numtowrite = SVAL(smb_buf(req->inbuf),-2);
data = smb_buf(req->inbuf);
} else {
- numtowrite = SVAL(req->inbuf,smb_vwv10);
- data = smb_base(req->inbuf) + SVAL(req->inbuf, smb_vwv11);
+ numtowrite = SVAL(req->vwv+10, 0);
+ data = smb_base(req->inbuf) + SVAL(req->vwv+11, 0);
}
/* Ensure we don't write bytes past the end of this packet. */
@@ -3648,7 +3580,7 @@ void reply_writeunlock(struct smb_request *req)
ssize_t nwritten = -1;
size_t numtowrite;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
NTSTATUS status = NT_STATUS_OK;
files_struct *fsp;
@@ -3660,7 +3592,7 @@ void reply_writeunlock(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteunlock);
@@ -3673,9 +3605,9 @@ void reply_writeunlock(struct smb_request *req)
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- data = smb_buf(req->inbuf) + 3;
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ data = (const char *)req->buf + 3;
if (numtowrite
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
@@ -3748,7 +3680,7 @@ void reply_write(struct smb_request *req)
size_t numtowrite;
ssize_t nwritten = -1;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
files_struct *fsp;
NTSTATUS status;
@@ -3767,7 +3699,7 @@ void reply_write(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwrite);
@@ -3780,9 +3712,9 @@ void reply_write(struct smb_request *req)
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- data = smb_buf(req->inbuf) + 3;
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ data = (const char *)req->buf + 3;
if (is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
(uint64_t)startpos, WRITE_LOCK)) {
@@ -3954,14 +3886,14 @@ void reply_write_and_X(struct smb_request *req)
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv10);
- smb_doff = SVAL(req->inbuf,smb_vwv11);
+ numtowrite = SVAL(req->vwv+10, 0);
+ smb_doff = SVAL(req->vwv+11, 0);
smblen = smb_len(req->inbuf);
if (req->unread_bytes > 0xFFFF ||
(smblen > smb_doff &&
smblen - smb_doff > 0xFFFF)) {
- numtowrite |= (((size_t)SVAL(req->inbuf,smb_vwv9))<<16);
+ numtowrite |= (((size_t)SVAL(req->vwv+9, 0))<<16);
}
if (req->unread_bytes) {
@@ -3997,9 +3929,9 @@ void reply_write_and_X(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv2));
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv3);
- write_through = BITSETW(req->inbuf+smb_vwv7,0);
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+3, 0);
+ write_through = BITSETW(req->vwv+7,0);
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteX);
@@ -4019,7 +3951,7 @@ void reply_write_and_X(struct smb_request *req)
/*
* This is a large offset (64 bit) write.
*/
- startpos |= (((SMB_OFF_T)IVAL(req->inbuf,smb_vwv12)) << 32);
+ startpos |= (((SMB_OFF_T)IVAL(req->vwv+12, 0)) << 32);
#else /* !LARGE_SMB_OFF_T */
@@ -4027,10 +3959,10 @@ void reply_write_and_X(struct smb_request *req)
* Ensure we haven't been sent a >32 bit offset.
*/
- if(IVAL(req->inbuf,smb_vwv12) != 0) {
+ if(IVAL(req->vwv+12, 0) != 0) {
DEBUG(0,("reply_write_and_X - large offset (%x << 32) "
"used and we don't support 64 bit offsets.\n",
- (unsigned int)IVAL(req->inbuf,smb_vwv12) ));
+ (unsigned int)IVAL(req->vwv+12, 0) ));
reply_doserror(req, ERRDOS, ERRbadaccess);
END_PROFILE(SMBwriteX);
return;
@@ -4118,7 +4050,7 @@ void reply_lseek(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
return;
@@ -4126,9 +4058,9 @@ void reply_lseek(struct smb_request *req)
flush_write_cache(fsp, SEEK_FLUSH);
- mode = SVAL(req->inbuf,smb_vwv1) & 3;
+ mode = SVAL(req->vwv+1, 0) & 3;
/* NB. This doesn't use IVAL_TO_SMB_OFF_T as startpos can be signed in this case. */
- startpos = (SMB_OFF_T)IVALS(req->inbuf,smb_vwv2);
+ startpos = (SMB_OFF_T)IVALS(req->vwv+2, 0);
switch (mode) {
case 0:
@@ -4203,7 +4135,7 @@ void reply_flush(struct smb_request *req)
return;
}
- fnum = SVAL(req->inbuf,smb_vwv0);
+ fnum = SVAL(req->vwv+0, 0);
fsp = file_fsp(req, fnum);
if ((fnum != 0xFFFF) && !check_fsp(conn, req, fsp)) {
@@ -4266,7 +4198,7 @@ void reply_close(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
/*
* We can only use check_fsp if we know it's not a directory.
@@ -4298,7 +4230,7 @@ void reply_close(struct smb_request *req)
* Take care of any time sent in the close.
*/
- t = srv_make_unix_date3(req->inbuf+smb_vwv1);
+ t = srv_make_unix_date3(req->vwv+1);
set_close_write_time(fsp, convert_time_t_to_timespec(t));
/*
@@ -4332,7 +4264,7 @@ void reply_writeclose(struct smb_request *req)
ssize_t nwritten = -1;
NTSTATUS close_status = NT_STATUS_OK;
SMB_OFF_T startpos;
- char *data;
+ const char *data;
struct timespec mtime;
files_struct *fsp;
@@ -4344,7 +4276,7 @@ void reply_writeclose(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBwriteclose);
@@ -4356,11 +4288,10 @@ void reply_writeclose(struct smb_request *req)
return;
}
- numtowrite = SVAL(req->inbuf,smb_vwv1);
- startpos = IVAL_TO_SMB_OFF_T(req->inbuf,smb_vwv2);
- mtime = convert_time_t_to_timespec(srv_make_unix_date3(
- req->inbuf+smb_vwv4));
- data = smb_buf(req->inbuf) + 1;
+ numtowrite = SVAL(req->vwv+1, 0);
+ startpos = IVAL_TO_SMB_OFF_T(req->vwv+2, 0);
+ mtime = convert_time_t_to_timespec(srv_make_unix_date3(req->vwv+4));
+ data = (const char *)req->buf + 1;
if (numtowrite
&& is_locked(fsp, (uint32)req->smbpid, (uint64_t)numtowrite,
@@ -4431,7 +4362,7 @@ void reply_lock(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBlock);
@@ -4440,8 +4371,8 @@ void reply_lock(struct smb_request *req)
release_level_2_oplocks_on_change(fsp);
- count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
- offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
+ count = (uint64_t)IVAL(req->vwv+1, 0);
+ offset = (uint64_t)IVAL(req->vwv+3, 0);
DEBUG(3,("lock fd=%d fnum=%d offset=%.0f count=%.0f\n",
fsp->fh->fd, fsp->fnum, (double)offset, (double)count));
@@ -4490,15 +4421,15 @@ void reply_unlock(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBunlock);
return;
}
- count = (uint64_t)IVAL(req->inbuf,smb_vwv1);
- offset = (uint64_t)IVAL(req->inbuf,smb_vwv3);
+ count = (uint64_t)IVAL(req->vwv+1, 0);
+ offset = (uint64_t)IVAL(req->vwv+3, 0);
status = do_unlock(smbd_messaging_context(),
fsp,
@@ -4562,7 +4493,6 @@ void reply_echo(struct smb_request *req)
connection_struct *conn = req->conn;
int smb_reverb;
int seq_num;
- unsigned int data_len = smb_buflen(req->inbuf);
START_PROFILE(SMBecho);
@@ -4572,20 +4502,13 @@ void reply_echo(struct smb_request *req)
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;
- }
+ smb_reverb = SVAL(req->vwv+0, 0);
- smb_reverb = SVAL(req->inbuf,smb_vwv0);
-
- reply_outbuf(req, 1, data_len);
+ reply_outbuf(req, 1, req->buflen);
/* copy any incoming data back out */
- if (data_len > 0) {
- memcpy(smb_buf(req->outbuf),smb_buf(req->inbuf),data_len);
+ if (req->buflen > 0) {
+ memcpy(smb_buf(req->outbuf), req->buf, req->buflen);
}
if (smb_reverb > 100) {
@@ -4672,7 +4595,7 @@ void reply_printclose(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplclose);
@@ -4720,8 +4643,8 @@ void reply_printqueue(struct smb_request *req)
return;
}
- max_count = SVAL(req->inbuf,smb_vwv0);
- start_index = SVAL(req->inbuf,smb_vwv1);
+ max_count = SVAL(req->vwv+0, 0);
+ start_index = SVAL(req->vwv+1, 0);
/* we used to allow the client to get the cnum wrong, but that
is really quite gross and only worked when there was only
@@ -4803,7 +4726,7 @@ void reply_printwrite(struct smb_request *req)
{
connection_struct *conn = req->conn;
int numtowrite;
- char *data;
+ const char *data;
files_struct *fsp;
START_PROFILE(SMBsplwr);
@@ -4814,7 +4737,7 @@ void reply_printwrite(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if (!check_fsp(conn, req, fsp)) {
END_PROFILE(SMBsplwr);
@@ -4833,15 +4756,15 @@ void reply_printwrite(struct smb_request *req)
return;
}
- numtowrite = SVAL(smb_buf(req->inbuf),1);
+ numtowrite = SVAL(req->buf, 1);
- if (smb_buflen(req->inbuf) < numtowrite + 3) {
+ if (req->buflen < numtowrite + 3) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBsplwr);
return;
}
- data = smb_buf(req->inbuf) + 3;
+ data = (const char *)req->buf + 3;
if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
reply_unixerror(req, ERRHRD, ERRdiskfull);
@@ -4869,9 +4792,8 @@ void reply_mkdir(struct smb_request *req)
START_PROFILE(SMBmkdir);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmkdir);
@@ -5140,9 +5062,8 @@ void reply_rmdir(struct smb_request *req)
START_PROFILE(SMBrmdir);
- srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &directory,
- smb_buf(req->inbuf) + 1, 0,
- STR_TERMINATE, &status);
+ srvstr_get_path_req(ctx, req, &directory, (const char *)req->buf + 1,
+ STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBrmdir);
@@ -5922,7 +5843,7 @@ void reply_mv(struct smb_request *req)
connection_struct *conn = req->conn;
char *name = NULL;
char *newname = NULL;
- char *p;
+ const char *p;
uint32 attrs;
NTSTATUS status;
bool src_has_wcard = False;
@@ -5937,21 +5858,19 @@ void reply_mv(struct smb_request *req)
return;
}
- attrs = SVAL(req->inbuf,smb_vwv0);
+ attrs = SVAL(req->vwv+0, 0);
- p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
- 0, STR_TERMINATE, &status,
- &src_has_wcard);
+ p = (const char *)req->buf + 1;
+ p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE,
+ &status, &src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmv);
return;
}
p++;
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
- 0, STR_TERMINATE, &status,
- &dest_has_wcard);
+ p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
+ &status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBmv);
@@ -6155,8 +6074,9 @@ void reply_copy(struct smb_request *req)
char *name = NULL;
char *newname = NULL;
char *directory = NULL;
- char *mask = NULL;
- char *p;
+ const char *mask = NULL;
+ const char mask_star[] = "*";
+ const char *p;
int count=0;
int error = ERRnoaccess;
int err = 0;
@@ -6178,22 +6098,20 @@ void reply_copy(struct smb_request *req)
return;
}
- tid2 = SVAL(req->inbuf,smb_vwv0);
- ofun = SVAL(req->inbuf,smb_vwv1);
- flags = SVAL(req->inbuf,smb_vwv2);
+ tid2 = SVAL(req->vwv+0, 0);
+ ofun = SVAL(req->vwv+1, 0);
+ flags = SVAL(req->vwv+2, 0);
- p = smb_buf(req->inbuf);
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &name, p,
- 0, STR_TERMINATE, &status,
- &source_has_wild);
+ p = (const char *)req->buf;
+ p += srvstr_get_path_req_wcard(ctx, req, &name, p, STR_TERMINATE,
+ &status, &source_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);
return;
}
- p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
- 0, STR_TERMINATE, &status,
- &dest_has_wild);
+ p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
+ &status, &dest_has_wild);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBcopy);
@@ -6283,23 +6201,18 @@ void reply_copy(struct smb_request *req)
}
p = strrchr_m(name,'/');
- if (!p) {
+ if (p != NULL) {
+ directory = talloc_strndup(ctx, name, PTR_DIFF(p, name));
+ mask = p+1;
+ } else {
directory = talloc_strdup(ctx, "./");
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
- }
mask = name;
- } else {
- *p = 0;
- directory = talloc_strdup(ctx, name);
- if (!directory) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- END_PROFILE(SMBcopy);
- return;
- }
- mask = p+1;
+ }
+
+ if (!directory) {
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBcopy);
+ return;
}
/*
@@ -6367,8 +6280,7 @@ void reply_copy(struct smb_request *req)
long offset = 0;
if (strequal(mask,"????????.???")) {
- mask[0] = '*';
- mask[1] = '\0';
+ mask = mask_star;
}
status = check_name(conn, directory);
@@ -6484,7 +6396,8 @@ void reply_copy(struct smb_request *req)
Get a lock pid, dealing with large count requests.
****************************************************************************/
-uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
+uint32 get_lock_pid(const uint8_t *data, int data_offset,
+ bool large_file_format)
{
if(!large_file_format)
return (uint32)SVAL(data,SMB_LPID_OFFSET(data_offset));
@@ -6496,7 +6409,8 @@ uint32 get_lock_pid( char *data, int data_offset, bool large_file_format)
Get a lock count, dealing with large count requests.
****************************************************************************/
-uint64_t get_lock_count( char *data, int data_offset, bool large_file_format)
+uint64_t get_lock_count(const uint8_t *data, int data_offset,
+ bool large_file_format)
{
uint64_t count = 0;
@@ -6568,7 +6482,8 @@ static uint32 map_lock_offset(uint32 high, uint32 low)
Get a lock offset, dealing with large offset requests.
****************************************************************************/
-uint64_t get_lock_offset( char *data, int data_offset, bool large_file_format, bool *err)
+uint64_t get_lock_offset(const uint8_t *data, int data_offset,
+ bool large_file_format, bool *err)
{
uint64_t offset = 0;
@@ -6629,7 +6544,7 @@ void reply_lockingX(struct smb_request *req)
uint32 lock_pid;
int32 lock_timeout;
int i;
- char *data;
+ const uint8_t *data;
bool large_file_format;
bool err;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
@@ -6642,12 +6557,12 @@ void reply_lockingX(struct smb_request *req)
return;
}
- fsp = file_fsp(req, 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);
+ fsp = file_fsp(req, SVAL(req->vwv+2, 0));
+ locktype = CVAL(req->vwv+3, 0);
+ oplocklevel = CVAL(req->vwv+3, 1);
+ num_ulocks = SVAL(req->vwv+6, 0);
+ num_locks = SVAL(req->vwv+7, 0);
+ lock_timeout = IVAL(req->vwv+4, 0);
large_file_format = (locktype & LOCKING_ANDX_LARGE_FILES)?True:False;
if (!check_fsp(conn, req, fsp)) {
@@ -6655,7 +6570,7 @@ void reply_lockingX(struct smb_request *req)
return;
}
- data = smb_buf(req->inbuf);
+ data = req->buf;
if (locktype & LOCKING_ANDX_CHANGE_LOCKTYPE) {
/* we don't support these - and CANCEL_LOCK makes w2k
@@ -6729,11 +6644,10 @@ void reply_lockingX(struct smb_request *req)
if (num_locks == 0 && num_ulocks == 0) {
/* Sanity check - ensure a pure oplock break is not a
chained request. */
- if(CVAL(req->inbuf,smb_vwv0) != 0xff)
+ if(CVAL(req->vwv+0, 0) != 0xff)
DEBUG(0,("reply_lockingX: Error : pure oplock "
"break is a chained %d request !\n",
- (unsigned int)CVAL(req->inbuf,
- smb_vwv0) ));
+ (unsigned int)CVAL(req->vwv+0, 0)));
END_PROFILE(SMBlockingX);
return;
}
@@ -6746,7 +6660,7 @@ void reply_lockingX(struct smb_request *req)
release_level_2_oplocks_on_change(fsp);
- if (smb_buflen(req->inbuf) <
+ if (req->buflen <
(num_ulocks + num_locks) * (large_file_format ? 20 : 10)) {
reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
END_PROFILE(SMBlockingX);
@@ -7018,7 +6932,7 @@ void reply_setattrE(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if(!fsp || (fsp->conn != conn)) {
reply_doserror(req, ERRDOS, ERRbadfid);
@@ -7033,9 +6947,9 @@ void reply_setattrE(struct smb_request *req)
*/
ts[0] = convert_time_t_to_timespec(
- srv_make_unix_date2(req->inbuf+smb_vwv3)); /* atime. */
+ srv_make_unix_date2(req->vwv+3)); /* atime. */
ts[1] = convert_time_t_to_timespec(
- srv_make_unix_date2(req->inbuf+smb_vwv5)); /* mtime. */
+ srv_make_unix_date2(req->vwv+5)); /* mtime. */
reply_outbuf(req, 0, 0);
@@ -7129,7 +7043,7 @@ void reply_getattrE(struct smb_request *req)
return;
}
- fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv0));
+ fsp = file_fsp(req, SVAL(req->vwv+0, 0));
if(!fsp || (fsp->conn != conn)) {
reply_doserror(req, ERRDOS, ERRbadfid);
diff --git a/source3/smbd/server.c b/source3/smbd/server.c
index 4e81263ee4..fff05a3aac 100644
--- a/source3/smbd/server.c
+++ b/source3/smbd/server.c
@@ -80,7 +80,7 @@ struct event_context *smbd_event_context(void)
{
static struct event_context *ctx;
- if (!ctx && !(ctx = event_context_init(NULL))) {
+ if (!ctx && !(ctx = event_context_init(talloc_autofree_context()))) {
smb_panic("Could not init smbd event context");
}
return ctx;
@@ -91,7 +91,7 @@ struct messaging_context *smbd_messaging_context(void)
static struct messaging_context *ctx;
if (ctx == NULL) {
- ctx = messaging_init(NULL, server_id_self(),
+ ctx = messaging_init(talloc_autofree_context(), server_id_self(),
smbd_event_context());
}
if (ctx == NULL) {
@@ -105,7 +105,7 @@ struct memcache *smbd_memcache(void)
static struct memcache *cache;
if (!cache
- && !(cache = memcache_init(NULL,
+ && !(cache = memcache_init(talloc_autofree_context(),
lp_max_stat_cache_size()*1024))) {
smb_panic("Could not init smbd memcache");
@@ -1415,7 +1415,7 @@ extern void build_options(bool screen);
}
if (*lp_rootdir()) {
- if (sys_chroot(lp_rootdir()) == 0)
+ if (chroot(lp_rootdir()) == 0)
DEBUG(2,("Changed root to %s\n", lp_rootdir()));
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index a482b3398a..fde6cdc160 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -1161,23 +1161,25 @@ static NTSTATUS check_spnego_blob_complete(uint16 smbpid, uint16 vuid,
static void reply_sesssetup_and_X_spnego(struct smb_request *req)
{
- uint8 *p;
+ const uint8 *p;
DATA_BLOB blob1;
size_t bufrem;
- fstring native_os, native_lanman, primary_domain;
+ char *tmp;
+ const char *native_os;
+ const char *native_lanman;
+ const char *primary_domain;
const char *p2;
- uint16 data_blob_len = SVAL(req->inbuf, smb_vwv7);
+ uint16 data_blob_len = SVAL(req->vwv+7, 0);
enum remote_arch_types ra_type = get_remote_arch();
int vuid = SVAL(req->inbuf,smb_uid);
user_struct *vuser = NULL;
NTSTATUS status = NT_STATUS_OK;
uint16 smbpid = req->smbpid;
- uint16 smb_flag2 = req->flags2;
DEBUG(3,("Doing spnego session setup\n"));
if (global_client_caps == 0) {
- global_client_caps = IVAL(req->inbuf,smb_vwv10);
+ global_client_caps = IVAL(req->vwv+10, 0);
if (!(global_client_caps & CAP_STATUS32)) {
remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
@@ -1185,7 +1187,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
}
- p = (uint8 *)smb_buf(req->inbuf);
+ p = req->buf;
if (data_blob_len == 0) {
/* an invalid request */
@@ -1193,7 +1195,7 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
- bufrem = smb_bufrem(req->inbuf, p);
+ bufrem = smbreq_bufrem(req, p);
/* pull the spnego blob */
blob1 = data_blob(p, MIN(bufrem, data_blob_len));
@@ -1202,12 +1204,19 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
#endif
p2 = (char *)req->inbuf + smb_vwv13 + data_blob_len;
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_os, p2,
- sizeof(native_os), STR_TERMINATE);
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, native_lanman, p2,
- sizeof(native_lanman), STR_TERMINATE);
- p2 += srvstr_pull_buf(req->inbuf, smb_flag2, primary_domain, p2,
- sizeof(primary_domain), STR_TERMINATE);
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ native_os = tmp ? tmp : "";
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ native_lanman = tmp ? tmp : "";
+
+ p2 += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p2,
+ STR_TERMINATE);
+ primary_domain = tmp ? tmp : "";
+
DEBUG(3,("NativeOS=[%s] NativeLanMan=[%s] PrimaryDomain=[%s]\n",
native_os, native_lanman, primary_domain));
@@ -1390,12 +1399,13 @@ void reply_sesssetup_and_X(struct smb_request *req)
DATA_BLOB lm_resp;
DATA_BLOB nt_resp;
DATA_BLOB plaintext_password;
- fstring user;
+ char *tmp;
+ const char *user;
fstring sub_user; /* Sainitised username for substituion */
- fstring domain;
- fstring native_os;
- fstring native_lanman;
- fstring primary_domain;
+ const char *domain;
+ const char *native_os;
+ const char *native_lanman;
+ const char *primary_domain;
static bool done_sesssetup = False;
auth_usersupplied_info *user_info = NULL;
auth_serversupplied_info *server_info = NULL;
@@ -1428,7 +1438,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
return;
}
- if (SVAL(req->inbuf,smb_vwv4) == 0) {
+ if (SVAL(req->vwv+4, 0) == 0) {
setup_new_vc_session();
}
@@ -1437,18 +1447,16 @@ void reply_sesssetup_and_X(struct smb_request *req)
return;
}
- smb_bufsize = SVAL(req->inbuf,smb_vwv2);
+ smb_bufsize = SVAL(req->vwv+2, 0);
if (Protocol < PROTOCOL_NT1) {
- uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
+ uint16 passlen1 = SVAL(req->vwv+7, 0);
/* Never do NT status codes with protocols before NT1 as we
* don't get client caps. */
remove_from_common_flags2(FLAGS2_32_BIT_ERROR_CODES);
- if ((passlen1 > MAX_PASS_LEN)
- || (passlen1 > smb_bufrem(req->inbuf,
- smb_buf(req->inbuf)))) {
+ if ((passlen1 > MAX_PASS_LEN) || (passlen1 > req->buflen)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
@@ -1456,30 +1464,30 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
if (doencrypt) {
- lm_resp = data_blob(smb_buf(req->inbuf), passlen1);
+ lm_resp = data_blob(req->buf, passlen1);
} else {
- plaintext_password = data_blob(smb_buf(req->inbuf),
- passlen1+1);
+ plaintext_password = data_blob(req->buf, passlen1+1);
/* Ensure null termination */
plaintext_password.data[passlen1] = 0;
}
- srvstr_pull_buf(req->inbuf, req->flags2, user,
- smb_buf(req->inbuf)+passlen1, sizeof(user),
- STR_TERMINATE);
- *domain = 0;
+ srvstr_pull_req_talloc(talloc_tos(), req, &tmp,
+ req->buf + passlen1, STR_TERMINATE);
+ user = tmp ? tmp : "";
+
+ domain = "";
} else {
- uint16 passlen1 = SVAL(req->inbuf,smb_vwv7);
- uint16 passlen2 = SVAL(req->inbuf,smb_vwv8);
+ uint16 passlen1 = SVAL(req->vwv+7, 0);
+ uint16 passlen2 = SVAL(req->vwv+8, 0);
enum remote_arch_types ra_type = get_remote_arch();
- char *p = smb_buf(req->inbuf);
- char *save_p = smb_buf(req->inbuf);
+ const uint8_t *p = req->buf;
+ const uint8_t *save_p = req->buf;
uint16 byte_count;
if(global_client_caps == 0) {
- global_client_caps = IVAL(req->inbuf,smb_vwv11);
+ global_client_caps = IVAL(req->vwv+11, 0);
if (!(global_client_caps & CAP_STATUS32)) {
remove_from_common_flags2(
@@ -1521,7 +1529,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
/* check for nasty tricks */
if (passlen1 > MAX_PASS_LEN
- || passlen1 > smb_bufrem(req->inbuf, p)) {
+ || passlen1 > smbreq_bufrem(req, p)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
@@ -1529,7 +1537,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
if (passlen2 > MAX_PASS_LEN
- || passlen2 > smb_bufrem(req->inbuf, p+passlen1)) {
+ || passlen2 > smbreq_bufrem(req, p+passlen1)) {
reply_nterror(req, nt_status_squash(
NT_STATUS_INVALID_PARAMETER));
END_PROFILE(SMBsesssetupX);
@@ -1559,7 +1567,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
req->inbuf,
req->flags2,
&pass,
- smb_buf(req->inbuf),
+ req->buf,
passlen1,
STR_TERMINATE|STR_ASCII);
} else {
@@ -1567,7 +1575,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
req->inbuf,
req->flags2,
&pass,
- smb_buf(req->inbuf),
+ req->buf,
unic ? passlen2 : passlen1,
STR_TERMINATE);
}
@@ -1581,15 +1589,22 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
p += passlen1 + passlen2;
- p += srvstr_pull_buf(req->inbuf, req->flags2, user, p,
- sizeof(user), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2, domain, p,
- sizeof(domain), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2, native_os,
- p, sizeof(native_os), STR_TERMINATE);
- p += srvstr_pull_buf(req->inbuf, req->flags2,
- native_lanman, p, sizeof(native_lanman),
- STR_TERMINATE);
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ user = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ domain = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ native_os = tmp ? tmp : "";
+
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ native_lanman = tmp ? tmp : "";
/* not documented or decoded by Ethereal but there is one more
* string in the extra bytes which is the same as the
@@ -1598,14 +1613,13 @@ void reply_sesssetup_and_X(struct smb_request *req)
* Windows 9x does not include a string here at all so we have
* to check if we have any extra bytes left */
- byte_count = SVAL(req->inbuf, smb_vwv13);
+ byte_count = SVAL(req->vwv+13, 0);
if ( PTR_DIFF(p, save_p) < byte_count) {
- p += srvstr_pull_buf(req->inbuf, req->flags2,
- primary_domain, p,
- sizeof(primary_domain),
- STR_TERMINATE);
+ p += srvstr_pull_req_talloc(talloc_tos(), req, &tmp, p,
+ STR_TERMINATE);
+ primary_domain = tmp ? tmp : "";
} else {
- fstrcpy( primary_domain, "null" );
+ primary_domain = talloc_strdup(talloc_tos(), "null");
}
DEBUG(3,("Domain=[%s] NativeOS=[%s] NativeLanMan=[%s] "
@@ -1621,7 +1635,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
}
- if (SVAL(req->inbuf,smb_vwv4) == 0) {
+ if (SVAL(req->vwv+4, 0) == 0) {
setup_new_vc_session();
}
@@ -1662,7 +1676,7 @@ void reply_sesssetup_and_X(struct smb_request *req)
add_session_user(sub_user);
add_session_workgroup(domain);
/* Then force it to null for the benfit of the code below */
- *user = 0;
+ user = "";
}
if (!*user) {
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 1da45a8b58..c385c6ccb1 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -768,6 +768,12 @@ void send_trans2_replies(connection_struct *conn,
reply_outbuf(req, 10, total_sent_thistime + alignment_offset
+ data_alignment_offset);
+ /*
+ * We might have SMBtrans2s in req which was transferred to
+ * the outbuf, fix that.
+ */
+ SCVAL(req->outbuf, smb_com, SMBtrans2);
+
/* Set total params and data to be sent */
SSVAL(req->outbuf,smb_tprcnt,paramsize);
SSVAL(req->outbuf,smb_tdrcnt,datasize);
@@ -2183,7 +2189,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
DEBUG( 4, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)),
+ smb_fn_name(req->cmd),
mask, directory, dirtype, numentries ) );
/*
@@ -2481,7 +2487,7 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
}
DEBUG( 3, ( "%s mask=%s directory=%s dirtype=%d numentries=%d\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)),
+ smb_fn_name(req->cmd),
mask, directory, dirtype, numentries ) );
/* Check if we can close the dirptr */
@@ -3118,7 +3124,7 @@ cBytesSector=%u, cUnitTotal=%u, cUnitAvail=%d\n", (unsigned int)bsize, (unsigned
max_data_bytes);
DEBUG( 4, ( "%s info_level = %d\n",
- smb_fn_name(CVAL(req->inbuf,smb_com)), info_level) );
+ smb_fn_name(req->cmd), info_level) );
return;
}
@@ -3846,7 +3852,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
files_struct *fsp = NULL;
struct file_id fileid;
struct ea_list *ea_list = NULL;
- uint32 access_mask = 0x12019F; /* Default - GENERIC_EXECUTE mapping from Windows */
char *lock_data = NULL;
bool ms_dfs_link = false;
TALLOC_CTX *ctx = talloc_tos();
@@ -3939,7 +3944,6 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
pos = fsp->fh->position_information;
fileid = vfs_file_id_from_sbuf(conn, &sbuf);
get_file_infos(fileid, &delete_pending, &write_time_ts);
- access_mask = fsp->access_mask;
}
} else {
@@ -4403,7 +4407,12 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
case SMB_FILE_ACCESS_INFORMATION:
DEBUG(10,("call_trans2qfilepathinfo: SMB_FILE_ACCESS_INFORMATION\n"));
- SIVAL(pdata,0,access_mask);
+ if (fsp) {
+ SIVAL(pdata,0,fsp->access_mask);
+ } else {
+ /* GENERIC_EXECUTE mapping from Windows */
+ SIVAL(pdata,0,0x12019F);
+ }
data_size = 4;
break;
@@ -5470,7 +5479,7 @@ static NTSTATUS smb_set_posix_acl(connection_struct *conn,
****************************************************************************/
static NTSTATUS smb_set_posix_lock(connection_struct *conn,
- const struct smb_request *req,
+ struct smb_request *req,
const char *pdata,
int total_data,
files_struct *fsp)
@@ -7251,7 +7260,7 @@ static void call_trans2ioctl(connection_struct *conn,
unsigned int max_data_bytes)
{
char *pdata = *ppdata;
- files_struct *fsp = file_fsp(req, SVAL(req->inbuf,smb_vwv15));
+ files_struct *fsp = file_fsp(req, SVAL(req->vwv+15, 0));
/* check for an invalid fid before proceeding */
@@ -7304,7 +7313,7 @@ void reply_findclose(struct smb_request *req)
return;
}
- dptr_num = SVALS(req->inbuf,smb_vwv0);
+ dptr_num = SVALS(req->vwv+0, 0);
DEBUG(3,("reply_findclose, dptr_num = %d\n", dptr_num));
@@ -7334,7 +7343,7 @@ void reply_findnclose(struct smb_request *req)
return;
}
- dptr_num = SVAL(req->inbuf,smb_vwv0);
+ dptr_num = SVAL(req->vwv+0, 0);
DEBUG(3,("reply_findnclose, dptr_num = %d\n", dptr_num));
@@ -7537,11 +7546,11 @@ void reply_trans2(struct smb_request *req)
return;
}
- dsoff = SVAL(req->inbuf, smb_dsoff);
- dscnt = SVAL(req->inbuf, smb_dscnt);
- psoff = SVAL(req->inbuf, smb_psoff);
- pscnt = SVAL(req->inbuf, smb_pscnt);
- tran_call = SVAL(req->inbuf, smb_setup0);
+ dsoff = SVAL(req->vwv+12, 0);
+ dscnt = SVAL(req->vwv+11, 0);
+ psoff = SVAL(req->vwv+10, 0);
+ pscnt = SVAL(req->vwv+9, 0);
+ tran_call = SVAL(req->vwv+14, 0);
size = smb_len(req->inbuf) + 4;
av_size = smb_len(req->inbuf);
@@ -7581,17 +7590,17 @@ void reply_trans2(struct smb_request *req)
state->mid = req->mid;
state->vuid = req->vuid;
- state->setup_count = SVAL(req->inbuf, smb_suwcnt);
+ state->setup_count = SVAL(req->vwv+13, 0);
state->setup = NULL;
- state->total_param = SVAL(req->inbuf, smb_tpscnt);
+ state->total_param = SVAL(req->vwv+0, 0);
state->param = NULL;
- state->total_data = SVAL(req->inbuf, smb_tdscnt);
+ state->total_data = SVAL(req->vwv+1, 0);
state->data = NULL;
- state->max_param_return = SVAL(req->inbuf, smb_mprcnt);
- state->max_data_return = SVAL(req->inbuf, smb_mdrcnt);
- state->max_setup_return = SVAL(req->inbuf, smb_msrcnt);
- state->close_on_completion = BITSETW(req->inbuf+smb_vwv5,0);
- state->one_way = BITSETW(req->inbuf+smb_vwv5,1);
+ state->max_param_return = SVAL(req->vwv+2, 0);
+ state->max_data_return = SVAL(req->vwv+3, 0);
+ state->max_setup_return = SVAL(req->vwv+4, 0);
+ state->close_on_completion = BITSETW(req->vwv+5, 0);
+ state->one_way = BITSETW(req->vwv+5, 1);
state->call = tran_call;
@@ -7755,18 +7764,18 @@ void reply_transs2(struct smb_request *req)
/* Revise state->total_param and state->total_data in case they have
changed downwards */
- if (SVAL(req->inbuf, smb_tpscnt) < state->total_param)
- state->total_param = SVAL(req->inbuf, smb_tpscnt);
- if (SVAL(req->inbuf, smb_tdscnt) < state->total_data)
- state->total_data = SVAL(req->inbuf, smb_tdscnt);
+ if (SVAL(req->vwv+0, 0) < state->total_param)
+ state->total_param = SVAL(req->vwv+0, 0);
+ if (SVAL(req->vwv+1, 0) < state->total_data)
+ state->total_data = SVAL(req->vwv+1, 0);
- pcnt = SVAL(req->inbuf, smb_spscnt);
- poff = SVAL(req->inbuf, smb_spsoff);
- pdisp = SVAL(req->inbuf, smb_spsdisp);
+ pcnt = SVAL(req->vwv+2, 0);
+ poff = SVAL(req->vwv+3, 0);
+ pdisp = SVAL(req->vwv+4, 0);
- dcnt = SVAL(req->inbuf, smb_sdscnt);
- doff = SVAL(req->inbuf, smb_sdsoff);
- ddisp = SVAL(req->inbuf, smb_sdsdisp);
+ dcnt = SVAL(req->vwv+5, 0);
+ doff = SVAL(req->vwv+6, 0);
+ ddisp = SVAL(req->vwv+7, 0);
state->received_param += pcnt;
state->received_data += dcnt;
@@ -7819,12 +7828,6 @@ void reply_transs2(struct smb_request *req)
return;
}
- /*
- * construct_reply_common will copy smb_com from inbuf to
- * outbuf. SMBtranss2 is wrong here.
- */
- SCVAL(req->inbuf,smb_com,SMBtrans2);
-
handle_trans2(conn, req, state);
DLIST_REMOVE(conn->pending_trans, state);
diff --git a/source3/smbd/uid.c b/source3/smbd/uid.c
index 8998f6a371..045de6f2d3 100644
--- a/source3/smbd/uid.c
+++ b/source3/smbd/uid.c
@@ -32,7 +32,7 @@ bool change_to_guest(void)
if (!pass) {
/* Don't need to free() this as its stored in a static */
- pass = getpwnam_alloc(NULL, lp_guestaccount());
+ pass = getpwnam_alloc(talloc_autofree_context(), lp_guestaccount());
if (!pass)
return(False);
}