r1936: Fix bug noticed by Steve - ensure extended security bit is on only
[sfrench/samba-autobuild/.git] / source3 / smbd / process.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process incoming packets - main loop
4    Copyright (C) Andrew Tridgell 1992-1998
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 struct timeval smb_last_time;
24
25 static char *InBuffer = NULL;
26 char *OutBuffer = NULL;
27 char *last_inbuf = NULL;
28
29 /* 
30  * Size of data we can send to client. Set
31  *  by the client for all protocols above CORE.
32  *  Set by us for CORE protocol.
33  */
34 int max_send = BUFFER_SIZE;
35 /*
36  * Size of the data we can receive. Set by us.
37  * Can be modified by the max xmit parameter.
38  */
39 int max_recv = BUFFER_SIZE;
40
41 extern int last_message;
42 extern int global_oplock_break;
43 extern userdom_struct current_user_info;
44 extern int smb_read_error;
45 SIG_ATOMIC_T reload_after_sighup = 0;
46 SIG_ATOMIC_T got_sig_term = 0;
47 BOOL global_machine_password_needs_changing = False;
48 extern int max_send;
49
50 /****************************************************************************
51  Function to return the current request mid from Inbuffer.
52 ****************************************************************************/
53
54 uint16 get_current_mid(void)
55 {
56         return SVAL(InBuffer,smb_mid);
57 }
58
59 /****************************************************************************
60  structure to hold a linked list of queued messages.
61  for processing.
62 ****************************************************************************/
63
64 static struct pending_message_list *smb_oplock_queue;
65 static struct pending_message_list *smb_sharing_violation_queue;
66
67 enum q_type { OPLOCK_QUEUE, SHARE_VIOLATION_QUEUE };
68
69 /****************************************************************************
70  Free up a message.
71 ****************************************************************************/
72
73 static void free_queued_message(struct pending_message_list *msg)
74 {
75         data_blob_free(&msg->buf);
76         data_blob_free(&msg->private_data);
77         SAFE_FREE(msg);
78 }
79
80 /****************************************************************************
81  Function to push a message onto the tail of a linked list of smb messages ready
82  for processing.
83 ****************************************************************************/
84
85 static BOOL push_queued_message(enum q_type qt, char *buf, int msg_len, struct timeval *ptv, char *private, size_t private_len)
86 {
87         struct pending_message_list *tmp_msg;
88         struct pending_message_list *msg = (struct pending_message_list *)
89                                malloc(sizeof(struct pending_message_list));
90
91         if(msg == NULL) {
92                 DEBUG(0,("push_message: malloc fail (1)\n"));
93                 return False;
94         }
95
96         memset(msg,'\0',sizeof(*msg));
97
98         msg->buf = data_blob(buf, msg_len);
99         if(msg->buf.data == NULL) {
100                 DEBUG(0,("push_message: malloc fail (2)\n"));
101                 SAFE_FREE(msg);
102                 return False;
103         }
104
105         if (ptv) {
106                 msg->msg_time = *ptv;
107         }
108
109         if (private) {
110                 msg->private_data = data_blob(private, private_len);
111                 if (msg->private_data.data == NULL) {
112                         DEBUG(0,("push_message: malloc fail (3)\n"));
113                         data_blob_free(&msg->buf);
114                         SAFE_FREE(msg);
115                 }
116         }
117
118         if (qt == OPLOCK_QUEUE) {
119                 DLIST_ADD_END(smb_oplock_queue, msg, tmp_msg);
120         } else {
121                 DLIST_ADD_END(smb_sharing_violation_queue, msg, tmp_msg);
122         }
123
124         DEBUG(10,("push_message: pushed message length %u on queue %s\n",
125                 (unsigned int)msg_len,
126                 qt == OPLOCK_QUEUE ? "smb_oplock_queue" : "smb_sharing_violation_queue" ));
127
128         return True;
129 }
130
131 /****************************************************************************
132  Function to push an oplock smb message onto a linked list of local smb messages ready
133  for processing.
134 ****************************************************************************/
135
136 BOOL push_oplock_pending_smb_message(char *buf, int msg_len)
137 {
138         BOOL ret = push_queued_message(OPLOCK_QUEUE, buf, msg_len, NULL, NULL, 0);
139         if (ret) {
140                 /* Push the MID of this packet on the signing queue. */
141                 srv_defer_sign_response(SVAL(buf,smb_mid));
142         }
143         return ret;
144 }
145
146 /****************************************************************************
147  Function to delete a sharing violation open message by mid.
148 ****************************************************************************/
149
150 void remove_sharing_violation_open_smb_message(uint16 mid)
151 {
152         struct pending_message_list *pml;
153
154         if (!lp_defer_sharing_violations()) {
155                 return;
156         }
157
158         for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
159                 if (mid == SVAL(pml->buf.data,smb_mid)) {
160                         DEBUG(10,("remove_sharing_violation_open_smb_message: deleting mid %u len %u\n",
161                                 (unsigned int)mid, (unsigned int)pml->buf.length ));
162                         DLIST_REMOVE(smb_sharing_violation_queue, pml);
163                         free_queued_message(pml);
164                         return;
165                 }
166         }
167 }
168
169 /****************************************************************************
170  Move a sharing violation open retry message to the front of the list and
171  schedule it for immediate processing.
172 ****************************************************************************/
173
174 void schedule_sharing_violation_open_smb_message(uint16 mid)
175 {
176         struct pending_message_list *pml;
177         int i = 0;
178
179         if (!lp_defer_sharing_violations()) {
180                 return;
181         }
182
183         for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
184                 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
185                 DEBUG(10,("schedule_sharing_violation_open_smb_message: [%d] msg_mid = %u\n", i++,
186                         (unsigned int)msg_mid ));
187                 if (mid == msg_mid) {
188                         DEBUG(10,("schedule_sharing_violation_open_smb_message: scheduling mid %u\n",
189                                 mid ));
190                         pml->msg_time.tv_sec = 0;
191                         pml->msg_time.tv_usec = 0;
192                         DLIST_PROMOTE(smb_sharing_violation_queue, pml);
193                         return;
194                 }
195         }
196
197         DEBUG(10,("schedule_sharing_violation_open_smb_message: failed to find message mid %u\n",
198                 mid ));
199 }
200
201 /****************************************************************************
202  Return true if this mid is on the deferred queue.
203 ****************************************************************************/
204
205 BOOL open_was_deferred(uint16 mid)
206 {
207         struct pending_message_list *pml;
208
209         if (!lp_defer_sharing_violations()) {
210                 return False;
211         }
212
213         for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
214                 if (SVAL(pml->buf.data,smb_mid) == mid) {
215                         return True;
216                 }
217         }
218         return False;
219 }
220
221 /****************************************************************************
222  Return the message queued by this mid.
223 ****************************************************************************/
224
225 struct pending_message_list *get_open_deferred_message(uint16 mid)
226 {
227         struct pending_message_list *pml;
228
229         if (!lp_defer_sharing_violations()) {
230                 return NULL;
231         }
232
233         for (pml = smb_sharing_violation_queue; pml; pml = pml->next) {
234                 if (SVAL(pml->buf.data,smb_mid) == mid) {
235                         return pml;
236                 }
237         }
238         return NULL;
239 }
240
241 /****************************************************************************
242  Function to push a sharing violation open smb message onto a linked list of local smb messages ready
243  for processing.
244 ****************************************************************************/
245
246 BOOL push_sharing_violation_open_smb_message(struct timeval *ptv, char *private, size_t priv_len)
247 {
248         uint16 mid = SVAL(InBuffer,smb_mid);
249         struct timeval tv;
250         SMB_BIG_INT tdif;
251
252         if (!lp_defer_sharing_violations()) {
253                 return True;
254         }
255
256         tv = *ptv;
257         tdif = tv.tv_sec;
258         tdif *= 1000000;
259         tdif += tv.tv_usec;
260
261         /* Add on the timeout. */
262         tdif += SHARING_VIOLATION_USEC_WAIT;
263         
264         tv.tv_sec = tdif / 1000000;
265         tv.tv_usec = tdif % 1000000;
266         
267         DEBUG(10,("push_sharing_violation_open_smb_message: pushing message len %u mid %u\
268  timeout time [%u.%06u]\n", (unsigned int) smb_len(InBuffer)+4, (unsigned int)mid,
269                 (unsigned int)tv.tv_sec, (unsigned int)tv.tv_usec));
270
271         return push_queued_message(SHARE_VIOLATION_QUEUE, InBuffer,
272                         smb_len(InBuffer)+4, &tv, private, priv_len);
273 }
274
275 /****************************************************************************
276  Do all async processing in here. This includes UDB oplock messages, kernel
277  oplock messages, change notify events etc.
278 ****************************************************************************/
279
280 static void async_processing(char *buffer, int buffer_len)
281 {
282         DEBUG(10,("async_processing: Doing async processing.\n"));
283
284         /* check for oplock messages (both UDP and kernel) */
285         if (receive_local_message(buffer, buffer_len, 1)) {
286                 process_local_message(buffer, buffer_len);
287         }
288
289         if (got_sig_term) {
290                 exit_server("Caught TERM signal");
291         }
292
293         /* check for async change notify events */
294         process_pending_change_notify_queue(0);
295
296         /* check for sighup processing */
297         if (reload_after_sighup) {
298                 change_to_root_user();
299                 DEBUG(1,("Reloading services after SIGHUP\n"));
300                 reload_services(False);
301                 reload_after_sighup = 0;
302         }
303 }
304
305 /****************************************************************************
306   Do a select on an two fd's - with timeout. 
307
308   If a local udp message has been pushed onto the
309   queue (this can only happen during oplock break
310   processing) call async_processing()
311
312   If a pending smb message has been pushed onto the
313   queue (this can only happen during oplock break
314   processing) return this next.
315
316   If the first smbfd is ready then read an smb from it.
317   if the second (loopback UDP) fd is ready then read a message
318   from it and setup the buffer header to identify the length
319   and from address.
320   Returns False on timeout or error.
321   Else returns True.
322
323 The timeout is in milliseconds
324 ****************************************************************************/
325
326 static BOOL receive_message_or_smb(char *buffer, int buffer_len, int timeout)
327 {
328         fd_set fds;
329         int selrtn;
330         struct timeval to;
331         struct timeval *pto;
332         int maxfd;
333
334         smb_read_error = 0;
335
336  again:
337
338         to.tv_sec = timeout / 1000;
339         to.tv_usec = (timeout % 1000) * 1000;
340         pto = timeout > 0 ? &to : NULL;
341
342         /*
343          * Note that this call must be before processing any SMB
344          * messages as we need to synchronously process any messages
345          * we may have sent to ourselves from the previous SMB.
346          */
347         message_dispatch();
348
349         /*
350          * Check to see if we already have a message on the smb queue.
351          * If so - copy and return it.
352          */
353         if(smb_oplock_queue != NULL) {
354                 struct pending_message_list *msg = smb_oplock_queue;
355                 memcpy(buffer, msg->buf.data, MIN(buffer_len, msg->buf.length));
356   
357                 /* Free the message we just copied. */
358                 DLIST_REMOVE(smb_oplock_queue, msg);
359                 free_queued_message(msg);
360                 
361                 DEBUG(5,("receive_message_or_smb: returning queued smb message.\n"));
362                 return True;
363         }
364
365         /*
366          * Check to see if we already have a message on the deferred open queue
367          * and it's time to schedule.
368          */
369         if(smb_sharing_violation_queue != NULL) {
370                 BOOL pop_message = False;
371                 struct pending_message_list *msg = smb_sharing_violation_queue;
372
373                 if (msg->msg_time.tv_sec == 0 && msg->msg_time.tv_usec == 0) {
374                         pop_message = True;
375                 } else {
376                         struct timeval tv;
377                         SMB_BIG_INT tdif;
378
379                         GetTimeOfDay(&tv);
380                         tdif = usec_time_diff(&msg->msg_time, &tv);
381                         if (tdif <= 0) {
382                                 /* Timed out. Schedule...*/
383                                 pop_message = True;
384                                 DEBUG(10,("receive_message_or_smb: queued message timed out.\n"));
385                         } else {
386                                 /* Make a more accurate select timeout. */
387                                 to.tv_sec = tdif / 1000000;
388                                 to.tv_usec = tdif % 1000000;
389                                 pto = &to;
390                                 DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
391                                         (unsigned int)pto->tv_sec, (unsigned int)pto->tv_usec ));
392                         }
393                 }
394
395                 if (pop_message) {
396                         memcpy(buffer, msg->buf.data, MIN(buffer_len, msg->buf.length));
397   
398                         /* We leave this message on the queue so the open code can
399                            know this is a retry. */
400                         DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
401                         return True;
402                 }
403         }
404
405         /*
406          * Setup the select read fd set.
407          */
408
409         FD_ZERO(&fds);
410
411         /*
412          * Ensure we process oplock break messages by preference.
413          * We have to do this before the select, after the select
414          * and if the select returns EINTR. This is due to the fact
415          * that the selects called from async_processing can eat an EINTR
416          * caused by a signal (we can't take the break message there).
417          * This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
418          */
419
420         if (oplock_message_waiting(&fds)) {
421                 DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
422                 async_processing(buffer, buffer_len);
423                 /*
424                  * After async processing we must go and do the select again, as
425                  * the state of the flag in fds for the server file descriptor is
426                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
427                  */
428                 goto again;
429         }
430         
431         FD_SET(smbd_server_fd(),&fds);
432         maxfd = setup_oplock_select_set(&fds);
433
434         selrtn = sys_select(MAX(maxfd,smbd_server_fd())+1,&fds,NULL,NULL,pto);
435
436         /* if we get EINTR then maybe we have received an oplock
437            signal - treat this as select returning 1. This is ugly, but
438            is the best we can do until the oplock code knows more about
439            signals */
440         if (selrtn == -1 && errno == EINTR) {
441                 async_processing(buffer, buffer_len);
442                 /*
443                  * After async processing we must go and do the select again, as
444                  * the state of the flag in fds for the server file descriptor is
445                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
446                  */
447                 goto again;
448         }
449
450         /* Check if error */
451         if (selrtn == -1) {
452                 /* something is wrong. Maybe the socket is dead? */
453                 smb_read_error = READ_ERROR;
454                 return False;
455         } 
456     
457         /* Did we timeout ? */
458         if (selrtn == 0) {
459                 smb_read_error = READ_TIMEOUT;
460                 return False;
461         }
462
463         /*
464          * Ensure we process oplock break messages by preference.
465          * This is IMPORTANT ! Otherwise we can starve other processes
466          * sending us an oplock break message. JRA.
467          */
468
469         if (oplock_message_waiting(&fds)) {
470                 async_processing(buffer, buffer_len);
471                 /*
472                  * After async processing we must go and do the select again, as
473                  * the state of the flag in fds for the server file descriptor is
474                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
475                  */
476                 goto again;
477         }
478         
479         return receive_smb(smbd_server_fd(), buffer, 0);
480 }
481
482 /****************************************************************************
483 Get the next SMB packet, doing the local message processing automatically.
484 ****************************************************************************/
485
486 BOOL receive_next_smb(char *inbuf, int bufsize, int timeout)
487 {
488         BOOL got_keepalive;
489         BOOL ret;
490
491         do {
492                 ret = receive_message_or_smb(inbuf,bufsize,timeout);
493                 
494                 got_keepalive = (ret && (CVAL(inbuf,0) == SMBkeepalive));
495         } while (ret && got_keepalive);
496
497         return ret;
498 }
499
500 /****************************************************************************
501  We're terminating and have closed all our files/connections etc.
502  If there are any pending local messages we need to respond to them
503  before termination so that other smbds don't think we just died whilst
504  holding oplocks.
505 ****************************************************************************/
506
507 void respond_to_all_remaining_local_messages(void)
508 {
509         char buffer[1024];
510
511         /*
512          * Assert we have no exclusive open oplocks.
513          */
514
515         if(get_number_of_exclusive_open_oplocks()) {
516                 DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
517                         get_number_of_exclusive_open_oplocks() ));
518                 return;
519         }
520
521         /*
522          * Keep doing receive_local_message with a 1 ms timeout until
523          * we have no more messages.
524          */
525
526         while(receive_local_message(buffer, sizeof(buffer), 1)) {
527                 /* Deal with oplock break requests from other smbd's. */
528                 process_local_message(buffer, sizeof(buffer));
529         }
530
531         return;
532 }
533
534
535 /*
536 These flags determine some of the permissions required to do an operation 
537
538 Note that I don't set NEED_WRITE on some write operations because they
539 are used by some brain-dead clients when printing, and I don't want to
540 force write permissions on print services.
541 */
542 #define AS_USER (1<<0)
543 #define NEED_WRITE (1<<1)
544 #define TIME_INIT (1<<2)
545 #define CAN_IPC (1<<3)
546 #define AS_GUEST (1<<5)
547 #define QUEUE_IN_OPLOCK (1<<6)
548 #define DO_CHDIR (1<<7)
549
550 /* 
551    define a list of possible SMB messages and their corresponding
552    functions. Any message that has a NULL function is unimplemented -
553    please feel free to contribute implementations!
554 */
555 static const struct smb_message_struct {
556         const char *name;
557         int (*fn)(connection_struct *conn, char *, char *, int, int);
558         int flags;
559 } smb_messages[256] = {
560
561 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
562 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
563 /* 0x02 */ { "SMBopen",reply_open,AS_USER | QUEUE_IN_OPLOCK },
564 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
565 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
566 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
567 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
568 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK},
569 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
570 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
571 /* 0x0a */ { "SMBread",reply_read,AS_USER},
572 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
573 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
574 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
575 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER | QUEUE_IN_OPLOCK },
576 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER}, 
577 /* 0x10 */ { "SMBchkpth",reply_chkpth,AS_USER},
578 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
579 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
580 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
581 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
582 /* 0x15 */ { NULL, NULL, 0 },
583 /* 0x16 */ { NULL, NULL, 0 },
584 /* 0x17 */ { NULL, NULL, 0 },
585 /* 0x18 */ { NULL, NULL, 0 },
586 /* 0x19 */ { NULL, NULL, 0 },
587 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
588 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
589 /* 0x1c */ { "SMBreadBs",NULL,0 },
590 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
591 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
592 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
593 /* 0x20 */ { "SMBwritec",NULL,0},
594 /* 0x21 */ { NULL, NULL, 0 },
595 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
596 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
597 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
598 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
599 /* 0x26 */ { "SMBtranss",NULL,AS_USER | CAN_IPC},
600 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
601 /* 0x28 */ { "SMBioctls",NULL,AS_USER},
602 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
603 /* 0x2a */ { "SMBmove",NULL,AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
604 /* 0x2b */ { "SMBecho",reply_echo,0},
605 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
606 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
607 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
608 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
609 /* 0x30 */ { NULL, NULL, 0 },
610 /* 0x31 */ { NULL, NULL, 0 },
611 /* 0x32 */ { "SMBtrans2", reply_trans2, AS_USER | CAN_IPC },
612 /* 0x33 */ { "SMBtranss2", reply_transs2, AS_USER},
613 /* 0x34 */ { "SMBfindclose", reply_findclose,AS_USER},
614 /* 0x35 */ { "SMBfindnclose", reply_findnclose, AS_USER},
615 /* 0x36 */ { NULL, NULL, 0 },
616 /* 0x37 */ { NULL, NULL, 0 },
617 /* 0x38 */ { NULL, NULL, 0 },
618 /* 0x39 */ { NULL, NULL, 0 },
619 /* 0x3a */ { NULL, NULL, 0 },
620 /* 0x3b */ { NULL, NULL, 0 },
621 /* 0x3c */ { NULL, NULL, 0 },
622 /* 0x3d */ { NULL, NULL, 0 },
623 /* 0x3e */ { NULL, NULL, 0 },
624 /* 0x3f */ { NULL, NULL, 0 },
625 /* 0x40 */ { NULL, NULL, 0 },
626 /* 0x41 */ { NULL, NULL, 0 },
627 /* 0x42 */ { NULL, NULL, 0 },
628 /* 0x43 */ { NULL, NULL, 0 },
629 /* 0x44 */ { NULL, NULL, 0 },
630 /* 0x45 */ { NULL, NULL, 0 },
631 /* 0x46 */ { NULL, NULL, 0 },
632 /* 0x47 */ { NULL, NULL, 0 },
633 /* 0x48 */ { NULL, NULL, 0 },
634 /* 0x49 */ { NULL, NULL, 0 },
635 /* 0x4a */ { NULL, NULL, 0 },
636 /* 0x4b */ { NULL, NULL, 0 },
637 /* 0x4c */ { NULL, NULL, 0 },
638 /* 0x4d */ { NULL, NULL, 0 },
639 /* 0x4e */ { NULL, NULL, 0 },
640 /* 0x4f */ { NULL, NULL, 0 },
641 /* 0x50 */ { NULL, NULL, 0 },
642 /* 0x51 */ { NULL, NULL, 0 },
643 /* 0x52 */ { NULL, NULL, 0 },
644 /* 0x53 */ { NULL, NULL, 0 },
645 /* 0x54 */ { NULL, NULL, 0 },
646 /* 0x55 */ { NULL, NULL, 0 },
647 /* 0x56 */ { NULL, NULL, 0 },
648 /* 0x57 */ { NULL, NULL, 0 },
649 /* 0x58 */ { NULL, NULL, 0 },
650 /* 0x59 */ { NULL, NULL, 0 },
651 /* 0x5a */ { NULL, NULL, 0 },
652 /* 0x5b */ { NULL, NULL, 0 },
653 /* 0x5c */ { NULL, NULL, 0 },
654 /* 0x5d */ { NULL, NULL, 0 },
655 /* 0x5e */ { NULL, NULL, 0 },
656 /* 0x5f */ { NULL, NULL, 0 },
657 /* 0x60 */ { NULL, NULL, 0 },
658 /* 0x61 */ { NULL, NULL, 0 },
659 /* 0x62 */ { NULL, NULL, 0 },
660 /* 0x63 */ { NULL, NULL, 0 },
661 /* 0x64 */ { NULL, NULL, 0 },
662 /* 0x65 */ { NULL, NULL, 0 },
663 /* 0x66 */ { NULL, NULL, 0 },
664 /* 0x67 */ { NULL, NULL, 0 },
665 /* 0x68 */ { NULL, NULL, 0 },
666 /* 0x69 */ { NULL, NULL, 0 },
667 /* 0x6a */ { NULL, NULL, 0 },
668 /* 0x6b */ { NULL, NULL, 0 },
669 /* 0x6c */ { NULL, NULL, 0 },
670 /* 0x6d */ { NULL, NULL, 0 },
671 /* 0x6e */ { NULL, NULL, 0 },
672 /* 0x6f */ { NULL, NULL, 0 },
673 /* 0x70 */ { "SMBtcon",reply_tcon,0},
674 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
675 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
676 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
677 /* 0x74 */ { "SMBulogoffX", reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
678 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
679 /* 0x76 */ { NULL, NULL, 0 },
680 /* 0x77 */ { NULL, NULL, 0 },
681 /* 0x78 */ { NULL, NULL, 0 },
682 /* 0x79 */ { NULL, NULL, 0 },
683 /* 0x7a */ { NULL, NULL, 0 },
684 /* 0x7b */ { NULL, NULL, 0 },
685 /* 0x7c */ { NULL, NULL, 0 },
686 /* 0x7d */ { NULL, NULL, 0 },
687 /* 0x7e */ { NULL, NULL, 0 },
688 /* 0x7f */ { NULL, NULL, 0 },
689 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
690 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
691 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
692 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
693 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
694 /* 0x85 */ { NULL, NULL, 0 },
695 /* 0x86 */ { NULL, NULL, 0 },
696 /* 0x87 */ { NULL, NULL, 0 },
697 /* 0x88 */ { NULL, NULL, 0 },
698 /* 0x89 */ { NULL, NULL, 0 },
699 /* 0x8a */ { NULL, NULL, 0 },
700 /* 0x8b */ { NULL, NULL, 0 },
701 /* 0x8c */ { NULL, NULL, 0 },
702 /* 0x8d */ { NULL, NULL, 0 },
703 /* 0x8e */ { NULL, NULL, 0 },
704 /* 0x8f */ { NULL, NULL, 0 },
705 /* 0x90 */ { NULL, NULL, 0 },
706 /* 0x91 */ { NULL, NULL, 0 },
707 /* 0x92 */ { NULL, NULL, 0 },
708 /* 0x93 */ { NULL, NULL, 0 },
709 /* 0x94 */ { NULL, NULL, 0 },
710 /* 0x95 */ { NULL, NULL, 0 },
711 /* 0x96 */ { NULL, NULL, 0 },
712 /* 0x97 */ { NULL, NULL, 0 },
713 /* 0x98 */ { NULL, NULL, 0 },
714 /* 0x99 */ { NULL, NULL, 0 },
715 /* 0x9a */ { NULL, NULL, 0 },
716 /* 0x9b */ { NULL, NULL, 0 },
717 /* 0x9c */ { NULL, NULL, 0 },
718 /* 0x9d */ { NULL, NULL, 0 },
719 /* 0x9e */ { NULL, NULL, 0 },
720 /* 0x9f */ { NULL, NULL, 0 },
721 /* 0xa0 */ { "SMBnttrans", reply_nttrans, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK},
722 /* 0xa1 */ { "SMBnttranss", reply_nttranss, AS_USER | CAN_IPC },
723 /* 0xa2 */ { "SMBntcreateX", reply_ntcreate_and_X, AS_USER | CAN_IPC | QUEUE_IN_OPLOCK },
724 /* 0xa3 */ { NULL, NULL, 0 },
725 /* 0xa4 */ { "SMBntcancel", reply_ntcancel, 0 },
726 /* 0xa5 */ { "SMBntrename", reply_ntrename, AS_USER | NEED_WRITE | QUEUE_IN_OPLOCK },
727 /* 0xa6 */ { NULL, NULL, 0 },
728 /* 0xa7 */ { NULL, NULL, 0 },
729 /* 0xa8 */ { NULL, NULL, 0 },
730 /* 0xa9 */ { NULL, NULL, 0 },
731 /* 0xaa */ { NULL, NULL, 0 },
732 /* 0xab */ { NULL, NULL, 0 },
733 /* 0xac */ { NULL, NULL, 0 },
734 /* 0xad */ { NULL, NULL, 0 },
735 /* 0xae */ { NULL, NULL, 0 },
736 /* 0xaf */ { NULL, NULL, 0 },
737 /* 0xb0 */ { NULL, NULL, 0 },
738 /* 0xb1 */ { NULL, NULL, 0 },
739 /* 0xb2 */ { NULL, NULL, 0 },
740 /* 0xb3 */ { NULL, NULL, 0 },
741 /* 0xb4 */ { NULL, NULL, 0 },
742 /* 0xb5 */ { NULL, NULL, 0 },
743 /* 0xb6 */ { NULL, NULL, 0 },
744 /* 0xb7 */ { NULL, NULL, 0 },
745 /* 0xb8 */ { NULL, NULL, 0 },
746 /* 0xb9 */ { NULL, NULL, 0 },
747 /* 0xba */ { NULL, NULL, 0 },
748 /* 0xbb */ { NULL, NULL, 0 },
749 /* 0xbc */ { NULL, NULL, 0 },
750 /* 0xbd */ { NULL, NULL, 0 },
751 /* 0xbe */ { NULL, NULL, 0 },
752 /* 0xbf */ { NULL, NULL, 0 },
753 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER | QUEUE_IN_OPLOCK },
754 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
755 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
756 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
757 /* 0xc4 */ { NULL, NULL, 0 },
758 /* 0xc5 */ { NULL, NULL, 0 },
759 /* 0xc6 */ { NULL, NULL, 0 },
760 /* 0xc7 */ { NULL, NULL, 0 },
761 /* 0xc8 */ { NULL, NULL, 0 },
762 /* 0xc9 */ { NULL, NULL, 0 },
763 /* 0xca */ { NULL, NULL, 0 },
764 /* 0xcb */ { NULL, NULL, 0 },
765 /* 0xcc */ { NULL, NULL, 0 },
766 /* 0xcd */ { NULL, NULL, 0 },
767 /* 0xce */ { NULL, NULL, 0 },
768 /* 0xcf */ { NULL, NULL, 0 },
769 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
770 /* 0xd1 */ { "SMBsendb",NULL,AS_GUEST},
771 /* 0xd2 */ { "SMBfwdname",NULL,AS_GUEST},
772 /* 0xd3 */ { "SMBcancelf",NULL,AS_GUEST},
773 /* 0xd4 */ { "SMBgetmac",NULL,AS_GUEST},
774 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
775 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
776 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
777 /* 0xd8 */ { NULL, NULL, 0 },
778 /* 0xd9 */ { NULL, NULL, 0 },
779 /* 0xda */ { NULL, NULL, 0 },
780 /* 0xdb */ { NULL, NULL, 0 },
781 /* 0xdc */ { NULL, NULL, 0 },
782 /* 0xdd */ { NULL, NULL, 0 },
783 /* 0xde */ { NULL, NULL, 0 },
784 /* 0xdf */ { NULL, NULL, 0 },
785 /* 0xe0 */ { NULL, NULL, 0 },
786 /* 0xe1 */ { NULL, NULL, 0 },
787 /* 0xe2 */ { NULL, NULL, 0 },
788 /* 0xe3 */ { NULL, NULL, 0 },
789 /* 0xe4 */ { NULL, NULL, 0 },
790 /* 0xe5 */ { NULL, NULL, 0 },
791 /* 0xe6 */ { NULL, NULL, 0 },
792 /* 0xe7 */ { NULL, NULL, 0 },
793 /* 0xe8 */ { NULL, NULL, 0 },
794 /* 0xe9 */ { NULL, NULL, 0 },
795 /* 0xea */ { NULL, NULL, 0 },
796 /* 0xeb */ { NULL, NULL, 0 },
797 /* 0xec */ { NULL, NULL, 0 },
798 /* 0xed */ { NULL, NULL, 0 },
799 /* 0xee */ { NULL, NULL, 0 },
800 /* 0xef */ { NULL, NULL, 0 },
801 /* 0xf0 */ { NULL, NULL, 0 },
802 /* 0xf1 */ { NULL, NULL, 0 },
803 /* 0xf2 */ { NULL, NULL, 0 },
804 /* 0xf3 */ { NULL, NULL, 0 },
805 /* 0xf4 */ { NULL, NULL, 0 },
806 /* 0xf5 */ { NULL, NULL, 0 },
807 /* 0xf6 */ { NULL, NULL, 0 },
808 /* 0xf7 */ { NULL, NULL, 0 },
809 /* 0xf8 */ { NULL, NULL, 0 },
810 /* 0xf9 */ { NULL, NULL, 0 },
811 /* 0xfa */ { NULL, NULL, 0 },
812 /* 0xfb */ { NULL, NULL, 0 },
813 /* 0xfc */ { NULL, NULL, 0 },
814 /* 0xfd */ { NULL, NULL, 0 },
815 /* 0xfe */ { NULL, NULL, 0 },
816 /* 0xff */ { NULL, NULL, 0 }
817
818 };
819
820 /*******************************************************************
821  Dump a packet to a file.
822 ********************************************************************/
823
824 static void smb_dump(const char *name, int type, char *data, ssize_t len)
825 {
826         int fd, i;
827         pstring fname;
828         if (DEBUGLEVEL < 50) return;
829
830         if (len < 4) len = smb_len(data)+4;
831         for (i=1;i<100;i++) {
832                 slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.%s", name, i,
833                                 type ? "req" : "resp");
834                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
835                 if (fd != -1 || errno != EEXIST) break;
836         }
837         if (fd != -1) {
838                 ssize_t ret = write(fd, data, len);
839                 if (ret != len)
840                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
841                 close(fd);
842                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
843         }
844 }
845
846
847 /****************************************************************************
848  Do a switch on the message type, and return the response size
849 ****************************************************************************/
850
851 static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize)
852 {
853         static pid_t pid= (pid_t)-1;
854         int outsize = 0;
855         extern uint16 global_smbpid;
856
857         type &= 0xff;
858
859         if (pid == (pid_t)-1)
860                 pid = sys_getpid();
861
862         errno = 0;
863         last_message = type;
864
865         /* Make sure this is an SMB packet. smb_size contains NetBIOS header so subtract 4 from it. */
866         if ((strncmp(smb_base(inbuf),"\377SMB",4) != 0) || (size < (smb_size - 4))) {
867                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",smb_len(inbuf)));
868                 exit_server("Non-SMB packet");
869                 return(-1);
870         }
871
872         /* yuck! this is an interim measure before we get rid of our
873                 current inbuf/outbuf system */
874         global_smbpid = SVAL(inbuf,smb_pid);
875
876         if (smb_messages[type].fn == NULL) {
877                 DEBUG(0,("Unknown message type %d!\n",type));
878                 smb_dump("Unknown", 1, inbuf, size);
879                 outsize = reply_unknown(inbuf,outbuf);
880         } else {
881                 int flags = smb_messages[type].flags;
882                 static uint16 last_session_tag = UID_FIELD_INVALID;
883                 /* In share mode security we must ignore the vuid. */
884                 uint16 session_tag = (lp_security() == SEC_SHARE) ? UID_FIELD_INVALID : SVAL(inbuf,smb_uid);
885                 connection_struct *conn = conn_find(SVAL(inbuf,smb_tid));
886
887                 DEBUG(3,("switch message %s (pid %d) conn 0x%x\n",smb_fn_name(type),(int)pid,(unsigned int)conn));
888
889                 smb_dump(smb_fn_name(type), 1, inbuf, size);
890                 if(global_oplock_break) {
891                         if(flags & QUEUE_IN_OPLOCK) {
892                                 /* 
893                                  * Queue this message as we are the process of an oplock break.
894                                  */
895
896                                 DEBUG( 2, ( "switch_message: queueing message due to being in " ) );
897                                 DEBUGADD( 2, ( "oplock break state.\n" ) );
898
899                                 push_oplock_pending_smb_message( inbuf, size );
900                                 return -1;
901                         }
902                 }
903
904                 /* Ensure this value is replaced in the incoming packet. */
905                 SSVAL(inbuf,smb_uid,session_tag);
906
907                 /*
908                  * Ensure the correct username is in current_user_info.
909                  * This is a really ugly bugfix for problems with
910                  * multiple session_setup_and_X's being done and
911                  * allowing %U and %G substitutions to work correctly.
912                  * There is a reason this code is done here, don't
913                  * move it unless you know what you're doing... :-).
914                  * JRA.
915                  */
916
917                 if (session_tag != last_session_tag) {
918                         user_struct *vuser = NULL;
919
920                         last_session_tag = session_tag;
921                         if(session_tag != UID_FIELD_INVALID)
922                                 vuser = get_valid_user_struct(session_tag);           
923                         if(vuser != NULL)
924                                 set_current_user_info(&vuser->user);
925                 }
926
927                 /* does this protocol need to be run as root? */
928                 if (!(flags & AS_USER))
929                         change_to_root_user();
930
931                 /* does this protocol need a valid tree connection? */
932                 if ((flags & AS_USER) && !conn)
933                         return ERROR_DOS(ERRSRV, ERRinvnid);
934
935
936                 /* does this protocol need to be run as the connected user? */
937                 if ((flags & AS_USER) && !change_to_user(conn,session_tag)) {
938                         if (flags & AS_GUEST) 
939                                 flags &= ~AS_USER;
940                         else
941                                 return(ERROR_FORCE_DOS(ERRSRV,ERRbaduid));
942                 }
943
944                 /* this code is to work around a bug is MS client 3 without
945                         introducing a security hole - it needs to be able to do
946                         print queue checks as guest if it isn't logged in properly */
947                 if (flags & AS_USER)
948                         flags &= ~AS_GUEST;
949
950                 /* does it need write permission? */
951                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn))
952                         return(ERROR_DOS(ERRSRV,ERRaccess));
953
954                 /* ipc services are limited */
955                 if (IS_IPC(conn) && (flags & AS_USER) && !(flags & CAN_IPC))
956                         return(ERROR_DOS(ERRSRV,ERRaccess));        
957
958                 /* load service specific parameters */
959                 if (conn && !set_current_service(conn,SVAL(inbuf,smb_flg),(flags & (AS_USER|DO_CHDIR)?True:False)))
960                         return(ERROR_DOS(ERRSRV,ERRaccess));
961
962                 /* does this protocol need to be run as guest? */
963                 if ((flags & AS_GUEST) && (!change_to_guest() || 
964                                 !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))))
965                         return(ERROR_DOS(ERRSRV,ERRaccess));
966
967                 last_inbuf = inbuf;
968
969                 outsize = smb_messages[type].fn(conn, inbuf,outbuf,size,bufsize);
970         }
971
972         smb_dump(smb_fn_name(type), 0, outbuf, outsize);
973
974         return(outsize);
975 }
976
977
978 /****************************************************************************
979  Construct a reply to the incoming packet.
980 ****************************************************************************/
981
982 static int construct_reply(char *inbuf,char *outbuf,int size,int bufsize)
983 {
984         int type = CVAL(inbuf,smb_com);
985         int outsize = 0;
986         int msg_type = CVAL(inbuf,0);
987
988         GetTimeOfDay(&smb_last_time);
989
990         chain_size = 0;
991         file_chain_reset();
992         reset_chain_p();
993
994         if (msg_type != 0)
995                 return(reply_special(inbuf,outbuf));  
996
997         construct_reply_common(inbuf, outbuf);
998
999         outsize = switch_message(type,inbuf,outbuf,size,bufsize);
1000
1001         outsize += chain_size;
1002
1003         if(outsize > 4)
1004                 smb_setlen(outbuf,outsize - 4);
1005         return(outsize);
1006 }
1007
1008 /****************************************************************************
1009  Keep track of the number of running smbd's. This functionality is used to
1010  'hard' limit Samba overhead on resource constrained systems. 
1011 ****************************************************************************/
1012
1013 static BOOL process_count_update_successful = False;
1014
1015 static int32 increment_smbd_process_count(void)
1016 {
1017         int32 total_smbds;
1018
1019         if (lp_max_smbd_processes()) {
1020                 total_smbds = 0;
1021                 if (tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, 1) == -1)
1022                         return 1;
1023                 process_count_update_successful = True;
1024                 return total_smbds + 1;
1025         }
1026         return 1;
1027 }
1028
1029 void decrement_smbd_process_count(void)
1030 {
1031         int32 total_smbds;
1032
1033         if (lp_max_smbd_processes() && process_count_update_successful) {
1034                 total_smbds = 1;
1035                 tdb_change_int32_atomic(conn_tdb_ctx(), "INFO/total_smbds", &total_smbds, -1);
1036         }
1037 }
1038
1039 static BOOL smbd_process_limit(void)
1040 {
1041         int32  total_smbds;
1042         
1043         if (lp_max_smbd_processes()) {
1044
1045                 /* Always add one to the smbd process count, as exit_server() always
1046                  * subtracts one.
1047                  */
1048
1049                 if (!conn_tdb_ctx()) {
1050                         DEBUG(0,("smbd_process_limit: max smbd processes parameter set with status parameter not \
1051 set. Ignoring max smbd restriction.\n"));
1052                         return False;
1053                 }
1054
1055                 total_smbds = increment_smbd_process_count();
1056                 return total_smbds > lp_max_smbd_processes();
1057         }
1058         else
1059                 return False;
1060 }
1061
1062 /****************************************************************************
1063  Process an smb from the client - split out from the smbd_process() code so
1064  it can be used by the oplock break code.
1065 ****************************************************************************/
1066
1067 void process_smb(char *inbuf, char *outbuf)
1068 {
1069         static int trans_num;
1070         int msg_type = CVAL(inbuf,0);
1071         int32 len = smb_len(inbuf);
1072         int nread = len + 4;
1073
1074         DO_PROFILE_INC(smb_count);
1075
1076         if (trans_num == 0) {
1077                 /* on the first packet, check the global hosts allow/ hosts
1078                 deny parameters before doing any parsing of the packet
1079                 passed to us by the client.  This prevents attacks on our
1080                 parsing code from hosts not in the hosts allow list */
1081                 if (smbd_process_limit() ||
1082                                 !check_access(smbd_server_fd(), lp_hostsallow(-1), lp_hostsdeny(-1))) {
1083                         /* send a negative session response "not listening on calling name" */
1084                         static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
1085                         DEBUG( 1, ( "Connection denied from %s\n", client_addr() ) );
1086                         (void)send_smb(smbd_server_fd(),(char *)buf);
1087                         exit_server("connection denied");
1088                 }
1089         }
1090
1091         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type, len ) );
1092         DEBUG( 3, ( "Transaction %d of length %d\n", trans_num, nread ) );
1093
1094         if (msg_type == 0)
1095                 show_msg(inbuf);
1096         else if(msg_type == SMBkeepalive)
1097                 return; /* Keepalive packet. */
1098
1099         nread = construct_reply(inbuf,outbuf,nread,max_send);
1100       
1101         if(nread > 0) {
1102                 if (CVAL(outbuf,0) == 0)
1103                         show_msg(outbuf);
1104         
1105                 if (nread != smb_len(outbuf) + 4) {
1106                         DEBUG(0,("ERROR: Invalid message response size! %d %d\n",
1107                                 nread, smb_len(outbuf)));
1108                 } else if (!send_smb(smbd_server_fd(),outbuf)) {
1109                         exit_server("process_smb: send_smb failed.");
1110                 }
1111         }
1112         trans_num++;
1113 }
1114
1115 /****************************************************************************
1116  Return a string containing the function name of a SMB command.
1117 ****************************************************************************/
1118
1119 const char *smb_fn_name(int type)
1120 {
1121         const char *unknown_name = "SMBunknown";
1122
1123         if (smb_messages[type].name == NULL)
1124                 return(unknown_name);
1125
1126         return(smb_messages[type].name);
1127 }
1128
1129 /****************************************************************************
1130  Helper functions for contruct_reply.
1131 ****************************************************************************/
1132
1133 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
1134
1135 void add_to_common_flags2(uint32 v)
1136 {
1137         common_flags2 |= v;
1138 }
1139
1140 void remove_from_common_flags2(uint32 v)
1141 {
1142         common_flags2 &= ~v;
1143 }
1144
1145 void construct_reply_common(char *inbuf,char *outbuf)
1146 {
1147         memset(outbuf,'\0',smb_size);
1148
1149         set_message(outbuf,0,0,True);
1150         SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
1151         
1152         memcpy(outbuf+4,inbuf+4,4);
1153         SCVAL(outbuf,smb_rcls,SMB_SUCCESS);
1154         SCVAL(outbuf,smb_reh,0);
1155         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1156         SSVAL(outbuf,smb_flg2,
1157                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1158                 common_flags2);
1159
1160         SSVAL(outbuf,smb_err,SMB_SUCCESS);
1161         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1162         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1163         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1164         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1165 }
1166
1167 /****************************************************************************
1168  Construct a chained reply and add it to the already made reply
1169 ****************************************************************************/
1170
1171 int chain_reply(char *inbuf,char *outbuf,int size,int bufsize)
1172 {
1173         static char *orig_inbuf;
1174         static char *orig_outbuf;
1175         int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
1176         unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
1177         char *inbuf2, *outbuf2;
1178         int outsize2;
1179         char inbuf_saved[smb_wct];
1180         char outbuf_saved[smb_wct];
1181         int wct = CVAL(outbuf,smb_wct);
1182         int outsize = smb_size + 2*wct + SVAL(outbuf,smb_vwv0+2*wct);
1183
1184         /* maybe its not chained */
1185         if (smb_com2 == 0xFF) {
1186                 SCVAL(outbuf,smb_vwv0,0xFF);
1187                 return outsize;
1188         }
1189
1190         if (chain_size == 0) {
1191                 /* this is the first part of the chain */
1192                 orig_inbuf = inbuf;
1193                 orig_outbuf = outbuf;
1194         }
1195
1196         /*
1197          * The original Win95 redirector dies on a reply to
1198          * a lockingX and read chain unless the chain reply is
1199          * 4 byte aligned. JRA.
1200          */
1201
1202         outsize = (outsize + 3) & ~3;
1203
1204         /* we need to tell the client where the next part of the reply will be */
1205         SSVAL(outbuf,smb_vwv1,smb_offset(outbuf+outsize,outbuf));
1206         SCVAL(outbuf,smb_vwv0,smb_com2);
1207
1208         /* remember how much the caller added to the chain, only counting stuff
1209                 after the parameter words */
1210         chain_size += outsize - smb_wct;
1211
1212         /* work out pointers into the original packets. The
1213                 headers on these need to be filled in */
1214         inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
1215         outbuf2 = orig_outbuf + SVAL(outbuf,smb_vwv1) + 4 - smb_wct;
1216
1217         /* remember the original command type */
1218         smb_com1 = CVAL(orig_inbuf,smb_com);
1219
1220         /* save the data which will be overwritten by the new headers */
1221         memcpy(inbuf_saved,inbuf2,smb_wct);
1222         memcpy(outbuf_saved,outbuf2,smb_wct);
1223
1224         /* give the new packet the same header as the last part of the SMB */
1225         memmove(inbuf2,inbuf,smb_wct);
1226
1227         /* create the in buffer */
1228         SCVAL(inbuf2,smb_com,smb_com2);
1229
1230         /* create the out buffer */
1231         construct_reply_common(inbuf2, outbuf2);
1232
1233         DEBUG(3,("Chained message\n"));
1234         show_msg(inbuf2);
1235
1236         /* process the request */
1237         outsize2 = switch_message(smb_com2,inbuf2,outbuf2,size-chain_size,
1238                                 bufsize-chain_size);
1239
1240         /* copy the new reply and request headers over the old ones, but
1241                 preserve the smb_com field */
1242         memmove(orig_outbuf,outbuf2,smb_wct);
1243         SCVAL(orig_outbuf,smb_com,smb_com1);
1244
1245         /* restore the saved data, being careful not to overwrite any
1246                 data from the reply header */
1247         memcpy(inbuf2,inbuf_saved,smb_wct);
1248
1249         {
1250                 int ofs = smb_wct - PTR_DIFF(outbuf2,orig_outbuf);
1251                 if (ofs < 0) ofs = 0;
1252                         memmove(outbuf2+ofs,outbuf_saved+ofs,smb_wct-ofs);
1253         }
1254
1255         return outsize2;
1256 }
1257
1258 /****************************************************************************
1259  Setup the needed select timeout.
1260 ****************************************************************************/
1261
1262 static int setup_select_timeout(void)
1263 {
1264         int select_timeout;
1265         int t;
1266
1267         select_timeout = blocking_locks_timeout(SMBD_SELECT_TIMEOUT);
1268         select_timeout *= 1000;
1269
1270         t = change_notify_timeout();
1271         if (t != -1)
1272                 select_timeout = MIN(select_timeout, t*1000);
1273
1274         if (print_notify_messages_pending())
1275                 select_timeout = MIN(select_timeout, 1000);
1276
1277         return select_timeout;
1278 }
1279
1280 /****************************************************************************
1281  Check if services need reloading.
1282 ****************************************************************************/
1283
1284 void check_reload(int t)
1285 {
1286         static time_t last_smb_conf_reload_time = 0;
1287         static time_t last_load_printers_reload_time = 0;
1288         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1289
1290         if(last_smb_conf_reload_time == 0) {
1291                 last_smb_conf_reload_time = t;
1292                 /* Our printing subsystem might not be ready at smbd start up.
1293                    Then no printer is available till the first printers check
1294                    is performed.  A lower initial interval circumvents this. */
1295                 if ( printcap_cache_time > 60 )
1296                         last_load_printers_reload_time = t - printcap_cache_time + 60;
1297                 else
1298                         last_load_printers_reload_time = t;
1299         }
1300
1301         if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
1302                 reload_services(True);
1303                 reload_after_sighup = False;
1304                 last_smb_conf_reload_time = t;
1305         }
1306
1307         /* 'printcap cache time = 0' disable the feature */
1308         
1309         if ( printcap_cache_time != 0 )
1310         { 
1311                 /* see if it's time to reload or if the clock has been set back */
1312                 
1313                 if ( (t >= last_load_printers_reload_time+printcap_cache_time) 
1314                         || (t-last_load_printers_reload_time  < 0) ) 
1315                 {
1316                         DEBUG( 3,( "Printcap cache time expired.\n"));
1317                         remove_stale_printers();
1318                         load_printers();
1319                         last_load_printers_reload_time = t;
1320                 }
1321         }
1322 }
1323
1324 /****************************************************************************
1325  Process any timeout housekeeping. Return False if the caller should exit.
1326 ****************************************************************************/
1327
1328 static BOOL timeout_processing(int deadtime, int *select_timeout, time_t *last_timeout_processing_time)
1329 {
1330         static time_t last_keepalive_sent_time = 0;
1331         static time_t last_idle_closed_check = 0;
1332         time_t t;
1333         BOOL allidle = True;
1334         extern int keepalive;
1335
1336         if (smb_read_error == READ_EOF) {
1337                 DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
1338                 return False;
1339         }
1340
1341         if (smb_read_error == READ_ERROR) {
1342                 DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
1343                         strerror(errno)));
1344                 return False;
1345         }
1346
1347         if (smb_read_error == READ_BAD_SIG) {
1348                 DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
1349                 return False;
1350         }
1351
1352         *last_timeout_processing_time = t = time(NULL);
1353
1354         if(last_keepalive_sent_time == 0)
1355                 last_keepalive_sent_time = t;
1356
1357         if(last_idle_closed_check == 0)
1358                 last_idle_closed_check = t;
1359
1360         /* become root again if waiting */
1361         change_to_root_user();
1362
1363         /* run all registered idle events */
1364         smb_run_idle_events(t);
1365
1366         /* check if we need to reload services */
1367         check_reload(t);
1368
1369         /* automatic timeout if all connections are closed */      
1370         if (conn_num_open()==0 && (t - last_idle_closed_check) >= IDLE_CLOSED_TIMEOUT) {
1371                 DEBUG( 2, ( "Closing idle connection\n" ) );
1372                 return False;
1373         } else {
1374                 last_idle_closed_check = t;
1375         }
1376
1377         if (keepalive && (t - last_keepalive_sent_time)>keepalive) {
1378                 extern struct auth_context *negprot_global_auth_context;
1379                 if (!send_keepalive(smbd_server_fd())) {
1380                         DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
1381                         return False;
1382                 }
1383
1384                 /* send a keepalive for a password server or the like.
1385                         This is attached to the auth_info created in the
1386                 negprot */
1387                 if (negprot_global_auth_context && negprot_global_auth_context->challenge_set_method 
1388                                 && negprot_global_auth_context->challenge_set_method->send_keepalive) {
1389
1390                         negprot_global_auth_context->challenge_set_method->send_keepalive
1391                         (&negprot_global_auth_context->challenge_set_method->private_data);
1392                 }
1393
1394                 last_keepalive_sent_time = t;
1395         }
1396
1397         /* check for connection timeouts */
1398         allidle = conn_idle_all(t, deadtime);
1399
1400         if (allidle && conn_num_open()>0) {
1401                 DEBUG(2,("Closing idle connection 2.\n"));
1402                 return False;
1403         }
1404
1405         if(global_machine_password_needs_changing && 
1406                         /* for ADS we need to do a regular ADS password change, not a domain
1407                                         password change */
1408                         lp_security() == SEC_DOMAIN) {
1409
1410                 unsigned char trust_passwd_hash[16];
1411                 time_t lct;
1412
1413                 /*
1414                  * We're in domain level security, and the code that
1415                  * read the machine password flagged that the machine
1416                  * password needs changing.
1417                  */
1418
1419                 /*
1420                  * First, open the machine password file with an exclusive lock.
1421                  */
1422
1423                 if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
1424                         DEBUG(0,("process: unable to lock the machine account password for \
1425 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
1426                         return True;
1427                 }
1428
1429                 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
1430                         DEBUG(0,("process: unable to read the machine account password for \
1431 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
1432                         secrets_lock_trust_account_password(lp_workgroup(), False);
1433                         return True;
1434                 }
1435
1436                 /*
1437                  * Make sure someone else hasn't already done this.
1438                  */
1439
1440                 if(t < lct + lp_machine_password_timeout()) {
1441                         global_machine_password_needs_changing = False;
1442                         secrets_lock_trust_account_password(lp_workgroup(), False);
1443                         return True;
1444                 }
1445
1446                 /* always just contact the PDC here */
1447     
1448                 change_trust_account_password( lp_workgroup(), NULL);
1449                 global_machine_password_needs_changing = False;
1450                 secrets_lock_trust_account_password(lp_workgroup(), False);
1451         }
1452
1453         /*
1454          * Check to see if we have any blocking locks
1455          * outstanding on the queue.
1456          */
1457         process_blocking_lock_queue(t);
1458
1459         /* update printer queue caches if necessary */
1460   
1461         update_monitored_printq_cache();
1462   
1463         /*
1464          * Check to see if we have any change notifies 
1465          * outstanding on the queue.
1466          */
1467         process_pending_change_notify_queue(t);
1468
1469         /*
1470          * Now we are root, check if the log files need pruning.
1471          * Force a log file check.
1472          */
1473         force_check_log_size();
1474         check_log_size();
1475
1476         /* Send any queued printer notify message to interested smbd's. */
1477
1478         print_notify_send_messages(0);
1479
1480         /*
1481          * Modify the select timeout depending upon
1482          * what we have remaining in our queues.
1483          */
1484
1485         *select_timeout = setup_select_timeout();
1486
1487         return True;
1488 }
1489
1490 /****************************************************************************
1491   process commands from the client
1492 ****************************************************************************/
1493
1494 void smbd_process(void)
1495 {
1496         extern int smb_echo_count;
1497         time_t last_timeout_processing_time = time(NULL);
1498         unsigned int num_smbs = 0;
1499         const size_t total_buffer_size = BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN;
1500
1501         InBuffer = (char *)malloc(total_buffer_size);
1502         OutBuffer = (char *)malloc(total_buffer_size);
1503         if ((InBuffer == NULL) || (OutBuffer == NULL)) 
1504                 return;
1505
1506 #if defined(DEVELOPER)
1507         clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
1508         clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
1509 #endif
1510
1511         max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
1512
1513         while (True) {
1514                 int deadtime = lp_deadtime()*60;
1515                 int select_timeout = setup_select_timeout();
1516                 int num_echos;
1517
1518                 if (deadtime <= 0)
1519                         deadtime = DEFAULT_SMBD_TIMEOUT;
1520
1521                 errno = 0;      
1522                 
1523                 /* free up temporary memory */
1524                 lp_talloc_free();
1525                 main_loop_talloc_free();
1526
1527                 /* run all registered idle events */
1528                 smb_run_idle_events(time(NULL));
1529
1530
1531                 /* Did someone ask for immediate checks on things like blocking locks ? */
1532                 if (select_timeout == 0) {
1533                         if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
1534                                 return;
1535                         num_smbs = 0; /* Reset smb counter. */
1536                 }
1537
1538 #if defined(DEVELOPER)
1539                 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, InBuffer, total_buffer_size);
1540 #endif
1541
1542                 while (!receive_message_or_smb(InBuffer,BUFFER_SIZE+LARGE_WRITEX_HDR_SIZE,select_timeout)) {
1543                         if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
1544                                 return;
1545                         num_smbs = 0; /* Reset smb counter. */
1546                 }
1547
1548                 /*
1549                  * Ensure we do timeout processing if the SMB we just got was
1550                  * only an echo request. This allows us to set the select
1551                  * timeout in 'receive_message_or_smb()' to any value we like
1552                  * without worrying that the client will send echo requests
1553                  * faster than the select timeout, thus starving out the
1554                  * essential processing (change notify, blocking locks) that
1555                  * the timeout code does. JRA.
1556                  */ 
1557                 num_echos = smb_echo_count;
1558
1559                 clobber_region(SAFE_STRING_FUNCTION_NAME, SAFE_STRING_LINE, OutBuffer, total_buffer_size);
1560
1561                 process_smb(InBuffer, OutBuffer);
1562
1563                 if (smb_echo_count != num_echos) {
1564                         if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
1565                                 return;
1566                         num_smbs = 0; /* Reset smb counter. */
1567                 }
1568
1569                 num_smbs++;
1570
1571                 /*
1572                  * If we are getting smb requests in a constant stream
1573                  * with no echos, make sure we attempt timeout processing
1574                  * every select_timeout milliseconds - but only check for this
1575                  * every 200 smb requests.
1576                  */
1577                 
1578                 if ((num_smbs % 200) == 0) {
1579                         time_t new_check_time = time(NULL);
1580                         if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
1581                                 if(!timeout_processing( deadtime, &select_timeout, &last_timeout_processing_time))
1582                                         return;
1583                                 num_smbs = 0; /* Reset smb counter. */
1584                                 last_timeout_processing_time = new_check_time; /* Reset time. */
1585                         }
1586                 }
1587
1588                 /* The timeout_processing function isn't run nearly
1589                    often enough to implement 'max log size' without
1590                    overrunning the size of the file by many megabytes.
1591                    This is especially true if we are running at debug
1592                    level 10.  Checking every 50 SMBs is a nice
1593                    tradeoff of performance vs log file size overrun. */
1594
1595                 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
1596                         change_to_root_user();
1597                         check_log_size();
1598                 }
1599         }
1600 }