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