Forgot arg type.
[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    Copyright (C) Volker Lendecke 2005-2007
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22
23 extern struct auth_context *negprot_global_auth_context;
24 extern int smb_echo_count;
25
26 const int total_buffer_size = (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE + SAFETY_MARGIN);
27
28 /*
29  * Size of data we can send to client. Set
30  *  by the client for all protocols above CORE.
31  *  Set by us for CORE protocol.
32  */
33 int max_send = BUFFER_SIZE;
34 /*
35  * Size of the data we can receive. Set by us.
36  * Can be modified by the max xmit parameter.
37  */
38 int max_recv = BUFFER_SIZE;
39
40 extern int last_message;
41 SIG_ATOMIC_T reload_after_sighup = 0;
42 SIG_ATOMIC_T got_sig_term = 0;
43 extern bool global_machine_password_needs_changing;
44 extern int max_send;
45
46 /* Socket functions for smbd packet processing. */
47
48 static bool valid_packet_size(size_t len)
49 {
50         /*
51          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
52          * of header. Don't print the error if this fits.... JRA.
53          */
54
55         if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
56                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
57                                         (unsigned long)len));
58                 if (len > BUFFER_SIZE + (SAFETY_MARGIN/2)) {
59
60                         /*
61                          * Correct fix. smb_read_error may have already been
62                          * set. Only set it here if not already set. Global
63                          * variables still suck :-). JRA.
64                          */
65
66                         cond_set_smb_read_error(SMB_READ_ERROR);
67                         return false;
68                 }
69         }
70         return true;
71 }
72
73 static ssize_t read_packet_remainder(int fd,
74                                         char *buffer,
75                                         unsigned int timeout,
76                                         ssize_t len)
77 {
78         ssize_t ret;
79
80         if(len <= 0) {
81                 return len;
82         }
83
84         if (timeout > 0) {
85                 ret = read_socket_with_timeout(fd,
86                                                 buffer,
87                                                 len,
88                                                 len,
89                                                 timeout);
90         } else {
91                 ret = read_data(fd, buffer, len);
92         }
93
94         if (ret != len) {
95                 cond_set_smb_read_error(SMB_READ_ERROR);
96                 return -1;
97         }
98
99         return len;
100 }
101
102 /****************************************************************************
103  Attempt a zerocopy writeX read. We know here that len > smb_size-4
104 ****************************************************************************/
105
106 /*
107  * Unfortunately, earlier versions of smbclient/libsmbclient
108  * don't send this "standard" writeX header. I've fixed this
109  * for 3.2 but we'll use the old method with earlier versions.
110  * Windows and CIFSFS at least use this standard size. Not
111  * sure about MacOSX.
112  */
113
114 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
115                                 (2*14) + /* word count (including bcc) */ \
116                                 1 /* pad byte */)
117
118 ssize_t receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
119                                         const char lenbuf[4],
120                                         int fd,
121                                         char **buffer,
122                                         unsigned int timeout,
123                                         size_t *p_unread)
124 {
125         /* Size of a WRITEX call (+4 byte len). */
126         char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
127         ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
128         ssize_t toread;
129         ssize_t ret;
130
131         memcpy(writeX_header, lenbuf, sizeof(lenbuf));
132
133         if (timeout > 0) {
134                 ret = read_socket_with_timeout(fd,
135                                         writeX_header + 4,
136                                         STANDARD_WRITE_AND_X_HEADER_SIZE,
137                                         STANDARD_WRITE_AND_X_HEADER_SIZE,
138                                         timeout);
139         } else {
140                 ret = read_data(fd,
141                                 writeX_header+4,
142                                 STANDARD_WRITE_AND_X_HEADER_SIZE);
143         }
144
145         if (ret != STANDARD_WRITE_AND_X_HEADER_SIZE) {
146                 cond_set_smb_read_error(SMB_READ_ERROR);
147                 return -1;
148         }
149
150         /*
151          * Ok - now try and see if this is a possible
152          * valid writeX call.
153          */
154
155         if (is_valid_writeX_buffer(writeX_header)) {
156                 /*
157                  * If the data offset is beyond what
158                  * we've read, drain the extra bytes.
159                  */
160                 uint16_t doff = SVAL(writeX_header,smb_vwv11);
161                 ssize_t newlen;
162
163                 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
164                         size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
165                         if (drain_socket(smbd_server_fd(), drain) != drain) {
166                                 smb_panic("receive_smb_raw_talloc_partial_read:"
167                                         " failed to drain pending bytes");
168                         }
169                 } else {
170                         doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
171                 }
172
173                 /* Spoof down the length and null out the bcc. */
174                 set_message_bcc(writeX_header, 0);
175                 newlen = smb_len(writeX_header);
176
177                 /* Copy the header we've written. */
178
179                 *buffer = TALLOC_MEMDUP(mem_ctx,
180                                 writeX_header,
181                                 sizeof(writeX_header));
182
183                 if (*buffer == NULL) {
184                         DEBUG(0, ("Could not allocate inbuf of length %d\n",
185                                   (int)sizeof(writeX_header)));
186                         cond_set_smb_read_error(SMB_READ_ERROR);
187                         return -1;
188                 }
189
190                 /* Work out the remaining bytes. */
191                 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
192
193                 return newlen + 4;
194         }
195
196         if (!valid_packet_size(len)) {
197                 return -1;
198         }
199
200         /*
201          * Not a valid writeX call. Just do the standard
202          * talloc and return.
203          */
204
205         *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
206
207         if (*buffer == NULL) {
208                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
209                           (int)len+4));
210                 cond_set_smb_read_error(SMB_READ_ERROR);
211                 return -1;
212         }
213
214         /* Copy in what we already read. */
215         memcpy(*buffer,
216                 writeX_header,
217                 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
218         toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
219
220         if(toread > 0) {
221                 ret = read_packet_remainder(fd,
222                         (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
223                                         timeout,
224                                         toread);
225                 if (ret != toread) {
226                         return -1;
227                 }
228         }
229
230         return len + 4;
231 }
232
233 static ssize_t receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
234                                         int fd,
235                                         char **buffer,
236                                         unsigned int timeout,
237                                         size_t *p_unread)
238 {
239         char lenbuf[4];
240         ssize_t len,ret;
241         int min_recv_size = lp_min_receive_file_size();
242
243         set_smb_read_error(SMB_READ_OK);
244         *p_unread = 0;
245
246         len = read_smb_length_return_keepalive(fd, lenbuf, timeout);
247         if (len < 0) {
248                 DEBUG(10,("receive_smb_raw: length < 0!\n"));
249
250                 /*
251                  * Correct fix. smb_read_error may have already been
252                  * set. Only set it here if not already set. Global
253                  * variables still suck :-). JRA.
254                  */
255
256                 cond_set_smb_read_error(SMB_READ_ERROR);
257                 return -1;
258         }
259
260         if (CVAL(lenbuf,0) != SMBkeepalive &&
261                         min_recv_size &&
262                         smb_len_large(lenbuf) > min_recv_size && /* Could be a UNIX large writeX. */
263                         !srv_is_signing_active()) {
264
265                 return receive_smb_raw_talloc_partial_read(mem_ctx,
266                                                         lenbuf,
267                                                         fd,
268                                                         buffer,
269                                                         timeout,
270                                                         p_unread);
271         }
272
273         if (!valid_packet_size(len)) {
274                 return -1;
275         }
276
277         /*
278          * The +4 here can't wrap, we've checked the length above already.
279          */
280
281         *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
282
283         if (*buffer == NULL) {
284                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
285                           (int)len+4));
286                 cond_set_smb_read_error(SMB_READ_ERROR);
287                 return -1;
288         }
289
290         memcpy(*buffer, lenbuf, sizeof(lenbuf));
291
292         ret = read_packet_remainder(fd, (*buffer)+4, timeout, len);
293         if (ret != len) {
294                 return -1;
295         }
296
297         return len + 4;
298 }
299
300 ssize_t receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd, char **buffer,
301                            unsigned int timeout, size_t *p_unread)
302 {
303         ssize_t len;
304
305         len = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout, p_unread);
306
307         if (len < 0) {
308                 return -1;
309         }
310
311         /* Check the incoming SMB signature. */
312         if (!srv_check_sign_mac(*buffer, true)) {
313                 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
314                           "incoming packet!\n"));
315                 cond_set_smb_read_error(SMB_READ_BAD_SIG);
316                 return -1;
317         }
318
319         return len;
320 }
321
322 /*
323  * Initialize a struct smb_request from an inbuf
324  */
325
326 void init_smb_request(struct smb_request *req,
327                         const uint8 *inbuf,
328                         size_t unread_bytes)
329 {
330         size_t req_size = smb_len(inbuf) + 4;
331         /* Ensure we have at least smb_size bytes. */
332         if (req_size < smb_size) {
333                 DEBUG(0,("init_smb_request: invalid request size %u\n",
334                         (unsigned int)req_size ));
335                 exit_server_cleanly("Invalid SMB request");
336         }
337         req->flags2 = SVAL(inbuf, smb_flg2);
338         req->smbpid = SVAL(inbuf, smb_pid);
339         req->mid    = SVAL(inbuf, smb_mid);
340         req->vuid   = SVAL(inbuf, smb_uid);
341         req->tid    = SVAL(inbuf, smb_tid);
342         req->wct    = CVAL(inbuf, smb_wct);
343         req->unread_bytes = unread_bytes;
344
345         /* Ensure we have at least wct words and 2 bytes of bcc. */
346         if (smb_size + req->wct*2 > req_size) {
347                 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
348                         (unsigned int)req->wct,
349                         (unsigned int)req_size));
350                 exit_server_cleanly("Invalid SMB request");
351         }
352         /* Ensure bcc is correct. */
353         if (((uint8 *)smb_buf(inbuf)) + smb_buflen(inbuf) > inbuf + req_size) {
354                 DEBUG(0,("init_smb_request: invalid bcc number %u "
355                         "(wct = %u, size %u)\n",
356                         (unsigned int)smb_buflen(inbuf),
357                         (unsigned int)req->wct,
358                         (unsigned int)req_size));
359                 exit_server_cleanly("Invalid SMB request");
360         }
361         req->inbuf  = inbuf;
362         req->outbuf = NULL;
363 }
364
365 /****************************************************************************
366  structure to hold a linked list of queued messages.
367  for processing.
368 ****************************************************************************/
369
370 static struct pending_message_list *deferred_open_queue;
371
372 /****************************************************************************
373  Function to push a message onto the tail of a linked list of smb messages ready
374  for processing.
375 ****************************************************************************/
376
377 static bool push_queued_message(struct smb_request *req,
378                                 struct timeval request_time,
379                                 struct timeval end_time,
380                                 char *private_data, size_t private_len)
381 {
382         int msg_len = smb_len(req->inbuf) + 4;
383         struct pending_message_list *msg;
384
385         msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
386
387         if(msg == NULL) {
388                 DEBUG(0,("push_message: malloc fail (1)\n"));
389                 return False;
390         }
391
392         msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
393         if(msg->buf.data == NULL) {
394                 DEBUG(0,("push_message: malloc fail (2)\n"));
395                 TALLOC_FREE(msg);
396                 return False;
397         }
398
399         msg->request_time = request_time;
400         msg->end_time = end_time;
401
402         if (private_data) {
403                 msg->private_data = data_blob_talloc(msg, private_data,
404                                                      private_len);
405                 if (msg->private_data.data == NULL) {
406                         DEBUG(0,("push_message: malloc fail (3)\n"));
407                         TALLOC_FREE(msg);
408                         return False;
409                 }
410         }
411
412         DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
413
414         DEBUG(10,("push_message: pushed message length %u on "
415                   "deferred_open_queue\n", (unsigned int)msg_len));
416
417         return True;
418 }
419
420 /****************************************************************************
421  Function to delete a sharing violation open message by mid.
422 ****************************************************************************/
423
424 void remove_deferred_open_smb_message(uint16 mid)
425 {
426         struct pending_message_list *pml;
427
428         for (pml = deferred_open_queue; pml; pml = pml->next) {
429                 if (mid == SVAL(pml->buf.data,smb_mid)) {
430                         DEBUG(10,("remove_sharing_violation_open_smb_message: "
431                                   "deleting mid %u len %u\n",
432                                   (unsigned int)mid,
433                                   (unsigned int)pml->buf.length ));
434                         DLIST_REMOVE(deferred_open_queue, pml);
435                         TALLOC_FREE(pml);
436                         return;
437                 }
438         }
439 }
440
441 /****************************************************************************
442  Move a sharing violation open retry message to the front of the list and
443  schedule it for immediate processing.
444 ****************************************************************************/
445
446 void schedule_deferred_open_smb_message(uint16 mid)
447 {
448         struct pending_message_list *pml;
449         int i = 0;
450
451         for (pml = deferred_open_queue; pml; pml = pml->next) {
452                 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
453                 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
454                         (unsigned int)msg_mid ));
455                 if (mid == msg_mid) {
456                         DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
457                                 mid ));
458                         pml->end_time.tv_sec = 0;
459                         pml->end_time.tv_usec = 0;
460                         DLIST_PROMOTE(deferred_open_queue, pml);
461                         return;
462                 }
463         }
464
465         DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
466                 mid ));
467 }
468
469 /****************************************************************************
470  Return true if this mid is on the deferred queue.
471 ****************************************************************************/
472
473 bool open_was_deferred(uint16 mid)
474 {
475         struct pending_message_list *pml;
476
477         for (pml = deferred_open_queue; pml; pml = pml->next) {
478                 if (SVAL(pml->buf.data,smb_mid) == mid) {
479                         return True;
480                 }
481         }
482         return False;
483 }
484
485 /****************************************************************************
486  Return the message queued by this mid.
487 ****************************************************************************/
488
489 struct pending_message_list *get_open_deferred_message(uint16 mid)
490 {
491         struct pending_message_list *pml;
492
493         for (pml = deferred_open_queue; pml; pml = pml->next) {
494                 if (SVAL(pml->buf.data,smb_mid) == mid) {
495                         return pml;
496                 }
497         }
498         return NULL;
499 }
500
501 /****************************************************************************
502  Function to push a deferred open smb message onto a linked list of local smb
503  messages ready for processing.
504 ****************************************************************************/
505
506 bool push_deferred_smb_message(struct smb_request *req,
507                                struct timeval request_time,
508                                struct timeval timeout,
509                                char *private_data, size_t priv_len)
510 {
511         struct timeval end_time;
512
513         if (req->unread_bytes) {
514                 DEBUG(0,("push_deferred_smb_message: logic error ! "
515                         "unread_bytes = %u\n",
516                         (unsigned int)req->unread_bytes ));
517                 smb_panic("push_deferred_smb_message: "
518                         "logic error unread_bytes != 0" );
519         }
520
521         end_time = timeval_sum(&request_time, &timeout);
522
523         DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
524                   "timeout time [%u.%06u]\n",
525                   (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
526                   (unsigned int)end_time.tv_sec,
527                   (unsigned int)end_time.tv_usec));
528
529         return push_queued_message(req, request_time, end_time,
530                                    private_data, priv_len);
531 }
532
533 struct idle_event {
534         struct timed_event *te;
535         struct timeval interval;
536         char *name;
537         bool (*handler)(const struct timeval *now, void *private_data);
538         void *private_data;
539 };
540
541 static void idle_event_handler(struct event_context *ctx,
542                                struct timed_event *te,
543                                const struct timeval *now,
544                                void *private_data)
545 {
546         struct idle_event *event =
547                 talloc_get_type_abort(private_data, struct idle_event);
548
549         TALLOC_FREE(event->te);
550
551         if (!event->handler(now, event->private_data)) {
552                 /* Don't repeat, delete ourselves */
553                 TALLOC_FREE(event);
554                 return;
555         }
556
557         event->te = event_add_timed(ctx, event,
558                                     timeval_sum(now, &event->interval),
559                                     event->name,
560                                     idle_event_handler, event);
561
562         /* We can't do much but fail here. */
563         SMB_ASSERT(event->te != NULL);
564 }
565
566 struct idle_event *event_add_idle(struct event_context *event_ctx,
567                                   TALLOC_CTX *mem_ctx,
568                                   struct timeval interval,
569                                   const char *name,
570                                   bool (*handler)(const struct timeval *now,
571                                                   void *private_data),
572                                   void *private_data)
573 {
574         struct idle_event *result;
575         struct timeval now = timeval_current();
576
577         result = TALLOC_P(mem_ctx, struct idle_event);
578         if (result == NULL) {
579                 DEBUG(0, ("talloc failed\n"));
580                 return NULL;
581         }
582
583         result->interval = interval;
584         result->handler = handler;
585         result->private_data = private_data;
586
587         if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
588                 DEBUG(0, ("talloc failed\n"));
589                 TALLOC_FREE(result);
590                 return NULL;
591         }
592
593         result->te = event_add_timed(event_ctx, result,
594                                      timeval_sum(&now, &interval),
595                                      result->name,
596                                      idle_event_handler, result);
597         if (result->te == NULL) {
598                 DEBUG(0, ("event_add_timed failed\n"));
599                 TALLOC_FREE(result);
600                 return NULL;
601         }
602
603         return result;
604 }
605
606 /****************************************************************************
607  Do all async processing in here. This includes kernel oplock messages, change
608  notify events etc.
609 ****************************************************************************/
610
611 static void async_processing(fd_set *pfds)
612 {
613         DEBUG(10,("async_processing: Doing async processing.\n"));
614
615         process_aio_queue();
616
617         process_kernel_oplocks(smbd_messaging_context(), pfds);
618
619         /* Do the aio check again after receive_local_message as it does a
620            select and may have eaten our signal. */
621         /* Is this till true? -- vl */
622         process_aio_queue();
623
624         if (got_sig_term) {
625                 exit_server_cleanly("termination signal");
626         }
627
628         /* check for sighup processing */
629         if (reload_after_sighup) {
630                 change_to_root_user();
631                 DEBUG(1,("Reloading services after SIGHUP\n"));
632                 reload_services(False);
633                 reload_after_sighup = 0;
634         }
635 }
636
637 /****************************************************************************
638  Add a fd to the set we will be select(2)ing on.
639 ****************************************************************************/
640
641 static int select_on_fd(int fd, int maxfd, fd_set *fds)
642 {
643         if (fd != -1) {
644                 FD_SET(fd, fds);
645                 maxfd = MAX(maxfd, fd);
646         }
647
648         return maxfd;
649 }
650
651 /****************************************************************************
652   Do a select on an two fd's - with timeout. 
653
654   If a local udp message has been pushed onto the
655   queue (this can only happen during oplock break
656   processing) call async_processing()
657
658   If a pending smb message has been pushed onto the
659   queue (this can only happen during oplock break
660   processing) return this next.
661
662   If the first smbfd is ready then read an smb from it.
663   if the second (loopback UDP) fd is ready then read a message
664   from it and setup the buffer header to identify the length
665   and from address.
666   Returns False on timeout or error.
667   Else returns True.
668
669 The timeout is in milliseconds
670 ****************************************************************************/
671
672 static bool receive_message_or_smb(TALLOC_CTX *mem_ctx,
673                                 char **buffer,
674                                 size_t *buffer_len,
675                                 int timeout,
676                                 size_t *p_unread)
677 {
678         fd_set r_fds, w_fds;
679         int selrtn;
680         struct timeval to;
681         int maxfd = 0;
682         ssize_t len;
683
684         *p_unread = 0;
685         set_smb_read_error(SMB_READ_OK);
686
687  again:
688
689         if (timeout >= 0) {
690                 to.tv_sec = timeout / 1000;
691                 to.tv_usec = (timeout % 1000) * 1000;
692         } else {
693                 to.tv_sec = SMBD_SELECT_TIMEOUT;
694                 to.tv_usec = 0;
695         }
696
697         /*
698          * Note that this call must be before processing any SMB
699          * messages as we need to synchronously process any messages
700          * we may have sent to ourselves from the previous SMB.
701          */
702         message_dispatch(smbd_messaging_context());
703
704         /*
705          * Check to see if we already have a message on the deferred open queue
706          * and it's time to schedule.
707          */
708         if(deferred_open_queue != NULL) {
709                 bool pop_message = False;
710                 struct pending_message_list *msg = deferred_open_queue;
711
712                 if (timeval_is_zero(&msg->end_time)) {
713                         pop_message = True;
714                 } else {
715                         struct timeval tv;
716                         SMB_BIG_INT tdif;
717
718                         GetTimeOfDay(&tv);
719                         tdif = usec_time_diff(&msg->end_time, &tv);
720                         if (tdif <= 0) {
721                                 /* Timed out. Schedule...*/
722                                 pop_message = True;
723                                 DEBUG(10,("receive_message_or_smb: queued message timed out.\n"));
724                         } else {
725                                 /* Make a more accurate select timeout. */
726                                 to.tv_sec = tdif / 1000000;
727                                 to.tv_usec = tdif % 1000000;
728                                 DEBUG(10,("receive_message_or_smb: select with timeout of [%u.%06u]\n",
729                                         (unsigned int)to.tv_sec, (unsigned int)to.tv_usec ));
730                         }
731                 }
732
733                 if (pop_message) {
734
735                         *buffer = (char *)talloc_memdup(mem_ctx, msg->buf.data,
736                                                         msg->buf.length);
737                         if (*buffer == NULL) {
738                                 DEBUG(0, ("talloc failed\n"));
739                                 set_smb_read_error(SMB_READ_ERROR);
740                                 return False;
741                         }
742                         *buffer_len = msg->buf.length;
743
744                         /* We leave this message on the queue so the open code can
745                            know this is a retry. */
746                         DEBUG(5,("receive_message_or_smb: returning deferred open smb message.\n"));
747                         return True;
748                 }
749         }
750
751         /*
752          * Setup the select fd sets.
753          */
754
755         FD_ZERO(&r_fds);
756         FD_ZERO(&w_fds);
757
758         /*
759          * Ensure we process oplock break messages by preference.
760          * We have to do this before the select, after the select
761          * and if the select returns EINTR. This is due to the fact
762          * that the selects called from async_processing can eat an EINTR
763          * caused by a signal (we can't take the break message there).
764          * This is hideously complex - *MUST* be simplified for 3.0 ! JRA.
765          */
766
767         if (oplock_message_waiting(&r_fds)) {
768                 DEBUG(10,("receive_message_or_smb: oplock_message is waiting.\n"));
769                 async_processing(&r_fds);
770                 /*
771                  * After async processing we must go and do the select again, as
772                  * the state of the flag in fds for the server file descriptor is
773                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
774                  */
775                 goto again;
776         }
777
778         /*
779          * Are there any timed events waiting ? If so, ensure we don't
780          * select for longer than it would take to wait for them.
781          */
782
783         {
784                 struct timeval now;
785                 GetTimeOfDay(&now);
786
787                 event_add_to_select_args(smbd_event_context(), &now,
788                                          &r_fds, &w_fds, &to, &maxfd);
789         }
790
791         if (timeval_is_zero(&to)) {
792                 /* Process a timed event now... */
793                 if (run_events(smbd_event_context(), 0, NULL, NULL)) {
794                         goto again;
795                 }
796         }
797         
798         {
799                 int sav;
800                 START_PROFILE(smbd_idle);
801
802                 maxfd = select_on_fd(smbd_server_fd(), maxfd, &r_fds);
803                 maxfd = select_on_fd(oplock_notify_fd(), maxfd, &r_fds);
804
805                 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
806                 sav = errno;
807
808                 END_PROFILE(smbd_idle);
809                 errno = sav;
810         }
811
812         if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
813                 goto again;
814         }
815
816         /* if we get EINTR then maybe we have received an oplock
817            signal - treat this as select returning 1. This is ugly, but
818            is the best we can do until the oplock code knows more about
819            signals */
820         if (selrtn == -1 && errno == EINTR) {
821                 async_processing(&r_fds);
822                 /*
823                  * After async processing we must go and do the select again, as
824                  * the state of the flag in fds for the server file descriptor is
825                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
826                  */
827                 goto again;
828         }
829
830         /* Check if error */
831         if (selrtn == -1) {
832                 /* something is wrong. Maybe the socket is dead? */
833                 set_smb_read_error(SMB_READ_ERROR);
834                 return False;
835         } 
836     
837         /* Did we timeout ? */
838         if (selrtn == 0) {
839                 set_smb_read_error(SMB_READ_TIMEOUT);
840                 return False;
841         }
842
843         /*
844          * Ensure we process oplock break messages by preference.
845          * This is IMPORTANT ! Otherwise we can starve other processes
846          * sending us an oplock break message. JRA.
847          */
848
849         if (oplock_message_waiting(&r_fds)) {
850                 async_processing(&r_fds);
851                 /*
852                  * After async processing we must go and do the select again, as
853                  * the state of the flag in fds for the server file descriptor is
854                  * indeterminate - we may have done I/O on it in the oplock processing. JRA.
855                  */
856                 goto again;
857         }
858
859         len = receive_smb_talloc(mem_ctx, smbd_server_fd(), buffer, 0, p_unread);
860
861         if (len == -1) {
862                 return False;
863         }
864
865         *buffer_len = (size_t)len;
866
867         return True;
868 }
869
870 /*
871  * Only allow 5 outstanding trans requests. We're allocating memory, so
872  * prevent a DoS.
873  */
874
875 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
876 {
877         int count = 0;
878         for (; list != NULL; list = list->next) {
879
880                 if (list->mid == mid) {
881                         return NT_STATUS_INVALID_PARAMETER;
882                 }
883
884                 count += 1;
885         }
886         if (count > 5) {
887                 return NT_STATUS_INSUFFICIENT_RESOURCES;
888         }
889
890         return NT_STATUS_OK;
891 }
892
893 /****************************************************************************
894  We're terminating and have closed all our files/connections etc.
895  If there are any pending local messages we need to respond to them
896  before termination so that other smbds don't think we just died whilst
897  holding oplocks.
898 ****************************************************************************/
899
900 void respond_to_all_remaining_local_messages(void)
901 {
902         /*
903          * Assert we have no exclusive open oplocks.
904          */
905
906         if(get_number_of_exclusive_open_oplocks()) {
907                 DEBUG(0,("respond_to_all_remaining_local_messages: PANIC : we have %d exclusive oplocks.\n",
908                         get_number_of_exclusive_open_oplocks() ));
909                 return;
910         }
911
912         process_kernel_oplocks(smbd_messaging_context(), NULL);
913
914         return;
915 }
916
917
918 /*
919 These flags determine some of the permissions required to do an operation 
920
921 Note that I don't set NEED_WRITE on some write operations because they
922 are used by some brain-dead clients when printing, and I don't want to
923 force write permissions on print services.
924 */
925 #define AS_USER (1<<0)
926 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
927 #define TIME_INIT (1<<2)
928 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
929 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
930 #define DO_CHDIR (1<<6)
931
932 /* 
933    define a list of possible SMB messages and their corresponding
934    functions. Any message that has a NULL function is unimplemented -
935    please feel free to contribute implementations!
936 */
937 static const struct smb_message_struct {
938         const char *name;
939         void (*fn_new)(connection_struct *conn, struct smb_request *req);
940         int flags;
941 } smb_messages[256] = {
942
943 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
944 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
945 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
946 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
947 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
948 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
949 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
950 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
951 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
952 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
953 /* 0x0a */ { "SMBread",reply_read,AS_USER},
954 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
955 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
956 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
957 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
958 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
959 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
960 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
961 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
962 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
963 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
964 /* 0x15 */ { NULL, NULL, 0 },
965 /* 0x16 */ { NULL, NULL, 0 },
966 /* 0x17 */ { NULL, NULL, 0 },
967 /* 0x18 */ { NULL, NULL, 0 },
968 /* 0x19 */ { NULL, NULL, 0 },
969 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
970 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
971 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
972 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
973 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
974 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
975 /* 0x20 */ { "SMBwritec", NULL,0},
976 /* 0x21 */ { NULL, NULL, 0 },
977 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
978 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
979 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
980 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
981 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
982 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
983 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
984 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
985 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
986 /* 0x2b */ { "SMBecho",reply_echo,0},
987 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
988 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
989 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
990 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
991 /* 0x30 */ { NULL, NULL, 0 },
992 /* 0x31 */ { NULL, NULL, 0 },
993 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
994 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER},
995 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
996 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
997 /* 0x36 */ { NULL, NULL, 0 },
998 /* 0x37 */ { NULL, NULL, 0 },
999 /* 0x38 */ { NULL, NULL, 0 },
1000 /* 0x39 */ { NULL, NULL, 0 },
1001 /* 0x3a */ { NULL, NULL, 0 },
1002 /* 0x3b */ { NULL, NULL, 0 },
1003 /* 0x3c */ { NULL, NULL, 0 },
1004 /* 0x3d */ { NULL, NULL, 0 },
1005 /* 0x3e */ { NULL, NULL, 0 },
1006 /* 0x3f */ { NULL, NULL, 0 },
1007 /* 0x40 */ { NULL, NULL, 0 },
1008 /* 0x41 */ { NULL, NULL, 0 },
1009 /* 0x42 */ { NULL, NULL, 0 },
1010 /* 0x43 */ { NULL, NULL, 0 },
1011 /* 0x44 */ { NULL, NULL, 0 },
1012 /* 0x45 */ { NULL, NULL, 0 },
1013 /* 0x46 */ { NULL, NULL, 0 },
1014 /* 0x47 */ { NULL, NULL, 0 },
1015 /* 0x48 */ { NULL, NULL, 0 },
1016 /* 0x49 */ { NULL, NULL, 0 },
1017 /* 0x4a */ { NULL, NULL, 0 },
1018 /* 0x4b */ { NULL, NULL, 0 },
1019 /* 0x4c */ { NULL, NULL, 0 },
1020 /* 0x4d */ { NULL, NULL, 0 },
1021 /* 0x4e */ { NULL, NULL, 0 },
1022 /* 0x4f */ { NULL, NULL, 0 },
1023 /* 0x50 */ { NULL, NULL, 0 },
1024 /* 0x51 */ { NULL, NULL, 0 },
1025 /* 0x52 */ { NULL, NULL, 0 },
1026 /* 0x53 */ { NULL, NULL, 0 },
1027 /* 0x54 */ { NULL, NULL, 0 },
1028 /* 0x55 */ { NULL, NULL, 0 },
1029 /* 0x56 */ { NULL, NULL, 0 },
1030 /* 0x57 */ { NULL, NULL, 0 },
1031 /* 0x58 */ { NULL, NULL, 0 },
1032 /* 0x59 */ { NULL, NULL, 0 },
1033 /* 0x5a */ { NULL, NULL, 0 },
1034 /* 0x5b */ { NULL, NULL, 0 },
1035 /* 0x5c */ { NULL, NULL, 0 },
1036 /* 0x5d */ { NULL, NULL, 0 },
1037 /* 0x5e */ { NULL, NULL, 0 },
1038 /* 0x5f */ { NULL, NULL, 0 },
1039 /* 0x60 */ { NULL, NULL, 0 },
1040 /* 0x61 */ { NULL, NULL, 0 },
1041 /* 0x62 */ { NULL, NULL, 0 },
1042 /* 0x63 */ { NULL, NULL, 0 },
1043 /* 0x64 */ { NULL, NULL, 0 },
1044 /* 0x65 */ { NULL, NULL, 0 },
1045 /* 0x66 */ { NULL, NULL, 0 },
1046 /* 0x67 */ { NULL, NULL, 0 },
1047 /* 0x68 */ { NULL, NULL, 0 },
1048 /* 0x69 */ { NULL, NULL, 0 },
1049 /* 0x6a */ { NULL, NULL, 0 },
1050 /* 0x6b */ { NULL, NULL, 0 },
1051 /* 0x6c */ { NULL, NULL, 0 },
1052 /* 0x6d */ { NULL, NULL, 0 },
1053 /* 0x6e */ { NULL, NULL, 0 },
1054 /* 0x6f */ { NULL, NULL, 0 },
1055 /* 0x70 */ { "SMBtcon",reply_tcon,0},
1056 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1057 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
1058 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1059 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1060 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1061 /* 0x76 */ { NULL, NULL, 0 },
1062 /* 0x77 */ { NULL, NULL, 0 },
1063 /* 0x78 */ { NULL, NULL, 0 },
1064 /* 0x79 */ { NULL, NULL, 0 },
1065 /* 0x7a */ { NULL, NULL, 0 },
1066 /* 0x7b */ { NULL, NULL, 0 },
1067 /* 0x7c */ { NULL, NULL, 0 },
1068 /* 0x7d */ { NULL, NULL, 0 },
1069 /* 0x7e */ { NULL, NULL, 0 },
1070 /* 0x7f */ { NULL, NULL, 0 },
1071 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1072 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1073 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1074 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1075 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1076 /* 0x85 */ { NULL, NULL, 0 },
1077 /* 0x86 */ { NULL, NULL, 0 },
1078 /* 0x87 */ { NULL, NULL, 0 },
1079 /* 0x88 */ { NULL, NULL, 0 },
1080 /* 0x89 */ { NULL, NULL, 0 },
1081 /* 0x8a */ { NULL, NULL, 0 },
1082 /* 0x8b */ { NULL, NULL, 0 },
1083 /* 0x8c */ { NULL, NULL, 0 },
1084 /* 0x8d */ { NULL, NULL, 0 },
1085 /* 0x8e */ { NULL, NULL, 0 },
1086 /* 0x8f */ { NULL, NULL, 0 },
1087 /* 0x90 */ { NULL, NULL, 0 },
1088 /* 0x91 */ { NULL, NULL, 0 },
1089 /* 0x92 */ { NULL, NULL, 0 },
1090 /* 0x93 */ { NULL, NULL, 0 },
1091 /* 0x94 */ { NULL, NULL, 0 },
1092 /* 0x95 */ { NULL, NULL, 0 },
1093 /* 0x96 */ { NULL, NULL, 0 },
1094 /* 0x97 */ { NULL, NULL, 0 },
1095 /* 0x98 */ { NULL, NULL, 0 },
1096 /* 0x99 */ { NULL, NULL, 0 },
1097 /* 0x9a */ { NULL, NULL, 0 },
1098 /* 0x9b */ { NULL, NULL, 0 },
1099 /* 0x9c */ { NULL, NULL, 0 },
1100 /* 0x9d */ { NULL, NULL, 0 },
1101 /* 0x9e */ { NULL, NULL, 0 },
1102 /* 0x9f */ { NULL, NULL, 0 },
1103 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1104 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1105 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1106 /* 0xa3 */ { NULL, NULL, 0 },
1107 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1108 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1109 /* 0xa6 */ { NULL, NULL, 0 },
1110 /* 0xa7 */ { NULL, NULL, 0 },
1111 /* 0xa8 */ { NULL, NULL, 0 },
1112 /* 0xa9 */ { NULL, NULL, 0 },
1113 /* 0xaa */ { NULL, NULL, 0 },
1114 /* 0xab */ { NULL, NULL, 0 },
1115 /* 0xac */ { NULL, NULL, 0 },
1116 /* 0xad */ { NULL, NULL, 0 },
1117 /* 0xae */ { NULL, NULL, 0 },
1118 /* 0xaf */ { NULL, NULL, 0 },
1119 /* 0xb0 */ { NULL, NULL, 0 },
1120 /* 0xb1 */ { NULL, NULL, 0 },
1121 /* 0xb2 */ { NULL, NULL, 0 },
1122 /* 0xb3 */ { NULL, NULL, 0 },
1123 /* 0xb4 */ { NULL, NULL, 0 },
1124 /* 0xb5 */ { NULL, NULL, 0 },
1125 /* 0xb6 */ { NULL, NULL, 0 },
1126 /* 0xb7 */ { NULL, NULL, 0 },
1127 /* 0xb8 */ { NULL, NULL, 0 },
1128 /* 0xb9 */ { NULL, NULL, 0 },
1129 /* 0xba */ { NULL, NULL, 0 },
1130 /* 0xbb */ { NULL, NULL, 0 },
1131 /* 0xbc */ { NULL, NULL, 0 },
1132 /* 0xbd */ { NULL, NULL, 0 },
1133 /* 0xbe */ { NULL, NULL, 0 },
1134 /* 0xbf */ { NULL, NULL, 0 },
1135 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1136 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1137 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1138 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1139 /* 0xc4 */ { NULL, NULL, 0 },
1140 /* 0xc5 */ { NULL, NULL, 0 },
1141 /* 0xc6 */ { NULL, NULL, 0 },
1142 /* 0xc7 */ { NULL, NULL, 0 },
1143 /* 0xc8 */ { NULL, NULL, 0 },
1144 /* 0xc9 */ { NULL, NULL, 0 },
1145 /* 0xca */ { NULL, NULL, 0 },
1146 /* 0xcb */ { NULL, NULL, 0 },
1147 /* 0xcc */ { NULL, NULL, 0 },
1148 /* 0xcd */ { NULL, NULL, 0 },
1149 /* 0xce */ { NULL, NULL, 0 },
1150 /* 0xcf */ { NULL, NULL, 0 },
1151 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1152 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1153 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1154 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1155 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1156 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1157 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1158 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1159 /* 0xd8 */ { NULL, NULL, 0 },
1160 /* 0xd9 */ { NULL, NULL, 0 },
1161 /* 0xda */ { NULL, NULL, 0 },
1162 /* 0xdb */ { NULL, NULL, 0 },
1163 /* 0xdc */ { NULL, NULL, 0 },
1164 /* 0xdd */ { NULL, NULL, 0 },
1165 /* 0xde */ { NULL, NULL, 0 },
1166 /* 0xdf */ { NULL, NULL, 0 },
1167 /* 0xe0 */ { NULL, NULL, 0 },
1168 /* 0xe1 */ { NULL, NULL, 0 },
1169 /* 0xe2 */ { NULL, NULL, 0 },
1170 /* 0xe3 */ { NULL, NULL, 0 },
1171 /* 0xe4 */ { NULL, NULL, 0 },
1172 /* 0xe5 */ { NULL, NULL, 0 },
1173 /* 0xe6 */ { NULL, NULL, 0 },
1174 /* 0xe7 */ { NULL, NULL, 0 },
1175 /* 0xe8 */ { NULL, NULL, 0 },
1176 /* 0xe9 */ { NULL, NULL, 0 },
1177 /* 0xea */ { NULL, NULL, 0 },
1178 /* 0xeb */ { NULL, NULL, 0 },
1179 /* 0xec */ { NULL, NULL, 0 },
1180 /* 0xed */ { NULL, NULL, 0 },
1181 /* 0xee */ { NULL, NULL, 0 },
1182 /* 0xef */ { NULL, NULL, 0 },
1183 /* 0xf0 */ { NULL, NULL, 0 },
1184 /* 0xf1 */ { NULL, NULL, 0 },
1185 /* 0xf2 */ { NULL, NULL, 0 },
1186 /* 0xf3 */ { NULL, NULL, 0 },
1187 /* 0xf4 */ { NULL, NULL, 0 },
1188 /* 0xf5 */ { NULL, NULL, 0 },
1189 /* 0xf6 */ { NULL, NULL, 0 },
1190 /* 0xf7 */ { NULL, NULL, 0 },
1191 /* 0xf8 */ { NULL, NULL, 0 },
1192 /* 0xf9 */ { NULL, NULL, 0 },
1193 /* 0xfa */ { NULL, NULL, 0 },
1194 /* 0xfb */ { NULL, NULL, 0 },
1195 /* 0xfc */ { NULL, NULL, 0 },
1196 /* 0xfd */ { NULL, NULL, 0 },
1197 /* 0xfe */ { NULL, NULL, 0 },
1198 /* 0xff */ { NULL, NULL, 0 }
1199
1200 };
1201
1202 /*******************************************************************
1203  allocate and initialize a reply packet
1204 ********************************************************************/
1205
1206 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1207 {
1208         /*
1209          * Protect against integer wrap
1210          */
1211         if ((num_bytes > 0xffffff)
1212             || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1213                 char *msg;
1214                 asprintf(&msg, "num_bytes too large: %u",
1215                          (unsigned)num_bytes);
1216                 smb_panic(msg);
1217         }
1218
1219         if (!(req->outbuf = TALLOC_ARRAY(
1220                       req, uint8,
1221                       smb_size + num_words*2 + num_bytes))) {
1222                 smb_panic("could not allocate output buffer\n");
1223         }
1224
1225         construct_reply_common((char *)req->inbuf, (char *)req->outbuf);
1226         set_message((char *)req->outbuf, num_words, num_bytes, False);
1227         /*
1228          * Zero out the word area, the caller has to take care of the bcc area
1229          * himself
1230          */
1231         if (num_words != 0) {
1232                 memset(req->outbuf + smb_vwv0, 0, num_words*2);
1233         }
1234
1235         return;
1236 }
1237
1238
1239 /*******************************************************************
1240  Dump a packet to a file.
1241 ********************************************************************/
1242
1243 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1244 {
1245         int fd, i;
1246         pstring fname;
1247         if (DEBUGLEVEL < 50) return;
1248
1249         if (len < 4) len = smb_len(data)+4;
1250         for (i=1;i<100;i++) {
1251                 slprintf(fname,sizeof(fname)-1, "/tmp/%s.%d.%s", name, i,
1252                                 type ? "req" : "resp");
1253                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1254                 if (fd != -1 || errno != EEXIST) break;
1255         }
1256         if (fd != -1) {
1257                 ssize_t ret = write(fd, data, len);
1258                 if (ret != len)
1259                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1260                 close(fd);
1261                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1262         }
1263 }
1264
1265 /****************************************************************************
1266  Prepare everything for calling the actual request function, and potentially
1267  call the request function via the "new" interface.
1268
1269  Return False if the "legacy" function needs to be called, everything is
1270  prepared.
1271
1272  Return True if we're done.
1273
1274  I know this API sucks, but it is the one with the least code change I could
1275  find.
1276 ****************************************************************************/
1277
1278 static void switch_message(uint8 type, struct smb_request *req, int size)
1279 {
1280         int flags;
1281         uint16 session_tag;
1282         connection_struct *conn;
1283
1284         static uint16 last_session_tag = UID_FIELD_INVALID;
1285
1286         errno = 0;
1287
1288         last_message = type;
1289
1290         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1291          * so subtract 4 from it. */
1292         if ((strncmp(smb_base(req->inbuf),"\377SMB",4) != 0)
1293             || (size < (smb_size - 4))) {
1294                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1295                          smb_len(req->inbuf)));
1296                 exit_server_cleanly("Non-SMB packet");
1297         }
1298
1299         if (smb_messages[type].fn_new == NULL) {
1300                 DEBUG(0,("Unknown message type %d!\n",type));
1301                 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1302                 reply_unknown_new(req, type);
1303                 return;
1304         }
1305
1306         flags = smb_messages[type].flags;
1307
1308         /* In share mode security we must ignore the vuid. */
1309         session_tag = (lp_security() == SEC_SHARE)
1310                 ? UID_FIELD_INVALID : req->vuid;
1311         conn = conn_find(req->tid);
1312
1313         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1314                  (int)sys_getpid(), (unsigned long)conn));
1315
1316         smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1317
1318         /* Ensure this value is replaced in the incoming packet. */
1319         SSVAL(req->inbuf,smb_uid,session_tag);
1320
1321         /*
1322          * Ensure the correct username is in current_user_info.  This is a
1323          * really ugly bugfix for problems with multiple session_setup_and_X's
1324          * being done and allowing %U and %G substitutions to work correctly.
1325          * There is a reason this code is done here, don't move it unless you
1326          * know what you're doing... :-).
1327          * JRA.
1328          */
1329
1330         if (session_tag != last_session_tag) {
1331                 user_struct *vuser = NULL;
1332
1333                 last_session_tag = session_tag;
1334                 if(session_tag != UID_FIELD_INVALID) {
1335                         vuser = get_valid_user_struct(session_tag);
1336                         if (vuser) {
1337                                 set_current_user_info(&vuser->user);
1338                         }
1339                 }
1340         }
1341
1342         /* Does this call need to be run as the connected user? */
1343         if (flags & AS_USER) {
1344
1345                 /* Does this call need a valid tree connection? */
1346                 if (!conn) {
1347                         /*
1348                          * Amazingly, the error code depends on the command
1349                          * (from Samba4).
1350                          */
1351                         if (type == SMBntcreateX) {
1352                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1353                         } else {
1354                                 reply_doserror(req, ERRSRV, ERRinvnid);
1355                         }
1356                         return;
1357                 }
1358
1359                 if (!change_to_user(conn,session_tag)) {
1360                         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1361                         return;
1362                 }
1363
1364                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1365
1366                 /* Does it need write permission? */
1367                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1368                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1369                         return;
1370                 }
1371
1372                 /* IPC services are limited */
1373                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1374                         reply_doserror(req, ERRSRV,ERRaccess);
1375                         return;
1376                 }
1377         } else {
1378                 /* This call needs to be run as root */
1379                 change_to_root_user();
1380         }
1381
1382         /* load service specific parameters */
1383         if (conn) {
1384                 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1385                                          (flags & (AS_USER|DO_CHDIR)
1386                                           ?True:False))) {
1387                         reply_doserror(req, ERRSRV, ERRaccess);
1388                         return;
1389                 }
1390                 conn->num_smb_operations++;
1391         }
1392
1393         /* does this protocol need to be run as guest? */
1394         if ((flags & AS_GUEST)
1395             && (!change_to_guest() ||
1396                 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1397                               lp_hostsdeny(-1)))) {
1398                 reply_doserror(req, ERRSRV, ERRaccess);
1399                 return;
1400         }
1401
1402         smb_messages[type].fn_new(conn, req);
1403 }
1404
1405 /****************************************************************************
1406  Construct a reply to the incoming packet.
1407 ****************************************************************************/
1408
1409 static void construct_reply(char *inbuf, int size, size_t unread_bytes)
1410 {
1411         uint8 type = CVAL(inbuf,smb_com);
1412         struct smb_request *req;
1413
1414         chain_size = 0;
1415         file_chain_reset();
1416         reset_chain_p();
1417
1418         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1419                 smb_panic("could not allocate smb_request");
1420         }
1421         init_smb_request(req, (uint8 *)inbuf, unread_bytes);
1422
1423         switch_message(type, req, size);
1424
1425         if (req->unread_bytes) {
1426                 /* writeX failed. drain socket. */
1427                 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1428                                 req->unread_bytes) {
1429                         smb_panic("failed to drain pending bytes");
1430                 }
1431                 req->unread_bytes = 0;
1432         }
1433
1434         if (req->outbuf == NULL) {
1435                 return;
1436         }
1437
1438         if (CVAL(req->outbuf,0) == 0) {
1439                 show_msg((char *)req->outbuf);
1440         }
1441
1442         if (!send_smb(smbd_server_fd(), (char *)req->outbuf)) {
1443                 exit_server_cleanly("construct_reply: send_smb failed.");
1444         }
1445
1446         TALLOC_FREE(req);
1447
1448         return;
1449 }
1450
1451 /****************************************************************************
1452  Process an smb from the client
1453 ****************************************************************************/
1454
1455 static void process_smb(char *inbuf, size_t nread, size_t unread_bytes)
1456 {
1457         static int trans_num;
1458         int msg_type = CVAL(inbuf,0);
1459
1460         DO_PROFILE_INC(smb_count);
1461
1462         if (trans_num == 0) {
1463                 char addr[INET6_ADDRSTRLEN];
1464
1465                 /* on the first packet, check the global hosts allow/ hosts
1466                 deny parameters before doing any parsing of the packet
1467                 passed to us by the client.  This prevents attacks on our
1468                 parsing code from hosts not in the hosts allow list */
1469
1470                 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
1471                                   lp_hostsdeny(-1))) {
1472                         /* send a negative session response "not listening on calling name" */
1473                         static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
1474                         DEBUG( 1, ( "Connection denied from %s\n",
1475                                 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
1476                         (void)send_smb(smbd_server_fd(),(char *)buf);
1477                         exit_server_cleanly("connection denied");
1478                 }
1479         }
1480
1481         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1482                     smb_len(inbuf) ) );
1483         DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1484                                 (int)nread,
1485                                 (unsigned int)unread_bytes ));
1486
1487         if (msg_type != 0) {
1488                 /*
1489                  * NetBIOS session request, keepalive, etc.
1490                  */
1491                 reply_special(inbuf);
1492                 return;
1493         }
1494
1495         show_msg(inbuf);
1496
1497         construct_reply(inbuf,nread,unread_bytes);
1498
1499         trans_num++;
1500 }
1501
1502 /****************************************************************************
1503  Return a string containing the function name of a SMB command.
1504 ****************************************************************************/
1505
1506 const char *smb_fn_name(int type)
1507 {
1508         const char *unknown_name = "SMBunknown";
1509
1510         if (smb_messages[type].name == NULL)
1511                 return(unknown_name);
1512
1513         return(smb_messages[type].name);
1514 }
1515
1516 /****************************************************************************
1517  Helper functions for contruct_reply.
1518 ****************************************************************************/
1519
1520 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
1521
1522 void add_to_common_flags2(uint32 v)
1523 {
1524         common_flags2 |= v;
1525 }
1526
1527 void remove_from_common_flags2(uint32 v)
1528 {
1529         common_flags2 &= ~v;
1530 }
1531
1532 void construct_reply_common(const char *inbuf, char *outbuf)
1533 {
1534         set_message(outbuf,0,0,False);
1535         
1536         SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
1537         SIVAL(outbuf,smb_rcls,0);
1538         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1539         SSVAL(outbuf,smb_flg2,
1540                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1541                 common_flags2);
1542         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1543
1544         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1545         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1546         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1547         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1548 }
1549
1550 /****************************************************************************
1551  Construct a chained reply and add it to the already made reply
1552 ****************************************************************************/
1553
1554 void chain_reply(struct smb_request *req)
1555 {
1556         static char *orig_inbuf;
1557
1558         /*
1559          * Dirty little const_discard: We mess with req->inbuf, which is
1560          * declared as const. If maybe at some point this routine gets
1561          * rewritten, this const_discard could go away.
1562          */
1563         char *inbuf = CONST_DISCARD(char *, req->inbuf);
1564         int size = smb_len(req->inbuf)+4;
1565
1566         int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
1567         unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
1568         char *inbuf2;
1569         int outsize2;
1570         int new_size;
1571         char inbuf_saved[smb_wct];
1572         char *outbuf = (char *)req->outbuf;
1573         size_t outsize = smb_len(outbuf) + 4;
1574         size_t outsize_padded;
1575         size_t ofs, to_move;
1576
1577         struct smb_request *req2;
1578         size_t caller_outputlen;
1579         char *caller_output;
1580
1581         /* Maybe its not chained, or it's an error packet. */
1582         if (smb_com2 == 0xFF || SVAL(outbuf,smb_rcls) != 0) {
1583                 SCVAL(outbuf,smb_vwv0,0xFF);
1584                 return;
1585         }
1586
1587         if (chain_size == 0) {
1588                 /* this is the first part of the chain */
1589                 orig_inbuf = inbuf;
1590         }
1591
1592         /*
1593          * We need to save the output the caller added to the chain so that we
1594          * can splice it into the final output buffer later.
1595          */
1596
1597         caller_outputlen = outsize - smb_wct;
1598
1599         caller_output = (char *)memdup(outbuf + smb_wct, caller_outputlen);
1600
1601         if (caller_output == NULL) {
1602                 /* TODO: NT_STATUS_NO_MEMORY */
1603                 smb_panic("could not dup outbuf");
1604         }
1605
1606         /*
1607          * The original Win95 redirector dies on a reply to
1608          * a lockingX and read chain unless the chain reply is
1609          * 4 byte aligned. JRA.
1610          */
1611
1612         outsize_padded = (outsize + 3) & ~3;
1613
1614         /*
1615          * remember how much the caller added to the chain, only counting
1616          * stuff after the parameter words
1617          */
1618         chain_size += outsize_padded - smb_wct;
1619
1620         /*
1621          * work out pointers into the original packets. The
1622          * headers on these need to be filled in
1623          */
1624         inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
1625
1626         /* remember the original command type */
1627         smb_com1 = CVAL(orig_inbuf,smb_com);
1628
1629         /* save the data which will be overwritten by the new headers */
1630         memcpy(inbuf_saved,inbuf2,smb_wct);
1631
1632         /* give the new packet the same header as the last part of the SMB */
1633         memmove(inbuf2,inbuf,smb_wct);
1634
1635         /* create the in buffer */
1636         SCVAL(inbuf2,smb_com,smb_com2);
1637
1638         /* work out the new size for the in buffer. */
1639         new_size = size - (inbuf2 - inbuf);
1640         if (new_size < 0) {
1641                 DEBUG(0,("chain_reply: chain packet size incorrect "
1642                          "(orig size = %d, offset = %d)\n",
1643                          size, (int)(inbuf2 - inbuf) ));
1644                 exit_server_cleanly("Bad chained packet");
1645                 return;
1646         }
1647
1648         /* And set it in the header. */
1649         smb_setlen(inbuf2, new_size - 4);
1650
1651         DEBUG(3,("Chained message\n"));
1652         show_msg(inbuf2);
1653
1654         if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
1655                 smb_panic("could not allocate smb_request");
1656         }
1657         init_smb_request(req2, (uint8 *)inbuf2,0);
1658
1659         /* process the request */
1660         switch_message(smb_com2, req2, new_size);
1661
1662         /*
1663          * We don't accept deferred operations in chained requests.
1664          */
1665         SMB_ASSERT(req2->outbuf != NULL);
1666         outsize2 = smb_len(req2->outbuf)+4;
1667
1668         /*
1669          * Move away the new command output so that caller_output fits in,
1670          * copy in the caller_output saved above.
1671          */
1672
1673         SMB_ASSERT(outsize_padded >= smb_wct);
1674
1675         /*
1676          * "ofs" is the space we need for caller_output. Equal to
1677          * caller_outputlen plus the padding.
1678          */
1679
1680         ofs = outsize_padded - smb_wct;
1681
1682         /*
1683          * "to_move" is the amount of bytes the secondary routine gave us
1684          */
1685
1686         to_move = outsize2 - smb_wct;
1687
1688         if (to_move + ofs + smb_wct + chain_size > max_send) {
1689                 smb_panic("replies too large -- would have to cut");
1690         }
1691
1692         /*
1693          * In the "new" API "outbuf" is allocated via reply_outbuf, just for
1694          * the first request in the chain. So we have to re-allocate it. In
1695          * the "old" API the only outbuf ever used is the global OutBuffer
1696          * which is always large enough.
1697          */
1698
1699         outbuf = TALLOC_REALLOC_ARRAY(NULL, outbuf, char,
1700                                       to_move + ofs + smb_wct);
1701         if (outbuf == NULL) {
1702                 smb_panic("could not realloc outbuf");
1703         }
1704
1705         req->outbuf = (uint8 *)outbuf;
1706
1707         memmove(outbuf + smb_wct + ofs, req2->outbuf + smb_wct, to_move);
1708         memcpy(outbuf + smb_wct, caller_output, caller_outputlen);
1709
1710         /*
1711          * copy the new reply header over the old one but preserve the smb_com
1712          * field
1713          */
1714         memmove(outbuf, req2->outbuf, smb_wct);
1715         SCVAL(outbuf, smb_com, smb_com1);
1716
1717         /*
1718          * We've just copied in the whole "wct" area from the secondary
1719          * function. Fix up the chaining: com2 and the offset need to be
1720          * readjusted.
1721          */
1722
1723         SCVAL(outbuf, smb_vwv0, smb_com2);
1724         SSVAL(outbuf, smb_vwv1, chain_size + smb_wct - 4);
1725
1726         if (outsize_padded > outsize) {
1727
1728                 /*
1729                  * Due to padding we have some uninitialized bytes after the
1730                  * caller's output
1731                  */
1732
1733                 memset(outbuf + outsize, 0, outsize_padded - outsize);
1734         }
1735
1736         smb_setlen(outbuf, outsize2 + chain_size - 4);
1737
1738         /*
1739          * restore the saved data, being careful not to overwrite any data
1740          * from the reply header
1741          */
1742         memcpy(inbuf2,inbuf_saved,smb_wct);
1743
1744         SAFE_FREE(caller_output);
1745         TALLOC_FREE(req2);
1746
1747         return;
1748 }
1749
1750 /****************************************************************************
1751  Setup the needed select timeout in milliseconds.
1752 ****************************************************************************/
1753
1754 static int setup_select_timeout(void)
1755 {
1756         int select_timeout;
1757
1758         select_timeout = SMBD_SELECT_TIMEOUT*1000;
1759
1760         if (print_notify_messages_pending()) {
1761                 select_timeout = MIN(select_timeout, 1000);
1762         }
1763
1764         return select_timeout;
1765 }
1766
1767 /****************************************************************************
1768  Check if services need reloading.
1769 ****************************************************************************/
1770
1771 void check_reload(time_t t)
1772 {
1773         static pid_t mypid = 0;
1774         static time_t last_smb_conf_reload_time = 0;
1775         static time_t last_printer_reload_time = 0;
1776         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1777
1778         if(last_smb_conf_reload_time == 0) {
1779                 last_smb_conf_reload_time = t;
1780                 /* Our printing subsystem might not be ready at smbd start up.
1781                    Then no printer is available till the first printers check
1782                    is performed.  A lower initial interval circumvents this. */
1783                 if ( printcap_cache_time > 60 )
1784                         last_printer_reload_time = t - printcap_cache_time + 60;
1785                 else
1786                         last_printer_reload_time = t;
1787         }
1788
1789         if (mypid != getpid()) { /* First time or fork happened meanwhile */
1790                 /* randomize over 60 second the printcap reload to avoid all
1791                  * process hitting cupsd at the same time */
1792                 int time_range = 60;
1793
1794                 last_printer_reload_time += random() % time_range;
1795                 mypid = getpid();
1796         }
1797
1798         if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
1799                 reload_services(True);
1800                 reload_after_sighup = False;
1801                 last_smb_conf_reload_time = t;
1802         }
1803
1804         /* 'printcap cache time = 0' disable the feature */
1805         
1806         if ( printcap_cache_time != 0 )
1807         { 
1808                 /* see if it's time to reload or if the clock has been set back */
1809                 
1810                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
1811                         || (t-last_printer_reload_time  < 0) ) 
1812                 {
1813                         DEBUG( 3,( "Printcap cache time expired.\n"));
1814                         reload_printers();
1815                         last_printer_reload_time = t;
1816                 }
1817         }
1818 }
1819
1820 /****************************************************************************
1821  Process any timeout housekeeping. Return False if the caller should exit.
1822 ****************************************************************************/
1823
1824 static bool timeout_processing(int *select_timeout,
1825                                time_t *last_timeout_processing_time)
1826 {
1827         time_t t;
1828
1829         if (get_smb_read_error() == SMB_READ_EOF) {
1830                 DEBUG(3,("timeout_processing: End of file from client (client has disconnected).\n"));
1831                 return false;
1832         }
1833
1834         if (get_smb_read_error() == SMB_READ_ERROR) {
1835                 DEBUG(3,("timeout_processing: receive_smb error (%s) Exiting\n",
1836                         strerror(errno)));
1837                 return false;
1838         }
1839
1840         if (get_smb_read_error() == SMB_READ_BAD_SIG) {
1841                 DEBUG(3,("timeout_processing: receive_smb error bad smb signature. Exiting\n"));
1842                 return false;
1843         }
1844
1845         *last_timeout_processing_time = t = time(NULL);
1846
1847         /* become root again if waiting */
1848         change_to_root_user();
1849
1850         /* check if we need to reload services */
1851         check_reload(t);
1852
1853         if(global_machine_password_needs_changing && 
1854                         /* for ADS we need to do a regular ADS password change, not a domain
1855                                         password change */
1856                         lp_security() == SEC_DOMAIN) {
1857
1858                 unsigned char trust_passwd_hash[16];
1859                 time_t lct;
1860
1861                 /*
1862                  * We're in domain level security, and the code that
1863                  * read the machine password flagged that the machine
1864                  * password needs changing.
1865                  */
1866
1867                 /*
1868                  * First, open the machine password file with an exclusive lock.
1869                  */
1870
1871                 if (secrets_lock_trust_account_password(lp_workgroup(), True) == False) {
1872                         DEBUG(0,("process: unable to lock the machine account password for \
1873 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
1874                         return True;
1875                 }
1876
1877                 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
1878                         DEBUG(0,("process: unable to read the machine account password for \
1879 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
1880                         secrets_lock_trust_account_password(lp_workgroup(), False);
1881                         return True;
1882                 }
1883
1884                 /*
1885                  * Make sure someone else hasn't already done this.
1886                  */
1887
1888                 if(t < lct + lp_machine_password_timeout()) {
1889                         global_machine_password_needs_changing = False;
1890                         secrets_lock_trust_account_password(lp_workgroup(), False);
1891                         return True;
1892                 }
1893
1894                 /* always just contact the PDC here */
1895     
1896                 change_trust_account_password( lp_workgroup(), NULL);
1897                 global_machine_password_needs_changing = False;
1898                 secrets_lock_trust_account_password(lp_workgroup(), False);
1899         }
1900
1901         /* update printer queue caches if necessary */
1902   
1903         update_monitored_printq_cache();
1904   
1905         /*
1906          * Now we are root, check if the log files need pruning.
1907          * Force a log file check.
1908          */
1909         force_check_log_size();
1910         check_log_size();
1911
1912         /* Send any queued printer notify message to interested smbd's. */
1913
1914         print_notify_send_messages(smbd_messaging_context(), 0);
1915
1916         /*
1917          * Modify the select timeout depending upon
1918          * what we have remaining in our queues.
1919          */
1920
1921         *select_timeout = setup_select_timeout();
1922
1923         return True;
1924 }
1925
1926 /****************************************************************************
1927  Process commands from the client
1928 ****************************************************************************/
1929
1930 void smbd_process(void)
1931 {
1932         time_t last_timeout_processing_time = time(NULL);
1933         unsigned int num_smbs = 0;
1934         size_t unread_bytes = 0;
1935
1936         max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
1937
1938         while (True) {
1939                 int select_timeout = setup_select_timeout();
1940                 int num_echos;
1941                 char *inbuf;
1942                 size_t inbuf_len;
1943                 TALLOC_CTX *frame = talloc_stackframe();
1944
1945                 errno = 0;
1946
1947                 /* Did someone ask for immediate checks on things like blocking locks ? */
1948                 if (select_timeout == 0) {
1949                         if(!timeout_processing(&select_timeout,
1950                                                &last_timeout_processing_time))
1951                                 return;
1952                         num_smbs = 0; /* Reset smb counter. */
1953                 }
1954
1955                 run_events(smbd_event_context(), 0, NULL, NULL);
1956
1957                 while (!receive_message_or_smb(NULL, &inbuf, &inbuf_len,
1958                                                select_timeout, &unread_bytes)) {
1959                         if(!timeout_processing(&select_timeout,
1960                                                &last_timeout_processing_time))
1961                                 return;
1962                         num_smbs = 0; /* Reset smb counter. */
1963                 }
1964
1965
1966                 /*
1967                  * Ensure we do timeout processing if the SMB we just got was
1968                  * only an echo request. This allows us to set the select
1969                  * timeout in 'receive_message_or_smb()' to any value we like
1970                  * without worrying that the client will send echo requests
1971                  * faster than the select timeout, thus starving out the
1972                  * essential processing (change notify, blocking locks) that
1973                  * the timeout code does. JRA.
1974                  */
1975                 num_echos = smb_echo_count;
1976
1977                 process_smb(inbuf, inbuf_len, unread_bytes);
1978
1979                 TALLOC_FREE(inbuf);
1980
1981                 if (smb_echo_count != num_echos) {
1982                         if(!timeout_processing( &select_timeout, &last_timeout_processing_time))
1983                                 return;
1984                         num_smbs = 0; /* Reset smb counter. */
1985                 }
1986
1987                 num_smbs++;
1988
1989                 /*
1990                  * If we are getting smb requests in a constant stream
1991                  * with no echos, make sure we attempt timeout processing
1992                  * every select_timeout milliseconds - but only check for this
1993                  * every 200 smb requests.
1994                  */
1995                 
1996                 if ((num_smbs % 200) == 0) {
1997                         time_t new_check_time = time(NULL);
1998                         if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
1999                                 if(!timeout_processing(
2000                                            &select_timeout,
2001                                            &last_timeout_processing_time))
2002                                         return;
2003                                 num_smbs = 0; /* Reset smb counter. */
2004                                 last_timeout_processing_time = new_check_time; /* Reset time. */
2005                         }
2006                 }
2007
2008                 /* The timeout_processing function isn't run nearly
2009                    often enough to implement 'max log size' without
2010                    overrunning the size of the file by many megabytes.
2011                    This is especially true if we are running at debug
2012                    level 10.  Checking every 50 SMBs is a nice
2013                    tradeoff of performance vs log file size overrun. */
2014
2015                 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
2016                         change_to_root_user();
2017                         check_log_size();
2018                 }
2019                 TALLOC_FREE(frame);
2020         }
2021 }