diff options
-rw-r--r-- | source3/include/local.h | 3 | ||||
-rw-r--r-- | source3/include/ntdomain.h | 4 | ||||
-rw-r--r-- | source3/include/proto.h | 18 | ||||
-rw-r--r-- | source3/lib/bitmap.c | 16 | ||||
-rw-r--r-- | source3/rpc_server/srv_pipe_hnd.c | 432 | ||||
-rw-r--r-- | source3/script/mkproto.awk | 2 | ||||
-rw-r--r-- | source3/smbd/files.c | 19 | ||||
-rw-r--r-- | source3/smbd/ipc.c | 2 | ||||
-rw-r--r-- | source3/smbd/nttrans.c | 43 | ||||
-rw-r--r-- | source3/smbd/pipes.c | 182 | ||||
-rw-r--r-- | source3/smbd/server.c | 2 |
11 files changed, 350 insertions, 373 deletions
diff --git a/source3/include/local.h b/source3/include/local.h index af12f83551..1db1e9d4c1 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -45,9 +45,6 @@ one time. */ #define MAX_CONNECTIONS 127 -/* this must be larger than the sum of the open files and directories */ -#define PIPE_HANDLE_OFFSET 0x7000 - /* Default size of shared memory used for share mode locking */ #ifndef SHMEM_SIZE #define SHMEM_SIZE (1024*1024) diff --git a/source3/include/ntdomain.h b/source3/include/ntdomain.h index 0b2648372b..ac411fa653 100644 --- a/source3/include/ntdomain.h +++ b/source3/include/ntdomain.h @@ -53,8 +53,10 @@ typedef struct } prs_struct; -typedef struct +typedef struct pipes_struct { + struct pipes_struct *next, *prev; + int pnum; connection_struct *conn; int uid; BOOL open; /* open connection */ diff --git a/source3/include/proto.h b/source3/include/proto.h index e52ffdcd7a..cda824c7d0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -55,7 +55,6 @@ struct bitmap *bitmap_allocate(int n); void bitmap_free(struct bitmap *bm); BOOL bitmap_set(struct bitmap *bm, unsigned i); BOOL bitmap_clear(struct bitmap *bm, unsigned i); -BOOL bitmap_query(struct bitmap *bm, unsigned i); int bitmap_find(struct bitmap *bm, unsigned ofs); /*The following definitions come from lib/charcnv.c */ @@ -1857,16 +1856,17 @@ BOOL api_netlog_rpc(pipes_struct *p, prs_struct *data); /*The following definitions come from rpc_server/srv_pipe_hnd.c */ -void reset_chain_pnum(void); -void set_chain_pnum(int new_pnum); +void reset_chain_p(void); +void set_chain_p(pipes_struct *new_p); void init_rpc_pipe_hnd(void); -int open_rpc_pipe_hnd(char *pipe_name, connection_struct *conn, uint16 vuid); -int read_pipe(uint16 pnum, char *data, uint32 pos, int n); -BOOL get_rpc_pipe(int pnum, pipes_struct **p); -char *get_rpc_pipe_hnd_name(int pnum); +pipes_struct *open_rpc_pipe_p(char *pipe_name, + connection_struct *conn, uint16 vuid); +int read_pipe(pipes_struct *p, char *data, uint32 pos, int n); +char *get_rpc_pipe_hnd_name(pipes_struct *p); BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state); -BOOL close_rpc_pipe_hnd(int pnum, connection_struct *conn); -int get_rpc_pipe_num(char *buf, int where); +BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn); +pipes_struct *get_rpc_pipe_p(char *buf, int where); +pipes_struct *get_rpc_pipe(int pnum); /*The following definitions come from rpc_server/srv_reg.c */ diff --git a/source3/lib/bitmap.c b/source3/lib/bitmap.c index ab84a2a84e..ce677f7846 100644 --- a/source3/lib/bitmap.c +++ b/source3/lib/bitmap.c @@ -21,6 +21,8 @@ #include "includes.h" +extern int DEBUGLEVEL; + /* these functions provide a simple way to allocate integers from a pool without repitition */ @@ -64,7 +66,11 @@ set a bit in a bitmap ****************************************************************************/ BOOL bitmap_set(struct bitmap *bm, unsigned i) { - if (i >= bm->n) return False; + if (i >= bm->n) { + DEBUG(0,("Setting invalid bitmap entry %d (of %d)\n", + i, bm->n)); + return False; + } bm->b[i/32] |= (1<<(i%32)); return True; } @@ -74,7 +80,11 @@ clear a bit in a bitmap ****************************************************************************/ BOOL bitmap_clear(struct bitmap *bm, unsigned i) { - if (i >= bm->n) return False; + if (i >= bm->n) { + DEBUG(0,("clearing invalid bitmap entry %d (of %d)\n", + i, bm->n)); + return False; + } bm->b[i/32] &= ~(1<<(i%32)); return True; } @@ -82,7 +92,7 @@ BOOL bitmap_clear(struct bitmap *bm, unsigned i) /**************************************************************************** query a bit in a bitmap ****************************************************************************/ -BOOL bitmap_query(struct bitmap *bm, unsigned i) +static BOOL bitmap_query(struct bitmap *bm, unsigned i) { if (i >= bm->n) return False; if (bm->b[i/32] & (1<<(i%32))) { diff --git a/source3/rpc_server/srv_pipe_hnd.c b/source3/rpc_server/srv_pipe_hnd.c index bd29578f0e..dfc4eeba5f 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; } diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 0b963cbc80..b998de2dcc 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -80,7 +80,7 @@ END { next; } -!/^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ { +!/^pipes_struct|^file_fd_struct|^files_struct|^connection_struct|^uid_t|^gid_t|^unsigned|^mode_t|^DIR|^user|^int|^char|^uint|^struct|^BOOL|^void|^time|^smb_shm_offset_t|^shm_offset_t|^enum remote_arch_types|^FILE/ { next; } diff --git a/source3/smbd/files.c b/source3/smbd/files.c index 8f1cefbbb6..bc3ea880bf 100644 --- a/source3/smbd/files.c +++ b/source3/smbd/files.c @@ -28,6 +28,8 @@ extern int DEBUGLEVEL; #define VALID_FNUM(fnum) (((fnum) >= 0) && ((fnum) < MAX_FNUMS)) +#define FILE_HANDLE_OFFSET 0x1000 + static struct bitmap *file_bmap; static struct bitmap *fd_bmap; @@ -57,11 +59,6 @@ files_struct *file_new(void ) than causing corruption */ if (first_file == 0) { first_file = (getpid() ^ (int)time(NULL)) % MAX_FNUMS; - if (first_file == 0) first_file = 1; - } - - if (first_file >= MAX_FNUMS) { - first_file = 1; } i = bitmap_find(file_bmap, first_file); @@ -89,12 +86,14 @@ files_struct *file_new(void ) if (!fsp) return NULL; memset(fsp, 0, sizeof(*fsp)); - first_file = i+1; - fsp->fnum = i; - string_init(&fsp->fsp_name,""); + + first_file = (i+1) % MAX_FNUMS; bitmap_set(file_bmap, i); files_used++; + + fsp->fnum = i + FILE_HANDLE_OFFSET; + string_init(&fsp->fsp_name,""); /* hook into the front of the list */ if (!Files) { @@ -245,8 +244,6 @@ files_struct *file_fsp(int fnum) { files_struct *fsp; - if (!VALID_FNUM(fnum)) return NULL; - for (fsp=Files;fsp;fsp=fsp->next) { if (fsp->fnum == fnum) return fsp; } @@ -368,7 +365,7 @@ void file_free(files_struct *fsp) fd_ptr_free(fsp->fd_ptr); } - bitmap_clear(file_bmap, fsp->fnum); + bitmap_clear(file_bmap, fsp->fnum - FILE_HANDLE_OFFSET); files_used--; DEBUG(5,("freed files structure %d (%d used)\n", diff --git a/source3/smbd/ipc.c b/source3/smbd/ipc.c index be7fb8d8e3..1a6fb3366a 100644 --- a/source3/smbd/ipc.c +++ b/source3/smbd/ipc.c @@ -3398,7 +3398,7 @@ static int api_fd_reply(connection_struct *conn,uint16 vuid,char *outbuf, /* Get the file handle and hence the file name. */ pnum = setup[1]; subcommand = setup[0]; - get_rpc_pipe(pnum, &p); + p = get_rpc_pipe(pnum); if (p != NULL) { diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c index 9bfdddf704..31bfac25c8 100644 --- a/source3/smbd/nttrans.c +++ b/source3/smbd/nttrans.c @@ -364,32 +364,33 @@ static int map_share_mode( uint32 desired_access, uint32 share_access, uint32 fi static int nt_open_pipe(char *fname, connection_struct *conn, char *inbuf, char *outbuf, int *ppnum) { - int pnum = -1; - uint16 vuid = SVAL(inbuf, smb_uid); - int i; + pipes_struct *p = NULL; - DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); + uint16 vuid = SVAL(inbuf, smb_uid); + int i; + + DEBUG(4,("nt_open_pipe: Opening pipe %s.\n", fname)); - /* See if it is one we want to handle. */ - for( i = 0; known_nt_pipes[i]; i++ ) - if( strequal(fname,known_nt_pipes[i])) - break; + /* See if it is one we want to handle. */ + for( i = 0; known_nt_pipes[i]; i++ ) + if( strequal(fname,known_nt_pipes[i])) + break; - if ( known_nt_pipes[i] == NULL ) - return(ERROR(ERRSRV,ERRaccess)); + if ( known_nt_pipes[i] == NULL ) + return(ERROR(ERRSRV,ERRaccess)); - /* Strip \\ off the name. */ - fname++; + /* Strip \\ off the name. */ + fname++; - DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); + DEBUG(3,("nt_open_pipe: Known pipe %s opening.\n", fname)); - pnum = open_rpc_pipe_hnd(fname, conn, vuid); - if (pnum < 0) - return(ERROR(ERRSRV,ERRnofids)); + p = open_rpc_pipe_p(fname, conn, vuid); + if (!p) + return(ERROR(ERRSRV,ERRnofids)); - *ppnum = pnum + PIPE_HANDLE_OFFSET; /* Mark file handle up into high - range. */ - return 0; + *ppnum = p->pnum; + + return 0; } /**************************************************************************** @@ -1258,8 +1259,8 @@ static int call_nt_transact_ioctl(connection_struct *conn, int bufsize, char **ppsetup, char **ppparams, char **ppdata) { - DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n")); - return(ERROR(ERRSRV,ERRnosupport)); + DEBUG(0,("call_nt_transact_ioctl: Currently not implemented.\n")); + return(ERROR(ERRSRV,ERRnosupport)); } /**************************************************************************** diff --git a/source3/smbd/pipes.c b/source3/smbd/pipes.c index 9ec77c08ca..84e31894a3 100644 --- a/source3/smbd/pipes.c +++ b/source3/smbd/pipes.c @@ -32,22 +32,7 @@ #define PIPE "\\PIPE\\" #define PIPELEN strlen(PIPE) -#define REALLOC(ptr,size) Realloc(ptr,MAX((size),4*1024)) - -/* look in server.c for some explanation of these variables */ -extern int Protocol; extern int DEBUGLEVEL; -extern char magic_char; -extern BOOL case_sensitive; -extern pstring sesssetup_user; -extern int Client; - -#define VALID_PNUM(pnum) (((pnum) >= 0) && ((pnum) < MAX_OPEN_PIPES)) -#define OPEN_PNUM(pnum) (VALID_PNUM(pnum) && Pipes[pnum].open) - -/* this macro should always be used to extract an pnum (smb_fid) from - a packet to ensure chaining works correctly */ -#define GETPNUM(buf,where) (chain_pnum!= -1?chain_pnum:SVAL(buf,where)) extern struct pipe_id_info pipe_names[]; @@ -60,66 +45,63 @@ extern struct pipe_id_info pipe_names[]; int reply_open_pipe_and_X(connection_struct *conn, char *inbuf,char *outbuf,int length,int bufsize) { - pstring fname; - uint16 vuid = SVAL(inbuf, smb_uid); - int pnum = -1; - int smb_ofun = SVAL(inbuf,smb_vwv8); - int size=0,fmode=0,mtime=0,rmode=0; - int i; - - /* XXXX we need to handle passed times, sattr and flags */ - pstrcpy(fname,smb_buf(inbuf)); - - /* If the name doesn't start \PIPE\ then this is directed */ - /* at a mailslot or something we really, really don't understand, */ - /* not just something we really don't understand. */ - if ( strncmp(fname,PIPE,PIPELEN) != 0 ) - return(ERROR(ERRSRV,ERRaccess)); - - DEBUG(4,("Opening pipe %s.\n", fname)); - - /* See if it is one we want to handle. */ - for( i = 0; pipe_names[i].client_pipe ; i++ ) - if( strequal(fname,pipe_names[i].client_pipe) ) - break; - - if (pipe_names[i].client_pipe == NULL) - return(ERROR(ERRSRV,ERRaccess)); - - /* Strip \PIPE\ off the name. */ - pstrcpy(fname,smb_buf(inbuf) + PIPELEN); - - /* Known pipes arrive with DIR attribs. Remove it so a regular file */ - /* can be opened and add it in after the open. */ - DEBUG(3,("Known pipe %s opening.\n",fname)); - smb_ofun |= 0x10; /* Add Create it not exists flag */ - - pnum = open_rpc_pipe_hnd(fname, conn, vuid); - if (pnum < 0) return(ERROR(ERRSRV,ERRnofids)); - - /* Prepare the reply */ - set_message(outbuf,15,0,True); - - /* Mark the opened file as an existing named pipe in message mode. */ - SSVAL(outbuf,smb_vwv9,2); - SSVAL(outbuf,smb_vwv10,0xc700); - - if (rmode == 2) - { - DEBUG(4,("Resetting open result to open from create.\n")); - rmode = 1; - } - - SSVAL(outbuf,smb_vwv2, pnum + PIPE_HANDLE_OFFSET); /* mark file - handle up into - high range */ - SSVAL(outbuf,smb_vwv3,fmode); - put_dos_date3(outbuf,smb_vwv4,mtime); - SIVAL(outbuf,smb_vwv6,size); - SSVAL(outbuf,smb_vwv8,rmode); - SSVAL(outbuf,smb_vwv11,0); - - return chain_reply(inbuf,outbuf,length,bufsize); + pstring fname; + uint16 vuid = SVAL(inbuf, smb_uid); + pipes_struct *p; + int smb_ofun = SVAL(inbuf,smb_vwv8); + int size=0,fmode=0,mtime=0,rmode=0; + int i; + + /* XXXX we need to handle passed times, sattr and flags */ + pstrcpy(fname,smb_buf(inbuf)); + + /* If the name doesn't start \PIPE\ then this is directed */ + /* at a mailslot or something we really, really don't understand, */ + /* not just something we really don't understand. */ + if ( strncmp(fname,PIPE,PIPELEN) != 0 ) + return(ERROR(ERRSRV,ERRaccess)); + + DEBUG(4,("Opening pipe %s.\n", fname)); + + /* See if it is one we want to handle. */ + for( i = 0; pipe_names[i].client_pipe ; i++ ) + if( strequal(fname,pipe_names[i].client_pipe) ) + break; + + if (pipe_names[i].client_pipe == NULL) + return(ERROR(ERRSRV,ERRaccess)); + + /* Strip \PIPE\ off the name. */ + pstrcpy(fname,smb_buf(inbuf) + PIPELEN); + + /* Known pipes arrive with DIR attribs. Remove it so a regular file */ + /* can be opened and add it in after the open. */ + DEBUG(3,("Known pipe %s opening.\n",fname)); + smb_ofun |= 0x10; /* Add Create it not exists flag */ + + p = open_rpc_pipe_p(fname, conn, vuid); + if (!p) return(ERROR(ERRSRV,ERRnofids)); + + /* Prepare the reply */ + set_message(outbuf,15,0,True); + + /* Mark the opened file as an existing named pipe in message mode. */ + SSVAL(outbuf,smb_vwv9,2); + SSVAL(outbuf,smb_vwv10,0xc700); + + if (rmode == 2) { + DEBUG(4,("Resetting open result to open from create.\n")); + rmode = 1; + } + + SSVAL(outbuf,smb_vwv2, p->pnum); + SSVAL(outbuf,smb_vwv3,fmode); + put_dos_date3(outbuf,smb_vwv4,mtime); + SIVAL(outbuf,smb_vwv6,size); + SSVAL(outbuf,smb_vwv8,rmode); + SSVAL(outbuf,smb_vwv11,0); + + return chain_reply(inbuf,outbuf,length,bufsize); } @@ -131,47 +113,47 @@ int reply_open_pipe_and_X(connection_struct *conn, ****************************************************************************/ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize) { - int pnum = get_rpc_pipe_num(inbuf,smb_vwv2); - uint32 smb_offs = IVAL(inbuf,smb_vwv3); - int smb_maxcnt = SVAL(inbuf,smb_vwv5); - int smb_mincnt = SVAL(inbuf,smb_vwv6); - int nread = -1; - char *data; - BOOL ok = False; + pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv2); + uint32 smb_offs = IVAL(inbuf,smb_vwv3); + int smb_maxcnt = SVAL(inbuf,smb_vwv5); + int smb_mincnt = SVAL(inbuf,smb_vwv6); + int nread = -1; + char *data; + BOOL ok = False; - set_message(outbuf,12,0,True); - data = smb_buf(outbuf); + set_message(outbuf,12,0,True); + data = smb_buf(outbuf); - nread = read_pipe(pnum, data, smb_offs, smb_maxcnt); + nread = read_pipe(p, data, smb_offs, smb_maxcnt); - ok = True; + ok = True; - if (nread < 0) - return(UNIXERROR(ERRDOS,ERRnoaccess)); + if (nread < 0) + return(UNIXERROR(ERRDOS,ERRnoaccess)); - SSVAL(outbuf,smb_vwv5,nread); - SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); - SSVAL(smb_buf(outbuf),-2,nread); + SSVAL(outbuf,smb_vwv5,nread); + SSVAL(outbuf,smb_vwv6,smb_offset(data,outbuf)); + SSVAL(smb_buf(outbuf),-2,nread); - DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", - pnum, smb_mincnt, smb_maxcnt, nread)); + DEBUG(3,("readX pnum=%04x min=%d max=%d nread=%d\n", + p->pnum, smb_mincnt, smb_maxcnt, nread)); - set_chain_pnum(pnum); + set_chain_p(p); - return chain_reply(inbuf,outbuf,length,bufsize); + return chain_reply(inbuf,outbuf,length,bufsize); } /**************************************************************************** reply to a close ****************************************************************************/ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf) { - int pnum = get_rpc_pipe_num(inbuf,smb_vwv0); - int outsize = set_message(outbuf,0,0,True); + pipes_struct *p = get_rpc_pipe_p(inbuf,smb_vwv0); + int outsize = set_message(outbuf,0,0,True); - DEBUG(5,("reply_pipe_close: pnum:%x\n", pnum)); + DEBUG(5,("reply_pipe_close: pnum:%x\n", p->pnum)); - if (!close_rpc_pipe_hnd(pnum, conn)) return(ERROR(ERRDOS,ERRbadfid)); + if (!close_rpc_pipe_hnd(p, conn)) return(ERROR(ERRDOS,ERRbadfid)); - return(outsize); + return(outsize); } diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 1ae402b902..e6117000a4 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -4700,7 +4700,7 @@ int construct_reply(char *inbuf,char *outbuf,int size,int bufsize) chain_size = 0; chain_fsp = NULL; - reset_chain_pnum(); + reset_chain_p(); if (msg_type != 0) return(reply_special(inbuf,outbuf)); |