summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/lib/util.c7
-rw-r--r--source3/libsmb/clifile.c15
-rw-r--r--source3/smbd/reply.c29
-rw-r--r--source3/torture/torture.c22
4 files changed, 48 insertions, 25 deletions
diff --git a/source3/lib/util.c b/source3/lib/util.c
index 3d2de63f38..0eaf7c01fc 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -335,20 +335,21 @@ int set_message(char *buf,int num_words,int num_bytes,BOOL zero)
/*******************************************************************
setup only the byte count for a smb message
********************************************************************/
-void set_message_bcc(char *buf,int num_bytes)
+int set_message_bcc(char *buf,int num_bytes)
{
int num_words = CVAL(buf,smb_wct);
SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
smb_setlen(buf,smb_size + num_words*2 + num_bytes - 4);
+ return (smb_size + num_words*2 + num_bytes);
}
/*******************************************************************
setup only the byte count for a smb message, using the end of the
message as a marker
********************************************************************/
-void set_message_end(void *outbuf,void *end_ptr)
+int set_message_end(void *outbuf,void *end_ptr)
{
- set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
+ return set_message_bcc((char *)outbuf,PTR_DIFF(end_ptr,smb_buf((char *)outbuf)));
}
/*******************************************************************
diff --git a/source3/libsmb/clifile.c b/source3/libsmb/clifile.c
index 4e6a89a9ae..e9981d7205 100644
--- a/source3/libsmb/clifile.c
+++ b/source3/libsmb/clifile.c
@@ -785,18 +785,20 @@ create and open a temporary file
****************************************************************************/
int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path)
{
+ int len;
char *p;
memset(cli->outbuf,'\0',smb_size);
memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,1,0,True);
+ set_message(cli->outbuf,3,0,True);
CVAL(cli->outbuf,smb_com) = SMBctemp;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0);
+ SIVALS(cli->outbuf,smb_vwv1,-1);
p = smb_buf(cli->outbuf);
*p++ = 4;
@@ -813,10 +815,17 @@ int cli_ctemp(struct cli_state *cli, char *path, char **tmp_path)
return -1;
}
+ /* despite the spec, the result has a -1, followed by
+ length, followed by name */
+ p = smb_buf(cli->inbuf);
+ p += 4;
+ len = smb_buflen(cli->inbuf) - 4;
+ if (len <= 0) return -1;
+
if (tmp_path) {
pstring path2;
- clistr_pull(cli, path2, smb_buf(cli->inbuf)+1,
- sizeof(path2), -1, STR_TERMINATE);
+ clistr_pull(cli, path2, p,
+ sizeof(path2), len, STR_ASCII);
*tmp_path = strdup(path2);
}
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 1559cd30df..3dca209581 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -1581,13 +1581,13 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
int oplock_request = CORE_OPLOCK_REQUEST(inbuf);
int tmpfd;
SMB_STRUCT_STAT sbuf;
- char *p;
+ char *p, *s;
START_PROFILE(SMBctemp);
createmode = SVAL(inbuf,smb_vwv0);
srvstr_pull(inbuf, fname, smb_buf(inbuf)+1, sizeof(fname), -1, STR_TERMINATE);
- pstrcat(fname,"/TMXXXXXX");
+ pstrcat(fname,"\\TMXXXXXX");
RESOLVE_DFSPATH(fname, conn, inbuf, outbuf);
@@ -1626,17 +1626,28 @@ int reply_ctemp(connection_struct *conn, char *inbuf,char *outbuf, int dum_size,
outsize = set_message(outbuf,1,0,True);
SSVAL(outbuf,smb_vwv0,fsp->fnum);
- CVAL(smb_buf(outbuf),0) = 4;
- p = smb_buf(outbuf) + 1;
- p += srvstr_push(outbuf, p, fname, -1, STR_TERMINATE);
- set_message_end(outbuf, p);
+
+ /* the returned filename is relative to the directory */
+ s = strrchr_m(fname, '/');
+ if (!s) {
+ s = fname;
+ } else {
+ s++;
+ }
+
+ p = smb_buf(outbuf);
+ SSVALS(p, 0, -1); /* what is this? not in spec */
+ SSVAL(p, 2, strlen(s));
+ p += 4;
+ p += srvstr_push(outbuf, p, s, -1, STR_ASCII);
+ outsize = set_message_end(outbuf, p);
if (oplock_request && lp_fake_oplocks(SNUM(conn))) {
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
}
- if(EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
- CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
+ if (EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type))
+ CVAL(outbuf,smb_flg) |= CORE_OPLOCK_GRANTED;
DEBUG( 2, ( "created temp file %s\n", fname ) );
DEBUG( 3, ( "ctemp %s fd=%d dmode=%d umode=%o\n",
diff --git a/source3/torture/torture.c b/source3/torture/torture.c
index fb581baa5e..33260dcc54 100644
--- a/source3/torture/torture.c
+++ b/source3/torture/torture.c
@@ -2639,6 +2639,7 @@ static BOOL run_opentest(int dummy)
char buf[20];
size_t fsize;
BOOL correct = True;
+ char *tmp_path;
printf("starting open test\n");
@@ -2774,16 +2775,17 @@ static BOOL run_opentest(int dummy)
printf("testing ctemp\n");
- {
- char *tmp_path;
- fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
- if (fnum1 == -1) {
- printf("ctemp failed (%s)\n", cli_errstr(&cli1));
- return False;
- }
- printf("ctemp gave path %s\n", tmp_path);
- cli_close(&cli1, fnum1);
- cli_unlink(&cli1, tmp_path);
+ fnum1 = cli_ctemp(&cli1, "\\", &tmp_path);
+ if (fnum1 == -1) {
+ printf("ctemp failed (%s)\n", cli_errstr(&cli1));
+ return False;
+ }
+ printf("ctemp gave path %s\n", tmp_path);
+ if (!cli_close(&cli1, fnum1)) {
+ printf("close of temp failed (%s)\n", cli_errstr(&cli1));
+ }
+ if (!cli_unlink(&cli1, tmp_path)) {
+ printf("unlink of temp failed (%s)\n", cli_errstr(&cli1));
}
if (!torture_close_connection(&cli1)) {