3 * Unix SMB/Netbios implementation.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1998,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
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;
136 p->prev_pdu_file_offset = 0;
139 p->ntlmssp_validated = False;
140 p->ntlmssp_auth = False;
142 fstrcpy(p->name, pipe_name);
144 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
145 pipe_name, i, pipes_open));
149 /* OVERWRITE p as a temp variable, to display all open pipes */
150 for (p = Pipes; p; p = p->next)
152 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
159 /****************************************************************************
160 writes data to a pipe.
162 SERIOUSLY ALPHA CODE!
163 ****************************************************************************/
164 ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
167 struct mem_buf data_buf;
169 DEBUG(6,("write_pipe: %x", p->pnum));
171 DEBUG(6,("name: %s open: %s len: %d",
172 p->name, BOOLSTR(p->open), n));
174 dump_data(50, data, n);
176 /* fake up a data buffer from the write_pipe data parameters */
177 mem_create(&data_buf, data, 0, n, 0, False);
178 data_buf.offset.start = 0;
179 data_buf.offset.end = n;
181 /* fake up a parsing structure */
187 return rpc_command(p, &pd) ? ((ssize_t)n) : -1;
191 /****************************************************************************
192 reads data from a pipe.
194 headers are interspersed with the data at regular intervals. by the time
195 this function is called, the start of the data could possibly have been
196 read by an SMBtrans (file_offset != 0).
198 calling create_rpc_reply() here is a fudge. the data should already
199 have been prepared into arrays of headers + data stream sections.
201 ****************************************************************************/
202 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
207 int pdu_data_sent; /* amount of current pdu already sent */
208 int data_pos; /* entire rpc data sent - no headers, no auth verifiers */
209 int this_pdu_data_pos;
211 DEBUG(6,("read_pipe: %x name: %s open: %s pos: %d len: %d",
212 p->pnum, p->name, BOOLSTR(p->open),
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));
231 /* the read request starts from where the SMBtrans2 left off. */
232 data_pos = p->file_offset - p->hdr_offsets;
233 pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
234 this_pdu_data_pos = (pdu_data_sent == 0) ? 0 : (pdu_data_sent - 0x18);
236 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
238 /* intermediate fragment - possibility of another header */
240 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
241 p->hdr.frag_len, data_pos, pdu_data_sent));
243 if (pdu_data_sent == 0)
245 DEBUG(6,("read_pipe: next fragment header\n"));
247 /* this is subtracted from the total data bytes, later */
249 p->hdr_offsets += 0x18;
252 /* create and copy in a new header. */
253 create_rpc_reply(p, data_pos, p->rdata.offset);
257 pdu_len = mem_buf_len(p->rhdr.data);
258 num = pdu_len - this_pdu_data_pos;
260 DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
262 if (num > n) num = n;
265 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
271 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
274 mem_buf_copy(data, p->rhdr.data, pdu_data_sent, num);
276 p->file_offset += num;
277 pdu_data_sent += num;
279 if (hdr_num == 0x18 && num == 0x18)
281 DEBUG(6,("read_pipe: just header read\n"));
284 if (pdu_data_sent == p->hdr.frag_len)
286 DEBUG(6,("read_pipe: next fragment expected\n"));
287 p->prev_pdu_file_offset = p->file_offset;
294 /****************************************************************************
295 wait device state on a pipe. exactly what this is for is unknown...
296 ****************************************************************************/
297 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
299 if (p == NULL) return False;
303 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
304 timestring(), priority, p->name));
306 p->priority = priority;
311 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
312 timestring(), priority, p->name));
317 /****************************************************************************
318 set device state on a pipe. exactly what this is for is unknown...
319 ****************************************************************************/
320 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
322 if (p == NULL) return False;
325 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
326 timestring(), device_state, p->name));
328 p->device_state = device_state;
333 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
334 timestring(), device_state, p->name));
339 /****************************************************************************
341 ****************************************************************************/
342 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
345 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
349 mem_buf_free(&(p->rdata.data));
350 mem_buf_free(&(p->rhdr .data));
352 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
356 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
357 p->name, p->pnum, pipes_open));
359 DLIST_REMOVE(Pipes, p);
368 /****************************************************************************
370 ****************************************************************************/
371 pipes_struct *get_rpc_pipe_p(char *buf, int where)
373 int pnum = SVAL(buf,where);
375 if (chain_p) return chain_p;
377 return get_rpc_pipe(pnum);
380 /****************************************************************************
382 ****************************************************************************/
383 pipes_struct *get_rpc_pipe(int pnum)
387 DEBUG(4,("search for pipe pnum=%x\n", pnum));
389 for (p=Pipes;p;p=p->next)
391 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
392 p->name, p->pnum, pipes_open));
395 for (p=Pipes;p;p=p->next)