summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2001-09-17 04:23:48 +0000
committerAndrew Tridgell <tridge@samba.org>2001-09-17 04:23:48 +0000
commit23af0743267d250a90af77c3bbce4d5fd0cdcc00 (patch)
tree61e3a082757066c96d1ab0e092a04ba9c5b328c6
parent81fdc3c3f76075babe3e1f4bf43ed2cfd5723472 (diff)
downloadsamba-23af0743267d250a90af77c3bbce4d5fd0cdcc00.tar.gz
samba-23af0743267d250a90af77c3bbce4d5fd0cdcc00.tar.bz2
samba-23af0743267d250a90af77c3bbce4d5fd0cdcc00.zip
fixed ctemp in server and client. It turns out that ctemp on NT is completely broken, and it's pointless to emulate their brokenness completely in this case, but at least this makes us use approximately the same packet format. The spec is complelet wrong in this case
(This used to be commit 2d507ec669def6d49304559e53d6c14af9b290a9)
-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)) {