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