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)
86 struct msrpc_state *m = NULL;
87 struct rpcsrv_struct *l = NULL;
88 user_struct *vuser = get_valid_user_struct(vuid);
89 struct user_creds usr;
93 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
94 pipe_name, pipes_open));
98 DEBUG(4,("invalid vuid %d\n", vuid));
102 /* set up unix credentials from the smb side, to feed over the pipe */
103 make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
104 vuser->real_name, vuser->guest);
106 make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
107 vuser->n_groups, vuser->groups);
110 /* set up nt credentials from the smb side, to feed over the pipe */
112 make_creds_nt(&usr.ntc);
113 make_creds_nt_sec(&usr.nts);
116 /* not repeating pipe numbers makes it easier to track things in
117 log files and prevents client bugs where pipe numbers are reused
118 over connection restarts */
121 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
124 i = bitmap_find(bmap, next_pipe);
127 DEBUG(0,("ERROR! Out of pipe structures\n"));
131 next_pipe = (i+1) % MAX_OPEN_PIPES;
133 for (p = Pipes; p; p = p->next)
135 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
138 if (strequal(pipe_name, "lsarpc"))
140 m = msrpc_use_add(pipe_name, &usr, False);
143 DEBUG(5,("open pipes: msrpc redirect failed\n"));
149 l = malloc(sizeof(*l));
152 DEBUG(5,("open pipes: local msrpc malloc failed\n"));
157 l->rdata.data = NULL;
161 l->ntlmssp_validated = False;
162 l->ntlmssp_auth = False;
164 memcpy(l->user_sess_key, vuser->user_sess_key,
165 sizeof(l->user_sess_key));
168 p = (pipes_struct *)malloc(sizeof(*p));
175 i += pipe_handle_offset;
190 p->prev_pdu_file_offset = 0;
193 fstrcpy(p->name, pipe_name);
195 prs_init(&p->smb_pdu, 0, 4, 0, True);
196 prs_init(&p->rsmb_pdu, 0, 4, 0, False);
198 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
199 pipe_name, i, pipes_open));
203 /* OVERWRITE p as a temp variable, to display all open pipes */
204 for (p = Pipes; p; p = p->next)
206 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
213 /****************************************************************************
214 writes data to a pipe.
216 SERIOUSLY ALPHA CODE!
217 ****************************************************************************/
218 ssize_t write_pipe(pipes_struct *p, char *data, size_t n)
220 DEBUG(6,("write_pipe: %x", p->pnum));
221 DEBUG(6,("name: %s open: %s len: %d",
222 p->name, BOOLSTR(p->open), n));
224 dump_data(50, data, n);
226 return rpc_to_smb(p, data, n) ? ((ssize_t)n) : -1;
230 /****************************************************************************
231 reads data from a pipe.
233 headers are interspersed with the data at regular intervals. by the time
234 this function is called, the start of the data could possibly have been
235 read by an SMBtrans (file_offset != 0).
237 calling create_rpc_reply() here is a fudge. the data should already
238 have been prepared into arrays of headers + data stream sections.
240 ****************************************************************************/
241 int read_pipe(pipes_struct *p, char *data, uint32 pos, int n)
246 int pdu_data_sent; /* amount of current pdu already sent */
247 int data_pos; /* entire rpc data sent - no headers, no auth verifiers */
248 int this_pdu_data_pos;
250 DEBUG(6,("read_pipe: %x name: %s open: %s pos: %d len: %d",
251 p->pnum, p->name, BOOLSTR(p->open),
256 DEBUG(6,("pipe not open\n"));
261 if (p->rsmb_pdu.data == NULL || p->rsmb_pdu.data->data == NULL ||
262 p->rsmb_pdu.data->data_used == 0)
267 DEBUG(6,("read_pipe: p: %p file_offset: %d file_pos: %d\n",
268 p, p->file_offset, n));
270 /* the read request starts from where the SMBtrans2 left off. */
271 data_pos = p->file_offset - p->hdr_offsets;
272 pdu_data_sent = p->file_offset - p->prev_pdu_file_offset;
273 this_pdu_data_pos = (pdu_data_sent == 0) ? 0 : (pdu_data_sent - 0x18);
275 if (!IS_BITS_SET_ALL(p->l->hdr.flags, RPC_FLG_LAST))
277 /* intermediate fragment - possibility of another header */
279 DEBUG(5,("read_pipe: frag_len: %d data_pos: %d pdu_data_sent: %d\n",
280 p->l->hdr.frag_len, data_pos, pdu_data_sent));
282 if (pdu_data_sent == 0)
284 DEBUG(6,("read_pipe: next fragment header\n"));
286 /* this is subtracted from the total data bytes, later */
288 p->hdr_offsets += 0x18;
291 /* create and copy in a new header. */
292 create_rpc_reply(p->l, data_pos);
296 pdu_len = mem_buf_len(p->rsmb_pdu.data);
297 num = pdu_len - this_pdu_data_pos;
299 DEBUG(6,("read_pipe: pdu_len: %d num: %d n: %d\n", pdu_len, num, n));
301 if (num > n) num = n;
304 DEBUG(5,("read_pipe: 0 or -ve data length\n"));
310 DEBUG(5,("read_pipe: warning - data read only part of a header\n"));
313 mem_buf_copy(data, p->rsmb_pdu.data, pdu_data_sent, num);
315 p->file_offset += num;
316 pdu_data_sent += num;
318 if (hdr_num == 0x18 && num == 0x18)
320 DEBUG(6,("read_pipe: just header read\n"));
323 if (pdu_data_sent == p->l->hdr.frag_len)
325 DEBUG(6,("read_pipe: next fragment expected\n"));
326 p->prev_pdu_file_offset = p->file_offset;
333 /****************************************************************************
334 wait device state on a pipe. exactly what this is for is unknown...
335 ****************************************************************************/
336 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
338 if (p == NULL) return False;
342 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
343 timestring(), priority, p->name));
345 p->priority = priority;
350 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
351 timestring(), priority, p->name));
356 /****************************************************************************
357 set device state on a pipe. exactly what this is for is unknown...
358 ****************************************************************************/
359 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
361 if (p == NULL) return False;
364 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
365 timestring(), device_state, p->name));
367 p->device_state = device_state;
372 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
373 timestring(), device_state, p->name));
378 /****************************************************************************
380 ****************************************************************************/
381 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
384 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
388 mem_buf_free(&(p->smb_pdu .data));
389 mem_buf_free(&(p->rsmb_pdu.data));
391 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
395 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
396 p->name, p->pnum, pipes_open));
398 DLIST_REMOVE(Pipes, p);
402 DEBUG(4,("closed msrpc redirect: "));
403 if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
409 DEBUG(4,("FAILED\n"));
415 DEBUG(4,("closed msrpc local: OK\n"));
417 mem_free_data(p->l->rdata .data);
418 rpcsrv_free_temp(p->l);
429 /****************************************************************************
431 ****************************************************************************/
432 pipes_struct *get_rpc_pipe_p(char *buf, int where)
434 int pnum = SVAL(buf,where);
436 if (chain_p) return chain_p;
438 return get_rpc_pipe(pnum);
441 /****************************************************************************
443 ****************************************************************************/
444 pipes_struct *get_rpc_pipe(int pnum)
448 DEBUG(4,("search for pipe pnum=%x\n", pnum));
450 for (p=Pipes;p;p=p->next)
452 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
453 p->name, p->pnum, pipes_open));
456 for (p=Pipes;p;p=p->next)