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