first pass at updating head branch to be to be the same as the SAMBA_2_0 branch
[gd/samba-autobuild/.git] / source3 / 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
117         DEBUG(4,("Open pipe requested %s (pipes_open=%d)\n",
118                  pipe_name, pipes_open));
119         
120         /* not repeating pipe numbers makes it easier to track things in 
121            log files and prevents client bugs where pipe numbers are reused
122            over connection restarts */
123         if (next_pipe == 0)
124                 next_pipe = (getpid() ^ time(NULL)) % MAX_OPEN_PIPES;
125
126         i = bitmap_find(bmap, next_pipe);
127
128         if (i == -1) {
129                 DEBUG(0,("ERROR! Out of pipe structures\n"));
130                 return NULL;
131         }
132
133         next_pipe = (i+1) % MAX_OPEN_PIPES;
134
135         for (p = Pipes; p; p = p->next)
136                 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
137
138         p = (pipes_struct *)malloc(sizeof(*p));
139         if (!p)
140                 return NULL;
141
142         ZERO_STRUCTP(p);
143
144         /*
145          * Initialize the RPC and PDU data buffers with no memory.
146          */     
147         prs_init(&p->rdata, 0, 4, MARSHALL);
148         
149         DLIST_ADD(Pipes, p);
150
151         bitmap_set(bmap, i);
152         i += pipe_handle_offset;
153
154         pipes_open++;
155
156         p->pnum = i;
157
158         p->open = True;
159         p->device_state = 0;
160         p->priority = 0;
161         p->conn = conn;
162         p->vuid  = vuid;
163
164         p->max_trans_reply = 0;
165         
166         p->ntlmssp_chal_flags = 0;
167         p->ntlmssp_auth_validated = False;
168         p->ntlmssp_auth_requested = False;
169
170         p->current_pdu_len = 0;
171         p->current_pdu_sent = 0;
172         p->data_sent_length = 0;
173
174         p->uid = (uid_t)-1;
175         p->gid = (gid_t)-1;
176         
177         fstrcpy(p->name, pipe_name);
178         
179         DEBUG(4,("Opened pipe %s with handle %x (pipes_open=%d)\n",
180                  pipe_name, i, pipes_open));
181         
182         chain_p = p;
183         
184         /* OVERWRITE p as a temp variable, to display all open pipes */ 
185         for (p = Pipes; p; p = p->next)
186                 DEBUG(5,("open pipes: name %s pnum=%x\n", p->name, p->pnum));  
187
188         return chain_p;
189 }
190
191
192 /****************************************************************************
193  Accepts incoming data on an rpc pipe.
194
195  This code is probably incorrect at the moment. The problem is
196  that the rpc request shouldn't really be executed until all the
197  data needed for it is received. This currently assumes that each
198  SMBwrite or SMBwriteX contains all the data needed for an rpc
199  request. JRA.
200  ****************************************************************************/
201
202 ssize_t write_to_pipe(pipes_struct *p, char *data, size_t n)
203 {
204         DEBUG(6,("write_pipe: %x", p->pnum));
205
206         DEBUG(6,("name: %s open: %s len: %d",
207                  p->name, BOOLSTR(p->open), (int)n));
208
209         dump_data(50, data, n);
210
211         return rpc_command(p, data, (int)n) ? ((ssize_t)n) : -1;
212 }
213
214
215 /****************************************************************************
216  Replyies to a request to read data from a pipe.
217
218  Headers are interspersed with the data at PDU intervals. By the time
219  this function is called, the start of the data could possibly have been
220  read by an SMBtrans (file_offset != 0).
221
222  Calling create_rpc_reply() here is a hack. The data should already
223  have been prepared into arrays of headers + data stream sections.
224
225  ****************************************************************************/
226
227 int read_from_pipe(pipes_struct *p, char *data, int n)
228 {
229         uint32 pdu_remaining = 0;
230         int data_returned = 0;
231
232         if (!p || !p->open) {
233                 DEBUG(0,("read_from_pipe: pipe not open\n"));
234                 return -1;              
235         }
236
237         DEBUG(6,("read_from_pipe: %x", p->pnum));
238
239         DEBUG(6,("name: %s len: %d\n", p->name, n));
240
241         /*
242          * We cannot return more than one PDU length per
243          * read request.
244          */
245
246         if(n > MAX_PDU_FRAG_LEN) {
247                 DEBUG(0,("read_from_pipe: loo large read (%d) requested on pipe %s. We can \
248 only service %d sized reads.\n", n, p->name, MAX_PDU_FRAG_LEN ));
249                 return -1;
250         }
251
252         /*
253          * Determine if there is still data to send in the
254          * pipe PDU buffer. Always send this first. Never
255          * send more than is left in the current PDU. The
256          * client should send a new read request for a new
257          * PDU.
258          */
259
260         if((pdu_remaining = p->current_pdu_len - p->current_pdu_sent) > 0) {
261                 data_returned = MIN(n, pdu_remaining);
262
263                 DEBUG(10,("read_from_pipe: %s: current_pdu_len = %u, current_pdu_sent = %u \
264 returning %d bytes.\n", p->name, (unsigned int)p->current_pdu_len, 
265                         (unsigned int)p->current_pdu_sent, (int)data_returned));
266
267                 memcpy( data, &p->current_pdu[p->current_pdu_sent], (size_t)data_returned);
268                 p->current_pdu_sent += (uint32)data_returned;
269                 return data_returned;
270         }
271
272         /*
273          * At this point p->current_pdu_len == p->current_pdu_sent (which
274          * may of course be zero if this is the first return fragment.
275          */
276
277         DEBUG(10,("read_from_pipe: %s: data_sent_length = %u, prs_offset(&p->rdata) = %u.\n",
278                 p->name, (unsigned int)p->data_sent_length, (unsigned int)prs_offset(&p->rdata) ));
279
280         if(p->data_sent_length >= prs_offset(&p->rdata)) {
281                 /*
282                  * We have sent all possible data. Return 0.
283                  */
284                 return 0;
285         }
286
287         /*
288          * We need to create a new PDU from the data left in p->rdata.
289          * Create the header/data/footers. This also sets up the fields
290          * p->current_pdu_len, p->current_pdu_sent, p->data_sent_length
291          * and stores the outgoing PDU in p->current_pdu.
292          */
293
294         if(!create_next_pdu(p)) {
295                 DEBUG(0,("read_from_pipe: %s: create_next_pdu failed.\n",
296                          p->name));
297                 return -1;
298         }
299
300         data_returned = MIN(n, p->current_pdu_len);
301
302         memcpy( data, p->current_pdu, (size_t)data_returned);
303         p->current_pdu_sent += (uint32)data_returned;
304         return data_returned;
305 }
306
307 /****************************************************************************
308  Wait device state on a pipe. Exactly what this is for is unknown...
309 ****************************************************************************/
310
311 BOOL wait_rpc_pipe_hnd_state(pipes_struct *p, uint16 priority)
312 {
313         if (p == NULL)
314                 return False;
315
316         if (p->open) {
317                 DEBUG(3,("wait_rpc_pipe_hnd_state: Setting pipe wait state priority=%x on pipe (name=%s)\n",
318                          priority, p->name));
319
320                 p->priority = priority;
321                 
322                 return True;
323         } 
324
325         DEBUG(3,("wait_rpc_pipe_hnd_state: Error setting pipe wait state priority=%x (name=%s)\n",
326                  priority, p->name));
327         return False;
328 }
329
330
331 /****************************************************************************
332  Set device state on a pipe. Exactly what this is for is unknown...
333 ****************************************************************************/
334
335 BOOL set_rpc_pipe_hnd_state(pipes_struct *p, uint16 device_state)
336 {
337         if (p == NULL)
338                 return False;
339
340         if (p->open) {
341                 DEBUG(3,("set_rpc_pipe_hnd_state: Setting pipe device state=%x on pipe (name=%s)\n",
342                          device_state, p->name));
343
344                 p->device_state = device_state;
345                 
346                 return True;
347         } 
348
349         DEBUG(3,("set_rpc_pipe_hnd_state: Error setting pipe device state=%x (name=%s)\n",
350                  device_state, p->name));
351         return False;
352 }
353
354
355 /****************************************************************************
356  Close an rpc pipe.
357 ****************************************************************************/
358
359 BOOL close_rpc_pipe_hnd(pipes_struct *p, connection_struct *conn)
360 {
361         if (!p) {
362                 DEBUG(0,("Invalid pipe in close_rpc_pipe_hnd\n"));
363                 return False;
364         }
365
366         prs_mem_free(&p->rdata);
367
368         bitmap_clear(bmap, p->pnum - pipe_handle_offset);
369
370         pipes_open--;
371
372         DEBUG(4,("closed pipe name %s pnum=%x (pipes_open=%d)\n", 
373                  p->name, p->pnum, pipes_open));  
374
375         DLIST_REMOVE(Pipes, p);
376
377         ZERO_STRUCTP(p);
378
379         free(p);
380         
381         return True;
382 }
383
384 /****************************************************************************
385  Find an rpc pipe given a pipe handle in a buffer and an offset.
386 ****************************************************************************/
387
388 pipes_struct *get_rpc_pipe_p(char *buf, int where)
389 {
390         int pnum = SVAL(buf,where);
391
392         if (chain_p)
393                 return chain_p;
394
395         return get_rpc_pipe(pnum);
396 }
397
398 /****************************************************************************
399  Find an rpc pipe given a pipe handle.
400 ****************************************************************************/
401
402 pipes_struct *get_rpc_pipe(int pnum)
403 {
404         pipes_struct *p;
405
406         DEBUG(4,("search for pipe pnum=%x\n", pnum));
407
408         for (p=Pipes;p;p=p->next)
409                 DEBUG(5,("pipe name %s pnum=%x (pipes_open=%d)\n", 
410                           p->name, p->pnum, pipes_open));  
411
412         for (p=Pipes;p;p=p->next) {
413                 if (p->pnum == pnum) {
414                         chain_p = p;
415                         return p;
416                 }
417         }
418
419         return NULL;
420 }