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