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