put server-side long dce/rpc code in main branch.
authorLuke Leighton <lkcl@samba.org>
Tue, 21 Apr 1998 02:36:37 +0000 (02:36 +0000)
committerLuke Leighton <lkcl@samba.org>
Tue, 21 Apr 1998 02:36:37 +0000 (02:36 +0000)
source/include/ntdomain.h
source/rpc_client/cli_pipe.c
source/rpc_server/srv_pipe_hnd.c
source/smbd/ipc.c

index 67fe879f9b2f1b488e231756b65be65081ece440..329cb1e32549b4219e41699404c0efa27d0b4a18 100644 (file)
  
 typedef struct
 {
-        struct mem_buf *data; /* memory buffer */
-        uint32 offset; /* offset currently being accessed in memory buffer */
-        uint8 align; /* data alignment */
-        BOOL io; /* parsing in or out of data stream */
+       struct mem_buf *data; /* memory buffer */
+       uint32 offset; /* offset currently being accessed in memory buffer */
+       uint8 align; /* data alignment */
+       BOOL io; /* parsing in or out of data stream */
 
 } prs_struct;
 
 typedef struct
 {
-        int cnum; 
-        int uid;
-        BOOL open; /* open connection */
-        uint16 device_state;
-        fstring name;
-        fstring pipe_srv_name;
-
-        prs_struct rhdr; /* output header */
-        prs_struct rdata; /* output data */
-        prs_struct rauth; /* output authentication verifier */
-        RPC_HDR     hdr;
-        RPC_HDR_BA  hdr_ba;
-        RPC_HDR_RB  hdr_rb;
-        RPC_HDR_REQ  hdr_req;
-        RPC_HDR_RESP hdr_resp;
-
-        RPC_AUTH_NTLMSSP_REQ  ntlmssp_req;
-        RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
-
-        uint32 max_rdata_len;
-        uint32 hdr_offsets;
+       int cnum; 
+       int uid;
+       BOOL open; /* open connection */
+       uint16 device_state;
+       fstring name;
+       fstring pipe_srv_name;
+
+       prs_struct rhdr; /* output header */
+       prs_struct rdata; /* output data */
+       prs_struct rauth; /* output authentication verifier */
+
+       RPC_HDR     hdr;
+       RPC_HDR_BA  hdr_ba;
+       RPC_HDR_RB  hdr_rb;
+       RPC_HDR_REQ  hdr_req;
+       RPC_HDR_RESP hdr_resp;
+
+       RPC_AUTH_NTLMSSP_REQ  ntlmssp_req;
+       RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
+
+       uint32 file_offset;
+       uint32 hdr_offsets;
+       uint32 frag_len_left;
+       uint32 next_frag_start;
 
 } pipes_struct;
 
 struct acct_info
 {  
-        fstring acct_name; /* account name */
-        uint32 smb_userid; /* domain-relative RID */
+       fstring acct_name; /* account name */
+       uint32 smb_userid; /* domain-relative RID */
 };
 
 struct api_struct
@@ -95,33 +97,33 @@ struct api_struct
 
 struct mem_desc
 {  
-        /* array memory offsets */
-        uint32 start; 
-        uint32 end;
+       /* array memory offsets */
+       uint32 start; 
+       uint32 end;
 };
    
 struct mem_buf
 {  
-        BOOL dynamic; /* True iff data has been dynamically allocated
-                         (and therefore can be freed) */
-        char *data;
-        uint32 data_size;
-        uint32 data_used;
+       BOOL dynamic; /* True iff data has been dynamically allocated
+                                        (and therefore can be freed) */
+       char *data;
+       uint32 data_size;
+       uint32 data_used;
 
-        uint32 margin; /* safety margin when reallocing. */
-                       /* this can be abused quite nicely */
-        uint8 align;   /* alignment of data structures (smb, dce/rpc, udp etc) */
+       uint32 margin; /* safety margin when reallocing. */
+                                  /* this can be abused quite nicely */
+       uint8 align;   /* alignment of data structures (smb, dce/rpc, udp etc) */
 
-        struct mem_desc offset;
+       struct mem_desc offset;
 
-        struct mem_buf *next;
+       struct mem_buf *next;
 };
 
 typedef struct
 {  
-        uint32 rid;
-        char *name;
-   
+       uint32 rid;
+       char *name;
+
 } rid_name;
 
 #endif /* _NT_DOMAIN_H */
index 625b7741673a126eee6d51f8b80ed1690f709ba4..91ba8a263ee92b76ffa761ca62b368251e6ae933 100644 (file)
@@ -47,18 +47,24 @@ uint32 get_rpc_call_id(void)
  uses SMBreadX to get rest of rpc data
  ********************************************************************/
 static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum,
-                               prs_struct *rdata, uint32 data_to_read)
+                               prs_struct *rdata, uint32 data_to_read, uint32 rdata_offset)
 {
-       uint32 data_offset = rdata->data->data_used;
-       int size = 512;
+       int size = 0x1630;
+       int file_offset = rdata_offset;
        int num_read;
        char *data = rdata->data->data;
        uint32 err;
-       data += rdata->data->data_used;
+       uint32 new_data_size = rdata->data->data_used + data_to_read;
+       data += rdata_offset;
 
-       if (data_offset + data_to_read > rdata->data->data_size)
+       file_offset -= rdata_offset;
+
+       DEBUG(5,("rpc_read: data_to_read: %d data offset: %d file offset: %d\n",
+                 data_to_read, rdata_offset, file_offset));
+
+       if (new_data_size > rdata->data->data_size)
        {
-               mem_grow_data(&rdata->data, True, rdata->data->data_used + data_to_read);
+               mem_grow_data(&rdata->data, True, new_data_size, True);
                DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
        }
 
@@ -66,27 +72,29 @@ static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum,
        {
                if (size > data_to_read) size = data_to_read;
 
-               if (data_offset + size > rdata->data->data_size)
+               new_data_size = rdata->data->data_used + size;
+
+               if (new_data_size > rdata->data->data_size)
                {
-                       mem_grow_data(&rdata->data, True, rdata->data->data_used + size);
+                       mem_grow_data(&rdata->data, True, new_data_size, True);
                        DEBUG(5,("rpc_read: grow buffer to %d\n", rdata->data->data_used));
                }
 
-               num_read = cli_readx(cli, t_idx, fnum, data, data_offset, size);
+               num_read = cli_readx(cli, t_idx, fnum, data, file_offset + 0x100000, size);
 
                DEBUG(5,("rpc_read: read offset: %d read: %d to read: %d\n",
-                                 data_offset, num_read, data_to_read));
+                                 file_offset, num_read, data_to_read));
 
                data_to_read -= num_read;
-               data_offset  += num_read;
+               file_offset  += num_read;
                data         += num_read;
 
                if (cli_error(cli, NULL, &err)) return False;
 
        } while (num_read > 0 && data_to_read > 0); /* && err == (0x80000000 | STATUS_BUFFER_OVERFLOW)); */
 
-       mem_realloc_data(rdata->data, rdata->data->data_used);
-       rdata->data->offset.end = rdata->data->data_used;
+       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));
 
@@ -97,10 +105,12 @@ static BOOL rpc_read(struct cli_state *cli, int t_idx, uint16 fnum,
  checks the header
  ****************************************************************************/
 static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
-                               BOOL *first, BOOL *last, uint32 *len)
+                               BOOL *first, BOOL *last, int *len)
 {
        RPC_HDR    rhdr;
 
+       DEBUG(5,("rpc_check_hdr: rdata->data->data_used: %d\n", rdata->data->data_used));
+
        smb_io_rpc_hdr   ("rpc_hdr   ", &rhdr   , rdata, 0);
 
        if (!rdata->offset || rdata->offset != 0x10)
@@ -109,6 +119,8 @@ static BOOL rpc_check_hdr(prs_struct *rdata, uint8 *pkt_type,
                return False;
        }
 
+       DEBUG(5,("rpc_check_hdr: (after smb_io_rpc_hdr call) rdata->data->data_used: %d\n", rdata->data->data_used));
+
        (*first   ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_FIRST);
        (*last    ) = IS_BITS_SET_ALL(rhdr.flags, RPC_FLG_LAST );
        (*len     ) = rhdr.frag_len - rdata->data->data_used;
@@ -139,7 +151,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
                                prs_struct *param , prs_struct *data,
                                prs_struct *rparam, prs_struct *rdata)
 {
-       uint32 len;
+       int len;
 
        uint16 setup[2]; /* only need 2 uint16 setup parameters */
        uint32 err;
@@ -188,30 +200,31 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
        
        if (pkt_type == RPC_RESPONSE)
        {
-               RPC_HDR_RR rhdr_rr;
-               smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, rdata, 0);
+               RPC_HDR_RESP rhdr_resp;
+               smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, rdata, 0);
        }
 
-       if (first && last)
-       {
-               DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
-               return True;
-       }
+       DEBUG(5,("rpc_api_pipe: len left: %d smbtrans read: %d\n",
+                       len, rdata->data->data_used));
 
        /* check if data to be sent back was too large for one SMB. */
        /* err status is only informational: the _real_ check is on the length */
-       if (len < rdata->data->data_used) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
+       if (len > 0) /* || err == (0x80000000 | STATUS_BUFFER_OVERFLOW)) */
        {
-               if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False;
+               if (!rpc_read(cli, t_idx, fnum, rdata, len, rdata->data->data_used)) return False;
        }
 
        /* only one rpc fragment, and it has been read */
-       if (first && last) return True;
+       if (first && last)
+       {
+               DEBUG(6,("rpc_api_pipe: fragment first and last both set\n"));
+               return True;
+       }
 
        while (!last) /* read more fragments until we get the last one */
        {
-               RPC_HDR    rhdr;
-               RPC_HDR_RR rhdr_rr;
+               RPC_HDR      rhdr;
+               RPC_HDR_RESP rhdr_resp;
                int num_read;
                prs_struct hps;
 
@@ -222,8 +235,8 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
 
                if (num_read != 0x18) return False;
 
-               smb_io_rpc_hdr   ("rpc_hdr   ", &rhdr   , &hps, 0);
-               smb_io_rpc_hdr_rr("rpc_hdr_rr", &rhdr_rr, &hps, 0);
+               smb_io_rpc_hdr     ("rpc_hdr     ", &rhdr     , &hps, 0);
+               smb_io_rpc_hdr_resp("rpc_hdr_resp", &rhdr_resp, &hps, 0);
 
                prs_mem_free(&hps);
 
@@ -239,7 +252,7 @@ BOOL rpc_api_pipe(struct cli_state *cli, int t_idx,
                }
 
                len = rhdr.frag_len - hps.offset;
-               if (!rpc_read(cli, t_idx, fnum, rdata, len)) return False;
+               if (!rpc_read(cli, t_idx, fnum, rdata, len, rdata->data->data_used)) return False;
        }
 
        return True;
@@ -332,22 +345,22 @@ static BOOL create_rpc_bind_req(prs_struct *rhdr,
  ********************************************************************/
 static BOOL create_rpc_request(prs_struct *rhdr, uint8 op_num, int data_len)
 {
-       RPC_HDR_RR hdr_rr;
-       RPC_HDR    hdr;
+       RPC_HDR_REQ hdr_req;
+       RPC_HDR     hdr;
 
        DEBUG(5,("create_rpc_request: opnum: 0x%x data_len: 0x%x\n",
-                               op_num, data_len));
+                 op_num, data_len));
 
        /* create the rpc header RPC_HDR */
-       make_rpc_hdr   (&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
-                       get_rpc_call_id(), data_len + 0x18, 0);
+       make_rpc_hdr(&hdr   , RPC_REQUEST, RPC_FLG_FIRST | RPC_FLG_LAST,
+                    get_rpc_call_id(), data_len + 0x18, 0);
 
-       /* create the rpc request RPC_HDR_RR */
-       make_rpc_hdr_rr(&hdr_rr, data_len, op_num);
+       /* create the rpc request RPC_HDR_REQ */
+       make_rpc_hdr_req(&hdr_req, data_len, op_num);
 
        /* stream-time... */
-       smb_io_rpc_hdr   ("hdr"   , &hdr   , rhdr, 0);
-       smb_io_rpc_hdr_rr("hdr_rr", &hdr_rr, rhdr, 0);
+       smb_io_rpc_hdr    ("hdr    ", &hdr    , rhdr, 0);
+       smb_io_rpc_hdr_req("hdr_req", &hdr_req, rhdr, 0);
 
        if (rhdr->data == NULL || rhdr->offset != 0x18) return False;
 
@@ -605,7 +618,7 @@ BOOL do_session_open(struct cli_state *cli, int t_idx,
 
 
        /******************* open the pipe *****************/
-       if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE,
+       if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE,
                                 NULL, NULL, NULL)) == 0xffff)
        {
                DEBUG(1,("do_session_open: cli_open failed\n"));
@@ -643,7 +656,7 @@ BOOL do_ntlm_session_open(struct cli_state *cli, int t_idx,
        RPC_IFACE transfer;
 
        /******************* open the pipe *****************/
-       if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_RDONLY, DENY_NONE,
+       if (((*fnum) = cli_open(cli, t_idx, pipe_name, O_CREAT|O_WRONLY, DENY_NONE,
                                 NULL, NULL, NULL)) == 0xffff)
        {
                DEBUG(1,("do_ntlm_session_open: cli_open failed\n"));
index a371e48bfd52eb97123e902a0462ceeee4f7b7bd..7ab2b3aec6bebb4a2cd5fa60909187cae458e847 100644 (file)
@@ -81,8 +81,10 @@ void init_rpc_pipe_hnd(void)
                Pipes[i].rhdr.offset  = 0;
                Pipes[i].rdata.offset = 0;
 
-               Pipes[i].max_rdata_len = 0;
-               Pipes[i].hdr_offsets   = 0;
+               Pipes[i].file_offset     = 0;
+               Pipes[i].hdr_offsets     = 0;
+               Pipes[i].frag_len_left   = 0;
+               Pipes[i].next_frag_start = 0;
        }
 
        return;
@@ -110,8 +112,10 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
                        Pipes[i].rhdr.offset  = 0;
                        Pipes[i].rdata.offset = 0;
 
-                       Pipes[i].max_rdata_len = 0;
-                       Pipes[i].hdr_offsets   = 0;
+                       Pipes[i].file_offset     = 0;
+                       Pipes[i].hdr_offsets     = 0;
+                       Pipes[i].frag_len_left   = 0;
+                       Pipes[i].next_frag_start = 0;
 
                        fstrcpy(Pipes[i].name, pipe_name);
 
@@ -134,7 +138,7 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
 
  headers are interspersed with the data at regular intervals.  by the time
  this function is called, the start of the data could possibly have been
- read by an SMBtrans (max_rdata_len != 0).
+ read by an SMBtrans (file_offset != 0).
 
  calling create_rpc_request() here is a fudge.  the data should already
  have been prepared into arrays of headers + data stream sections.
@@ -142,13 +146,14 @@ int open_rpc_pipe_hnd(char *pipe_name, int cnum, uint16 vuid)
  ****************************************************************************/
 int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
 {
-       int data_pos = pos;
+       int data_hdr_pos;
+       int data_pos;
        pipes_struct *p = &Pipes[pnum - PIPE_HANDLE_OFFSET];
        DEBUG(6,("read_pipe: %x", pnum));
 
        if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET))
        {
-               DEBUG(6,("name: %s cnum: %d open: %s data_pos: %lx len: %lx",
+               DEBUG(6,("name: %s cnum: %d open: %s data_pos: %d len: %d",
                          p->name,
                          p->cnum,
                          BOOLSTR(p->open),
@@ -160,7 +165,6 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
                int num = 0;
                int len = 0;
                uint32 hdr_num = 0;
-               uint32 rpc_frag_pos = 0;
 
                DEBUG(6,("OK\n"));
 
@@ -170,29 +174,38 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
                        return 0;
                }
 
-               DEBUG(6,("read_pipe: p: %p max_rdata_len: %d data_pos: %d num: %d\n",
-                         p, p->max_rdata_len, data_pos, num));
+               DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
+                         p, p->file_offset, n));
+               DEBUG(6,("read_pipe: frag_len_left: %d next_frag_start: %d\n",
+                         p->frag_len_left, p->next_frag_start));
 
                /* the read request starts from where the SMBtrans2 left off. */
-               data_pos += p->max_rdata_len;
-
-               rpc_frag_pos = data_pos % p->hdr.frag_len;
-
-               /* headers accumulate an offset */
-               data_pos -= p->hdr_offsets;
+               data_pos     = p->file_offset - p->hdr_offsets;
+               data_hdr_pos = p->file_offset;
 
                len = mem_buf_len(p->rhdr.data);
                num = len - (int)data_pos;
 
+               DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n));
+
                if (num > n) num = n;
+               if (num <= 0)
+               {
+                       DEBUG(5,("read_pipe: 0 or -ve data length\n"));
+                       return 0;
+               }
 
                if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
                {
-                       DEBUG(5,("read_pipe: hdr_offsets: %d rpc_frag_pos: %d frag_len: %d\n",
-                                 p->hdr_offsets, rpc_frag_pos, p->hdr.frag_len));
+                       /* intermediate fragment - possibility of another header */
+
+                       DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n",
+                                 p->hdr.frag_len, data_pos, data_hdr_pos));
 
-                       if (rpc_frag_pos == 0)
+                       if (data_hdr_pos == p->next_frag_start)
                        {
+                               DEBUG(6,("read_pipe: next fragment header\n"));
+
                                /* this is subtracted from the total data bytes, later */
                                hdr_num = 0x18;
 
@@ -200,24 +213,44 @@ int read_pipe(uint16 pnum, char *data, uint32 pos, int n)
                                create_rpc_reply(p, data_pos, p->rdata.offset);
                                mem_buf_copy(data, p->rhdr.data, 0, 0x18);
 
-                               /* make room in data stream for header */
-                               p->hdr_offsets += 0x18;
                                data += 0x18;
+                               p->frag_len_left = p->hdr.frag_len;
+                               p->next_frag_start += p->hdr.frag_len;
+                               p->hdr_offsets += 0x18;
 
-                               DEBUG(6,("read_pipe: hdr_offsets: %d\n", p->hdr_offsets));
+                               /*DEBUG(6,("read_pipe: hdr_offsets: %d\n", p->hdr_offsets));*/
                        }
                }
 
-               if (num > 0)
+               if (num < hdr_num)
                {
-                       DEBUG(6,("read_pipe: adjusted data_pos: %d num: %d\n",
-                                 data_pos, num - hdr_num));
-                       mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
+                       DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
+               }
+
+               DEBUG(6,("read_pipe: adjusted data_pos: %d num-hdr_num: %d\n",
+                                 data_pos, num - hdr_num));
+               mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
+
+               data_pos += num;
+               data_hdr_pos += num;
+
+               if (hdr_num == 0x18 && num == 0x18)
+               {
+                       DEBUG(6,("read_pipe: just header read\n"));
 
-                       return num;
+                       /* advance to the next fragment */
+                       p->frag_len_left -= 0x18; 
                }
+               else if (data_hdr_pos == p->next_frag_start)
+               {
+                       DEBUG(6,("read_pipe: next fragment expected\n"));
+
+                       /* advance to the next fragment */
+               }
+
+               p->file_offset  += num;
 
-               return 0;
+               return num;
 
        }
        else
index 7cf4d6f5b8485df2d88d686284792faecf315184..74ae1152171b34b272ba833a79613f8a9a74b345 100644 (file)
@@ -3255,9 +3255,9 @@ static BOOL api_dce_rpc_command(char *outbuf,
        if (reply)
        {
                /* now send the reply */
-               send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->max_rdata_len);
+               send_trans_reply(outbuf, p->rhdr.data, NULL, NULL, 0, p->file_offset);
 
-               if (mem_buf_len(p->rhdr.data) <= p->max_rdata_len)
+               if (mem_buf_len(p->rhdr.data) <= p->file_offset)
                {
                        /* all of data was sent: no need to wait for SMBreadX calls */
                        mem_free_data(p->rhdr .data);
@@ -3283,7 +3283,7 @@ static BOOL api_SNPHS(char *outbuf, pipes_struct *p, char *param)
        if (set_rpc_pipe_hnd_state(p, id))
        {
                /* now send the reply */
-               send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->max_rdata_len);
+               send_trans_reply(outbuf, NULL, NULL, NULL, 0, p->file_offset);
 
                return True;
        }
@@ -3366,10 +3366,10 @@ static int api_fd_reply(int cnum,uint16 vuid,char *outbuf,
                                  tdscnt,tpscnt,mdrcnt,mprcnt,cnum,vuid));
 
                /* record maximum data length that can be transmitted in an SMBtrans */
-               p->max_rdata_len = mdrcnt;
+               p->file_offset = mdrcnt;
 
-                DEBUG(10,("api_fd_reply: p:%p max_rdata_len: %d\n",
-                           p, p->max_rdata_len));
+                DEBUG(10,("api_fd_reply: p:%p file_offset: %d\n",
+                           p, p->file_offset));
 
                switch (subcommand)
                {