attempting to delineate smbd / msrpc more.
[Samba.git] / source / rpc_server / srv_pipe_hnd.c
blob6f2b7688a601f91bcb25bbd5ad107ec9364ce3fb
2 /*
3 * Unix SMB/Netbios implementation.
4 * Version 1.9.
5 * RPC Pipe client / server routines
6 * Copyright (C) Andrew Tridgell 1992-1998,
7 * Copyright (C) Luke Kenneth Casson Leighton 1996-1998,
8 *
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.
25 #include "includes.h"
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
37 #endif
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;
53 else
54 pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
57 /****************************************************************************
58 reset pipe chain handle number
59 ****************************************************************************/
60 void reset_chain_p(void)
62 chain_p = NULL;
65 /****************************************************************************
66 initialise pipe handle states...
67 ****************************************************************************/
68 void init_rpc_pipe_hnd(void)
70 bmap = bitmap_allocate(MAX_OPEN_PIPES);
71 if (!bmap) {
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)
83 int i;
84 pipes_struct *p;
85 static int next_pipe;
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;
91 ZERO_STRUCT(usr);
93 DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
94 pipe_name, pipes_open));
96 if (vuser == NULL)
98 DEBUG(4,("invalid vuid %d\n", vuid));
99 return NULL;
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);
105 usr.ptr_uxc = 1;
106 make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
107 vuser->n_groups, vuser->groups);
108 usr.ptr_uxs = 1;
110 /* set up nt credentials from the smb side, to feed over the pipe */
111 /* lkclXXXX todo!
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 */
119 if (next_pipe == 0)
121 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
124 i = bitmap_find(bmap, next_pipe);
126 if (i == -1) {
127 DEBUG(0,("ERROR! Out of pipe structures\n"));
128 return NULL;
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);
142 if (m == NULL)
144 DEBUG(5,("open pipes: msrpc redirect failed\n"));
145 return NULL;
147 #if 0
149 else
151 l = malloc(sizeof(*l));
152 if (l == NULL)
154 DEBUG(5,("open pipes: local msrpc malloc failed\n"));
155 return NULL;
157 ZERO_STRUCTP(l);
158 l->rhdr.data = NULL;
159 l->rdata.data = NULL;
160 l->rhdr.offset = 0;
161 l->rdata.offset = 0;
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));
169 #endif
171 p = (pipes_struct *)malloc(sizeof(*p));
172 if (!p) return NULL;
174 ZERO_STRUCTP(p);
175 DLIST_ADD(Pipes, p);
177 bitmap_set(bmap, i);
178 i += pipe_handle_offset;
180 pipes_open++;
182 p->pnum = i;
183 p->m = m;
184 p->l = l;
186 p->open = True;
187 p->device_state = 0;
188 p->priority = 0;
189 p->conn = conn;
190 p->vuid = vuid;
192 p->file_offset = 0;
193 p->prev_pdu_file_offset = 0;
194 p->hdr_offsets = 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));
204 chain_p = p;
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));
212 return chain_p;
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;
224 if (p->open)
226 DEBUG(3,("%s Setting pipe wait state priority=%x on pipe (name=%s)\n",
227 timestring(), priority, p->name));
229 p->priority = priority;
231 return True;
234 DEBUG(3,("%s Error setting pipe wait state priority=%x (name=%s)\n",
235 timestring(), priority, p->name));
236 return False;
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;
247 if (p->open) {
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;
253 return True;
256 DEBUG(3,("%s Error setting pipe device state=%x (name=%s)\n",
257 timestring(), device_state, p->name));
258 return False;
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 /****************************************************************************
277 close an rpc pipe
278 ****************************************************************************/
279 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
281 if (!p) {
282 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
283 return False;
286 prs_free_data(&p->smb_pdu );
287 prs_free_data(&p->rsmb_pdu);
289 bitmap_clear(bmap, p->pnum - pipe_handle_offset);
291 pipes_open--;
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);
298 if (p->m != NULL)
300 DEBUG(4,("closed msrpc redirect: "));
301 if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
303 DEBUG(4,("OK\n"));
305 else
307 DEBUG(4,("FAILED\n"));
311 if (p->l != NULL)
313 DEBUG(4,("closed msrpc local: OK\n"));
315 prs_free_data(&p->l->rdata);
316 rpcsrv_free_temp(p->l);
318 free(p->l);
321 ZERO_STRUCTP(p);
322 free(p);
324 return True;
327 /****************************************************************************
328 close an rpc pipe
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 /****************************************************************************
340 close an rpc pipe
341 ****************************************************************************/
342 pipes_struct *get_rpc_pipe(int pnum)
344 pipes_struct *p;
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)
356 if (p->pnum == pnum)
358 chain_p = p;
359 return p;
363 return NULL;