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", p->pnum));
213 DEBUG(6,("name: %s open: %s pos: %d len: %d",
220 DEBUG(6,("pipe not open\n"));
225 if (p->rhdr.data == NULL || p->rhdr.data->data == NULL ||
226 p->rhdr.data->data_used == 0)
231 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
232 p, p->file_offset, n));
234 /* the read request starts from where the SMBtrans2 left off. */
235 data_pos = p->file_offset - p->hdr_offsets;
236 this_pdu_data_pos = data_pos - p->prev_pdu_file_offset;
237 pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
239 if (!IS_BITS_SET_ALL(p->hdr.flags, RPC_FLG_LAST))
241 /* intermediate fragment - possibility of another header */
243 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
244 p->hdr.frag_len, data_pos, pdu_data_sent));
246 if (pdu_data_sent == 0)
248 DEBUG(6,("read_pipe: next fragment header\n"));
250 /* this is subtracted from the total data bytes, later */
252 p->hdr_offsets += 0x18;
255 /* create and copy in a new header. */
256 create_rpc_reply(p, data_pos, p->rdata.offset);
260 pdu_len = mem_buf_len(p->rhdr.data);
261 num = pdu_len - (int)this_pdu_data_pos;
263 DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
265 if (num > n) num = n;
268 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
274 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
277 mem_buf_copy(data, p->rhdr.data, pdu_data_sent, num);
279 p->file_offset += num;
280 pdu_data_sent += num;
282 if (hdr_num == 0x18 && num == 0x18)
284 DEBUG(6,("read_pipe: just header read\n"));
287 if (pdu_data_sent == p->hdr.frag_len)
289 DEBUG(6,("read_pipe: next fragment expected\n"));
290 p->prev_pdu_file_offset = p->file_offset;
297 /****************************************************************************
298 wait device state on a pipe. exactly what this is for is unknown...
299 ****************************************************************************/
300 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
302 if (p == NULL) return False;
306 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
307 timestring(), priority, p->name));
309 p->priority = priority;
314 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
315 timestring(), priority, p->name));
320 /****************************************************************************
321 set device state on a pipe. exactly what this is for is unknown...
322 ****************************************************************************/
323 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
325 if (p == NULL) return False;
328 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
329 timestring(), device_state, p->name));
331 p->device_state = device_state;
336 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
337 timestring(), device_state, p->name));
342 /****************************************************************************
344 ****************************************************************************/
345 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
348 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
352 mem_buf_free(&(p->rdata.data));
353 mem_buf_free(&(p->rhdr .data));
355 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
359 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
360 p->name, p->pnum, pipes_open));
362 DLIST_REMOVE(Pipes, p);
371 /****************************************************************************
373 ****************************************************************************/
374 pipes_struct *get_rpc_pipe_p(char *buf, int where)
376 int pnum = SVAL(buf,where);
378 if (chain_p) return chain_p;
380 return get_rpc_pipe(pnum);
383 /****************************************************************************
385 ****************************************************************************/
386 pipes_struct *get_rpc_pipe(int pnum)
390 DEBUG(4,("search for pipe pnum=%x\n", pnum));
392 for (p=Pipes;p;p=p->next)
394 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
395 p->name, p->pnum, pipes_open));
398 for (p=Pipes;p;p=p->next)