modified smbd/msrpc credential transfer system. user session key
[samba.git] / source / rpc_server / srv_pipe_hnd.c
1
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  *  Copyright (C) Jeremy Allison                                    1999.
9  *  
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.
14  *  
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.
19  *  
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.
23  */
24
25
26 #include "includes.h"
27
28
29 #define PIPE            "\\PIPE\\"
30 #define PIPELEN         strlen(PIPE)
31
32 extern int DEBUGLEVEL;
33 static pipes_struct *chain_p;
34 static int pipes_open;
35
36 #ifndef MAX_OPEN_PIPES
37 #define MAX_OPEN_PIPES 64
38 #endif
39
40 static pipes_struct *Pipes;
41 static struct bitmap *bmap;
42
43 /* this must be larger than the sum of the open files and directories */
44 static int pipe_handle_offset;
45
46 /****************************************************************************
47  Set the pipe_handle_offset. Called from smbd/files.c
48 ****************************************************************************/
49
50 void set_pipe_handle_offset(int max_open_files)
51 {
52   if(max_open_files < 0x7000)
53     pipe_handle_offset = 0x7000;
54   else
55     pipe_handle_offset = max_open_files + 10; /* For safety. :-) */
56 }
57
58 /****************************************************************************
59  Reset pipe chain handle number.
60 ****************************************************************************/
61 void reset_chain_p(void)
62 {
63         chain_p = NULL;
64 }
65
66 /****************************************************************************
67  Initialise pipe handle states.
68 ****************************************************************************/
69
70 void init_rpc_pipe_hnd(void)
71 {
72         bmap = bitmap_allocate(MAX_OPEN_PIPES);
73         if (!bmap)
74                 exit_server("out of memory in init_rpc_pipe_hnd\n");
75 }
76
77 /****************************************************************************
78  Initialise an outgoing packet.
79 ****************************************************************************/
80
81 BOOL pipe_init_outgoing_data( pipes_struct *p)
82 {
83
84         memset(p->current_pdu, '\0', sizeof(p->current_pdu));
85
86         /* Free any memory in the current return data buffer. */
87         prs_mem_free(&p->rdata);
88
89         /*
90          * Initialize the outgoing RPC data buffer.
91          * we will use this as the raw data area for replying to rpc requests.
92          */     
93         if(!prs_init(&p->rdata, 1024, 4, MARSHALL)) {
94                 DEBUG(0,("pipe_init_outgoing_data: malloc fail.\n"));
95                 return False;
96         }
97
98         /* Reset the offset counters. */
99         p->data_sent_length = 0;
100         p->current_pdu_len = 0;
101         p->current_pdu_sent = 0;
102
103         return True;
104 }
105
106 /****************************************************************************
107  Find first available pipe slot.
108 ****************************************************************************/
109
110 pipes_struct *open_rpc_pipe_p(char *pipe_name, 
111                               connection_struct *conn, uint16 vuid)
112 {
113         int i;
114         pipes_struct *p;
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;
119
120         ZERO_STRUCT(usr);
121
122         DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
123                  pipe_name, pipes_open));
124         
125         if (vuser == NULL)
126         {
127                 DEBUG(4,("invalid vuid %d\n", vuid));
128                 return NULL;
129         }
130
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);
134         usr.ptr_uxc = 1;
135         make_creds_unix_sec(&usr.uxs, vuser->uid, vuser->gid,
136                                       vuser->n_groups, vuser->groups);
137         usr.ptr_uxs = 1;
138
139         usr.ptr_ssk = 1;
140         DEBUG(0,("user session key not available (yet).\n"));
141         DEBUG(0,("password-change operations may fail.\n"));
142
143 #if USER_SESSION_KEY_DEFINED_IN_VUSER_STRUCT
144         memcpy(usr.usr_sess_key, vuser->usr_sess_key, sizeof(usr.usr_sess_key));
145 #else
146         memset(usr.usr_sess_key, 0, sizeof(usr.usr_sess_key));
147 #endif
148
149         /* set up nt credentials from the smb side, to feed over the pipe */
150         /* lkclXXXX todo!
151         make_creds_nt(&usr.ntc);
152         make_creds_nt_sec(&usr.nts);
153         */
154
155         become_root(False); /* to connect to pipe */
156         m = msrpc_use_add(pipe_name, &usr, False);
157         unbecome_root(False);
158
159         if (m == NULL)
160         {
161                 DEBUG(10,("open pipes: msrpc redirect failed - go local.\n"));
162         }
163
164         /* not repeating pipe numbers makes it easier to track things in 
165            log files and prevents client bugs where pipe numbers are reused
166            over connection restarts */
167         if (next_pipe == 0)
168                 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
169
170         i = bitmap_find(bmap, next_pipe);
171
172         if (i == -1) {
173                 DEBUG(0,("ERROR! Out of pipe structures\n"));
174                 return NULL;
175         }
176
177         next_pipe = (i+1) % MAX_OPEN_PIPES;
178
179         for (p = Pipes; p; p = p->next)
180                 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
181
182         p = (pipes_struct *)malloc(sizeof(*p));
183         if (!p)
184                 return NULL;
185
186         ZERO_STRUCTP(p);
187
188         /*
189          * Initialize the RPC and PDU data buffers with no memory.
190          */     
191         prs_init(&p->rdata, 0, 4, MARSHALL);
192         
193         DLIST_ADD(Pipes, p);
194
195         bitmap_set(bmap, i);
196         i += pipe_handle_offset;
197
198         pipes_open++;
199
200         p->pnum = i;
201
202         p->open = True;
203         p->device_state = 0;
204         p->priority = 0;
205         p->conn = conn;
206         p->vuid  = vuid;
207         
208         p->m = m;
209
210         p->max_trans_reply = 0;
211         
212         p->ntlmssp_chal_flags = 0;
213         p->ntlmssp_auth_validated = False;
214         p->ntlmssp_auth_requested = False;
215
216         p->current_pdu_len = 0;
217         p->current_pdu_sent = 0;
218         p->data_sent_length = 0;
219
220         p->uid = (uid_t)-1;
221         p->gid = (gid_t)-1;
222         
223         fstrcpy(p->name, pipe_name);
224         
225         DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
226                  pipe_name, i, pipes_open));
227         
228         chain_p = p;
229         
230         /* OVERWRITE p as a temp variable, to display all open pipes */ 
231         for (p = Pipes; p; p = p->next)
232                 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
233
234         return chain_p;
235 }
236
237
238 /****************************************************************************
239  Accepts incoming data on an rpc pipe.
240
241  This code is probably incorrect at the moment. The problem is
242  that the rpc request shouldn't really be executed until all the
243  data needed for it is received. This currently assumes that each
244  SMBwrite or SMBwriteX contains all the data needed for an rpc
245  request. JRA.
246  ****************************************************************************/
247
248 ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
249 {
250         DEBUG(6,("write_to_pipe: %x", p->pnum));
251
252         DEBUG(6,("name: %s open: %s len: %d",
253                  p->name, BOOLSTR(p->open), (int)n));
254
255         dump_data(50, data, n);
256
257         return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
258 }
259
260
261 /****************************************************************************
262  Replyies to a request to read data from a pipe.
263
264  Headers are interspersed with the data at PDU intervals. By the time
265  this function is called, the start of the data could possibly have been
266  read by an SMBtrans (file_offset != 0).
267
268  Calling create_rpc_reply() here is a hack. The data should already
269  have been prepared into arrays of headers + data stream sections.
270
271  ****************************************************************************/
272
273 int read_from_pipe(pipes_struct *p, char *data, int n)
274 {
275         uint32 pdu_remaining = 0;
276         int data_returned = 0;
277
278         if (!p || !p->open) {
279                 DEBUG(0,("read_from_pipe: pipe not open\n"));
280                 return -1;              
281         }
282
283         DEBUG(6,("read_from_pipe: %x", p->pnum));
284
285         DEBUG(6,("name: %s len: %d\n", p->name, n));
286
287         /*
288          * We cannot return more than one PDU length per
289          * read request.
290          */
291
292         if(n > MAX_PDU_FRAG_LEN) {
293                 DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
294 only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
295                 return -1;
296         }
297
298         /*
299          * Determine if there is still data to send in the
300          * pipe PDU buffer. Always send this first. Never
301          * send more than is left in the current PDU. The
302          * client should send a new read request for a new
303          * PDU.
304          */
305
306         if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) {
307                 data_returned = MIN(n, pdu_remaining);
308
309                 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
310 returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, 
311                         (unsigned int)p->current_pdu_sent, (int)data_returned));
312
313                 memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned);
314                 p->current_pdu_sent += (uint32)data_returned;
315                 return data_returned;
316         }
317
318         /*
319          * At this point p->current_pdu_len == p->current_pdu_sent (which
320          * may of course be zero if this is the first return fragment.
321          */
322
323         DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n",
324                 p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) ));
325
326         if(p->data_sent_length >= prs_offset(&p->rdata)) {
327                 /*
328                  * We have sent all possible data. Return 0.
329                  */
330                 return 0;
331         }
332
333         /*
334          * We need to create a new PDU from the data left in p->rdata.
335          * Create the header/data/footers. This also sets up the fields
336          * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
337          * and stores the outgoing PDU in p->current_pdu.
338          */
339
340         if(!create_next_pdu(p)) {
341                 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
342                          p->name));
343                 return -1;
344         }
345
346         data_returned = MIN(n, p->current_pdu_len);
347
348         memcpy( data, p->current_pdu, (size_t)data_returned);
349         p->current_pdu_sent += (uint32)data_returned;
350         return data_returned;
351 }
352
353 /****************************************************************************
354  Wait device state on a pipe. Exactly what this is for is unknown...
355 ****************************************************************************/
356
357 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
358 {
359         if (p == NULL)
360                 return False;
361
362         if (p->open) {
363                 DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
364                          priority, p->name));
365
366                 p->priority = priority;
367                 
368                 return True;
369         } 
370
371         DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
372                  priority, p->name));
373         return False;
374 }
375
376
377 /****************************************************************************
378  Set device state on a pipe. Exactly what this is for is unknown...
379 ****************************************************************************/
380
381 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
382 {
383         if (p == NULL)
384                 return False;
385
386         if (p->open) {
387                 DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
388                          device_state, p->name));
389
390                 p->device_state = device_state;
391                 
392                 return True;
393         } 
394
395         DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
396                  device_state, p->name));
397         return False;
398 }
399
400
401 /****************************************************************************
402  Close an rpc pipe.
403 ****************************************************************************/
404
405 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
406 {
407         if (!p) {
408                 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
409                 return False;
410         }
411
412         prs_mem_free(&p->rdata);
413
414         bitmap_clear(bmap, p->pnum - pipe_handle_offset);
415
416         pipes_open--;
417
418         DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n", 
419                  p->name, p->pnum, pipes_open));  
420
421         if (p->m != NULL)
422         {
423                 DEBUG(4,("closed msrpc redirect: "));
424                 if (msrpc_use_del(p->m->pipe_name, &p->m->usr, False, NULL))
425                 {
426                         DEBUG(4,("OK\n"));
427                 }
428                 else
429                 {
430                         DEBUG(4,("FAILED\n"));
431                 }
432         }
433
434         DLIST_REMOVE(Pipes, p);
435
436         ZERO_STRUCTP(p);
437
438         free(p);
439         
440         return True;
441 }
442
443 /****************************************************************************
444  Find an rpc pipe given a pipe handle in a buffer and an offset.
445 ****************************************************************************/
446
447 pipes_struct *get_rpc_pipe_p(char *buf, int where)
448 {
449         int pnum = SVAL(buf,where);
450
451         if (chain_p)
452                 return chain_p;
453
454         return get_rpc_pipe(pnum);
455 }
456
457 /****************************************************************************
458  Find an rpc pipe given a pipe handle.
459 ****************************************************************************/
460
461 pipes_struct *get_rpc_pipe(int pnum)
462 {
463         pipes_struct *p;
464
465         DEBUG(4,("search for pipe pnum=%x\n", pnum));
466
467         for (p=Pipes;p;p=p->next)
468                 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n", 
469                           p->name, p->pnum, pipes_open));  
470
471         for (p=Pipes;p;p=p->next) {
472                 if (p->pnum == pnum) {
473                         chain_p = p;
474                         return p;
475                 }
476         }
477
478         return NULL;
479 }