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