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