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