]> git.samba.org - metze/samba/wip.git/blob - source3/smbd/process.c
fix smb_len calculation for chained requests
[metze/samba/wip.git] / source3 / smbd / process.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process incoming packets - main loop
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Volker Lendecke 2005-2007
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22
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 bool create_outbuf(TALLOC_CTX *mem_ctx, const char *inbuf, char **outbuf,
1249                    uint8_t num_words, uint32_t num_bytes)
1250 {
1251         /*
1252          * Protect against integer wrap
1253          */
1254         if ((num_bytes > 0xffffff)
1255             || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1256                 char *msg;
1257                 if (asprintf(&msg, "num_bytes too large: %u",
1258                              (unsigned)num_bytes) == -1) {
1259                         msg = CONST_DISCARD(char *, "num_bytes too large");
1260                 }
1261                 smb_panic(msg);
1262         }
1263
1264         *outbuf = TALLOC_ARRAY(mem_ctx, char,
1265                                smb_size + num_words*2 + num_bytes);
1266         if (*outbuf == NULL) {
1267                 return false;
1268         }
1269
1270         construct_reply_common(inbuf, *outbuf);
1271         srv_set_message(*outbuf, num_words, num_bytes, false);
1272         /*
1273          * Zero out the word area, the caller has to take care of the bcc area
1274          * himself
1275          */
1276         if (num_words != 0) {
1277                 memset(*outbuf + smb_vwv0, 0, num_words*2);
1278         }
1279
1280         return true;
1281 }
1282
1283 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1284 {
1285         char *outbuf;
1286         if (!create_outbuf(req, (char *)req->inbuf, &outbuf, num_words,
1287                            num_bytes)) {
1288                 smb_panic("could not allocate output buffer\n");
1289         }
1290         req->outbuf = (uint8_t *)outbuf;
1291 }
1292
1293
1294 /*******************************************************************
1295  Dump a packet to a file.
1296 ********************************************************************/
1297
1298 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1299 {
1300         int fd, i;
1301         char *fname = NULL;
1302         if (DEBUGLEVEL < 50) {
1303                 return;
1304         }
1305
1306         if (len < 4) len = smb_len(data)+4;
1307         for (i=1;i<100;i++) {
1308                 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1309                              type ? "req" : "resp") == -1) {
1310                         return;
1311                 }
1312                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1313                 if (fd != -1 || errno != EEXIST) break;
1314         }
1315         if (fd != -1) {
1316                 ssize_t ret = write(fd, data, len);
1317                 if (ret != len)
1318                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1319                 close(fd);
1320                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1321         }
1322         SAFE_FREE(fname);
1323 }
1324
1325 /****************************************************************************
1326  Prepare everything for calling the actual request function, and potentially
1327  call the request function via the "new" interface.
1328
1329  Return False if the "legacy" function needs to be called, everything is
1330  prepared.
1331
1332  Return True if we're done.
1333
1334  I know this API sucks, but it is the one with the least code change I could
1335  find.
1336 ****************************************************************************/
1337
1338 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1339 {
1340         int flags;
1341         uint16 session_tag;
1342         connection_struct *conn = NULL;
1343
1344         static uint16 last_session_tag = UID_FIELD_INVALID;
1345
1346         errno = 0;
1347
1348         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1349          * so subtract 4 from it. */
1350         if (!valid_smb_header(req->inbuf)
1351             || (size < (smb_size - 4))) {
1352                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1353                          smb_len(req->inbuf)));
1354                 exit_server_cleanly("Non-SMB packet");
1355         }
1356
1357         if (smb_messages[type].fn_new == NULL) {
1358                 DEBUG(0,("Unknown message type %d!\n",type));
1359                 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1360                 reply_unknown_new(req, type);
1361                 return NULL;
1362         }
1363
1364         flags = smb_messages[type].flags;
1365
1366         /* In share mode security we must ignore the vuid. */
1367         session_tag = (lp_security() == SEC_SHARE)
1368                 ? UID_FIELD_INVALID : req->vuid;
1369         conn = req->conn;
1370
1371         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1372                  (int)sys_getpid(), (unsigned long)conn));
1373
1374         smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1375
1376         /* Ensure this value is replaced in the incoming packet. */
1377         SSVAL(req->inbuf,smb_uid,session_tag);
1378
1379         /*
1380          * Ensure the correct username is in current_user_info.  This is a
1381          * really ugly bugfix for problems with multiple session_setup_and_X's
1382          * being done and allowing %U and %G substitutions to work correctly.
1383          * There is a reason this code is done here, don't move it unless you
1384          * know what you're doing... :-).
1385          * JRA.
1386          */
1387
1388         if (session_tag != last_session_tag) {
1389                 user_struct *vuser = NULL;
1390
1391                 last_session_tag = session_tag;
1392                 if(session_tag != UID_FIELD_INVALID) {
1393                         vuser = get_valid_user_struct(session_tag);
1394                         if (vuser) {
1395                                 set_current_user_info(
1396                                         vuser->server_info->sanitized_username,
1397                                         vuser->server_info->unix_name,
1398                                         pdb_get_fullname(vuser->server_info
1399                                                          ->sam_account),
1400                                         pdb_get_domain(vuser->server_info
1401                                                        ->sam_account));
1402                         }
1403                 }
1404         }
1405
1406         /* Does this call need to be run as the connected user? */
1407         if (flags & AS_USER) {
1408
1409                 /* Does this call need a valid tree connection? */
1410                 if (!conn) {
1411                         /*
1412                          * Amazingly, the error code depends on the command
1413                          * (from Samba4).
1414                          */
1415                         if (type == SMBntcreateX) {
1416                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1417                         } else {
1418                                 reply_doserror(req, ERRSRV, ERRinvnid);
1419                         }
1420                         return NULL;
1421                 }
1422
1423                 if (!change_to_user(conn,session_tag)) {
1424                         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1425                         return conn;
1426                 }
1427
1428                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1429
1430                 /* Does it need write permission? */
1431                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1432                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1433                         return conn;
1434                 }
1435
1436                 /* IPC services are limited */
1437                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1438                         reply_doserror(req, ERRSRV,ERRaccess);
1439                         return conn;
1440                 }
1441         } else {
1442                 /* This call needs to be run as root */
1443                 change_to_root_user();
1444         }
1445
1446         /* load service specific parameters */
1447         if (conn) {
1448                 if (req->encrypted) {
1449                         conn->encrypted_tid = true;
1450                         /* encrypted required from now on. */
1451                         conn->encrypt_level = Required;
1452                 } else if (ENCRYPTION_REQUIRED(conn)) {
1453                         uint8 com = CVAL(req->inbuf,smb_com);
1454                         if (com != SMBtrans2 && com != SMBtranss2) {
1455                                 exit_server_cleanly("encryption required "
1456                                         "on connection");
1457                                 return conn;
1458                         }
1459                 }
1460
1461                 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1462                                          (flags & (AS_USER|DO_CHDIR)
1463                                           ?True:False))) {
1464                         reply_doserror(req, ERRSRV, ERRaccess);
1465                         return conn;
1466                 }
1467                 conn->num_smb_operations++;
1468         }
1469
1470         /* does this protocol need to be run as guest? */
1471         if ((flags & AS_GUEST)
1472             && (!change_to_guest() ||
1473                 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1474                               lp_hostsdeny(-1)))) {
1475                 reply_doserror(req, ERRSRV, ERRaccess);
1476                 return conn;
1477         }
1478
1479         smb_messages[type].fn_new(req);
1480         return req->conn;
1481 }
1482
1483 /****************************************************************************
1484  Construct a reply to the incoming packet.
1485 ****************************************************************************/
1486
1487 static void construct_reply(char *inbuf, int size, size_t unread_bytes, bool encrypted)
1488 {
1489         uint8 type = CVAL(inbuf,smb_com);
1490         connection_struct *conn;
1491         struct smb_request *req;
1492
1493         chain_size = 0;
1494         file_chain_reset();
1495         reset_chain_p();
1496
1497         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1498                 smb_panic("could not allocate smb_request");
1499         }
1500         init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1501
1502         conn = switch_message(type, req, size);
1503
1504         if (req->unread_bytes) {
1505                 /* writeX failed. drain socket. */
1506                 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1507                                 req->unread_bytes) {
1508                         smb_panic("failed to drain pending bytes");
1509                 }
1510                 req->unread_bytes = 0;
1511         }
1512
1513         if (req->outbuf == NULL) {
1514                 return;
1515         }
1516
1517         if (CVAL(req->outbuf,0) == 0) {
1518                 show_msg((char *)req->outbuf);
1519         }
1520
1521         if (!srv_send_smb(smbd_server_fd(),
1522                         (char *)req->outbuf,
1523                         IS_CONN_ENCRYPTED(conn)||req->encrypted)) {
1524                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1525         }
1526
1527         TALLOC_FREE(req);
1528
1529         return;
1530 }
1531
1532 /****************************************************************************
1533  Process an smb from the client
1534 ****************************************************************************/
1535
1536 static void process_smb(char *inbuf, size_t nread, size_t unread_bytes, bool encrypted)
1537 {
1538         static int trans_num;
1539         int msg_type = CVAL(inbuf,0);
1540
1541         DO_PROFILE_INC(smb_count);
1542
1543         if (trans_num == 0) {
1544                 char addr[INET6_ADDRSTRLEN];
1545
1546                 /* on the first packet, check the global hosts allow/ hosts
1547                 deny parameters before doing any parsing of the packet
1548                 passed to us by the client.  This prevents attacks on our
1549                 parsing code from hosts not in the hosts allow list */
1550
1551                 if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
1552                                   lp_hostsdeny(-1))) {
1553                         /* send a negative session response "not listening on calling name" */
1554                         static unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
1555                         DEBUG( 1, ( "Connection denied from %s\n",
1556                                 client_addr(get_client_fd(),addr,sizeof(addr)) ) );
1557                         (void)srv_send_smb(smbd_server_fd(),(char *)buf,false);
1558                         exit_server_cleanly("connection denied");
1559                 }
1560         }
1561
1562         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1563                     smb_len(inbuf) ) );
1564         DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1565                                 (int)nread,
1566                                 (unsigned int)unread_bytes ));
1567
1568         if (msg_type != 0) {
1569                 /*
1570                  * NetBIOS session request, keepalive, etc.
1571                  */
1572                 reply_special(inbuf);
1573                 return;
1574         }
1575
1576         show_msg(inbuf);
1577
1578         construct_reply(inbuf,nread,unread_bytes,encrypted);
1579
1580         trans_num++;
1581 }
1582
1583 /****************************************************************************
1584  Return a string containing the function name of a SMB command.
1585 ****************************************************************************/
1586
1587 const char *smb_fn_name(int type)
1588 {
1589         const char *unknown_name = "SMBunknown";
1590
1591         if (smb_messages[type].name == NULL)
1592                 return(unknown_name);
1593
1594         return(smb_messages[type].name);
1595 }
1596
1597 /****************************************************************************
1598  Helper functions for contruct_reply.
1599 ****************************************************************************/
1600
1601 static uint32 common_flags2 = FLAGS2_LONG_PATH_COMPONENTS|FLAGS2_32_BIT_ERROR_CODES;
1602
1603 void add_to_common_flags2(uint32 v)
1604 {
1605         common_flags2 |= v;
1606 }
1607
1608 void remove_from_common_flags2(uint32 v)
1609 {
1610         common_flags2 &= ~v;
1611 }
1612
1613 void construct_reply_common(const char *inbuf, char *outbuf)
1614 {
1615         srv_set_message(outbuf,0,0,false);
1616         
1617         SCVAL(outbuf,smb_com,CVAL(inbuf,smb_com));
1618         SIVAL(outbuf,smb_rcls,0);
1619         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1620         SSVAL(outbuf,smb_flg2,
1621                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1622                 common_flags2);
1623         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1624
1625         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1626         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1627         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1628         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1629 }
1630
1631 /****************************************************************************
1632  Construct a chained reply and add it to the already made reply
1633 ****************************************************************************/
1634
1635 void chain_reply(struct smb_request *req)
1636 {
1637         static char *orig_inbuf;
1638
1639         /*
1640          * Dirty little const_discard: We mess with req->inbuf, which is
1641          * declared as const. If maybe at some point this routine gets
1642          * rewritten, this const_discard could go away.
1643          */
1644         char *inbuf = CONST_DISCARD(char *, req->inbuf);
1645         int size = smb_len(req->inbuf)+4;
1646
1647         int smb_com1, smb_com2 = CVAL(inbuf,smb_vwv0);
1648         unsigned smb_off2 = SVAL(inbuf,smb_vwv1);
1649         char *inbuf2;
1650         int outsize2;
1651         int new_size;
1652         char inbuf_saved[smb_wct];
1653         char *outbuf = (char *)req->outbuf;
1654         size_t outsize = smb_len(outbuf) + 4;
1655         size_t outsize_padded;
1656         size_t padding;
1657         size_t ofs, to_move;
1658
1659         struct smb_request *req2;
1660         size_t caller_outputlen;
1661         char *caller_output;
1662
1663         /* Maybe its not chained, or it's an error packet. */
1664         if (smb_com2 == 0xFF || SVAL(outbuf,smb_rcls) != 0) {
1665                 SCVAL(outbuf,smb_vwv0,0xFF);
1666                 return;
1667         }
1668
1669         if (chain_size == 0) {
1670                 /* this is the first part of the chain */
1671                 orig_inbuf = inbuf;
1672         }
1673
1674         /*
1675          * We need to save the output the caller added to the chain so that we
1676          * can splice it into the final output buffer later.
1677          */
1678
1679         caller_outputlen = outsize - smb_wct;
1680
1681         caller_output = (char *)memdup(outbuf + smb_wct, caller_outputlen);
1682
1683         if (caller_output == NULL) {
1684                 /* TODO: NT_STATUS_NO_MEMORY */
1685                 smb_panic("could not dup outbuf");
1686         }
1687
1688         /*
1689          * The original Win95 redirector dies on a reply to
1690          * a lockingX and read chain unless the chain reply is
1691          * 4 byte aligned. JRA.
1692          */
1693
1694         outsize_padded = (outsize + 3) & ~3;
1695         padding = outsize_padded - outsize;
1696
1697         /*
1698          * remember how much the caller added to the chain, only counting
1699          * stuff after the parameter words
1700          */
1701         chain_size += (outsize_padded - smb_wct);
1702
1703         /*
1704          * work out pointers into the original packets. The
1705          * headers on these need to be filled in
1706          */
1707         inbuf2 = orig_inbuf + smb_off2 + 4 - smb_wct;
1708
1709         /* remember the original command type */
1710         smb_com1 = CVAL(orig_inbuf,smb_com);
1711
1712         /* save the data which will be overwritten by the new headers */
1713         memcpy(inbuf_saved,inbuf2,smb_wct);
1714
1715         /* give the new packet the same header as the last part of the SMB */
1716         memmove(inbuf2,inbuf,smb_wct);
1717
1718         /* create the in buffer */
1719         SCVAL(inbuf2,smb_com,smb_com2);
1720
1721         /* work out the new size for the in buffer. */
1722         new_size = size - (inbuf2 - inbuf);
1723         if (new_size < 0) {
1724                 DEBUG(0,("chain_reply: chain packet size incorrect "
1725                          "(orig size = %d, offset = %d)\n",
1726                          size, (int)(inbuf2 - inbuf) ));
1727                 exit_server_cleanly("Bad chained packet");
1728                 return;
1729         }
1730
1731         /* And set it in the header. */
1732         smb_setlen(inbuf2, new_size - 4);
1733
1734         DEBUG(3,("Chained message\n"));
1735         show_msg(inbuf2);
1736
1737         if (!(req2 = talloc(talloc_tos(), struct smb_request))) {
1738                 smb_panic("could not allocate smb_request");
1739         }
1740         init_smb_request(req2, (uint8 *)inbuf2,0, req->encrypted);
1741
1742         /* process the request */
1743         switch_message(smb_com2, req2, new_size);
1744
1745         /*
1746          * We don't accept deferred operations in chained requests.
1747          */
1748         SMB_ASSERT(req2->outbuf != NULL);
1749         outsize2 = smb_len(req2->outbuf)+4;
1750
1751         /*
1752          * Move away the new command output so that caller_output fits in,
1753          * copy in the caller_output saved above.
1754          */
1755
1756         SMB_ASSERT(outsize_padded >= smb_wct);
1757
1758         /*
1759          * "ofs" is the space we need for caller_output. Equal to
1760          * caller_outputlen plus the padding.
1761          */
1762
1763         ofs = outsize_padded - smb_wct;
1764
1765         /*
1766          * "to_move" is the amount of bytes the secondary routine gave us
1767          */
1768
1769         to_move = outsize2 - smb_wct;
1770
1771         if (to_move + ofs + smb_wct + chain_size > max_send) {
1772                 smb_panic("replies too large -- would have to cut");
1773         }
1774
1775         /*
1776          * In the "new" API "outbuf" is allocated via reply_outbuf, just for
1777          * the first request in the chain. So we have to re-allocate it. In
1778          * the "old" API the only outbuf ever used is the global OutBuffer
1779          * which is always large enough.
1780          */
1781
1782         outbuf = TALLOC_REALLOC_ARRAY(NULL, outbuf, char,
1783                                       to_move + ofs + smb_wct);
1784         if (outbuf == NULL) {
1785                 smb_panic("could not realloc outbuf");
1786         }
1787
1788         req->outbuf = (uint8 *)outbuf;
1789
1790         memmove(outbuf + smb_wct + ofs, req2->outbuf + smb_wct, to_move);
1791         memcpy(outbuf + smb_wct, caller_output, caller_outputlen);
1792
1793         /*
1794          * copy the new reply header over the old one but preserve the smb_com
1795          * field
1796          */
1797         memmove(outbuf, req2->outbuf, smb_wct);
1798         SCVAL(outbuf, smb_com, smb_com1);
1799
1800         /*
1801          * We've just copied in the whole "wct" area from the secondary
1802          * function. Fix up the chaining: com2 and the offset need to be
1803          * readjusted.
1804          */
1805
1806         SCVAL(outbuf, smb_vwv0, smb_com2);
1807         SSVAL(outbuf, smb_vwv1, chain_size + smb_wct - 4);
1808
1809         if (padding != 0) {
1810
1811                 /*
1812                  * Due to padding we have some uninitialized bytes after the
1813                  * caller's output
1814                  */
1815
1816                 memset(outbuf + outsize, 0, padding);
1817         }
1818
1819         smb_setlen(outbuf, outsize2 + caller_outputlen + padding - 4);
1820
1821         /*
1822          * restore the saved data, being careful not to overwrite any data
1823          * from the reply header
1824          */
1825         memcpy(inbuf2,inbuf_saved,smb_wct);
1826
1827         SAFE_FREE(caller_output);
1828         TALLOC_FREE(req2);
1829
1830         /*
1831          * Reset the chain_size for our caller's offset calculations
1832          */
1833
1834         chain_size -= (outsize_padded - smb_wct);
1835
1836         return;
1837 }
1838
1839 /****************************************************************************
1840  Setup the needed select timeout in milliseconds.
1841 ****************************************************************************/
1842
1843 static int setup_select_timeout(void)
1844 {
1845         int select_timeout;
1846
1847         select_timeout = SMBD_SELECT_TIMEOUT*1000;
1848
1849         if (print_notify_messages_pending()) {
1850                 select_timeout = MIN(select_timeout, 1000);
1851         }
1852
1853         return select_timeout;
1854 }
1855
1856 /****************************************************************************
1857  Check if services need reloading.
1858 ****************************************************************************/
1859
1860 void check_reload(time_t t)
1861 {
1862         static pid_t mypid = 0;
1863         static time_t last_smb_conf_reload_time = 0;
1864         static time_t last_printer_reload_time = 0;
1865         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1866
1867         if(last_smb_conf_reload_time == 0) {
1868                 last_smb_conf_reload_time = t;
1869                 /* Our printing subsystem might not be ready at smbd start up.
1870                    Then no printer is available till the first printers check
1871                    is performed.  A lower initial interval circumvents this. */
1872                 if ( printcap_cache_time > 60 )
1873                         last_printer_reload_time = t - printcap_cache_time + 60;
1874                 else
1875                         last_printer_reload_time = t;
1876         }
1877
1878         if (mypid != getpid()) { /* First time or fork happened meanwhile */
1879                 /* randomize over 60 second the printcap reload to avoid all
1880                  * process hitting cupsd at the same time */
1881                 int time_range = 60;
1882
1883                 last_printer_reload_time += random() % time_range;
1884                 mypid = getpid();
1885         }
1886
1887         if (reload_after_sighup || (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK)) {
1888                 reload_services(True);
1889                 reload_after_sighup = False;
1890                 last_smb_conf_reload_time = t;
1891         }
1892
1893         /* 'printcap cache time = 0' disable the feature */
1894         
1895         if ( printcap_cache_time != 0 )
1896         { 
1897                 /* see if it's time to reload or if the clock has been set back */
1898                 
1899                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
1900                         || (t-last_printer_reload_time  < 0) ) 
1901                 {
1902                         DEBUG( 3,( "Printcap cache time expired.\n"));
1903                         reload_printers();
1904                         last_printer_reload_time = t;
1905                 }
1906         }
1907 }
1908
1909 /****************************************************************************
1910  Process any timeout housekeeping. Return False if the caller should exit.
1911 ****************************************************************************/
1912
1913 static void timeout_processing(int *select_timeout,
1914                                time_t *last_timeout_processing_time)
1915 {
1916         time_t t;
1917
1918         *last_timeout_processing_time = t = time(NULL);
1919
1920         /* become root again if waiting */
1921         change_to_root_user();
1922
1923         /* check if we need to reload services */
1924         check_reload(t);
1925
1926         if(global_machine_password_needs_changing && 
1927                         /* for ADS we need to do a regular ADS password change, not a domain
1928                                         password change */
1929                         lp_security() == SEC_DOMAIN) {
1930
1931                 unsigned char trust_passwd_hash[16];
1932                 time_t lct;
1933                 void *lock;
1934
1935                 /*
1936                  * We're in domain level security, and the code that
1937                  * read the machine password flagged that the machine
1938                  * password needs changing.
1939                  */
1940
1941                 /*
1942                  * First, open the machine password file with an exclusive lock.
1943                  */
1944
1945                 lock = secrets_get_trust_account_lock(NULL, lp_workgroup());
1946
1947                 if (lock == NULL) {
1948                         DEBUG(0,("process: unable to lock the machine account password for \
1949 machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
1950                         return;
1951                 }
1952
1953                 if(!secrets_fetch_trust_account_password(lp_workgroup(), trust_passwd_hash, &lct, NULL)) {
1954                         DEBUG(0,("process: unable to read the machine account password for \
1955 machine %s in domain %s.\n", global_myname(), lp_workgroup()));
1956                         TALLOC_FREE(lock);
1957                         return;
1958                 }
1959
1960                 /*
1961                  * Make sure someone else hasn't already done this.
1962                  */
1963
1964                 if(t < lct + lp_machine_password_timeout()) {
1965                         global_machine_password_needs_changing = False;
1966                         TALLOC_FREE(lock);
1967                         return;
1968                 }
1969
1970                 /* always just contact the PDC here */
1971     
1972                 change_trust_account_password( lp_workgroup(), NULL);
1973                 global_machine_password_needs_changing = False;
1974                 TALLOC_FREE(lock);
1975         }
1976
1977         /* update printer queue caches if necessary */
1978   
1979         update_monitored_printq_cache();
1980   
1981         /*
1982          * Now we are root, check if the log files need pruning.
1983          * Force a log file check.
1984          */
1985         force_check_log_size();
1986         check_log_size();
1987
1988         /* Send any queued printer notify message to interested smbd's. */
1989
1990         print_notify_send_messages(smbd_messaging_context(), 0);
1991
1992         /*
1993          * Modify the select timeout depending upon
1994          * what we have remaining in our queues.
1995          */
1996
1997         *select_timeout = setup_select_timeout();
1998
1999         return;
2000 }
2001
2002 /****************************************************************************
2003  Process commands from the client
2004 ****************************************************************************/
2005
2006 void smbd_process(void)
2007 {
2008         time_t last_timeout_processing_time = time(NULL);
2009         unsigned int num_smbs = 0;
2010         size_t unread_bytes = 0;
2011
2012         max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2013
2014         while (True) {
2015                 int select_timeout = setup_select_timeout();
2016                 int num_echos;
2017                 char *inbuf = NULL;
2018                 size_t inbuf_len = 0;
2019                 bool encrypted = false;
2020                 TALLOC_CTX *frame = talloc_stackframe_pool(8192);
2021
2022                 errno = 0;
2023
2024                 /* Did someone ask for immediate checks on things like blocking locks ? */
2025                 if (select_timeout == 0) {
2026                         timeout_processing(&select_timeout,
2027                                            &last_timeout_processing_time);
2028                         num_smbs = 0; /* Reset smb counter. */
2029                 }
2030
2031                 run_events(smbd_event_context(), 0, NULL, NULL);
2032
2033                 while (True) {
2034                         NTSTATUS status;
2035
2036                         status = receive_message_or_smb(
2037                                 talloc_tos(), &inbuf, &inbuf_len,
2038                                 select_timeout, &unread_bytes, &encrypted);
2039
2040                         if (NT_STATUS_IS_OK(status)) {
2041                                 break;
2042                         }
2043
2044                         if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) {
2045                                 timeout_processing(
2046                                         &select_timeout,
2047                                         &last_timeout_processing_time);
2048                                 continue;
2049                         }
2050
2051                         DEBUG(3, ("receive_message_or_smb failed: %s, "
2052                                   "exiting\n", nt_errstr(status)));
2053                         return;
2054
2055                         num_smbs = 0; /* Reset smb counter. */
2056                 }
2057
2058
2059                 /*
2060                  * Ensure we do timeout processing if the SMB we just got was
2061                  * only an echo request. This allows us to set the select
2062                  * timeout in 'receive_message_or_smb()' to any value we like
2063                  * without worrying that the client will send echo requests
2064                  * faster than the select timeout, thus starving out the
2065                  * essential processing (change notify, blocking locks) that
2066                  * the timeout code does. JRA.
2067                  */
2068                 num_echos = smb_echo_count;
2069
2070                 process_smb(inbuf, inbuf_len, unread_bytes, encrypted);
2071
2072                 TALLOC_FREE(inbuf);
2073
2074                 if (smb_echo_count != num_echos) {
2075                         timeout_processing(&select_timeout,
2076                                            &last_timeout_processing_time);
2077                         num_smbs = 0; /* Reset smb counter. */
2078                 }
2079
2080                 num_smbs++;
2081
2082                 /*
2083                  * If we are getting smb requests in a constant stream
2084                  * with no echos, make sure we attempt timeout processing
2085                  * every select_timeout milliseconds - but only check for this
2086                  * every 200 smb requests.
2087                  */
2088                 
2089                 if ((num_smbs % 200) == 0) {
2090                         time_t new_check_time = time(NULL);
2091                         if(new_check_time - last_timeout_processing_time >= (select_timeout/1000)) {
2092                                 timeout_processing(
2093                                         &select_timeout,
2094                                         &last_timeout_processing_time);
2095                                 num_smbs = 0; /* Reset smb counter. */
2096                                 last_timeout_processing_time = new_check_time; /* Reset time. */
2097                         }
2098                 }
2099
2100                 /* The timeout_processing function isn't run nearly
2101                    often enough to implement 'max log size' without
2102                    overrunning the size of the file by many megabytes.
2103                    This is especially true if we are running at debug
2104                    level 10.  Checking every 50 SMBs is a nice
2105                    tradeoff of performance vs log file size overrun. */
2106
2107                 if ((num_smbs % 50) == 0 && need_to_check_log_size()) {
2108                         change_to_root_user();
2109                         check_log_size();
2110                 }
2111                 TALLOC_FREE(frame);
2112         }
2113 }