2 * Unix SMB/Netbios implementation.
4 * RPC Pipe client / server routines
5 * Copyright (C) Andrew Tridgell 1992-1998,
6 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
7 * Copyright (C) Jeremy Allison 1999.
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 ****************************************************************************/
69 void init_rpc_pipe_hnd(void)
71 bmap = bitmap_allocate(MAX_OPEN_PIPES);
73 exit_server("out of memory in init_rpc_pipe_hnd\n");
76 /****************************************************************************
77 Initialise an outgoing packet.
78 ****************************************************************************/
80 BOOL pipe_init_outgoing_data(output_data *o_data)
83 memset(o_data->current_pdu, '\0', sizeof(o_data->current_pdu));
85 /* Free any memory in the current return data buffer. */
86 prs_mem_free(&o_data->rdata);
89 * Initialize the outgoing RPC data buffer.
90 * we will use this as the raw data area for replying to rpc requests.
92 if(!prs_init(&o_data->rdata, MAX_PDU_FRAG_LEN, 4, MARSHALL)) {
93 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
97 /* Reset the offset counters. */
98 o_data->data_sent_length = 0;
99 o_data->current_pdu_len = 0;
100 o_data->current_pdu_sent = 0;
105 /****************************************************************************
106 HACK !!! Attempt to find a remote process to communicate RPC's with.
107 ****************************************************************************/
109 static void attempt_remote_rpc_connect(pipes_struct *p)
111 struct user_creds usr;
112 user_struct *vuser = get_valid_user_struct(p->vuid);
117 DEBUG(4,("attempt_remote_rpc_connect: invalid vuid %d\n", (int)p->vuid));
123 /* set up unix credentials from the smb side, to feed over the pipe */
124 make_creds_unix(&usr.uxc, vuser->name, vuser->requested_name,
125 vuser->real_name, vuser->guest);
127 make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
128 vuser->n_groups, vuser->groups);
132 DEBUG(10,("user session key not available (yet).\n"));
133 DEBUG(10,("password-change operations may fail.\n"));
135 #if USER_SESSION_KEY_DEFINED_IN_VUSER_STRUCT
136 memcpy(usr.usr_sess_key, vuser->usr_sess_key, sizeof(usr.usr_sess_key));
138 memset(usr.usr_sess_key, 0, sizeof(usr.usr_sess_key));
141 /* set up nt credentials from the smb side, to feed over the pipe */
143 make_creds_nt(&usr.ntc);
144 make_creds_nt_sec(&usr.nts);
147 become_root(False); /* to connect to pipe */
148 p->m = msrpc_use_add(p->name, getpid(), &usr, False);
149 unbecome_root(False);
152 DEBUG(10,("attempt_remote_rpc_connect: msrpc redirect failed - using local implementation.\n"));
155 /****************************************************************************
156 Find first available pipe slot.
157 ****************************************************************************/
159 pipes_struct *open_rpc_pipe_p(char *pipe_name,
160 connection_struct *conn, uint16 vuid)
164 static int next_pipe;
166 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
167 pipe_name, pipes_open));
170 /* not repeating pipe numbers makes it easier to track things in
171 log files and prevents client bugs where pipe numbers are reused
172 over connection restarts */
174 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
176 i = bitmap_find(bmap, next_pipe);
179 DEBUG(0,("ERROR! Out of pipe structures\n"));
183 next_pipe = (i+1) % MAX_OPEN_PIPES;
185 for (p = Pipes; p; p = p->next)
186 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
188 p = (pipes_struct *)malloc(sizeof(*p));
198 * Initialize the incoming RPC data buffer with one PDU worth of memory.
199 * We cheat here and say we're marshalling, as we intend to add incoming
200 * data directly into the prs_struct and we want it to auto grow. We will
201 * change the type to UNMARSALLING before processing the stream.
204 if(!prs_init(&p->in_data.data, MAX_PDU_FRAG_LEN, 4, MARSHALL)) {
205 DEBUG(0,("open_rpc_pipe_p: malloc fail for in_data struct.\n"));
210 i += pipe_handle_offset;
222 p->max_trans_reply = 0;
224 p->ntlmssp_chal_flags = 0;
225 p->ntlmssp_auth_validated = False;
226 p->ntlmssp_auth_requested = False;
228 p->pipe_bound = False;
229 p->fault_state = False;
232 * Initialize the incoming RPC struct.
235 p->in_data.pdu_needed_len = 0;
236 p->in_data.pdu_received_len = 0;
239 * Initialize the outgoing RPC struct.
242 p->out_data.current_pdu_len = 0;
243 p->out_data.current_pdu_sent = 0;
244 p->out_data.data_sent_length = 0;
247 * Initialize the outgoing RPC data buffer with no memory.
249 prs_init(&p->out_data.rdata, 0, 4, MARSHALL);
254 fstrcpy(p->name, pipe_name);
257 * HACK !!! For Luke - attempt to connect to RPC redirect process.
260 attempt_remote_rpc_connect(p);
262 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
263 pipe_name, i, pipes_open));
267 /* OVERWRITE p as a temp variable, to display all open pipes */
268 for (p = Pipes; p; p = p->next)
269 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));
274 /****************************************************************************
275 Sets the fault state on incoming packets.
276 ****************************************************************************/
278 static void set_incoming_fault(pipes_struct *p)
280 prs_mem_free(&p->in_data.data);
281 p->in_data.pdu_needed_len = 0;
282 p->in_data.pdu_received_len = 0;
283 p->fault_state = True;
284 DEBUG(10,("set_incoming_fault: Setting fault state on pipe %s : pnum = 0x%x\n",
288 /****************************************************************************
289 Ensures we have at least RPC_HEADER_LEN amount of data in the incoming buffer.
290 ****************************************************************************/
292 static ssize_t fill_rpc_header(pipes_struct *p, char *data, size_t data_to_copy)
294 size_t len_needed_to_complete_hdr = MIN(data_to_copy, RPC_HEADER_LEN - p->in_data.pdu_received_len);
296 DEBUG(10,("fill_rpc_header: data_to_copy = %u, len_needed_to_complete_hdr = %u, receive_len = %u\n",
297 (unsigned int)data_to_copy, (unsigned int)len_needed_to_complete_hdr,
298 (unsigned int)p->in_data.pdu_received_len ));
300 memcpy((char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, len_needed_to_complete_hdr);
301 p->in_data.pdu_received_len += len_needed_to_complete_hdr;
303 return (ssize_t)len_needed_to_complete_hdr;
306 /****************************************************************************
307 Unmarshalls a new PDU header. Assumes the raw header data is in current_in_pdu.
308 ****************************************************************************/
310 static ssize_t unmarshall_rpc_header(pipes_struct *p)
313 * Unmarshall the header to determine the needed length.
318 if(p->in_data.pdu_received_len != RPC_HEADER_LEN) {
319 DEBUG(0,("unmarshall_rpc_header: assert on rpc header length failed.\n"));
320 set_incoming_fault(p);
324 prs_init( &rpc_in, 0, 4, UNMARSHALL);
325 prs_give_memory( &rpc_in, (char *)&p->in_data.current_in_pdu[0],
326 p->in_data.pdu_received_len, False);
329 * Unmarshall the header as this will tell us how much
330 * data we need to read to get the complete pdu.
333 if(!smb_io_rpc_hdr("", &p->hdr, &rpc_in, 0)) {
334 DEBUG(0,("unmarshall_rpc_header: failed to unmarshall RPC_HDR.\n"));
335 set_incoming_fault(p);
340 * Validate the RPC header.
343 if(p->hdr.major != 5 && p->hdr.minor != 0) {
344 DEBUG(0,("unmarshall_rpc_header: invalid major/minor numbers in RPC_HDR.\n"));
345 set_incoming_fault(p);
350 * If there is no data in the incoming buffer and it's a requst pdu then
351 * ensure that the FIRST flag is set. If not then we have
352 * a stream missmatch.
355 if((p->hdr.pkt_type == RPC_REQUEST) && (prs_offset(&p->in_data.data) == 0) && !(p->hdr.flags & RPC_FLG_FIRST)) {
356 DEBUG(0,("unmarshall_rpc_header: FIRST flag not set in first PDU !\n"));
357 set_incoming_fault(p);
362 * Ensure that the pdu length is sane.
365 if((p->hdr.frag_len < RPC_HEADER_LEN) || (p->hdr.frag_len > MAX_PDU_FRAG_LEN)) {
366 DEBUG(0,("unmarshall_rpc_header: assert on frag length failed.\n"));
367 set_incoming_fault(p);
371 DEBUG(10,("unmarshall_rpc_header: type = %u, flags = %u\n", (unsigned int)p->hdr.pkt_type,
372 (unsigned int)p->hdr.flags ));
375 * Adjust for the header we just ate.
377 p->in_data.pdu_received_len = 0;
378 p->in_data.pdu_needed_len = (uint32)p->hdr.frag_len - RPC_HEADER_LEN;
381 * Null the data we just ate.
384 memset((char *)&p->in_data.current_in_pdu[0], '\0', RPC_HEADER_LEN);
386 return 0; /* No extra data processed. */
389 /****************************************************************************
390 Processes a request pdu. This will do auth processing if needed, and
391 appends the data into the complete stream if the LAST flag is not set.
392 ****************************************************************************/
394 static BOOL process_request_pdu(pipes_struct *p, prs_struct *rpc_in_p)
396 BOOL auth_verify = IS_BITS_SET_ALL(p->ntlmssp_chal_flags, NTLMSSP_NEGOTIATE_SIGN);
397 size_t data_len = p->hdr.frag_len - RPC_HEADER_LEN - RPC_HDR_REQ_LEN -
398 (auth_verify ? RPC_HDR_AUTH_LEN : 0) - p->hdr.auth_len;
401 DEBUG(0,("process_request_pdu: rpc request with no bind.\n"));
402 set_incoming_fault(p);
407 * Check if we need to do authentication processing.
408 * This is only done on requests, not binds.
412 * Read the RPC request header.
415 if(!smb_io_rpc_hdr_req("req", &p->hdr_req, rpc_in_p, 0)) {
416 DEBUG(0,("process_request_pdu: failed to unmarshall RPC_HDR_REQ.\n"));
417 set_incoming_fault(p);
421 if(p->ntlmssp_auth_validated && !api_pipe_auth_process(p, rpc_in_p)) {
422 DEBUG(0,("process_request_pdu: failed to do auth processing.\n"));
423 set_incoming_fault(p);
427 if (p->ntlmssp_auth_requested && !p->ntlmssp_auth_validated) {
430 * Authentication _was_ requested and it already failed.
433 DEBUG(0,("process_request_pdu: RPC request received on pipe %s where \
434 authentication failed. Denying the request.\n", p->name));
435 set_incoming_fault(p);
440 * Check the data length doesn't go over the 1Mb limit.
443 if(prs_data_size(&p->in_data.data) + data_len > 1024*1024) {
444 DEBUG(0,("process_request_pdu: rpc data buffer too large (%u) + (%u)\n",
445 (unsigned int)prs_data_size(&p->in_data.data), (unsigned int)data_len ));
446 set_incoming_fault(p);
451 * Append the data portion into the buffer and return.
455 char *data_from = prs_data_p(rpc_in_p) + prs_offset(rpc_in_p);
457 if(!prs_append_data(&p->in_data.data, data_from, data_len)) {
458 DEBUG(0,("process_request_pdu: Unable to append data size %u to parse buffer of size %u.\n",
459 (unsigned int)data_len, (unsigned int)prs_data_size(&p->in_data.data) ));
460 set_incoming_fault(p);
466 if(p->hdr.flags & RPC_FLG_LAST) {
469 * Ok - we finally have a complete RPC stream.
470 * Call the rpc command to process it.
474 * Set the parse offset to the start of the data and set the
475 * prs_struct to UNMARSHALL.
478 prs_set_offset(&p->in_data.data, 0);
479 prs_switch_type(&p->in_data.data, UNMARSHALL);
482 * Process the complete data stream here.
485 ret = api_pipe_request(p);
488 * We have consumed the whole data stream. Set back to
489 * marshalling and set the offset back to the start of
490 * the buffer to re-use it (we could also do a prs_mem_free()
491 * and then re_init on the next start of PDU. Not sure which
492 * is best here.... JRA.
495 prs_switch_type(&p->in_data.data, MARSHALL);
496 prs_set_offset(&p->in_data.data, 0);
503 /****************************************************************************
504 Processes a finished PDU stored in current_in_pdu. The RPC_HEADER has
505 already been parsed and stored in p->hdr.
506 ****************************************************************************/
508 static ssize_t process_complete_pdu(pipes_struct *p)
511 size_t data_len = p->in_data.pdu_received_len;
512 char *data_p = (char *)&p->in_data.current_in_pdu[0];
516 DEBUG(10,("process_complete_pdu: pipe %s in fault state.\n",
518 set_incoming_fault(p);
520 return (ssize_t)data_len;
523 prs_init( &rpc_in, 0, 4, UNMARSHALL);
524 prs_give_memory( &rpc_in, data_p, (uint32)data_len, False);
526 DEBUG(10,("process_complete_pdu: processing packet type %u\n",
527 (unsigned int)p->hdr.pkt_type ));
529 switch (p->hdr.pkt_type) {
533 * We assume that a pipe bind is only in one pdu.
535 reply = api_pipe_bind_req(p, &rpc_in);
539 * We assume that a pipe bind_resp is only in one pdu.
541 reply = api_pipe_bind_auth_resp(p, &rpc_in);
544 reply = process_request_pdu(p, &rpc_in);
547 DEBUG(0,("process_complete_pdu: Unknown rpc type = %u received.\n", (unsigned int)p->hdr.pkt_type ));
552 DEBUG(3,("process_complete_pdu: DCE/RPC fault sent on pipe %s\n", p->pipe_srv_name));
553 set_incoming_fault(p);
557 * Reset the lengths. We're ready for a new pdu.
559 p->in_data.pdu_needed_len = 0;
560 p->in_data.pdu_received_len = 0;
563 return (ssize_t)data_len;
566 /****************************************************************************
567 Accepts incoming data on an rpc pipe. Processes the data in pdu sized units.
568 ****************************************************************************/
570 static ssize_t process_incoming_data(pipes_struct *p, char *data, size_t n)
572 size_t data_to_copy = MIN(n, MAX_PDU_FRAG_LEN - p->in_data.pdu_received_len);
574 DEBUG(10,("process_incoming_data: Start: pdu_received_len = %u, pdu_needed_len = %u, incoming data = %u\n",
575 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len,
578 if(data_to_copy == 0) {
580 * This is an error - data is being received and there is no
581 * space in the PDU. Free the received data and go into the fault state.
583 DEBUG(0,("process_incoming_data: No space in incoming pdu buffer. Current size = %u \
584 incoming data size = %u\n", (unsigned int)p->in_data.pdu_received_len, (unsigned int)n ));
585 set_incoming_fault(p);
590 * If we have no data already, wait until we get at least a RPC_HEADER_LEN
591 * number of bytes before we can do anything.
594 if((p->in_data.pdu_needed_len == 0) && (p->in_data.pdu_received_len < RPC_HEADER_LEN)) {
596 * Always return here. If we have more data then the RPC_HEADER
597 * will be processed the next time around the loop.
599 return fill_rpc_header(p, data, data_to_copy);
603 * At this point we know we have at least an RPC_HEADER_LEN amount of data
604 * stored in current_in_pdu.
608 * If pdu_needed_len is zero this is a new pdu.
609 * Unmarshall the header so we know how much more
610 * data we need, then loop again.
613 if(p->in_data.pdu_needed_len == 0)
614 return unmarshall_rpc_header(p);
617 * Ok - at this point we have a valid RPC_HEADER in p->hdr.
618 * Keep reading until we have a full pdu.
621 data_to_copy = MIN(data_to_copy, p->in_data.pdu_needed_len);
624 * Copy as much of the data as we need into the current_in_pdu buffer.
627 memcpy( (char *)&p->in_data.current_in_pdu[p->in_data.pdu_received_len], data, data_to_copy);
628 p->in_data.pdu_received_len += data_to_copy;
631 * Do we have a complete PDU ?
634 if(p->in_data.pdu_received_len == p->in_data.pdu_needed_len)
635 return process_complete_pdu(p);
637 DEBUG(10,("process_incoming_data: not a complete PDU yet. pdu_received_len = %u, pdu_needed_len = %u\n",
638 (unsigned int)p->in_data.pdu_received_len, (unsigned int)p->in_data.pdu_needed_len ));
640 return (ssize_t)data_to_copy;
644 /****************************************************************************
645 Accepts incoming data on an rpc pipe.
646 ****************************************************************************/
648 ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
650 size_t data_left = n;
652 DEBUG(6,("write_to_pipe: %x", p->pnum));
654 DEBUG(6,(" name: %s open: %s len: %d\n",
655 p->name, BOOLSTR(p->open), (int)n));
657 dump_data(50, data, n);
662 DEBUG(10,("write_to_pipe: data_left = %u\n", (unsigned int)data_left ));
664 data_used = process_incoming_data(p, data, data_left);
666 DEBUG(10,("write_to_pipe: data_used = %d\n", (int)data_used ));
671 data_left -= data_used;
679 /****************************************************************************
680 Replyies to a request to read data from a pipe.
682 Headers are interspersed with the data at PDU intervals. By the time
683 this function is called, the start of the data could possibly have been
684 read by an SMBtrans (file_offset != 0).
686 Calling create_rpc_reply() here is a hack. The data should already
687 have been prepared into arrays of headers + data stream sections.
689 ****************************************************************************/
691 int read_from_pipe(pipes_struct *p, char *data, int n)
693 uint32 pdu_remaining = 0;
694 int data_returned = 0;
696 if (!p || !p->open) {
697 DEBUG(0,("read_from_pipe: pipe not open\n"));
701 DEBUG(6,("read_from_pipe: %x", p->pnum));
703 DEBUG(6,(" name: %s len: %d\n", p->name, n));
706 * We cannot return more than one PDU length per
710 if(n > MAX_PDU_FRAG_LEN) {
711 DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
712 only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
717 * Determine if there is still data to send in the
718 * pipe PDU buffer. Always send this first. Never
719 * send more than is left in the current PDU. The
720 * client should send a new read request for a new
724 if((pdu_remaining = p->out_data.current_pdu_len - p->out_data.current_pdu_sent) > 0) {
725 data_returned = MIN(n, pdu_remaining);
727 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
728 returning %d bytes.\n", p->name, (unsigned int)p->out_data.current_pdu_len,
729 (unsigned int)p->out_data.current_pdu_sent, (int)data_returned));
731 memcpy( data, &p->out_data.current_pdu[p->out_data.current_pdu_sent], (size_t)data_returned);
732 p->out_data.current_pdu_sent += (uint32)data_returned;
733 return data_returned;
737 * At this point p->current_pdu_len == p->current_pdu_sent (which
738 * may of course be zero if this is the first return fragment.
741 DEBUG(10,("read_from_pipe: %s: fault_state = %d : data_sent_length \
742 = %u, prs_offset(&p->out_data.rdata) = %u.\n",
743 p->name, (int)p->fault_state, (unsigned int)p->out_data.data_sent_length, (unsigned int)prs_offset(&p->out_data.rdata) ));
745 if(p->out_data.data_sent_length >= prs_offset(&p->out_data.rdata)) {
747 * We have sent all possible data. Return 0.
753 * We need to create a new PDU from the data left in p->rdata.
754 * Create the header/data/footers. This also sets up the fields
755 * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
756 * and stores the outgoing PDU in p->current_pdu.
759 if(!create_next_pdu(p)) {
760 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
765 data_returned = MIN(n, p->out_data.current_pdu_len);
767 memcpy( data, p->out_data.current_pdu, (size_t)data_returned);
768 p->out_data.current_pdu_sent += (uint32)data_returned;
769 return data_returned;
772 /****************************************************************************
773 Wait device state on a pipe. Exactly what this is for is unknown...
774 ****************************************************************************/
776 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
782 DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
785 p->priority = priority;
790 DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
796 /****************************************************************************
797 Set device state on a pipe. Exactly what this is for is unknown...
798 ****************************************************************************/
800 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
806 DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
807 device_state, p->name));
809 p->device_state = device_state;
814 DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
815 device_state, p->name));
820 /****************************************************************************
822 ****************************************************************************/
824 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
827 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
831 prs_mem_free(&p->out_data.rdata);
833 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
838 DEBUG(4,("close_rpc_pipe_hnd: closing msrpc redirect: "));
839 if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
842 DEBUG(4,("FAILED\n"));
845 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
846 p->name, p->pnum, pipes_open));
848 DLIST_REMOVE(Pipes, p);
857 /****************************************************************************
858 Find an rpc pipe given a pipe handle in a buffer and an offset.
859 ****************************************************************************/
861 pipes_struct *get_rpc_pipe_p(char *buf, int where)
863 int pnum = SVAL(buf,where);
868 return get_rpc_pipe(pnum);
871 /****************************************************************************
872 Find an rpc pipe given a pipe handle.
873 ****************************************************************************/
875 pipes_struct *get_rpc_pipe(int pnum)
879 DEBUG(4,("search for pipe pnum=%x\n", pnum));
881 for (p=Pipes;p;p=p->next)
882 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
883 p->name, p->pnum, pipes_open));
885 for (p=Pipes;p;p=p->next) {
886 if (p->pnum == pnum) {