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 become_root(False
); /* to connect to pipe */
139 m
= msrpc_use_add(pipe_name
, &usr
, False
);
140 unbecome_root(False
);
144 DEBUG(5,("open pipes: msrpc redirect failed\n"));
151 l
= malloc(sizeof(*l
));
154 DEBUG(5,("open pipes: local msrpc malloc failed\n"));
159 l
->rdata
.data
= NULL
;
163 l
->ntlmssp_validated
= False
;
164 l
->ntlmssp_auth
= False
;
166 memcpy(l
->user_sess_key
, vuser
->user_sess_key
,
167 sizeof(l
->user_sess_key
));
171 p
= (pipes_struct
*)malloc(sizeof(*p
));
178 i
+= pipe_handle_offset
;
193 p
->prev_pdu_file_offset
= 0;
196 fstrcpy(p
->name
, pipe_name
);
198 prs_init(&p
->smb_pdu
, 0, 4, True
);
199 prs_init(&p
->rsmb_pdu
, 0, 4, False
);
201 DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
202 pipe_name
, i
, pipes_open
));
206 /* OVERWRITE p as a temp variable, to display all open pipes */
207 for (p
= Pipes
; p
; p
= p
->next
)
209 DEBUG(5,("open pipes: name %s pnum=%x\n", p
->name
, p
->pnum
));
217 /****************************************************************************
218 wait device state on a pipe. exactly what this is for is unknown...
219 ****************************************************************************/
220 BOOL
wait_rpc_pipe_hnd_state(pipes_struct
*p
, uint16 priority
)
222 if (p
== NULL
) return False
;
226 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
227 timestring(), priority
, p
->name
));
229 p
->priority
= priority
;
234 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
235 timestring(), priority
, p
->name
));
240 /****************************************************************************
241 set device state on a pipe. exactly what this is for is unknown...
242 ****************************************************************************/
243 BOOL
set_rpc_pipe_hnd_state(pipes_struct
*p
, uint16 device_state
)
245 if (p
== NULL
) return False
;
248 DEBUG(3,("%s Setting pipe device state=%x on pipe (name=%s)\n",
249 timestring(), device_state
, p
->name
));
251 p
->device_state
= device_state
;
256 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
257 timestring(), device_state
, p
->name
));
261 /*******************************************************************
262 frees all temporary data used in construction of pdu
263 ********************************************************************/
264 void rpcsrv_free_temp(rpcsrv_struct
*l
)
266 prs_free_data(&l
->data_i
);
268 prs_free_data(&l
->rhdr
);
269 prs_free_data(&l
->rfault
);
270 prs_free_data(&l
->rdata_i
);
271 prs_free_data(&l
->rauth
);
272 prs_free_data(&l
->rverf
);
273 prs_free_data(&l
->rntlm
);
276 /****************************************************************************
278 ****************************************************************************/
279 BOOL
close_rpc_pipe_hnd(pipes_struct
*p
, connection_struct
*conn
)
282 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
286 prs_free_data(&p
->smb_pdu
);
287 prs_free_data(&p
->rsmb_pdu
);
289 bitmap_clear(bmap
, p
->pnum
- pipe_handle_offset
);
293 DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n",
294 p
->name
, p
->pnum
, pipes_open
));
296 DLIST_REMOVE(Pipes
, p
);
300 DEBUG(4,("closed msrpc redirect: "));
301 if (msrpc_use_del(p
->m
->pipe_name
, &p
->m
->usr
, False
, NULL
))
307 DEBUG(4,("FAILED\n"));
313 DEBUG(4,("closed msrpc local: OK\n"));
315 prs_free_data(&p
->l
->rdata
);
316 rpcsrv_free_temp(p
->l
);
327 /****************************************************************************
329 ****************************************************************************/
330 pipes_struct
*get_rpc_pipe_p(char *buf
, int where
)
332 int pnum
= SVAL(buf
,where
);
334 if (chain_p
) return chain_p
;
336 return get_rpc_pipe(pnum
);
339 /****************************************************************************
341 ****************************************************************************/
342 pipes_struct
*get_rpc_pipe(int pnum
)
346 DEBUG(4,("search for pipe pnum=%x\n", pnum
));
348 for (p
=Pipes
;p
;p
=p
->next
)
350 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n",
351 p
->name
, p
->pnum
, pipes_open
));
354 for (p
=Pipes
;p
;p
=p
->next
)