some quite important bug-fixes i missed because i transferred the wrong
authorLuke Leighton <lkcl@samba.org>
Tue, 20 Oct 1998 18:27:49 +0000 (18:27 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 20 Oct 1998 18:27:49 +0000 (18:27 +0000)
smb.tgz file from my portable.

particularly the call to mem_data followed by a realloc of that data in
cli_pipe.c's rpc_read() function.

smbd responses now use p->rdata_i which is a faked-up pointer into
p->rdata's response data.  rdata can be very long; rdata_i is limited
to point to no more than max_tsize - 0x18 in length.  this will make
it an almost trivial task to add the encrypted rpc headers after
rdata_i, and mem_buf_copy will cope admirably with rhdr chained to
rdata_i chained to auth_verifier etc etc...
(This used to be commit 05a297e3a98c14360782af4ad0d851638fb5da9a)

source3/include/ntdomain.h
source3/include/proto.h
source3/lib/membuffer.c
source3/lib/util.c
source3/rpc_client/cli_pipe.c
source3/rpc_server/srv_pipe_hnd.c
source3/rpc_server/srv_util.c
source3/smbd/ipc.c

index b7c3b5b577f599f53cc7f426451bcd5f056c2b10..97122c8169ab8b295e38db0527c86d6f0c76742a 100644 (file)
@@ -67,6 +67,7 @@ typedef struct pipes_struct
 
        prs_struct rhdr; /* output header */
        prs_struct rdata; /* output data */
+       prs_struct rdata_i; /* output data (intermediate, for fragments) */
        prs_struct rauth; /* output authentication verifier */
        prs_struct rverf; /* output verifier */
        prs_struct rntlm; /* output ntlmssp */
index b1322f5e9f306b30014eb9f1f589aaf43a4eb048..2cec5f91f734bc8d6a7c8afe22ce71b190f8fad7 100644 (file)
@@ -122,7 +122,7 @@ void mdfour(unsigned char *out, unsigned char *in, int n);
 /*The following definitions come from  lib/membuffer.c  */
 
 void mem_init(struct mem_buf *buf, int margin);
-void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic);
+void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic);
 BOOL mem_alloc_data(struct mem_buf *buf, int size);
 BOOL mem_buf_copy(char *copy_into, struct mem_buf *buf,
                                uint32 offset, uint32 len);
index 18e9fa94532594b1526a0b8e2786fdb126d0de6e..92bc2be439726bf9987ec66c8417e2787f83a9af 100644 (file)
@@ -79,7 +79,7 @@ void mem_init(struct mem_buf *buf, int margin)
  dynamic indicates memory has been dynamically allocated.
  if mem_free is called, the memory will be freed.
  ********************************************************************/
-void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dynamic)
+void mem_create(struct mem_buf *buf, char *data, int offset, int size, int margin, BOOL dynamic)
 {
        buf->dynamic   = dynamic;
        buf->data      = data;
@@ -90,8 +90,8 @@ void mem_create(struct mem_buf *buf, char *data, int size, int margin, BOOL dyna
 
        buf->next      = NULL;
 
-       buf->offset.start = 0;
-       buf->offset.end   = size;
+       buf->offset.start = offset;
+       buf->offset.end   = offset + size;
 }
 
 /*******************************************************************
@@ -109,7 +109,7 @@ BOOL mem_alloc_data(struct mem_buf *buf, int size)
 
        buf->data = malloc(buf->data_size);
 
-       if (buf->data == NULL)
+       if (buf->data == NULL && size != 0)
        {
                DEBUG(3,("mem_alloc: could not malloc size %d\n",
                                          buf->data_size));
index f2cd2a99d11b2bd10085657ff3cdd6ab68c13002..e5486e6159e949d326d207c9d2194cedf91d829e 100644 (file)
@@ -2262,8 +2262,10 @@ BOOL client_receive_smb(int fd,char *buffer, unsigned int timeout)
   {
     ret = receive_smb(fd, buffer, timeout);
 
-    if(ret == False)
+    if (!ret)
+    {
       return ret;
+    }
 
     /* Ignore session keepalive packets. */
     if(CVAL(buffer,0) != 0x85)
index 08b357573354f65710bc42e9b966bc1944e50c6d..f5587567cd4b53adccfae2883c1a0fc222e13459 100644 (file)
@@ -54,12 +54,10 @@ static BOOL rpc_read(struct cli_state *cli,
        int size = cli->max_recv_frag;
        int file_offset = rdata_offset;
        int num_read;
-       char *data = rdata->data->data;
+       char *data;
        uint32 err;
        uint32 new_data_size = rdata->data->data_used + data_to_read;
 
-       data += rdata_offset;
-
        file_offset -= rdata_offset;
 
        DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
@@ -71,6 +69,8 @@ static BOOL rpc_read(struct cli_state *cli,
                DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
        }
 
+       data = rdata->data->data + rdata_offset;
+
        do /* read data using SMBreadX */
        {
                if (size > data_to_read)
@@ -84,7 +84,7 @@ static BOOL rpc_read(struct cli_state *cli,
                        DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
                }
 
-               num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset + 0x100000, size);
+               num_read = cli_read(cli, cli->nt_pipe_fnum, data, file_offset, size);
 
                DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
                          file_offset, num_read, data_to_read));
@@ -101,9 +101,10 @@ static BOOL rpc_read(struct cli_state *cli,
        mem_realloc_data(rdata->data, file_offset + rdata_offset);
        rdata->data->offset.end = file_offset + rdata_offset;
 
-       DEBUG(5,("rpc_read: data supposedly left to read:0x%x\n", data_to_read));
+       DEBUG(5,("rpc_read: offset end: 0x%x.  data left to read:0x%x\n",
+                 rdata->data->offset.end, data_to_read));
 
-       return data_to_read == 0;
+       return data_to_read >= 0;
 }
 
 /****************************************************************************
index d5c99b89c415555598022e1d13bd681c8d4ddfee..54ecbf707e2f60a13b9162ef6a3341c70a20692f 100644 (file)
@@ -3,8 +3,8 @@
  *  Unix SMB/Netbios implementation.
  *  Version 1.9.
  *  RPC Pipe client / server routines
- *  Copyright (C) Andrew Tridgell              1992-1997,
- *  Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
+ *  Copyright (C) Andrew Tridgell              1992-1998,
+ *  Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
  *  
  *  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
@@ -175,7 +175,7 @@ ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
        dump_data(50, data, n);
 
        /* fake up a data buffer from the write_pipe data parameters */
-       mem_create(&data_buf, data, n, 0, False);
+       mem_create(&data_buf, data, 0, n, 0, False);
        data_buf.offset.start = 0;
        data_buf.offset.end   = n;
 
@@ -196,7 +196,7 @@ ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
  this function is called, the start of the data could possibly have been
  read by an SMBtrans (file_offset != 0).
 
- calling create_rpc_request() here is a fudge.  the data should already
+ calling create_rpc_reply() here is a fudge.  the data should already
  have been prepared into arrays of headers + data stream sections.
 
  ****************************************************************************/
@@ -268,8 +268,6 @@ int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
                        mem_buf_copy(data, p->rhdr.data, 0, 0x18);
                        
                        data += 0x18;
-                       p->frag_len_left = p->hdr.frag_len;
-                       p->next_frag_start += p->hdr.frag_len;
                        p->hdr_offsets += 0x18;
                }                       
        }
index 7ddc2da5d1a3a323cdacb4f5d3c11d2f9ad9e430..59db0bed2cac62c6fd7a54f4a3e3430dd6d85195 100644 (file)
@@ -165,6 +165,9 @@ int make_dom_gids(char *gids_str, DOM_GID **ppgids)
 BOOL create_rpc_reply(pipes_struct *p,
                                uint32 data_start, uint32 data_end)
 {
+       char *data;
+       uint32 data_len;
+
        DEBUG(5,("create_rpc_reply: data_start: %d data_end: %d max_tsize: %d\n",
                  data_start, data_end, p->hdr_ba.bba.max_tsize));
 
@@ -197,6 +200,8 @@ BOOL create_rpc_reply(pipes_struct *p,
                p->hdr.frag_len = p->hdr_ba.bba.max_tsize;
        }
 
+       data_len = p->hdr.frag_len;
+
        p->rhdr.data->offset.start = 0;
        p->rhdr.data->offset.end   = 0x18;
 
@@ -205,6 +210,20 @@ BOOL create_rpc_reply(pipes_struct *p,
        smb_io_rpc_hdr   ("hdr", &(p->hdr   ), &(p->rhdr), 0);
        smb_io_rpc_hdr_resp("resp", &(p->hdr_resp), &(p->rhdr), 0);
 
+       p->frag_len_left   = p->hdr.frag_len - p->file_offset;
+       p->next_frag_start = p->hdr.frag_len; 
+       
+       /* don't use rdata: use rdata_i instead, which moves... */
+       /* make a pointer to the rdata data.  NOT A COPY */
+
+       prs_init(&p->rdata_i, 0, p->rdata.align, p->rdata.data->margin, p->rdata.io);
+       data = mem_data(&(p->rdata.data), data_start);
+       mem_create(p->rdata_i.data, data, data_start, data_len, 0, False); 
+
+       /* set up the data chain */
+       prs_link(NULL    , &p->rhdr   , &p->rdata_i);
+       prs_link(&p->rhdr, &p->rdata_i, NULL       );
+
        return p->rhdr.data != NULL && p->rhdr.offset == 0x18;
 }
 
@@ -703,18 +722,6 @@ BOOL api_rpcTNP(pipes_struct *p, char *rpc_name, struct api_struct *api_rpc_cmds
                return False;
        }
 
-       p->frag_len_left   = p->hdr.frag_len - p->file_offset;
-       p->next_frag_start = p->hdr.frag_len; 
-       
-       /* set up the data chain */
-       p->rhdr.data->offset.start = 0;
-       p->rhdr.data->offset.end   = p->rhdr.offset;
-       p->rhdr.data->next = p->rdata.data;
-
-       p->rdata.data->offset.start = p->rhdr.data->offset.end;
-       p->rdata.data->offset.end   = p->rhdr.data->offset.end + p->rdata.offset;
-       p->rdata.data->next = NULL;
-
        return True;
 }
 
index 2b8b8698db4e754affa7b4fe6f65c205ddf74671..3e697a59ce5f05cc5bb1d190b88611f08ad35833 100644 (file)
@@ -3101,6 +3101,7 @@ static void api_rpc_trans_reply(char *outbuf,
                /* all of data was sent: no need to wait for SMBreadX calls */
                mem_free_data(p->rhdr .data);
                mem_free_data(p->rdata.data);
+               mem_free_data(p->rdata_i.data);
        }
 }
 
@@ -3190,20 +3191,12 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
        int subcommand;
        pipes_struct *p = NULL;
        prs_struct pd;
-       struct mem_buf data_buf;
 
        DEBUG(5,("api_fd_reply\n"));
 
-       /* fake up a data buffer from the api_fd_reply data parameters */
-       mem_create(&data_buf, data, tdscnt, 0, False);
-       data_buf.offset.start = 0;
-       data_buf.offset.end   = tdscnt;
-
-       /* fake up a parsing structure */
-       pd.data = &data_buf;
-       pd.align = 4;
-       pd.io = True;
-       pd.offset = 0;
+       /* make a static data parsing structure from the api_fd_reply data */
+       prs_init(&pd, 0, 4, True, 0);
+       mem_create(pd.data, data, 0, tdscnt, 0, False);
 
        /* First find out the name of this file. */
        if (suwcnt != 2)
@@ -3259,6 +3252,8 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf,
                DEBUG(1,("api_fd_reply: INVALID PIPE HANDLE: %x\n", pnum));
        }
 
+       mem_free_data(pd.data);
+
        if (!reply)
        {
                return api_no_reply(outbuf, mdrcnt);
@@ -3410,14 +3405,8 @@ static int api_reply(connection_struct *conn,uint16 vuid,char *outbuf,char *data
                    &rdata,&rparam,&rdata_len,&rparam_len);
 
       
-  mem_create(&rdata_buf , rdata , rdata_len , 0, False);
-  mem_create(&rparam_buf, rparam, rparam_len, 0, False);
-
-  rdata_buf.offset.start = 0;
-  rdata_buf.offset.end   = rdata_len;
-
-  rparam_buf.offset.start = 0;
-  rparam_buf.offset.end   = rparam_len;
+  mem_create(&rdata_buf , rdata , 0, rdata_len , 0, False);
+  mem_create(&rparam_buf, rparam, 0, rparam_len, 0, False);
 
   /* now send the reply */
   send_trans_reply(outbuf, &rdata_buf, &rparam_buf, NULL, 0, 0);