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