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,
8 * Copyright (C) Jeremy Allison 1999.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 #define PIPE "\\PIPE\\"
30 #define PIPELEN strlen(PIPE)
32 extern int DEBUGLEVEL;
33 static pipes_struct *chain_p;
34 static int pipes_open;
36 #ifndef MAX_OPEN_PIPES
37 #define MAX_OPEN_PIPES 64
40 static pipes_struct *Pipes;
41 static struct bitmap *bmap;
43 /* this must be larger than the sum of the open files and directories */
44 static int pipe_handle_offset;
46 /****************************************************************************
47 Set the pipe_handle_offset. Called from smbd/files.c
48 ****************************************************************************/
50 void set_pipe_handle_offset(int max_open_files)
52 if(max_open_files < 0x7000)
53 pipe_handle_offset = 0x7000;
55 pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
58 /****************************************************************************
59 Reset pipe chain handle number.
60 ****************************************************************************/
61 void reset_chain_p(void)
66 /****************************************************************************
67 Initialise pipe handle states.
68 ****************************************************************************/
70 void init_rpc_pipe_hnd(void)
72 bmap = bitmap_allocate(MAX_OPEN_PIPES);
74 exit_server("out of memory in init_rpc_pipe_hnd\n");
77 /****************************************************************************
78 Initialise an outgoing packet.
79 ****************************************************************************/
81 BOOL pipe_init_outgoing_data( pipes_struct *p)
84 memset(p->current_pdu, '\0', sizeof(p->current_pdu));
86 /* Free any memory in the current return data buffer. */
87 prs_mem_free(&p->rdata);
90 * Initialize the outgoing RPC data buffer.
91 * we will use this as the raw data area for replying to rpc requests.
93 if(!prs_init(&p->rdata, 1024, 4, MARSHALL)) {
94 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
98 /* Reset the offset counters. */
99 p->data_sent_length = 0;
100 p->current_pdu_len = 0;
101 p->current_pdu_sent = 0;
106 /****************************************************************************
107 Find first available pipe slot.
108 ****************************************************************************/
110 pipes_struct *open_rpc_pipe_p(char *pipe_name,
111 connection_struct *conn, uint16 vuid)
115 static int next_pipe;
116 struct msrpc_state *m = NULL;
117 user_struct *vuser = get_valid_user_struct(vuid);
118 struct user_creds usr;
122 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
123 pipe_name, pipes_open));
127 DEBUG(4,("invalid vuid %d\n", vuid));
131 /* set up unix credentials from the smb side, to feed over the pipe */
132 make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
133 vuser->real_name, vuser->guest);
135 make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
136 vuser->n_groups, vuser->groups);
139 /* set up nt credentials from the smb side, to feed over the pipe */
141 make_creds_nt(&usr.ntc);
142 make_creds_nt_sec(&usr.nts);
145 become_root(False); /* to connect to pipe */
146 m = msrpc_use_add(pipe_name, &usr, False);
147 unbecome_root(False);
151 DEBUG(10,("open pipes: msrpc redirect failed - go local.\n"));
154 /* not repeating pipe numbers makes it easier to track things in
155 log files and prevents client bugs where pipe numbers are reused
156 over connection restarts */
158 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
160 i = bitmap_find(bmap, next_pipe);
163 DEBUG(0,("ERROR! Out of pipe structures\n"));
167 next_pipe = (i+1) % MAX_OPEN_PIPES;
169 for (p = Pipes; p; p = p->next)
170 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
172 p = (pipes_struct *)malloc(sizeof(*p));
179 * Initialize the RPC and PDU data buffers with no memory.
181 prs_init(&p->rdata, 0, 4, MARSHALL);
186 i += pipe_handle_offset;
200 p->max_trans_reply = 0;
202 p->ntlmssp_chal_flags = 0;
203 p->ntlmssp_auth_validated = False;
204 p->ntlmssp_auth_requested = False;
206 p->current_pdu_len = 0;
207 p->current_pdu_sent = 0;
208 p->data_sent_length = 0;
213 fstrcpy(p->name, pipe_name);
215 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
216 pipe_name, i, pipes_open));
220 /* OVERWRITE p as a temp variable, to display all open pipes */
221 for (p = Pipes; p; p = p->next)
222 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
228 /****************************************************************************
229 Accepts incoming data on an rpc pipe.
231 This code is probably incorrect at the moment. The problem is
232 that the rpc request shouldn't really be executed until all the
233 data needed for it is received. This currently assumes that each
234 SMBwrite or SMBwriteX contains all the data needed for an rpc
236 ****************************************************************************/
238 ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
240 DEBUG(6,("write_to_pipe: %x", p->pnum));
242 DEBUG(6,("name: %s open: %s len: %d",
243 p->name, BOOLSTR(p->open), (int)n));
245 dump_data(50, data, n);
247 return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
251 /****************************************************************************
252 Replyies to a request to read data from a pipe.
254 Headers are interspersed with the data at PDU intervals. By the time
255 this function is called, the start of the data could possibly have been
256 read by an SMBtrans (file_offset != 0).
258 Calling create_rpc_reply() here is a hack. The data should already
259 have been prepared into arrays of headers + data stream sections.
261 ****************************************************************************/
263 int read_from_pipe(pipes_struct *p, char *data, int n)
265 uint32 pdu_remaining = 0;
266 int data_returned = 0;
268 if (!p || !p->open) {
269 DEBUG(0,("read_from_pipe: pipe not open\n"));
273 DEBUG(6,("read_from_pipe: %x", p->pnum));
275 DEBUG(6,("name: %s len: %d\n", p->name, n));
278 * We cannot return more than one PDU length per
282 if(n > MAX_PDU_FRAG_LEN) {
283 DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
284 only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
289 * Determine if there is still data to send in the
290 * pipe PDU buffer. Always send this first. Never
291 * send more than is left in the current PDU. The
292 * client should send a new read request for a new
296 if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) {
297 data_returned = MIN(n, pdu_remaining);
299 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
300 returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len,
301 (unsigned int)p->current_pdu_sent, (int)data_returned));
303 memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned);
304 p->current_pdu_sent += (uint32)data_returned;
305 return data_returned;
309 * At this point p->current_pdu_len == p->current_pdu_sent (which
310 * may of course be zero if this is the first return fragment.
313 DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n",
314 p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) ));
316 if(p->data_sent_length >= prs_offset(&p->rdata)) {
318 * We have sent all possible data. Return 0.
324 * We need to create a new PDU from the data left in p->rdata.
325 * Create the header/data/footers. This also sets up the fields
326 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
327 * and stores the outgoing PDU in p->current_pdu.
330 if(!create_next_pdu(p)) {
331 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
336 data_returned = MIN(n, p->current_pdu_len);
338 memcpy( data, p->current_pdu, (size_t)data_returned);
339 p->current_pdu_sent += (uint32)data_returned;
340 return data_returned;
343 /****************************************************************************
344 Wait device state on a pipe. Exactly what this is for is unknown...
345 ****************************************************************************/
347 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
353 DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
356 p->priority = priority;
361 DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
367 /****************************************************************************
368 Set device state on a pipe. Exactly what this is for is unknown...
369 ****************************************************************************/
371 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
377 DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
378 device_state, p->name));
380 p->device_state = device_state;
385 DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
386 device_state, p->name));
391 /****************************************************************************
393 ****************************************************************************/
395 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
398 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
402 prs_mem_free(&p->rdata);
404 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
408 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
409 p->name, p->pnum, pipes_open));
413 DEBUG(4,("closed msrpc redirect: "));
414 if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
420 DEBUG(4,("FAILED\n"));
424 DLIST_REMOVE(Pipes, p);
433 /****************************************************************************
434 Find an rpc pipe given a pipe handle in a buffer and an offset.
435 ****************************************************************************/
437 pipes_struct *get_rpc_pipe_p(char *buf, int where)
439 int pnum = SVAL(buf,where);
444 return get_rpc_pipe(pnum);
447 /****************************************************************************
448 Find an rpc pipe given a pipe handle.
449 ****************************************************************************/
451 pipes_struct *get_rpc_pipe(int pnum)
455 DEBUG(4,("search for pipe pnum=%x\n", pnum));
457 for (p=Pipes;p;p=p->next)
458 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
459 p->name, p->pnum, pipes_open));
461 for (p=Pipes;p;p=p->next) {
462 if (p->pnum == pnum) {