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 extern int DEBUGLEVEL;
32 static pipes_struct *chain_p;
33 static int pipes_open;
35 #ifndef MAX_OPEN_PIPES
36 #define MAX_OPEN_PIPES 64
39 static pipes_struct *Pipes;
40 static struct bitmap *bmap;
42 /* this must be larger than the sum of the open files and directories */
43 static int pipe_handle_offset;
45 /****************************************************************************
46 Set the pipe_handle_offset. Called from smbd/files.c
47 ****************************************************************************/
49 void set_pipe_handle_offset(int max_open_files)
51 if(max_open_files < 0x7000)
52 pipe_handle_offset = 0x7000;
54 pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
57 /****************************************************************************
58 reset pipe chain handle number
59 ****************************************************************************/
60 void reset_chain_p(void)
65 /****************************************************************************
66 initialise pipe handle states...
67 ****************************************************************************/
68 void init_rpc_pipe_hnd(void)
70 bmap = bitmap_allocate(MAX_OPEN_PIPES);
72 exit_server("out of memory in init_rpc_pipe_hnd\n");
77 /****************************************************************************
78 find first available file slot
79 ****************************************************************************/
80 pipes_struct *open_rpc_pipe_p(char *pipe_name,
81 connection_struct *conn, uint16 vuid)
87 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
88 pipe_name, pipes_open));
90 /* not repeating pipe numbers makes it easier to track things in
91 log files and prevents client bugs where pipe numbers are reused
92 over connection restarts */
94 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
97 i = bitmap_find(bmap, next_pipe);
100 DEBUG(0,("ERROR! Out of pipe structures\n"));
104 next_pipe = (i+1) % MAX_OPEN_PIPES;
106 for (p = Pipes; p; p = p->next)
108 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
111 p = (pipes_struct *)malloc(sizeof(*p));
118 i += pipe_handle_offset;
131 p->rdata.data = NULL;
137 p->frag_len_left = 0;
138 p->next_frag_start = 0;
140 fstrcpy(p->name, pipe_name);
142 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
143 pipe_name, i, pipes_open));
147 /* OVERWRITE p as a temp variable, to display all open pipes */
148 for (p = Pipes; p; p = p->next)
150 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
157 /****************************************************************************
158 writes data to a pipe.
160 SERIOUSLY ALPHA CODE!
161 ****************************************************************************/
162 int write_pipe(pipes_struct *p, char *data, int n)
165 struct mem_buf data_buf;
167 DEBUG(6,("write_pipe: %x", p->pnum));
169 DEBUG(6,("name: %s open: %s len: %d",
170 p->name, BOOLSTR(p->open), n));
172 dump_data(50, data, n);
174 /* fake up a data buffer from the write_pipe data parameters */
175 mem_create(&data_buf, data, n, 0, False);
176 data_buf.offset.start = 0;
177 data_buf.offset.end = n;
179 /* fake up a parsing structure */
185 return rpc_command(p, &pd) ? n : -1;
189 /****************************************************************************
190 reads data from a pipe.
192 headers are interspersed with the data at regular intervals. by the time
193 this function is called, the start of the data could possibly have been
194 read by an SMBtrans (file_offset != 0).
196 calling create_rpc_request() here is a fudge. the data should already
197 have been prepared into arrays of headers + data stream sections.
199 ****************************************************************************/
200 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
208 DEBUG(6,("read_pipe: %x", p->pnum));
210 DEBUG(6,("name: %s open: %s pos: %d len: %d",
217 DEBUG(6,("pipe not open\n"));
222 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
223 p->rhdr.data->data_used == 0)
228 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
229 p, p->file_offset, n));
230 DEBUG(6,("read_pipe: frag_len_left: %d next_frag_start: %d\n",
231 p->frag_len_left, p->next_frag_start));
233 /* the read request starts from where the SMBtrans2 left off. */
234 data_pos = p->file_offset - p->hdr_offsets;
235 data_hdr_pos = p->file_offset;
237 len = mem_buf_len(p->rhdr.data);
238 num = len - (int)data_pos;
240 DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n));
242 if (num > n) num = n;
245 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
249 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
251 /* intermediate fragment - possibility of another header */
253 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n",
254 p->hdr.frag_len, data_pos, data_hdr_pos));
256 if (data_hdr_pos == p->next_frag_start)
258 DEBUG(6,("read_pipe: next fragment header\n"));
260 /* this is subtracted from the total data bytes, later */
263 /* create and copy in a new header. */
264 create_rpc_reply(p, data_pos, p->rdata.offset);
265 mem_buf_copy(data, p->rhdr.data, 0, 0x18);
268 p->frag_len_left = p->hdr.frag_len;
269 p->next_frag_start += p->hdr.frag_len;
270 p->hdr_offsets += 0x18;
276 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
279 DEBUG(6,("read_pipe: adjusted data_pos: %d num-hdr_num: %d\n",
280 data_pos, num - hdr_num));
281 mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
286 if (hdr_num == 0x18 && num == 0x18)
288 DEBUG(6,("read_pipe: just header read\n"));
290 /* advance to the next fragment */
291 p->frag_len_left -= 0x18;
293 else if (data_hdr_pos == p->next_frag_start)
295 DEBUG(6,("read_pipe: next fragment expected\n"));
298 p->file_offset += num;
304 /****************************************************************************
305 wait device state on a pipe. exactly what this is for is unknown...
306 ****************************************************************************/
307 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
309 if (p == NULL) return False;
313 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
314 timestring(), priority, p->name));
316 p->priority = priority;
321 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
322 timestring(), priority, p->name));
327 /****************************************************************************
328 set device state on a pipe. exactly what this is for is unknown...
329 ****************************************************************************/
330 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
332 if (p == NULL) return False;
335 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
336 timestring(), device_state, p->name));
338 p->device_state = device_state;
343 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
344 timestring(), device_state, p->name));
349 /****************************************************************************
351 ****************************************************************************/
352 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
355 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
359 mem_buf_free(&(p->rdata.data));
360 mem_buf_free(&(p->rhdr .data));
362 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
366 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
367 p->name, p->pnum, pipes_open));
369 DLIST_REMOVE(Pipes, p);
378 /****************************************************************************
380 ****************************************************************************/
381 pipes_struct *get_rpc_pipe_p(char *buf, int where)
383 int pnum = SVAL(buf,where);
385 if (chain_p) return chain_p;
387 return get_rpc_pipe(pnum);
390 /****************************************************************************
392 ****************************************************************************/
393 pipes_struct *get_rpc_pipe(int pnum)
397 DEBUG(4,("search for pipe pnum=%x\n", pnum));
399 for (p=Pipes;p;p=p->next)
401 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
402 p->name, p->pnum, pipes_open));
405 for (p=Pipes;p;p=p->next)