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 */
188 return rpc_command(p, &pd) ? ((ssize_t)n) : -1;
192 /****************************************************************************
193 reads data from a pipe.
195 headers are interspersed with the data at regular intervals. by the time
196 this function is called, the start of the data could possibly have been
197 read by an SMBtrans (file_offset != 0).
199 calling create_rpc_reply() here is a fudge. the data should already
200 have been prepared into arrays of headers + data stream sections.
202 ****************************************************************************/
203 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
208 int pdu_data_sent; /* amount of current pdu already sent */
209 int data_pos; /* entire rpc data sent - no headers, no auth verifiers */
210 int this_pdu_data_pos;
212 DEBUG(6,("read_pipe: %x name: %s open: %s pos: %d len: %d",
213 p->pnum, p->name, BOOLSTR(p->open),
218 DEBUG(6,("pipe not open\n"));
223 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
224 p->rhdr.data->data_used == 0)
229 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
230 p, p->file_offset, n));
232 /* the read request starts from where the SMBtrans2 left off. */
233 data_pos = p->file_offset - p->hdr_offsets;
234 pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
235 this_pdu_data_pos = (pdu_data_sent == 0) ? 0 : (pdu_data_sent - 0x18);
237 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
239 /* intermediate fragment - possibility of another header */
241 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
242 p->hdr.frag_len, data_pos, pdu_data_sent));
244 if (pdu_data_sent == 0)
246 DEBUG(6,("read_pipe: next fragment header\n"));
248 /* this is subtracted from the total data bytes, later */
250 p->hdr_offsets += 0x18;
253 /* create and copy in a new header. */
254 create_rpc_reply(p, data_pos, p->rdata.offset);
258 pdu_len = mem_buf_len(p->rhdr.data);
259 num = pdu_len - this_pdu_data_pos;
261 DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
263 if (num > n) num = n;
266 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
272 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
275 mem_buf_copy(data, p->rhdr.data, pdu_data_sent, num);
277 p->file_offset += num;
278 pdu_data_sent += num;
280 if (hdr_num == 0x18 && num == 0x18)
282 DEBUG(6,("read_pipe: just header read\n"));
285 if (pdu_data_sent == p->hdr.frag_len)
287 DEBUG(6,("read_pipe: next fragment expected\n"));
288 p->prev_pdu_file_offset = p->file_offset;
295 /****************************************************************************
296 wait device state on a pipe. exactly what this is for is unknown...
297 ****************************************************************************/
298 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
300 if (p == NULL) return False;
304 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
305 timestring(), priority, p->name));
307 p->priority = priority;
312 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
313 timestring(), priority, p->name));
318 /****************************************************************************
319 set device state on a pipe. exactly what this is for is unknown...
320 ****************************************************************************/
321 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
323 if (p == NULL) return False;
326 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
327 timestring(), device_state, p->name));
329 p->device_state = device_state;
334 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
335 timestring(), device_state, p->name));
340 /****************************************************************************
342 ****************************************************************************/
343 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
346 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
350 mem_buf_free(&(p->rdata.data));
351 mem_buf_free(&(p->rhdr .data));
353 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
357 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
358 p->name, p->pnum, pipes_open));
360 DLIST_REMOVE(Pipes, p);
369 /****************************************************************************
371 ****************************************************************************/
372 pipes_struct *get_rpc_pipe_p(char *buf, int where)
374 int pnum = SVAL(buf,where);
376 if (chain_p) return chain_p;
378 return get_rpc_pipe(pnum);
381 /****************************************************************************
383 ****************************************************************************/
384 pipes_struct *get_rpc_pipe(int pnum)
388 DEBUG(4,("search for pipe pnum=%x\n", pnum));
390 for (p=Pipes;p;p=p->next)
392 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
393 p->name, p->pnum, pipes_open));
396 for (p=Pipes;p;p=p->next)