summaryrefslogtreecommitdiff
path: root/source3/smbd/nttrans.c
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-09-11 23:57:59 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:30:41 -0500
commit3a9d3821649c9ea88a6cd424f0838a453165a00a (patch)
tree4b4f61570a20e0a252436ebd88b1d0dee58c704e /source3/smbd/nttrans.c
parent1ef2464451ee64023173637fa03e703405dc8c85 (diff)
downloadsamba-3a9d3821649c9ea88a6cd424f0838a453165a00a.tar.gz
samba-3a9d3821649c9ea88a6cd424f0838a453165a00a.tar.bz2
samba-3a9d3821649c9ea88a6cd424f0838a453165a00a.zip
r25111: Move to talloced pathnames on most code paths.
There are now ony 17 pstrings left in reply.c, and these will be easy to remove (and I'll be doing that shortly). Had to fix an interesting bug in pull_ucs2_base_talloc() when a source string is not null terminated :-). Jeremy. (This used to be commit 0c9a8c4dff10974dbffd2a302ae982896122fcc0)
Diffstat (limited to 'source3/smbd/nttrans.c')
-rw-r--r--source3/smbd/nttrans.c376
1 files changed, 206 insertions, 170 deletions
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index 114050ae16..7886ee86ce 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -1,7 +1,7 @@
/*
Unix SMB/CIFS implementation.
SMB NT transaction handling
- Copyright (C) Jeremy Allison 1994-1998
+ Copyright (C) Jeremy Allison 1994-2007
Copyright (C) Stefan (metze) Metzmacher 2003
This program is free software; you can redistribute it and/or modify
@@ -51,7 +51,7 @@ static char *nttrans_realloc(char **ptr, size_t size)
if (ptr==NULL) {
smb_panic("nttrans_realloc() called with NULL ptr");
}
-
+
*ptr = (char *)SMB_REALLOC(*ptr, size);
if(*ptr == NULL) {
return NULL;
@@ -80,7 +80,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
int alignment_offset = 3;
int data_alignment_offset = 0;
- /*
+ /*
* If there genuinely are no parameters or data to send just send
* the empty packet.
*/
@@ -101,10 +101,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
data_alignment_offset = 4 - (params_to_send % 4);
}
- /*
+ /*
* Space is bufsize minus Netbios over TCP header minus SMB header.
* The alignment_offset is to align the param bytes on a four byte
- * boundary (2 bytes for data len, one byte pad).
+ * boundary (2 bytes for data len, one byte pad).
* NT needs this to work correctly.
*/
@@ -131,7 +131,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
total_sent_thistime = params_to_send + data_to_send +
alignment_offset + data_alignment_offset;
- /*
+ /*
* We can never send more than useable_space.
*/
@@ -146,7 +146,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
SIVAL(req->outbuf,smb_ntr_TotalParameterCount,paramsize);
SIVAL(req->outbuf,smb_ntr_TotalDataCount,datasize);
- /*
+ /*
* Calculate how many parameters and data we can fit into
* this packet. Parameters get precedence.
*/
@@ -172,7 +172,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
SIVAL(req->outbuf,smb_ntr_ParameterOffset,
((smb_buf(req->outbuf)+alignment_offset)
- smb_base(req->outbuf)));
- /*
+ /*
* Absolute displacement of param bytes sent in this packet.
*/
@@ -202,7 +202,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
SIVAL(req->outbuf,smb_ntr_DataDisplacement, pd - pdata);
}
- /*
+ /*
* Copy the param bytes into the packet.
*/
@@ -229,7 +229,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
+params_sent_thistime+data_alignment_offset,
pd,data_sent_thistime);
}
-
+
DEBUG(9,("nt_rep: params_sent_thistime = %d, data_sent_thistime = %d, useable_space = %d\n",
params_sent_thistime, data_sent_thistime, useable_space));
DEBUG(9,("nt_rep: params_to_send = %d, data_to_send = %d, paramsize = %d, datasize = %d\n",
@@ -240,7 +240,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
0, 0, nt_error,
__LINE__,__FILE__);
}
-
+
/* Send the packet */
show_msg((char *)req->outbuf);
if (!send_smb(smbd_server_fd(),(char *)req->outbuf)) {
@@ -248,10 +248,10 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
}
TALLOC_FREE(req->outbuf);
-
+
pp += params_sent_thistime;
pd += data_sent_thistime;
-
+
params_to_send -= params_sent_thistime;
data_to_send -= data_sent_thistime;
@@ -264,7 +264,7 @@ void send_nt_replies(struct smb_request *req, NTSTATUS nt_error,
params_to_send, data_to_send));
return;
}
- }
+ }
}
/****************************************************************************
@@ -385,14 +385,20 @@ static void nt_open_pipe(char *fname, connection_struct *conn,
static void do_ntcreate_pipe_open(connection_struct *conn,
struct smb_request *req)
{
- pstring fname;
+ char *fname = NULL;
int pnum = -1;
char *p = NULL;
uint32 flags = IVAL(req->inbuf,smb_ntcreate_Flags);
+ TALLOC_CTX *ctx = talloc_tos();
- srvstr_pull_buf((char *)req->inbuf, req->flags2, fname,
- smb_buf(req->inbuf), sizeof(fname), STR_TERMINATE);
+ srvstr_pull_buf_talloc(ctx, (char *)req->inbuf, req->flags2, &fname,
+ smb_buf(req->inbuf), STR_TERMINATE);
+ if (!fname) {
+ reply_botherror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND,
+ ERRDOS, ERRbadpipe);
+ return;
+ }
nt_open_pipe(fname, conn, req, &pnum);
if (req->outbuf) {
@@ -402,7 +408,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
/*
* Deal with pipe return.
- */
+ */
if (flags & EXTENDED_RESPONSE_REQUIRED) {
/* This is very strange. We
@@ -434,7 +440,7 @@ static void do_ntcreate_pipe_open(connection_struct *conn,
if (flags & EXTENDED_RESPONSE_REQUIRED) {
p += 25;
SIVAL(p,0,FILE_GENERIC_ALL);
- /*
+ /*
* For pipes W2K3 seems to return
* 0x12019B next.
* This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
@@ -470,9 +476,9 @@ static void reply_ntcreate_and_X_quota(connection_struct *conn,
}
reply_outbuf(req, 34, 0);
-
+
p = (char *)req->outbuf + smb_vwv2;
-
+
/* SCVAL(p,0,NO_OPLOCK_RETURN); */
p++;
SSVAL(p,0,fsp->fnum);
@@ -488,8 +494,7 @@ static void reply_ntcreate_and_X_quota(connection_struct *conn,
void reply_ntcreate_and_X(connection_struct *conn,
struct smb_request *req)
-{
- pstring fname_in;
+{
char *fname = NULL;
uint32 flags;
uint32 access_mask;
@@ -578,7 +583,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
/*
* This filename is relative to a directory fid.
*/
- pstring rel_fname;
+ char *rel_fname = NULL;
files_struct *dir_fsp = file_fsp(
SVAL(req->inbuf, smb_ntcreate_RootDirectoryFid));
size_t dir_name_len;
@@ -591,8 +596,9 @@ void reply_ntcreate_and_X(connection_struct *conn,
if(!dir_fsp->is_directory) {
- srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
- smb_buf(req->inbuf), sizeof(fname_in), 0,
+ srvstr_get_path(ctx, (char *)req->inbuf,
+ req->flags2, &fname,
+ smb_buf(req->inbuf), 0,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -604,7 +610,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
* Check to see if this is a mac fork of some kind.
*/
- if( is_ntfs_stream_name(fname_in)) {
+ if( is_ntfs_stream_name(fname)) {
reply_nterror(
req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
END_PROFILE(SMBntcreateX);
@@ -627,30 +633,47 @@ void reply_ntcreate_and_X(connection_struct *conn,
* Copy in the base directory name.
*/
- pstrcpy( fname_in, dir_fsp->fsp_name );
- dir_name_len = strlen(fname_in);
+ dir_name_len = strlen(dir_fsp->fsp_name);
+ fname = TALLOC_SIZE(ctx, dir_name_len+2);
+ if (!fname) {
+ reply_nterror(
+ req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBntcreateX);
+ return;
+ }
+ memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
/*
- * Ensure it ends in a '\'.
+ * Ensure it ends in a '/'.
+ * We used TALLOC_SIZE +2 to add space for the '/'.
*/
- if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) {
- pstrcat(fname_in, "/");
+ if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
+ fname[dir_name_len] = '/';
+ fname[dir_name_len+1] = '\0';
dir_name_len++;
}
- srvstr_get_path((char *)req->inbuf, req->flags2, rel_fname,
- smb_buf(req->inbuf), sizeof(rel_fname), 0,
+ srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &rel_fname,
+ smb_buf(req->inbuf), 0,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
END_PROFILE(SMBntcreateX);
return;
}
- pstrcat(fname_in, rel_fname);
+ fname = talloc_asprintf(ctx, "%s%s",
+ fname,
+ rel_fname);
+ if (!fname) {
+ reply_nterror(
+ req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBntcreateX);
+ return;
+ }
} else {
- srvstr_get_path((char *)req->inbuf, req->flags2, fname_in,
- smb_buf(req->inbuf), sizeof(fname_in), 0,
+ srvstr_get_path(ctx, (char *)req->inbuf, req->flags2, &fname,
+ smb_buf(req->inbuf), 0,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -662,8 +685,8 @@ void reply_ntcreate_and_X(connection_struct *conn,
* Check to see if this is a mac fork of some kind.
*/
- if( is_ntfs_stream_name(fname_in)) {
- enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname_in);
+ if( is_ntfs_stream_name(fname)) {
+ enum FAKE_FILE_TYPE fake_file_type = is_fake_file(fname);
if (fake_file_type!=FAKE_FILE_TYPE_NONE) {
/*
* Here we go! support for changing the disk quotas --metze
@@ -675,7 +698,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
* xp also tries a QUERY_FILE_INFO on the file and then close it
*/
reply_ntcreate_and_X_quota(conn, req,
- fake_file_type, fname_in);
+ fake_file_type, fname);
} else {
reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
}
@@ -690,7 +713,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
*/
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname_in,
+ fname,
&fname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -890,8 +913,8 @@ void reply_ntcreate_and_X(connection_struct *conn,
reply_doserror(req, ERRDOS, ERRnoaccess);
END_PROFILE(SMBntcreateX);
return;
- }
-
+ }
+
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
if (allocation_size && (allocation_size > (SMB_BIG_UINT)file_len)) {
@@ -914,7 +937,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
}
}
- /*
+ /*
* If the caller set the extended oplock request bit
* and we granted one (by whatever means) - set the
* correct bit for extended oplock reply.
@@ -941,7 +964,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
}
p = (char *)req->outbuf + smb_vwv2;
-
+
/*
* Currently as we don't support level II oplocks we just report
* exclusive & batch here.
@@ -958,7 +981,7 @@ void reply_ntcreate_and_X(connection_struct *conn,
} else {
SCVAL(p,0,NO_OPLOCK_RETURN);
}
-
+
p++;
SSVAL(p,0,fsp->fnum);
p += 2;
@@ -1028,13 +1051,14 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
char **ppparams, uint32 parameter_count,
char **ppdata, uint32 data_count)
{
- pstring fname;
+ char *fname = NULL;
char *params = *ppparams;
int pnum = -1;
char *p = NULL;
NTSTATUS status;
size_t param_len;
uint32 flags;
+ TALLOC_CTX *ctx = talloc_tos();
/*
* Ensure minimum number of parameters sent.
@@ -1048,8 +1072,8 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
flags = IVAL(params,0);
- srvstr_get_path(params, req->flags2, fname, params+53,
- sizeof(fname), parameter_count-53, STR_TERMINATE,
+ srvstr_get_path(ctx, params, req->flags2, &fname, params+53,
+ parameter_count-53, STR_TERMINATE,
&status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1062,7 +1086,7 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
/* Error return */
return;
}
-
+
/* Realloc the size of parameters and data we will return */
if (flags & EXTENDED_RESPONSE_REQUIRED) {
/* Extended response is 32 more byyes. */
@@ -1075,16 +1099,16 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
reply_doserror(req, ERRDOS, ERRnomem);
return;
}
-
+
p = params;
SCVAL(p,0,NO_OPLOCK_RETURN);
-
+
p += 2;
SSVAL(p,0,pnum);
p += 2;
SIVAL(p,0,FILE_WAS_OPENED);
p += 8;
-
+
p += 32;
SIVAL(p,0,FILE_ATTRIBUTE_NORMAL); /* File Attributes. */
p += 20;
@@ -1093,11 +1117,11 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
/* Device state. */
SSVAL(p,2, 0x5FF); /* ? */
p += 4;
-
+
if (flags & EXTENDED_RESPONSE_REQUIRED) {
p += 25;
SIVAL(p,0,FILE_GENERIC_ALL);
- /*
+ /*
* For pipes W2K3 seems to return
* 0x12019B next.
* This is ((FILE_GENERIC_READ|FILE_GENERIC_WRITE) & ~FILE_APPEND_DATA)
@@ -1106,10 +1130,10 @@ static void do_nt_transact_create_pipe(connection_struct *conn,
}
DEBUG(5,("do_nt_transact_create_pipe: open name = %s\n", fname));
-
+
/* Send the required number of replies */
send_nt_replies(req, NT_STATUS_OK, params, param_len, *ppdata, 0);
-
+
return;
}
@@ -1123,7 +1147,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
SEC_DESC *psd = NULL;
TALLOC_CTX *mem_ctx;
NTSTATUS status;
-
+
if (sd_len == 0 || !lp_nt_acl_support(SNUM(fsp->conn))) {
return NT_STATUS_OK;
}
@@ -1143,7 +1167,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
* Setup the prs_struct to point at the memory we just
* allocated.
*/
-
+
prs_give_memory( &pd, data, sd_len, False);
/*
@@ -1154,11 +1178,11 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
DEBUG(0,("set_sd: Error in unmarshalling security descriptor.\n"));
/*
* Return access denied for want of a better error message..
- */
+ */
talloc_destroy(mem_ctx);
return NT_STATUS_NO_MEMORY;
}
-
+
if (psd->owner_sid==0) {
security_info_sent &= ~OWNER_SECURITY_INFORMATION;
}
@@ -1171,9 +1195,9 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
if (psd->dacl==0) {
security_info_sent &= ~DACL_SECURITY_INFORMATION;
}
-
+
status = SMB_VFS_FSET_NT_ACL( fsp, fsp->fh->fd, security_info_sent, psd);
-
+
talloc_destroy(mem_ctx);
return status;
}
@@ -1181,7 +1205,7 @@ static NTSTATUS set_sd(files_struct *fsp, char *data, uint32 sd_len, uint32 secu
/****************************************************************************
Read a list of EA names and data from an incoming data buffer. Create an ea_list with them.
****************************************************************************/
-
+
static struct ea_list *read_nttrans_ea_list(TALLOC_CTX *ctx, const char *pdata, size_t data_size)
{
struct ea_list *ea_list_head = NULL;
@@ -1220,7 +1244,6 @@ static void call_nt_transact_create(connection_struct *conn,
char **ppdata, uint32 data_count,
uint32 max_data_count)
{
- pstring fname_in;
char *fname = NULL;
char *params = *ppparams;
char *data = *ppdata;
@@ -1331,6 +1354,7 @@ static void call_nt_transact_create(connection_struct *conn,
/*
* This filename is relative to a directory fid.
*/
+ char *tmpname = NULL;
files_struct *dir_fsp = file_fsp(SVAL(params,4));
size_t dir_name_len;
@@ -1340,8 +1364,8 @@ static void call_nt_transact_create(connection_struct *conn,
}
if(!dir_fsp->is_directory) {
- srvstr_get_path(params, req->flags2, fname_in,
- params+53, sizeof(fname_in),
+ srvstr_get_path(ctx, params, req->flags2, &fname,
+ params+53,
parameter_count-53, STR_TERMINATE,
&status);
if (!NT_STATUS_IS_OK(status)) {
@@ -1353,7 +1377,7 @@ static void call_nt_transact_create(connection_struct *conn,
* Check to see if this is a mac fork of some kind.
*/
- if( is_ntfs_stream_name(fname_in)) {
+ if( is_ntfs_stream_name(fname)) {
reply_nterror(req,
NT_STATUS_OBJECT_PATH_NOT_FOUND);
return;
@@ -1367,33 +1391,46 @@ static void call_nt_transact_create(connection_struct *conn,
* Copy in the base directory name.
*/
- pstrcpy( fname_in, dir_fsp->fsp_name );
- dir_name_len = strlen(fname_in);
+ dir_name_len = strlen(dir_fsp->fsp_name);
+ fname = TALLOC_SIZE(ctx, dir_name_len+2);
+ if (!fname) {
+ reply_nterror(
+ req, NT_STATUS_NO_MEMORY);
+ END_PROFILE(SMBntcreateX);
+ return;
+ }
+ memcpy(fname, dir_fsp->fsp_name, dir_name_len+1);
/*
- * Ensure it ends in a '\'.
+ * Ensure it ends in a '/'.
+ * We used TALLOC_SIZE +2 to add space for the '/'.
*/
- if((fname_in[dir_name_len-1] != '\\') && (fname_in[dir_name_len-1] != '/')) {
- pstrcat(fname_in, "/");
+ if(dir_name_len && (fname[dir_name_len-1] != '\\') && (fname[dir_name_len-1] != '/')) {
+ fname[dir_name_len] = '/';
+ fname[dir_name_len+1] = '\0';
dir_name_len++;
}
- {
- pstring tmpname;
- srvstr_get_path(params, req->flags2, tmpname,
- params+53, sizeof(tmpname),
- parameter_count-53, STR_TERMINATE,
- &status);
- if (!NT_STATUS_IS_OK(status)) {
- reply_nterror(req, status);
- return;
- }
- pstrcat(fname_in, tmpname);
+ srvstr_get_path(ctx, params, req->flags2, &tmpname,
+ params+53,
+ parameter_count-53, STR_TERMINATE,
+ &status);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, status);
+ return;
+ }
+ fname = talloc_asprintf(ctx, "%s%s",
+ fname,
+ tmpname);
+ if (!fname) {
+ reply_nterror(
+ req, NT_STATUS_NO_MEMORY);
+ return;
}
} else {
- srvstr_get_path(params, req->flags2, fname_in, params+53,
- sizeof(fname_in), parameter_count-53,
+ srvstr_get_path(ctx, params, req->flags2, &fname, params+53,
+ parameter_count-53,
STR_TERMINATE, &status);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1404,7 +1441,7 @@ static void call_nt_transact_create(connection_struct *conn,
* Check to see if this is a mac fork of some kind.
*/
- if( is_ntfs_stream_name(fname_in)) {
+ if( is_ntfs_stream_name(fname)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
return;
}
@@ -1430,7 +1467,7 @@ static void call_nt_transact_create(connection_struct *conn,
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
- fname_in,
+ fname,
&fname);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(case_state);
@@ -1584,7 +1621,7 @@ static void call_nt_transact_create(connection_struct *conn,
* According to the MS documentation, the only time the security
* descriptor is applied to the opened file is iff we *created* the
* file; an existing file stays the same.
- *
+ *
* Also, it seems (from observation) that you can open the file with
* any access mask but you can still write the sd. We need to override
* the granted access before we call set_sd
@@ -1607,7 +1644,7 @@ static void call_nt_transact_create(connection_struct *conn,
}
fsp->access_mask = saved_access_mask;
}
-
+
if (ea_len && (info == FILE_WAS_CREATED)) {
status = set_ea(conn, fsp, fname, ea_list);
if (!NT_STATUS_IS_OK(status)) {
@@ -1629,8 +1666,8 @@ static void call_nt_transact_create(connection_struct *conn,
close_file(fsp,ERROR_CLOSE);
reply_doserror(req, ERRDOS, ERRnoaccess);
return;
- }
-
+ }
+
/* Save the requested allocation size. */
if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
SMB_BIG_UINT allocation_size = (SMB_BIG_UINT)IVAL(params,12);
@@ -1655,7 +1692,7 @@ static void call_nt_transact_create(connection_struct *conn,
}
}
- /*
+ /*
* If the caller set the extended oplock request bit
* and we granted one (by whatever means) - set the
* correct bit for extended oplock reply.
@@ -1694,7 +1731,7 @@ static void call_nt_transact_create(connection_struct *conn,
} else {
SCVAL(p,0,NO_OPLOCK_RETURN);
}
-
+
p += 2;
SSVAL(p,0,fsp->fnum);
p += 2;
@@ -1765,12 +1802,12 @@ void reply_ntcancel(connection_struct *conn, struct smb_request *req)
/*
* Go through and cancel any pending change notifies.
*/
-
+
START_PROFILE(SMBntcancel);
remove_pending_change_notify_requests_by_mid(req->mid);
remove_pending_lock_requests_by_mid(req->mid);
srv_cancel_sign_response(req->mid);
-
+
DEBUG(3,("reply_ntcancel: cancel called on mid = %d.\n", req->mid));
END_PROFILE(SMBntcancel);
@@ -1923,8 +1960,6 @@ static NTSTATUS copy_internals(connection_struct *conn,
void reply_ntrename(connection_struct *conn, struct smb_request *req)
{
- pstring oldname_in;
- pstring newname_in;
char *oldname = NULL;
char *newname = NULL;
char *p;
@@ -1947,8 +1982,8 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
rename_type = SVAL(req->inbuf,smb_vwv1);
p = smb_buf(req->inbuf) + 1;
- p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, oldname_in, p,
- sizeof(oldname_in), 0, STR_TERMINATE, &status,
+ p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &oldname, p,
+ 0, STR_TERMINATE, &status,
&src_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1956,22 +1991,22 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
return;
}
- if( is_ntfs_stream_name(oldname_in)) {
+ if( is_ntfs_stream_name(oldname)) {
/* Can't rename a stream. */
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
END_PROFILE(SMBntrename);
return;
}
- if (ms_has_wild(oldname_in)) {
+ if (ms_has_wild(oldname)) {
reply_nterror(req, NT_STATUS_OBJECT_PATH_SYNTAX_BAD);
END_PROFILE(SMBntrename);
return;
}
p++;
- p += srvstr_get_path_wcard((char *)req->inbuf, req->flags2, newname_in, p,
- sizeof(newname_in), 0, STR_TERMINATE, &status,
+ p += srvstr_get_path_wcard(ctx, (char *)req->inbuf, req->flags2, &newname, p,
+ 0, STR_TERMINATE, &status,
&dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -1981,7 +2016,7 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
- oldname_in,
+ oldname,
&oldname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1997,7 +2032,7 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
status = resolve_dfspath(ctx, conn,
req->flags2 & FLAGS2_DFS_PATHNAMES,
- newname_in,
+ newname,
&newname);
if (!NT_STATUS_IS_OK(status)) {
if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -2057,13 +2092,13 @@ void reply_ntrename(connection_struct *conn, struct smb_request *req)
}
reply_outbuf(req, 0, 0);
-
+
END_PROFILE(SMBntrename);
return;
}
/****************************************************************************
- Reply to a notify change - queue the request and
+ Reply to a notify change - queue the request and
don't allow a directory to be opened.
****************************************************************************/
@@ -2175,11 +2210,12 @@ static void call_nt_transact_rename(connection_struct *conn,
uint32 max_data_count)
{
char *params = *ppparams;
- pstring new_name;
+ char *new_name = NULL;
files_struct *fsp = NULL;
BOOL replace_if_exists = False;
BOOL dest_has_wcard = False;
NTSTATUS status;
+ TALLOC_CTX *ctx = talloc_tos();
if(parameter_count < 5) {
reply_doserror(req, ERRDOS, ERRbadfunc);
@@ -2191,8 +2227,8 @@ static void call_nt_transact_rename(connection_struct *conn,
if (!check_fsp(conn, req, fsp, &current_user)) {
return;
}
- srvstr_get_path_wcard(params, req->flags2, new_name, params+4,
- sizeof(new_name), parameter_count - 4,
+ srvstr_get_path_wcard(ctx, params, req->flags2, &new_name, params+4,
+ parameter_count - 4,
STR_TERMINATE, &status, &dest_has_wcard);
if (!NT_STATUS_IS_OK(status)) {
reply_nterror(req, status);
@@ -2215,10 +2251,10 @@ static void call_nt_transact_rename(connection_struct *conn,
* Rename was successful.
*/
send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
-
+
DEBUG(3,("nt transact rename from = %s, to = %s succeeded.\n",
fsp->fsp_name, new_name));
-
+
return;
}
@@ -2351,7 +2387,7 @@ static void call_nt_transact_query_security_desc(connection_struct *conn,
security descriptor.\n"));
/*
* Return access denied for want of a better error message..
- */
+ */
talloc_destroy(mem_ctx);
reply_unixerror(req, ERRDOS, ERRnoaccess);
return;
@@ -2421,7 +2457,7 @@ static void call_nt_transact_set_security_desc(connection_struct *conn,
send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
}
-
+
/****************************************************************************
Reply to NT IOCTL
****************************************************************************/
@@ -2469,7 +2505,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
DEBUG(10,("FSCTL_SET_SPARSE: called on FID[0x%04X](but not implemented)\n", fidnum));
send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
-
+
case FSCTL_CREATE_OR_GET_OBJECT_ID:
{
unsigned char objid[16];
@@ -2515,7 +2551,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
DEBUG(10,("FSCTL_SET_REPARSE_POINT: called on FID[0x%04X](but not implemented)\n",fidnum));
reply_nterror(req, NT_STATUS_NOT_A_REPARSE_POINT);
return;
-
+
case FSCTL_GET_SHADOW_COPY_DATA: /* don't know if this name is right...*/
{
/*
@@ -2564,9 +2600,9 @@ static void call_nt_transact_ioctl(connection_struct *conn,
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
}
-
+
shadow_data->mem_ctx = shadow_mem_ctx;
-
+
/*
* Call the VFS routine to actually do the work.
*/
@@ -2606,7 +2642,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
talloc_destroy(shadow_data->mem_ctx);
reply_nterror(req, NT_STATUS_NO_MEMORY);
return;
- }
+ }
cur_pdata = pdata;
@@ -2643,11 +2679,11 @@ static void call_nt_transact_ioctl(connection_struct *conn,
return;
}
-
+
case FSCTL_FIND_FILES_BY_SID: /* I hope this name is right */
{
- /* pretend this succeeded -
- *
+ /* pretend this succeeded -
+ *
* we have to send back a list with all files owned by this SID
*
* but I have to check that --metze
@@ -2655,7 +2691,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
DOM_SID sid;
uid_t uid;
size_t sid_len = MIN(data_count-4,SID_MAX_SIZE);
-
+
DEBUG(10,("FSCTL_FIND_FILES_BY_SID: called on FID[0x%04X]\n",fidnum));
if (!fsp_belongs_conn(conn, req, fsp, &current_user)) {
@@ -2664,7 +2700,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
/* unknown 4 bytes: this is not the length of the sid :-( */
/*unknown = IVAL(pdata,0);*/
-
+
sid_parse(pdata+4,sid_len,&sid);
DEBUGADD(10,("for SID: %s\n",sid_string_static(&sid)));
@@ -2673,7 +2709,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
sid_string_static(&sid),(unsigned long)sid_len));
uid = (-1);
}
-
+
/* we can take a look at the find source :-)
*
* find ./ -uid $uid -name '*' is what we need here
@@ -2686,16 +2722,16 @@ static void call_nt_transact_ioctl(connection_struct *conn,
* (maybe we can hang the result anywhere in the fsp struct)
*
* we don't send all files at once
- * and at the next we should *not* start from the beginning,
- * so we have to cache the result
+ * and at the next we should *not* start from the beginning,
+ * so we have to cache the result
*
* --metze
*/
-
+
/* this works for now... */
send_nt_replies(req, NT_STATUS_OK, NULL, 0, NULL, 0);
return;
- }
+ }
default:
if (!logged_message) {
logged_message = True; /* Only print this once... */
@@ -2710,7 +2746,7 @@ static void call_nt_transact_ioctl(connection_struct *conn,
#ifdef HAVE_SYS_QUOTAS
/****************************************************************************
- Reply to get user quota
+ Reply to get user quota
****************************************************************************/
static void call_nt_transact_get_user_quota(connection_struct *conn,
@@ -2758,7 +2794,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
reply_doserror(req, ERRDOS, ERRinvalidparam);
return;
}
-
+
/* maybe we can check the quota_fnum */
fsp = file_fsp(SVAL(params,0));
if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
@@ -2773,16 +2809,16 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
qt_handle = (SMB_NTQUOTA_HANDLE *)fsp->fake_file_handle->pd;
level = SVAL(params,2);
-
- /* unknown 12 bytes leading in params */
-
+
+ /* unknown 12 bytes leading in params */
+
switch (level) {
case TRANSACT_GET_USER_QUOTA_LIST_CONTINUE:
/* seems that we should continue with the enum here --metze */
- if (qt_handle->quota_list!=NULL &&
+ if (qt_handle->quota_list!=NULL &&
qt_handle->tmp_list==NULL) {
-
+
/* free the list */
free_ntquota_list(&(qt_handle->quota_list));
@@ -2824,7 +2860,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
/* we should not trust the value in max_data_count*/
max_data_count = MIN(max_data_count,2048);
-
+
pdata = nttrans_realloc(ppdata, max_data_count);/* should be max data count from client*/
if(pdata == NULL) {
reply_doserror(req, ERRDOS, ERRnomem);
@@ -2835,7 +2871,7 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
/* set params Size of returned Quota Data 4 bytes*/
/* but set it later when we know it */
-
+
/* for each entry push the data */
if (start_enum) {
@@ -2852,28 +2888,28 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
/* nextoffset entry 4 bytes */
SIVAL(entry,0,entry_len);
-
+
/* then the len of the SID 4 bytes */
SIVAL(entry,4,sid_len);
-
+
/* unknown data 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-metze*/
-
+
/* the used disk space 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,16,tmp_list->quotas->usedspace);
-
+
/* the soft quotas 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,24,tmp_list->quotas->softlim);
-
+
/* the hard quotas 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,32,tmp_list->quotas->hardlim);
-
+
/* and now the SID */
sid_linearize(entry+40, sid_len, &tmp_list->quotas->sid);
}
-
+
qt_handle->tmp_list = tmp_list;
-
+
/* overwrite the offset of the last entry */
SIVAL(entry-entry_len,0,0);
@@ -2884,9 +2920,9 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
break;
case TRANSACT_GET_USER_QUOTA_FOR_SID:
-
- /* unknown 4 bytes IVAL(pdata,0) */
-
+
+ /* unknown 4 bytes IVAL(pdata,0) */
+
if (data_count < 8) {
DEBUG(0,("TRANSACT_GET_USER_QUOTA_FOR_SID: requires %d >= %d bytes data\n",data_count,8));
reply_doserror(req, ERRDOS, ERRunknownlevel);
@@ -2919,11 +2955,11 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
}
sid_parse(pdata+8,sid_len,&sid);
-
+
if (vfs_get_ntquota(fsp, SMB_USER_QUOTA_TYPE, &sid, &qt)!=0) {
ZERO_STRUCT(qt);
- /*
- * we have to return zero's in all fields
+ /*
+ * we have to return zero's in all fields
* instead of returning an error here
* --metze
*/
@@ -2947,25 +2983,25 @@ static void call_nt_transact_get_user_quota(connection_struct *conn,
/* set params Size of returned Quota Data 4 bytes*/
SIVAL(params,0,data_len);
-
+
/* nextoffset entry 4 bytes */
SIVAL(entry,0,0);
-
+
/* then the len of the SID 4 bytes */
SIVAL(entry,4,sid_len);
-
+
/* unknown data 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,8,(SMB_BIG_UINT)0); /* this is not 0 in windows...-mezte*/
-
+
/* the used disk space 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,16,qt.usedspace);
-
+
/* the soft quotas 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,24,qt.softlim);
-
+
/* the hard quotas 8 bytes SMB_BIG_UINT */
SBIG_UINT(entry,32,qt.hardlim);
-
+
/* and now the SID */
sid_linearize(entry+40, sid_len, &sid);
@@ -3023,7 +3059,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
reply_doserror(req, ERRDOS, ERRinvalidparam);
return;
}
-
+
/* maybe we can check the quota_fnum */
fsp = file_fsp(SVAL(params,0));
if (!CHECK_NTQUOTA_HANDLE_OK(fsp,conn)) {
@@ -3052,7 +3088,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
return;
}
- /* unknown 8 bytes in pdata
+ /* unknown 8 bytes in pdata
* maybe its the change time in NTTIME
*/
@@ -3097,7 +3133,7 @@ static void call_nt_transact_set_user_quota(connection_struct *conn,
return;
}
#endif /* LARGE_SMB_OFF_T */
-
+
sid_parse(pdata+40,sid_len,&sid);
DEBUGADD(8,("SID: %s\n",sid_string_static(&sid)));
@@ -3227,7 +3263,7 @@ static void handle_nttrans(connection_struct *conn,
&state->data, state->total_data,
state->max_data_return);
END_PROFILE(NT_transact_set_user_quota);
- break;
+ break;
}
#endif /* HAVE_SYS_QUOTAS */
@@ -3307,7 +3343,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req)
state->setup = NULL;
state->call = function_code;
- /*
+ /*
* All nttrans messages we handle have smb_wct == 19 +
* state->setup_count. Ensure this is so as a sanity check.
*/
@@ -3339,7 +3375,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req)
reply_doserror(req, ERRDOS, ERRnomem);
END_PROFILE(SMBnttrans);
return;
- }
+ }
if ((dsoff+dscnt < dsoff) || (dsoff+dscnt < dscnt))
goto bad_param;
if ((smb_base(req->inbuf)+dsoff+dscnt
@@ -3361,7 +3397,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req)
reply_doserror(req, ERRDOS, ERRnomem);
END_PROFILE(SMBnttrans);
return;
- }
+ }
if ((psoff+pscnt < psoff) || (psoff+pscnt < pscnt))
goto bad_param;
if ((smb_base(req->inbuf)+psoff+pscnt
@@ -3431,7 +3467,7 @@ void reply_nttrans(connection_struct *conn, struct smb_request *req)
END_PROFILE(SMBnttrans);
return;
}
-
+
/****************************************************************************
Reply to a SMBnttranss
****************************************************************************/
@@ -3489,7 +3525,7 @@ void reply_nttranss(connection_struct *conn, struct smb_request *req)
state->received_param += pcnt;
state->received_data += dcnt;
-
+
if ((state->received_data > state->total_data) ||
(state->received_param > state->total_param))
goto bad_param;
@@ -3529,7 +3565,7 @@ void reply_nttranss(connection_struct *conn, struct smb_request *req)
goto bad_param;
memcpy(state->data+ddisp, smb_base(req->inbuf)+doff,
- dcnt);
+ dcnt);
}
if ((state->received_param < state->total_param) ||