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;
130 p->rdata.data = NULL;
136 p->frag_len_left = 0;
137 p->next_frag_start = 0;
139 fstrcpy(p->name, pipe_name);
141 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
142 pipe_name, i, pipes_open));
146 /* OVERWRITE p as a temp variable, to display all open pipes */
147 for (p = Pipes; p; p = p->next)
149 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
156 /****************************************************************************
157 writes data to a pipe.
159 SERIOUSLY ALPHA CODE!
160 ****************************************************************************/
161 int write_pipe(pipes_struct *p, char *data, int n)
164 struct mem_buf data_buf;
166 DEBUG(6,("write_pipe: %x", p->pnum));
168 DEBUG(6,("name: %s open: %s len: %d",
169 p->name, BOOLSTR(p->open), n));
171 dump_data(50, data, n);
173 /* fake up a data buffer from the write_pipe data parameters */
174 mem_create(&data_buf, data, n, 0, False);
175 data_buf.offset.start = 0;
176 data_buf.offset.end = n;
178 /* fake up a parsing structure */
184 return rpc_command(p, &pd) ? n : -1;
188 /****************************************************************************
189 reads data from a pipe.
191 headers are interspersed with the data at regular intervals. by the time
192 this function is called, the start of the data could possibly have been
193 read by an SMBtrans (file_offset != 0).
195 calling create_rpc_request() here is a fudge. the data should already
196 have been prepared into arrays of headers + data stream sections.
198 ****************************************************************************/
199 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
207 DEBUG(6,("read_pipe: %x", p->pnum));
209 DEBUG(6,("name: %s open: %s pos: %d len: %d",
216 DEBUG(6,("pipe not open\n"));
221 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
222 p->rhdr.data->data_used == 0)
227 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
228 p, p->file_offset, n));
229 DEBUG(6,("read_pipe: frag_len_left: %d next_frag_start: %d\n",
230 p->frag_len_left, p->next_frag_start));
232 /* the read request starts from where the SMBtrans2 left off. */
233 data_pos = p->file_offset - p->hdr_offsets;
234 data_hdr_pos = p->file_offset;
236 len = mem_buf_len(p->rhdr.data);
237 num = len - (int)data_pos;
239 DEBUG(6,("read_pipe: len: %d num: %d n: %d\n", len, num, n));
241 if (num > n) num = n;
244 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
248 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
250 /* intermediate fragment - possibility of another header */
252 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d data_hdr_pos: %d\n",
253 p->hdr.frag_len, data_pos, data_hdr_pos));
255 if (data_hdr_pos == p->next_frag_start)
257 DEBUG(6,("read_pipe: next fragment header\n"));
259 /* this is subtracted from the total data bytes, later */
262 /* create and copy in a new header. */
263 create_rpc_reply(p, data_pos, p->rdata.offset);
264 mem_buf_copy(data, p->rhdr.data, 0, 0x18);
267 p->frag_len_left = p->hdr.frag_len;
268 p->next_frag_start += p->hdr.frag_len;
269 p->hdr_offsets += 0x18;
275 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
278 DEBUG(6,("read_pipe: adjusted data_pos: %d num-hdr_num: %d\n",
279 data_pos, num - hdr_num));
280 mem_buf_copy(data, p->rhdr.data, data_pos, num - hdr_num);
285 if (hdr_num == 0x18 && num == 0x18)
287 DEBUG(6,("read_pipe: just header read\n"));
289 /* advance to the next fragment */
290 p->frag_len_left -= 0x18;
292 else if (data_hdr_pos == p->next_frag_start)
294 DEBUG(6,("read_pipe: next fragment expected\n"));
297 p->file_offset += num;
303 /****************************************************************************
304 set device state on a pipe. exactly what this is for is unknown...
305 ****************************************************************************/
306 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
308 if (p == NULL) return False;
311 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
312 timestring(), device_state, p->name));
314 p->device_state = device_state;
319 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
320 timestring(), device_state, p->name));
325 /****************************************************************************
327 ****************************************************************************/
328 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
331 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
335 mem_buf_free(&(p->rdata.data));
336 mem_buf_free(&(p->rhdr .data));
338 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
342 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
343 p->name, p->pnum, pipes_open));
345 DLIST_REMOVE(Pipes, p);
354 /****************************************************************************
356 ****************************************************************************/
357 pipes_struct *get_rpc_pipe_p(char *buf, int where)
359 int pnum = SVAL(buf,where);
361 if (chain_p) return chain_p;
363 return get_rpc_pipe(pnum);
366 /****************************************************************************
368 ****************************************************************************/
369 pipes_struct *get_rpc_pipe(int pnum)
373 DEBUG(4,("search for pipe pnum=%x\n", pnum));
375 for (p=Pipes;p;p=p->next)
377 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
378 p->name, p->pnum, pipes_open));
381 for (p=Pipes;p;p=p->next)