diff options
-rw-r--r-- | source3/lib/util.c | 7 | ||||
-rw-r--r-- | source3/libsmb/clifile.c | 15 | ||||
-rw-r--r-- | source3/smbd/reply.c | 29 | ||||
-rw-r--r-- | source3/torture/torture.c | 22 |
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)) { |