3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1997,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1997,
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #define PIPE "\\PIPE\\"
29 #define PIPELEN strlen(PIPE)
31 /* this must be larger than the sum of the open files and directories */
32 #define PIPE_HANDLE_OFFSET 0x7000
34 extern int DEBUGLEVEL;
35 static pipes_struct *chain_p;
36 static int pipes_open;
38 #ifndef MAX_OPEN_PIPES
39 #define MAX_OPEN_PIPES 64
42 static pipes_struct *Pipes;
43 static struct bitmap *bmap;
45 /****************************************************************************
46 reset pipe chain handle number
47 ****************************************************************************/
48 void reset_chain_p(void)
53 /****************************************************************************
54 initialise pipe handle states...
55 ****************************************************************************/
56 void init_rpc_pipe_hnd(void)
58 bmap = bitmap_allocate(MAX_OPEN_PIPES);
60 exit_server("out of memory in init_rpc_pipe_hnd\n");
65 /****************************************************************************
66 find first available file slot
67 ****************************************************************************/
68 pipes_struct *open_rpc_pipe_p(char *pipe_name,
69 connection_struct *conn, uint16 vuid)
75 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
76 pipe_name, pipes_open));
78 /* not repeating pipe numbers makes it easier to track things in
79 log files and prevents client bugs where pipe numbers are reused
80 over connection restarts */
82 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
85 i = bitmap_find(bmap, next_pipe);
88 DEBUG(0,("ERROR! Out of pipe structures\n"));
92 next_pipe = (i+1) % MAX_OPEN_PIPES;
94 for (p = Pipes; p; p = p->next)
96 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
99 p = (pipes_struct *)malloc(sizeof(*p));
106 i += PIPE_HANDLE_OFFSET;
118 p->rdata.data = NULL;
124 p->frag_len_left = 0;
125 p->next_frag_start = 0;
127 fstrcpy(p->name, pipe_name);
129 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
130 pipe_name, i, pipes_open));
134 /* OVERWRITE p as a temp variable, to display all open pipes */
135 for (p = Pipes; p; p = p->next)
137 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
144 /****************************************************************************
145 reads data from a pipe.
147 headers are interspersed with the data at regular intervals. by the time
148 this function is called, the start of the data could possibly have been
149 read by an SMBtrans (file_offset != 0).
151 calling create_rpc_request() here is a fudge. the data should already
152 have been prepared into arrays of headers + data stream sections.
154 ****************************************************************************/
155 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
163 DEBUG(6,("read_pipe: %x", p->pnum));
165 DEBUG(6,("name: %s open: %s pos: %d len: %d",
170 if (!p || !p->open) {
171 DEBUG(6,("pipe not open\n"));
176 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
177 p->rhdr.data->data_used == 0) {
181 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
182 p, p->file_offset, n));
183 DEBUG(6,("read_pipe: frag_len_left: %d next_frag_start: %d\n",
184 p->frag_len_left, p->next_frag_start));
186 /* the read request starts from where the SMBtrans2 left off. */
187 data_pos = p->file_offset - p->hdr_offsets;
188 data_hdr_pos = p->file_offset;
190 len = mem_buf_len(p->rhdr.data);
191 num = len - (int)data_pos;
193 DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n));
195 if (num > n) num = n;
197 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
201 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST)) {
202 /* intermediate fragment - possibility of another header */
204 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n",
205 p->hdr.frag_len, data_pos, data_hdr_pos));
207 if (data_hdr_pos == p->next_frag_start) {
208 DEBUG(6,("read_pipe: next fragment header\n"));
210 /* this is subtracted from the total data bytes, later */
213 /* create and copy in a new header. */
214 create_rpc_reply(p, data_pos, p->rdata.offset);
215 mem_buf_copy(data, p->rhdr.data, 0, 0x18);
218 p->frag_len_left = p->hdr.frag_len;
219 p->next_frag_start += p->hdr.frag_len;
220 p->hdr_offsets += 0x18;
226 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
229 DEBUG(6,("read_pipe: adjusted data_pos: %d num-hdr_num: %d\n",
230 data_pos, num - hdr_num));
231 mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
236 if (hdr_num == 0x18 && num == 0x18) {
237 DEBUG(6,("read_pipe: just header read\n"));
239 /* advance to the next fragment */
240 p->frag_len_left -= 0x18;
241 } else if (data_hdr_pos == p->next_frag_start) {
242 DEBUG(6,("read_pipe: next fragment expected\n"));
245 p->file_offset += num;
251 /****************************************************************************
252 set device state on a pipe. exactly what this is for is unknown...
253 ****************************************************************************/
254 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
256 if (p == NULL) return False;
259 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
260 timestring(), device_state, p->name));
262 p->device_state = device_state;
267 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
268 timestring(), device_state, p->name));
273 /****************************************************************************
275 ****************************************************************************/
276 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
279 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
283 mem_buf_free(&(p->rdata.data));
284 mem_buf_free(&(p->rhdr .data));
286 bitmap_clear(bmap, p->pnum - PIPE_HANDLE_OFFSET);
290 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
291 p->name, p->pnum, pipes_open));
293 DLIST_REMOVE(Pipes, p);
302 /****************************************************************************
304 ****************************************************************************/
305 pipes_struct *get_rpc_pipe_p(char *buf, int where)
307 int pnum = SVAL(buf,where);
309 if (chain_p) return chain_p;
311 return get_rpc_pipe(pnum);
314 /****************************************************************************
316 ****************************************************************************/
317 pipes_struct *get_rpc_pipe(int pnum)
321 DEBUG(4,("search for pipe pnum=%x\n", pnum));
323 for (p=Pipes;p;p=p->next)
325 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
326 p->name, p->pnum, pipes_open));
329 for (p=Pipes;p;p=p->next)