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