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