diff options
author | Andrew Tridgell <tridge@samba.org> | 1998-08-17 03:06:20 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1998-08-17 03:06:20 +0000 |
commit | f2d538a105a61ce6d2852700fc328e15ac158827 (patch) | |
tree | 47c819007b231a5a8ebfcc7faa0c1354561366df /source3/rpc_server/srv_pipe_hnd.c | |
parent | c5e2c883c0415ca3c7e366357c8c6ba573713aa6 (diff) | |
download | samba-f2d538a105a61ce6d2852700fc328e15ac158827.tar.gz samba-f2d538a105a61ce6d2852700fc328e15ac158827.tar.xz samba-f2d538a105a61ce6d2852700fc328e15ac158827.zip |
some cleanups from the conversion of Pipes[] to a linked list. I also
removed most cases where a pnum is used and substituted a pipes_struct*.
in files.c I added a offset of 0x1000 to all file handles on the
wire. This makes it much less likely that bad parsing will give us the
wrong field.
(This used to be commit 8bc2627ff28d340db65bfa017daca2dc291d5ef7)
Diffstat (limited to 'source3/rpc_server/srv_pipe_hnd.c')
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 432 |
1 files changed, 210 insertions, 222 deletions
diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index bd29578f0e3..dfc4eeba5f9 100644 --- a/source3/rpc_server/srv_pipe_hnd.c +++ b/source3/rpc_server/srv_pipe_hnd.c @@ -28,36 +28,34 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) +/* this must be larger than the sum of the open files and directories */ +#define PIPE_HANDLE_OFFSET 0x7000 + extern int DEBUGLEVEL; -static int chain_pnum = -1; +static pipes_struct *chain_p; +static int pipes_open; #ifndef MAX_OPEN_PIPES -#define MAX_OPEN_PIPES 50 +#define MAX_OPEN_PIPES 64 #endif -pipes_struct Pipes[MAX_OPEN_PIPES]; - -#define P_OPEN(p) ((p)->open) -#define P_OK(p,c) (P_OPEN(p) && (c)==((p)->conn)) -#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) -#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && P_OPEN(&(Pipes[pnum]))) -#define PNUM_OK(pnum,c) (OPEN_PNUM(pnum) && (c)==Pipes[pnum].cnum) - +static pipes_struct *Pipes; +static struct bitmap *bmap; /**************************************************************************** reset pipe chain handle number ****************************************************************************/ -void reset_chain_pnum(void) +void reset_chain_p(void) { - chain_pnum = -1; + chain_p = NULL; } /**************************************************************************** sets chain pipe-file handle ****************************************************************************/ -void set_chain_pnum(int new_pnum) +void set_chain_p(pipes_struct *new_p) { - chain_pnum = new_pnum; + chain_p = new_p; } /**************************************************************************** @@ -65,71 +63,85 @@ void set_chain_pnum(int new_pnum) ****************************************************************************/ void init_rpc_pipe_hnd(void) { - int i; - /* we start at 1 here for an obscure reason I can't now remember, - but I think is important :-) */ - for (i = 1; i < MAX_OPEN_PIPES; i++) - { - Pipes[i].open = False; - Pipes[i].name[0] = 0; - Pipes[i].pipe_srv_name[0] = 0; - - Pipes[i].rhdr.data = NULL; - Pipes[i].rdata.data = NULL; - Pipes[i].rhdr.offset = 0; - Pipes[i].rdata.offset = 0; - - Pipes[i].file_offset = 0; - Pipes[i].hdr_offsets = 0; - Pipes[i].frag_len_left = 0; - Pipes[i].next_frag_start = 0; + bmap = bitmap_allocate(MAX_OPEN_PIPES); + if (!bmap) { + exit_server("out of memory in init_rpc_pipe_hnd\n"); } - - return; } + /**************************************************************************** find first available file slot ****************************************************************************/ -int open_rpc_pipe_hnd(char *pipe_name, connection_struct *conn, uint16 vuid) +pipes_struct *open_rpc_pipe_p(char *pipe_name, + connection_struct *conn, uint16 vuid) { int i; - /* we start at 1 here for an obscure reason I can't now remember, - but I think is important :-) */ - for (i = 1; i < MAX_OPEN_PIPES; i++) { - if (!Pipes[i].open) break; + pipes_struct *p; + static int next_pipe; + + /* not repeating pipe numbers makes it easier to track things in + log files and prevents client bugs where pipe numbers are reused + over connection restarts */ + if (next_pipe == 0) { + next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES; } - if (i == MAX_OPEN_PIPES) { - DEBUG(1,("ERROR! Out of pipe structures\n")); - return(-1); + i = bitmap_find(bmap, next_pipe); + + if (i == -1) { + DEBUG(0,("ERROR! Out of pipe structures\n")); + return NULL; + } + + next_pipe = (i+1) % MAX_OPEN_PIPES; + + p = (pipes_struct *)malloc(sizeof(*p)); + if (!p) return NULL; + + /* hook into the front of the list */ + if (!Pipes) { + Pipes = p; + } else { + Pipes->prev = p; + p->next = Pipes; + Pipes = p; } - Pipes[i].open = True; - Pipes[i].device_state = 0; - Pipes[i].conn = conn; - Pipes[i].uid = vuid; + bitmap_set(bmap, i); + i += PIPE_HANDLE_OFFSET; + + pipes_open++; + + memset(p, 0, sizeof(*p)); + p->pnum = i; + + p->open = True; + p->device_state = 0; + p->conn = conn; + p->uid = vuid; - Pipes[i].rhdr.data = NULL; - Pipes[i].rdata.data = NULL; - Pipes[i].rhdr.offset = 0; - Pipes[i].rdata.offset = 0; + p->rhdr.data = NULL; + p->rdata.data = NULL; + p->rhdr.offset = 0; + p->rdata.offset = 0; - Pipes[i].file_offset = 0; - Pipes[i].hdr_offsets = 0; - Pipes[i].frag_len_left = 0; - Pipes[i].next_frag_start = 0; + p->file_offset = 0; + p->hdr_offsets = 0; + p->frag_len_left = 0; + p->next_frag_start = 0; - fstrcpy(Pipes[i].name, pipe_name); + fstrcpy(p->name, pipe_name); - DEBUG(4,("Opened pipe %s with handle %x\n", - pipe_name, i + PIPE_HANDLE_OFFSET)); + DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n", + pipe_name, i, pipes_open)); - set_chain_pnum(i); + set_chain_p(p); - return(i); + return p; } + /**************************************************************************** reads data from a pipe. @@ -141,157 +153,111 @@ int open_rpc_pipe_hnd(char *pipe_name, connection_struct *conn, uint16 vuid) have been prepared into arrays of headers + data stream sections. ****************************************************************************/ -int read_pipe(uint16 pnum, char *data, uint32 pos, int n) +int read_pipe(pipes_struct *p, char *data, uint32 pos, int n) { - 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 open: %s pos: %d len: %d", - p->name, - BOOLSTR(p->open), - pos, n)); + int num = 0; + int len = 0; + uint32 hdr_num = 0; + int data_hdr_pos; + int data_pos; + + DEBUG(6,("read_pipe: %x", p->pnum)); + + DEBUG(6,("name: %s open: %s pos: %d len: %d", + p->name, + BOOLSTR(p->open), + pos, n)); + + if (!p || !p->open) { + DEBUG(6,("pipe not open\n")); + return -1; } - if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET)) - { - int num = 0; - int len = 0; - uint32 hdr_num = 0; - int data_hdr_pos; - int data_pos; - - DEBUG(6,("OK\n")); - - if (p->rhdr.data == NULL || p->rhdr.data->data == NULL || - p->rhdr.data->data_used == 0) - { - return 0; - } - - 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->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)) - { - /* 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 (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; - - /* create and copy in a new header. */ - create_rpc_reply(p, data_pos, p->rdata.offset); - 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; - - /*DEBUG(6,("read_pipe: hdr_offsets: %d\n", p->hdr_offsets));*/ - } - } - - if (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")); + if (p->rhdr.data == NULL || p->rhdr.data->data == NULL || + p->rhdr.data->data_used == 0) { + return 0; + } - /* 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")); - } + 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)); - p->file_offset += num; + /* the read request starts from where the SMBtrans2 left off. */ + data_pos = p->file_offset - p->hdr_offsets; + data_hdr_pos = p->file_offset; - return num; + 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)) { + /* 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 (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; + + /* create and copy in a new header. */ + create_rpc_reply(p, data_pos, p->rdata.offset); + 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; + } + } - else - { - DEBUG(6,("NOT\n")); - return -1; + + if (num < hdr_num) { + DEBUG(5,("read_pipe: warning - data read only part of a header\n")); } -} - -/**************************************************************************** - gets the name of a pipe -****************************************************************************/ -BOOL get_rpc_pipe(int pnum, pipes_struct **p) -{ - DEBUG(6,("get_rpc_pipe: ")); - /* mapping is PIPE_HANDLE_OFFSET up... */ + 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")); - if (VALID_PNUM(pnum - PIPE_HANDLE_OFFSET)) - { - DEBUG(6,("name: %s open: %s ", - Pipes[pnum - PIPE_HANDLE_OFFSET].name, - BOOLSTR(Pipes[pnum - PIPE_HANDLE_OFFSET].open))); - } - if (OPEN_PNUM(pnum - PIPE_HANDLE_OFFSET)) - { - DEBUG(6,("OK\n")); - (*p) = &(Pipes[pnum - PIPE_HANDLE_OFFSET]); - return True; - } - else - { - DEBUG(6,("NOT\n")); - return False; + /* 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")); } + + p->file_offset += num; + + return num; } + /**************************************************************************** gets the name of a pipe ****************************************************************************/ -char *get_rpc_pipe_hnd_name(int pnum) +char *get_rpc_pipe_hnd_name(pipes_struct *p) { - pipes_struct *p = NULL; - get_rpc_pipe(pnum, &p); - return p != NULL ? p->name : NULL; + return p?p->name:NULL; } + /**************************************************************************** set device state on a pipe. exactly what this is for is unknown... ****************************************************************************/ @@ -299,57 +265,79 @@ BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state) { if (p == NULL) return False; - if (P_OPEN(p)) - { + if (p->open) { DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n", timestring(), device_state, p->name)); p->device_state = device_state; - + return True; - } - else - { - DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n", - timestring(), device_state, p->name)); - return False; - } + } + + DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n", + timestring(), device_state, p->name)); + return False; } + /**************************************************************************** close an rpc pipe ****************************************************************************/ -BOOL close_rpc_pipe_hnd(int pnum, connection_struct *conn) +BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn) { - pipes_struct *p = NULL; - get_rpc_pipe(pnum, &p); - /* mapping is PIPE_HANDLE_OFFSET up... */ - - if (p != NULL && P_OK(p, conn)) { - DEBUG(3,("%s Closed pipe name %s pnum=%x\n", - timestring(),Pipes[pnum-PIPE_HANDLE_OFFSET].name, - pnum)); - - p->open = False; - - p->rdata.offset = 0; - p->rhdr.offset = 0; - mem_buf_free(&(p->rdata.data)); - mem_buf_free(&(p->rhdr .data)); - - return True; - } else { - DEBUG(3,("%s Error closing pipe pnum=%x\n", - timestring(),pnum)); + if (!p) { + DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n")); return False; } + + mem_buf_free(&(p->rdata.data)); + mem_buf_free(&(p->rhdr .data)); + + bitmap_clear(bmap, p->pnum - PIPE_HANDLE_OFFSET); + + pipes_open--; + + DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n", + p->name, p->pnum, pipes_open)); + + if (p == Pipes) { + Pipes = p->next; + if (Pipes) Pipes->prev = NULL; + } else { + p->prev->next = p->next; + if (p->next) p->next->prev = p->prev; + } + + memset(p, 0, sizeof(*p)); + + free(p); + + return True; } /**************************************************************************** close an rpc pipe ****************************************************************************/ -int get_rpc_pipe_num(char *buf, int where) +pipes_struct *get_rpc_pipe_p(char *buf, int where) { - return (chain_pnum != -1 ? chain_pnum : SVAL(buf,where)); + int pnum = SVAL(buf,where); + + if (chain_p) return chain_p; + + return get_rpc_pipe(pnum); +} + +/**************************************************************************** + close an rpc pipe +****************************************************************************/ +pipes_struct *get_rpc_pipe(int pnum) +{ + pipes_struct *p; + + for (p=Pipes;p;p=p->next) { + if (p->pnum == pnum) return p; + } + + return NULL; } |