s3-build: only include async headers where needed.
[samba.git] / source3 / smbd / process.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process incoming packets - main loop
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Volker Lendecke 2005-2007
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/globals.h"
23 #include "librpc/gen_ndr/netlogon.h"
24 #include "librpc/gen_ndr/messaging.h"
25 #include "../lib/async_req/async_sock.h"
26
27 extern bool global_machine_password_needs_changing;
28
29 static void construct_reply_common(struct smb_request *req, const char *inbuf,
30                                    char *outbuf);
31 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
32
33 static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
34 {
35         bool ok;
36
37         if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
38                 return true;
39         }
40
41         sconn->smb1.echo_handler.ref_count++;
42
43         if (sconn->smb1.echo_handler.ref_count > 1) {
44                 return true;
45         }
46
47         DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
48
49         ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
50                         SMB_F_SETLKW, 0, 0, F_WRLCK);
51         if (!ok) {
52                 return false;
53         }
54
55         DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
56
57         return true;
58 }
59
60 void smbd_lock_socket(struct smbd_server_connection *sconn)
61 {
62         if (!smbd_lock_socket_internal(sconn)) {
63                 exit_server_cleanly("failed to lock socket");
64         }
65 }
66
67 static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
68 {
69         bool ok;
70
71         if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
72                 return true;
73         }
74
75         sconn->smb1.echo_handler.ref_count--;
76
77         if (sconn->smb1.echo_handler.ref_count > 0) {
78                 return true;
79         }
80
81         ok = fcntl_lock(sconn->smb1.echo_handler.socket_lock_fd,
82                         SMB_F_SETLKW, 0, 0, F_UNLCK);
83         if (!ok) {
84                 return false;
85         }
86
87         DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
88
89         return true;
90 }
91
92 void smbd_unlock_socket(struct smbd_server_connection *sconn)
93 {
94         if (!smbd_unlock_socket_internal(sconn)) {
95                 exit_server_cleanly("failed to unlock socket");
96         }
97 }
98
99 /* Accessor function for smb_read_error for smbd functions. */
100
101 /****************************************************************************
102  Send an smb to a fd.
103 ****************************************************************************/
104
105 bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
106                   bool do_signing, uint32_t seqnum,
107                   bool do_encrypt,
108                   struct smb_perfcount_data *pcd)
109 {
110         size_t len = 0;
111         size_t nwritten=0;
112         ssize_t ret;
113         char *buf_out = buffer;
114
115         smbd_lock_socket(sconn);
116
117         if (do_signing) {
118                 /* Sign the outgoing packet if required. */
119                 srv_calculate_sign_mac(sconn, buf_out, seqnum);
120         }
121
122         if (do_encrypt) {
123                 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
124                 if (!NT_STATUS_IS_OK(status)) {
125                         DEBUG(0, ("send_smb: SMB encryption failed "
126                                 "on outgoing packet! Error %s\n",
127                                 nt_errstr(status) ));
128                         goto out;
129                 }
130         }
131
132         len = smb_len(buf_out) + 4;
133
134         ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
135         if (ret <= 0) {
136
137                 char addr[INET6_ADDRSTRLEN];
138                 /*
139                  * Try and give an error message saying what
140                  * client failed.
141                  */
142                 DEBUG(0,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
143                          (int)sys_getpid(), (int)len,
144                          get_peer_addr(sconn->sock, addr, sizeof(addr)),
145                          (int)ret, strerror(errno) ));
146
147                 srv_free_enc_buffer(buf_out);
148                 goto out;
149         }
150
151         SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
152         srv_free_enc_buffer(buf_out);
153 out:
154         SMB_PERFCOUNT_END(pcd);
155
156         smbd_unlock_socket(sconn);
157         return true;
158 }
159
160 /*******************************************************************
161  Setup the word count and byte count for a smb message.
162 ********************************************************************/
163
164 int srv_set_message(char *buf,
165                         int num_words,
166                         int num_bytes,
167                         bool zero)
168 {
169         if (zero && (num_words || num_bytes)) {
170                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
171         }
172         SCVAL(buf,smb_wct,num_words);
173         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
174         smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
175         return (smb_size + num_words*2 + num_bytes);
176 }
177
178 static bool valid_smb_header(const uint8_t *inbuf)
179 {
180         if (is_encrypted_packet(inbuf)) {
181                 return true;
182         }
183         /*
184          * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
185          * but it just looks weird to call strncmp for this one.
186          */
187         return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
188 }
189
190 /* Socket functions for smbd packet processing. */
191
192 static bool valid_packet_size(size_t len)
193 {
194         /*
195          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
196          * of header. Don't print the error if this fits.... JRA.
197          */
198
199         if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
200                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
201                                         (unsigned long)len));
202                 return false;
203         }
204         return true;
205 }
206
207 static NTSTATUS read_packet_remainder(int fd, char *buffer,
208                                       unsigned int timeout, ssize_t len)
209 {
210         NTSTATUS status;
211
212         if (len <= 0) {
213                 return NT_STATUS_OK;
214         }
215
216         status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
217         if (!NT_STATUS_IS_OK(status)) {
218                 char addr[INET6_ADDRSTRLEN];
219                 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
220                           "error = %s.\n",
221                           get_peer_addr(fd, addr, sizeof(addr)),
222                           nt_errstr(status)));
223         }
224         return status;
225 }
226
227 /****************************************************************************
228  Attempt a zerocopy writeX read. We know here that len > smb_size-4
229 ****************************************************************************/
230
231 /*
232  * Unfortunately, earlier versions of smbclient/libsmbclient
233  * don't send this "standard" writeX header. I've fixed this
234  * for 3.2 but we'll use the old method with earlier versions.
235  * Windows and CIFSFS at least use this standard size. Not
236  * sure about MacOSX.
237  */
238
239 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
240                                 (2*14) + /* word count (including bcc) */ \
241                                 1 /* pad byte */)
242
243 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
244                                                     const char lenbuf[4],
245                                                     int fd, char **buffer,
246                                                     unsigned int timeout,
247                                                     size_t *p_unread,
248                                                     size_t *len_ret)
249 {
250         /* Size of a WRITEX call (+4 byte len). */
251         char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
252         ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
253         ssize_t toread;
254         NTSTATUS status;
255
256         memcpy(writeX_header, lenbuf, 4);
257
258         status = read_fd_with_timeout(
259                 fd, writeX_header + 4,
260                 STANDARD_WRITE_AND_X_HEADER_SIZE,
261                 STANDARD_WRITE_AND_X_HEADER_SIZE,
262                 timeout, NULL);
263
264         if (!NT_STATUS_IS_OK(status)) {
265                 char addr[INET6_ADDRSTRLEN];
266                 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
267                           "error = %s.\n",
268                           get_peer_addr(fd, addr, sizeof(addr)),
269                           nt_errstr(status)));
270                 return status;
271         }
272
273         /*
274          * Ok - now try and see if this is a possible
275          * valid writeX call.
276          */
277
278         if (is_valid_writeX_buffer(smbd_server_conn,
279                                    (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(fd, 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                         fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
345                         timeout, toread);
346
347                 if (!NT_STATUS_IS_OK(status)) {
348                         DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
349                                    nt_errstr(status)));
350                         return status;
351                 }
352         }
353
354         *len_ret = len + 4;
355         return NT_STATUS_OK;
356 }
357
358 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
359                                        char **buffer, unsigned int timeout,
360                                        size_t *p_unread, size_t *plen)
361 {
362         char lenbuf[4];
363         size_t len;
364         int min_recv_size = lp_min_receive_file_size();
365         NTSTATUS status;
366
367         *p_unread = 0;
368
369         status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
370         if (!NT_STATUS_IS_OK(status)) {
371                 return status;
372         }
373
374         if (CVAL(lenbuf,0) == 0 && min_recv_size &&
375             (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
376                 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
377             !srv_is_signing_active(smbd_server_conn) &&
378             smbd_server_conn->smb1.echo_handler.trusted_fde == NULL) {
379
380                 return receive_smb_raw_talloc_partial_read(
381                         mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
382         }
383
384         if (!valid_packet_size(len)) {
385                 return NT_STATUS_INVALID_PARAMETER;
386         }
387
388         /*
389          * The +4 here can't wrap, we've checked the length above already.
390          */
391
392         *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
393
394         if (*buffer == NULL) {
395                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
396                           (int)len+4));
397                 return NT_STATUS_NO_MEMORY;
398         }
399
400         memcpy(*buffer, lenbuf, sizeof(lenbuf));
401
402         status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
403         if (!NT_STATUS_IS_OK(status)) {
404                 return status;
405         }
406
407         *plen = len + 4;
408         return NT_STATUS_OK;
409 }
410
411 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
412                                    char **buffer, unsigned int timeout,
413                                    size_t *p_unread, bool *p_encrypted,
414                                    size_t *p_len,
415                                    uint32_t *seqnum,
416                                    bool trusted_channel)
417 {
418         size_t len = 0;
419         NTSTATUS status;
420
421         *p_encrypted = false;
422
423         status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
424                                         p_unread, &len);
425         if (!NT_STATUS_IS_OK(status)) {
426                 char addr[INET6_ADDRSTRLEN];
427                 DEBUG(0, ("read_smb_length_return_keepalive failed for "
428                           "client %s read error = %s.\n",
429                           get_peer_addr(fd, addr, sizeof(addr)),
430                           nt_errstr(status)));
431                 return status;
432         }
433
434         if (is_encrypted_packet((uint8_t *)*buffer)) {
435                 status = srv_decrypt_buffer(*buffer);
436                 if (!NT_STATUS_IS_OK(status)) {
437                         DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
438                                 "incoming packet! Error %s\n",
439                                 nt_errstr(status) ));
440                         return status;
441                 }
442                 *p_encrypted = true;
443         }
444
445         /* Check the incoming SMB signature. */
446         if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum, trusted_channel)) {
447                 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
448                           "incoming packet!\n"));
449                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
450         }
451
452         *p_len = len;
453         return NT_STATUS_OK;
454 }
455
456 /*
457  * Initialize a struct smb_request from an inbuf
458  */
459
460 static bool init_smb_request(struct smb_request *req,
461                              struct smbd_server_connection *sconn,
462                              const uint8 *inbuf,
463                              size_t unread_bytes, bool encrypted,
464                              uint32_t seqnum)
465 {
466         size_t req_size = smb_len(inbuf) + 4;
467         /* Ensure we have at least smb_size bytes. */
468         if (req_size < smb_size) {
469                 DEBUG(0,("init_smb_request: invalid request size %u\n",
470                         (unsigned int)req_size ));
471                 return false;
472         }
473         req->cmd    = CVAL(inbuf, smb_com);
474         req->flags2 = SVAL(inbuf, smb_flg2);
475         req->smbpid = SVAL(inbuf, smb_pid);
476         req->mid    = (uint64_t)SVAL(inbuf, smb_mid);
477         req->seqnum = seqnum;
478         req->vuid   = SVAL(inbuf, smb_uid);
479         req->tid    = SVAL(inbuf, smb_tid);
480         req->wct    = CVAL(inbuf, smb_wct);
481         req->vwv    = (uint16_t *)(inbuf+smb_vwv);
482         req->buflen = smb_buflen(inbuf);
483         req->buf    = (const uint8_t *)smb_buf(inbuf);
484         req->unread_bytes = unread_bytes;
485         req->encrypted = encrypted;
486         req->sconn = sconn;
487         req->conn = conn_find(sconn,req->tid);
488         req->chain_fsp = NULL;
489         req->chain_outbuf = NULL;
490         req->done = false;
491         req->smb2req = NULL;
492         smb_init_perfcount_data(&req->pcd);
493
494         /* Ensure we have at least wct words and 2 bytes of bcc. */
495         if (smb_size + req->wct*2 > req_size) {
496                 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
497                         (unsigned int)req->wct,
498                         (unsigned int)req_size));
499                 return false;
500         }
501         /* Ensure bcc is correct. */
502         if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
503                 DEBUG(0,("init_smb_request: invalid bcc number %u "
504                         "(wct = %u, size %u)\n",
505                         (unsigned int)req->buflen,
506                         (unsigned int)req->wct,
507                         (unsigned int)req_size));
508                 return false;
509         }
510
511         req->outbuf = NULL;
512         return true;
513 }
514
515 static void process_smb(struct smbd_server_connection *conn,
516                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
517                         uint32_t seqnum, bool encrypted,
518                         struct smb_perfcount_data *deferred_pcd);
519
520 static void smbd_deferred_open_timer(struct event_context *ev,
521                                      struct timed_event *te,
522                                      struct timeval _tval,
523                                      void *private_data)
524 {
525         struct pending_message_list *msg = talloc_get_type(private_data,
526                                            struct pending_message_list);
527         TALLOC_CTX *mem_ctx = talloc_tos();
528         uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
529         uint8_t *inbuf;
530
531         inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
532                                          msg->buf.length);
533         if (inbuf == NULL) {
534                 exit_server("smbd_deferred_open_timer: talloc failed\n");
535                 return;
536         }
537
538         /* We leave this message on the queue so the open code can
539            know this is a retry. */
540         DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
541                 (unsigned long long)mid ));
542
543         /* Mark the message as processed so this is not
544          * re-processed in error. */
545         msg->processed = true;
546
547         process_smb(smbd_server_conn, inbuf,
548                     msg->buf.length, 0,
549                     msg->seqnum, msg->encrypted, &msg->pcd);
550
551         /* If it's still there and was processed, remove it. */
552         msg = get_deferred_open_message_smb(mid);
553         if (msg && msg->processed) {
554                 remove_deferred_open_message_smb(mid);
555         }
556 }
557
558 /****************************************************************************
559  Function to push a message onto the tail of a linked list of smb messages ready
560  for processing.
561 ****************************************************************************/
562
563 static bool push_queued_message(struct smb_request *req,
564                                 struct timeval request_time,
565                                 struct timeval end_time,
566                                 char *private_data, size_t private_len)
567 {
568         int msg_len = smb_len(req->inbuf) + 4;
569         struct pending_message_list *msg;
570
571         msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
572
573         if(msg == NULL) {
574                 DEBUG(0,("push_message: malloc fail (1)\n"));
575                 return False;
576         }
577
578         msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
579         if(msg->buf.data == NULL) {
580                 DEBUG(0,("push_message: malloc fail (2)\n"));
581                 TALLOC_FREE(msg);
582                 return False;
583         }
584
585         msg->request_time = request_time;
586         msg->seqnum = req->seqnum;
587         msg->encrypted = req->encrypted;
588         msg->processed = false;
589         SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
590
591         if (private_data) {
592                 msg->private_data = data_blob_talloc(msg, private_data,
593                                                      private_len);
594                 if (msg->private_data.data == NULL) {
595                         DEBUG(0,("push_message: malloc fail (3)\n"));
596                         TALLOC_FREE(msg);
597                         return False;
598                 }
599         }
600
601         msg->te = event_add_timed(smbd_event_context(),
602                                   msg,
603                                   end_time,
604                                   smbd_deferred_open_timer,
605                                   msg);
606         if (!msg->te) {
607                 DEBUG(0,("push_message: event_add_timed failed\n"));
608                 TALLOC_FREE(msg);
609                 return false;
610         }
611
612         DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
613
614         DEBUG(10,("push_message: pushed message length %u on "
615                   "deferred_open_queue\n", (unsigned int)msg_len));
616
617         return True;
618 }
619
620 /****************************************************************************
621  Function to delete a sharing violation open message by mid.
622 ****************************************************************************/
623
624 void remove_deferred_open_message_smb(uint64_t mid)
625 {
626         struct pending_message_list *pml;
627
628         if (smbd_server_conn->using_smb2) {
629                 remove_deferred_open_message_smb2(smbd_server_conn, mid);
630                 return;
631         }
632
633         for (pml = deferred_open_queue; pml; pml = pml->next) {
634                 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
635                         DEBUG(10,("remove_deferred_open_message_smb: "
636                                   "deleting mid %llu len %u\n",
637                                   (unsigned long long)mid,
638                                   (unsigned int)pml->buf.length ));
639                         DLIST_REMOVE(deferred_open_queue, pml);
640                         TALLOC_FREE(pml);
641                         return;
642                 }
643         }
644 }
645
646 /****************************************************************************
647  Move a sharing violation open retry message to the front of the list and
648  schedule it for immediate processing.
649 ****************************************************************************/
650
651 void schedule_deferred_open_message_smb(uint64_t mid)
652 {
653         struct pending_message_list *pml;
654         int i = 0;
655
656         if (smbd_server_conn->using_smb2) {
657                 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
658                 return;
659         }
660
661         for (pml = deferred_open_queue; pml; pml = pml->next) {
662                 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
663
664                 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
665                         "msg_mid = %llu\n",
666                         i++,
667                         (unsigned long long)msg_mid ));
668
669                 if (mid == msg_mid) {
670                         struct timed_event *te;
671
672                         if (pml->processed) {
673                                 /* A processed message should not be
674                                  * rescheduled. */
675                                 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
676                                         "message mid %llu was already processed\n",
677                                         (unsigned long long)msg_mid ));
678                                 continue;
679                         }
680
681                         DEBUG(10,("schedule_deferred_open_message_smb: "
682                                 "scheduling mid %llu\n",
683                                 (unsigned long long)mid ));
684
685                         te = event_add_timed(smbd_event_context(),
686                                              pml,
687                                              timeval_zero(),
688                                              smbd_deferred_open_timer,
689                                              pml);
690                         if (!te) {
691                                 DEBUG(10,("schedule_deferred_open_message_smb: "
692                                         "event_add_timed() failed, "
693                                         "skipping mid %llu\n",
694                                         (unsigned long long)msg_mid ));
695                         }
696
697                         TALLOC_FREE(pml->te);
698                         pml->te = te;
699                         DLIST_PROMOTE(deferred_open_queue, pml);
700                         return;
701                 }
702         }
703
704         DEBUG(10,("schedule_deferred_open_message_smb: failed to "
705                 "find message mid %llu\n",
706                 (unsigned long long)mid ));
707 }
708
709 /****************************************************************************
710  Return true if this mid is on the deferred queue and was not yet processed.
711 ****************************************************************************/
712
713 bool open_was_deferred(uint64_t mid)
714 {
715         struct pending_message_list *pml;
716
717         if (smbd_server_conn->using_smb2) {
718                 return open_was_deferred_smb2(smbd_server_conn, mid);
719         }
720
721         for (pml = deferred_open_queue; pml; pml = pml->next) {
722                 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
723                         return True;
724                 }
725         }
726         return False;
727 }
728
729 /****************************************************************************
730  Return the message queued by this mid.
731 ****************************************************************************/
732
733 static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
734 {
735         struct pending_message_list *pml;
736
737         for (pml = deferred_open_queue; pml; pml = pml->next) {
738                 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
739                         return pml;
740                 }
741         }
742         return NULL;
743 }
744
745 /****************************************************************************
746  Get the state data queued by this mid.
747 ****************************************************************************/
748
749 bool get_deferred_open_message_state(struct smb_request *smbreq,
750                                 struct timeval *p_request_time,
751                                 void **pp_state)
752 {
753         struct pending_message_list *pml;
754
755         if (smbd_server_conn->using_smb2) {
756                 return get_deferred_open_message_state_smb2(smbreq->smb2req,
757                                         p_request_time,
758                                         pp_state);
759         }
760
761         pml = get_deferred_open_message_smb(smbreq->mid);
762         if (!pml) {
763                 return false;
764         }
765         if (p_request_time) {
766                 *p_request_time = pml->request_time;
767         }
768         if (pp_state) {
769                 *pp_state = (void *)pml->private_data.data;
770         }
771         return true;
772 }
773
774 /****************************************************************************
775  Function to push a deferred open smb message onto a linked list of local smb
776  messages ready for processing.
777 ****************************************************************************/
778
779 bool push_deferred_open_message_smb(struct smb_request *req,
780                                struct timeval request_time,
781                                struct timeval timeout,
782                                struct file_id id,
783                                char *private_data, size_t priv_len)
784 {
785         struct timeval end_time;
786
787         if (req->smb2req) {
788                 return push_deferred_open_message_smb2(req->smb2req,
789                                                 request_time,
790                                                 timeout,
791                                                 id,
792                                                 private_data,
793                                                 priv_len);
794         }
795
796         if (req->unread_bytes) {
797                 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
798                         "unread_bytes = %u\n",
799                         (unsigned int)req->unread_bytes ));
800                 smb_panic("push_deferred_open_message_smb: "
801                         "logic error unread_bytes != 0" );
802         }
803
804         end_time = timeval_sum(&request_time, &timeout);
805
806         DEBUG(10,("push_deferred_open_message_smb: pushing message "
807                 "len %u mid %llu timeout time [%u.%06u]\n",
808                 (unsigned int) smb_len(req->inbuf)+4,
809                 (unsigned long long)req->mid,
810                 (unsigned int)end_time.tv_sec,
811                 (unsigned int)end_time.tv_usec));
812
813         return push_queued_message(req, request_time, end_time,
814                                    private_data, priv_len);
815 }
816
817 struct idle_event {
818         struct timed_event *te;
819         struct timeval interval;
820         char *name;
821         bool (*handler)(const struct timeval *now, void *private_data);
822         void *private_data;
823 };
824
825 static void smbd_idle_event_handler(struct event_context *ctx,
826                                     struct timed_event *te,
827                                     struct timeval now,
828                                     void *private_data)
829 {
830         struct idle_event *event =
831                 talloc_get_type_abort(private_data, struct idle_event);
832
833         TALLOC_FREE(event->te);
834
835         DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
836                   event->name, event->te));
837
838         if (!event->handler(&now, event->private_data)) {
839                 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
840                           event->name, event->te));
841                 /* Don't repeat, delete ourselves */
842                 TALLOC_FREE(event);
843                 return;
844         }
845
846         DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
847                   event->name, event->te));
848
849         event->te = event_add_timed(ctx, event,
850                                     timeval_sum(&now, &event->interval),
851                                     smbd_idle_event_handler, event);
852
853         /* We can't do much but fail here. */
854         SMB_ASSERT(event->te != NULL);
855 }
856
857 struct idle_event *event_add_idle(struct event_context *event_ctx,
858                                   TALLOC_CTX *mem_ctx,
859                                   struct timeval interval,
860                                   const char *name,
861                                   bool (*handler)(const struct timeval *now,
862                                                   void *private_data),
863                                   void *private_data)
864 {
865         struct idle_event *result;
866         struct timeval now = timeval_current();
867
868         result = TALLOC_P(mem_ctx, struct idle_event);
869         if (result == NULL) {
870                 DEBUG(0, ("talloc failed\n"));
871                 return NULL;
872         }
873
874         result->interval = interval;
875         result->handler = handler;
876         result->private_data = private_data;
877
878         if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
879                 DEBUG(0, ("talloc failed\n"));
880                 TALLOC_FREE(result);
881                 return NULL;
882         }
883
884         result->te = event_add_timed(event_ctx, result,
885                                      timeval_sum(&now, &interval),
886                                      smbd_idle_event_handler, result);
887         if (result->te == NULL) {
888                 DEBUG(0, ("event_add_timed failed\n"));
889                 TALLOC_FREE(result);
890                 return NULL;
891         }
892
893         DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
894         return result;
895 }
896
897 static void smbd_sig_term_handler(struct tevent_context *ev,
898                                   struct tevent_signal *se,
899                                   int signum,
900                                   int count,
901                                   void *siginfo,
902                                   void *private_data)
903 {
904         exit_server_cleanly("termination signal");
905 }
906
907 void smbd_setup_sig_term_handler(void)
908 {
909         struct tevent_signal *se;
910
911         se = tevent_add_signal(smbd_event_context(),
912                                smbd_event_context(),
913                                SIGTERM, 0,
914                                smbd_sig_term_handler,
915                                NULL);
916         if (!se) {
917                 exit_server("failed to setup SIGTERM handler");
918         }
919 }
920
921 static void smbd_sig_hup_handler(struct tevent_context *ev,
922                                   struct tevent_signal *se,
923                                   int signum,
924                                   int count,
925                                   void *siginfo,
926                                   void *private_data)
927 {
928         struct messaging_context *msg_ctx = talloc_get_type_abort(
929                 private_data, struct messaging_context);
930         change_to_root_user();
931         DEBUG(1,("Reloading services after SIGHUP\n"));
932         reload_services(msg_ctx, smbd_server_conn->sock, False);
933 }
934
935 void smbd_setup_sig_hup_handler(struct tevent_context *ev,
936                                 struct messaging_context *msg_ctx)
937 {
938         struct tevent_signal *se;
939
940         se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
941                                msg_ctx);
942         if (!se) {
943                 exit_server("failed to setup SIGHUP handler");
944         }
945 }
946
947 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
948 {
949         fd_set r_fds, w_fds;
950         int selrtn;
951         struct timeval to;
952         int maxfd = 0;
953
954         to.tv_sec = SMBD_SELECT_TIMEOUT;
955         to.tv_usec = 0;
956
957         /*
958          * Setup the select fd sets.
959          */
960
961         FD_ZERO(&r_fds);
962         FD_ZERO(&w_fds);
963
964         /*
965          * Are there any timed events waiting ? If so, ensure we don't
966          * select for longer than it would take to wait for them.
967          */
968
969         {
970                 struct timeval now;
971                 GetTimeOfDay(&now);
972
973                 event_add_to_select_args(smbd_event_context(), &now,
974                                          &r_fds, &w_fds, &to, &maxfd);
975         }
976
977         /* Process a signal and timed events now... */
978         if (run_events(smbd_event_context(), 0, NULL, NULL)) {
979                 return NT_STATUS_RETRY;
980         }
981
982         {
983                 int sav;
984                 START_PROFILE(smbd_idle);
985
986                 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
987                 sav = errno;
988
989                 END_PROFILE(smbd_idle);
990                 errno = sav;
991         }
992
993         if ((conn->smb1.echo_handler.trusted_fd != -1)
994             && FD_ISSET(conn->sock, &r_fds)
995             && FD_ISSET(conn->smb1.echo_handler.trusted_fd, &r_fds)) {
996                 /*
997                  * Prefer to read pending requests from the echo handler. To
998                  * quote Jeremy (da70f8ab1): This is a hack of monstrous
999                  * proportions...
1000                  */
1001                 FD_CLR(conn->sock, &r_fds);
1002         }
1003
1004         if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
1005                 return NT_STATUS_RETRY;
1006         }
1007
1008         /* Check if error */
1009         if (selrtn == -1) {
1010                 /* something is wrong. Maybe the socket is dead? */
1011                 return map_nt_error_from_unix(errno);
1012         }
1013
1014         /* Did we timeout ? */
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(char *inbuf, int size, size_t unread_bytes,
1574                             uint32_t seqnum, bool encrypted,
1575                             struct smb_perfcount_data *deferred_pcd)
1576 {
1577         connection_struct *conn;
1578         struct smb_request *req;
1579
1580         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1581                 smb_panic("could not allocate smb_request");
1582         }
1583
1584         if (!init_smb_request(req, smbd_server_conn, (uint8 *)inbuf,
1585                               unread_bytes, encrypted, seqnum)) {
1586                 exit_server_cleanly("Invalid SMB request");
1587         }
1588
1589         req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
1590
1591         /* we popped this message off the queue - keep original perf data */
1592         if (deferred_pcd)
1593                 req->pcd = *deferred_pcd;
1594         else {
1595                 SMB_PERFCOUNT_START(&req->pcd);
1596                 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1597                 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1598         }
1599
1600         conn = switch_message(req->cmd, req, size);
1601
1602         if (req->unread_bytes) {
1603                 /* writeX failed. drain socket. */
1604                 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1605                                 req->unread_bytes) {
1606                         smb_panic("failed to drain pending bytes");
1607                 }
1608                 req->unread_bytes = 0;
1609         }
1610
1611         if (req->done) {
1612                 TALLOC_FREE(req);
1613                 return;
1614         }
1615
1616         if (req->outbuf == NULL) {
1617                 return;
1618         }
1619
1620         if (CVAL(req->outbuf,0) == 0) {
1621                 show_msg((char *)req->outbuf);
1622         }
1623
1624         if (!srv_send_smb(req->sconn,
1625                         (char *)req->outbuf,
1626                         true, req->seqnum+1,
1627                         IS_CONN_ENCRYPTED(conn)||req->encrypted,
1628                         &req->pcd)) {
1629                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1630         }
1631
1632         TALLOC_FREE(req);
1633
1634         return;
1635 }
1636
1637 /****************************************************************************
1638  Process an smb from the client
1639 ****************************************************************************/
1640 static void process_smb(struct smbd_server_connection *conn,
1641                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
1642                         uint32_t seqnum, bool encrypted,
1643                         struct smb_perfcount_data *deferred_pcd)
1644 {
1645         int msg_type = CVAL(inbuf,0);
1646
1647         DO_PROFILE_INC(smb_count);
1648
1649         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1650                     smb_len(inbuf) ) );
1651         DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1652                   conn->trans_num, (int)nread, (unsigned int)unread_bytes));
1653
1654         if (msg_type != 0) {
1655                 /*
1656                  * NetBIOS session request, keepalive, etc.
1657                  */
1658                 reply_special(conn, (char *)inbuf);
1659                 goto done;
1660         }
1661
1662         if (smbd_server_conn->using_smb2) {
1663                 /* At this point we're not really using smb2,
1664                  * we make the decision here.. */
1665                 if (smbd_is_smb2_header(inbuf, nread)) {
1666                         smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1667                         return;
1668                 } else if (nread >= smb_size && valid_smb_header(inbuf)
1669                                 && CVAL(inbuf, smb_com) != 0x72) {
1670                         /* This is a non-negprot SMB1 packet.
1671                            Disable SMB2 from now on. */
1672                         smbd_server_conn->using_smb2 = false;
1673                 }
1674         }
1675
1676         show_msg((char *)inbuf);
1677
1678         construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1679         conn->trans_num++;
1680
1681 done:
1682         conn->smb1.num_requests++;
1683
1684         /* The timeout_processing function isn't run nearly
1685            often enough to implement 'max log size' without
1686            overrunning the size of the file by many megabytes.
1687            This is especially true if we are running at debug
1688            level 10.  Checking every 50 SMBs is a nice
1689            tradeoff of performance vs log file size overrun. */
1690
1691         if ((conn->smb1.num_requests % 50) == 0 &&
1692             need_to_check_log_size()) {
1693                 change_to_root_user();
1694                 check_log_size();
1695         }
1696 }
1697
1698 /****************************************************************************
1699  Return a string containing the function name of a SMB command.
1700 ****************************************************************************/
1701
1702 const char *smb_fn_name(int type)
1703 {
1704         const char *unknown_name = "SMBunknown";
1705
1706         if (smb_messages[type].name == NULL)
1707                 return(unknown_name);
1708
1709         return(smb_messages[type].name);
1710 }
1711
1712 /****************************************************************************
1713  Helper functions for contruct_reply.
1714 ****************************************************************************/
1715
1716 void add_to_common_flags2(uint32 v)
1717 {
1718         common_flags2 |= v;
1719 }
1720
1721 void remove_from_common_flags2(uint32 v)
1722 {
1723         common_flags2 &= ~v;
1724 }
1725
1726 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1727                                    char *outbuf)
1728 {
1729         srv_set_message(outbuf,0,0,false);
1730
1731         SCVAL(outbuf, smb_com, req->cmd);
1732         SIVAL(outbuf,smb_rcls,0);
1733         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1734         SSVAL(outbuf,smb_flg2,
1735                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1736                 common_flags2);
1737         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1738
1739         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1740         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1741         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1742         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1743 }
1744
1745 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1746 {
1747         construct_reply_common(req, (char *)req->inbuf, outbuf);
1748 }
1749
1750 /*
1751  * How many bytes have we already accumulated up to the current wct field
1752  * offset?
1753  */
1754
1755 size_t req_wct_ofs(struct smb_request *req)
1756 {
1757         size_t buf_size;
1758
1759         if (req->chain_outbuf == NULL) {
1760                 return smb_wct - 4;
1761         }
1762         buf_size = talloc_get_size(req->chain_outbuf);
1763         if ((buf_size % 4) != 0) {
1764                 buf_size += (4 - (buf_size % 4));
1765         }
1766         return buf_size - 4;
1767 }
1768
1769 /*
1770  * Hack around reply_nterror & friends not being aware of chained requests,
1771  * generating illegal (i.e. wct==0) chain replies.
1772  */
1773
1774 static void fixup_chain_error_packet(struct smb_request *req)
1775 {
1776         uint8_t *outbuf = req->outbuf;
1777         req->outbuf = NULL;
1778         reply_outbuf(req, 2, 0);
1779         memcpy(req->outbuf, outbuf, smb_wct);
1780         TALLOC_FREE(outbuf);
1781         SCVAL(req->outbuf, smb_vwv0, 0xff);
1782 }
1783
1784 /**
1785  * @brief Find the smb_cmd offset of the last command pushed
1786  * @param[in] buf       The buffer we're building up
1787  * @retval              Where can we put our next andx cmd?
1788  *
1789  * While chaining requests, the "next" request we're looking at needs to put
1790  * its SMB_Command before the data the previous request already built up added
1791  * to the chain. Find the offset to the place where we have to put our cmd.
1792  */
1793
1794 static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1795 {
1796         uint8_t cmd;
1797         size_t ofs;
1798
1799         cmd = CVAL(buf, smb_com);
1800
1801         SMB_ASSERT(is_andx_req(cmd));
1802
1803         ofs = smb_vwv0;
1804
1805         while (CVAL(buf, ofs) != 0xff) {
1806
1807                 if (!is_andx_req(CVAL(buf, ofs))) {
1808                         return false;
1809                 }
1810
1811                 /*
1812                  * ofs is from start of smb header, so add the 4 length
1813                  * bytes. The next cmd is right after the wct field.
1814                  */
1815                 ofs = SVAL(buf, ofs+2) + 4 + 1;
1816
1817                 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1818         }
1819
1820         *pofs = ofs;
1821         return true;
1822 }
1823
1824 /**
1825  * @brief Do the smb chaining at a buffer level
1826  * @param[in] poutbuf           Pointer to the talloc'ed buffer to be modified
1827  * @param[in] smb_command       The command that we want to issue
1828  * @param[in] wct               How many words?
1829  * @param[in] vwv               The words, already in network order
1830  * @param[in] bytes_alignment   How shall we align "bytes"?
1831  * @param[in] num_bytes         How many bytes?
1832  * @param[in] bytes             The data the request ships
1833  *
1834  * smb_splice_chain() adds the vwv and bytes to the request already present in
1835  * *poutbuf.
1836  */
1837
1838 static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1839                              uint8_t wct, const uint16_t *vwv,
1840                              size_t bytes_alignment,
1841                              uint32_t num_bytes, const uint8_t *bytes)
1842 {
1843         uint8_t *outbuf;
1844         size_t old_size, new_size;
1845         size_t ofs;
1846         size_t chain_padding = 0;
1847         size_t bytes_padding = 0;
1848         bool first_request;
1849
1850         old_size = talloc_get_size(*poutbuf);
1851
1852         /*
1853          * old_size == smb_wct means we're pushing the first request in for
1854          * libsmb/
1855          */
1856
1857         first_request = (old_size == smb_wct);
1858
1859         if (!first_request && ((old_size % 4) != 0)) {
1860                 /*
1861                  * Align the wct field of subsequent requests to a 4-byte
1862                  * boundary
1863                  */
1864                 chain_padding = 4 - (old_size % 4);
1865         }
1866
1867         /*
1868          * After the old request comes the new wct field (1 byte), the vwv's
1869          * and the num_bytes field. After at we might need to align the bytes
1870          * given to us to "bytes_alignment", increasing the num_bytes value.
1871          */
1872
1873         new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1874
1875         if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1876                 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1877         }
1878
1879         new_size += bytes_padding + num_bytes;
1880
1881         if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1882                 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1883                           (unsigned)new_size));
1884                 return false;
1885         }
1886
1887         outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1888         if (outbuf == NULL) {
1889                 DEBUG(0, ("talloc failed\n"));
1890                 return false;
1891         }
1892         *poutbuf = outbuf;
1893
1894         if (first_request) {
1895                 SCVAL(outbuf, smb_com, smb_command);
1896         } else {
1897                 size_t andx_cmd_ofs;
1898
1899                 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1900                         DEBUG(1, ("invalid command chain\n"));
1901                         *poutbuf = TALLOC_REALLOC_ARRAY(
1902                                 NULL, *poutbuf, uint8_t, old_size);
1903                         return false;
1904                 }
1905
1906                 if (chain_padding != 0) {
1907                         memset(outbuf + old_size, 0, chain_padding);
1908                         old_size += chain_padding;
1909                 }
1910
1911                 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1912                 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1913         }
1914
1915         ofs = old_size;
1916
1917         /*
1918          * Push the chained request:
1919          *
1920          * wct field
1921          */
1922
1923         SCVAL(outbuf, ofs, wct);
1924         ofs += 1;
1925
1926         /*
1927          * vwv array
1928          */
1929
1930         memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1931         ofs += sizeof(uint16_t) * wct;
1932
1933         /*
1934          * bcc (byte count)
1935          */
1936
1937         SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1938         ofs += sizeof(uint16_t);
1939
1940         /*
1941          * padding
1942          */
1943
1944         if (bytes_padding != 0) {
1945                 memset(outbuf + ofs, 0, bytes_padding);
1946                 ofs += bytes_padding;
1947         }
1948
1949         /*
1950          * The bytes field
1951          */
1952
1953         memcpy(outbuf + ofs, bytes, num_bytes);
1954
1955         return true;
1956 }
1957
1958 /****************************************************************************
1959  Construct a chained reply and add it to the already made reply
1960 ****************************************************************************/
1961
1962 void chain_reply(struct smb_request *req)
1963 {
1964         size_t smblen = smb_len(req->inbuf);
1965         size_t already_used, length_needed;
1966         uint8_t chain_cmd;
1967         uint32_t chain_offset;  /* uint32_t to avoid overflow */
1968
1969         uint8_t wct;
1970         uint16_t *vwv;
1971         uint16_t buflen;
1972         uint8_t *buf;
1973
1974         if (IVAL(req->outbuf, smb_rcls) != 0) {
1975                 fixup_chain_error_packet(req);
1976         }
1977
1978         /*
1979          * Any of the AndX requests and replies have at least a wct of
1980          * 2. vwv[0] is the next command, vwv[1] is the offset from the
1981          * beginning of the SMB header to the next wct field.
1982          *
1983          * None of the AndX requests put anything valuable in vwv[0] and [1],
1984          * so we can overwrite it here to form the chain.
1985          */
1986
1987         if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1988                 if (req->chain_outbuf == NULL) {
1989                         req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1990                                 req, req->outbuf, uint8_t,
1991                                 smb_len(req->outbuf) + 4);
1992                         if (req->chain_outbuf == NULL) {
1993                                 smb_panic("talloc failed");
1994                         }
1995                 }
1996                 req->outbuf = NULL;
1997                 goto error;
1998         }
1999
2000         /*
2001          * Here we assume that this is the end of the chain. For that we need
2002          * to set "next command" to 0xff and the offset to 0. If we later find
2003          * more commands in the chain, this will be overwritten again.
2004          */
2005
2006         SCVAL(req->outbuf, smb_vwv0, 0xff);
2007         SCVAL(req->outbuf, smb_vwv0+1, 0);
2008         SSVAL(req->outbuf, smb_vwv1, 0);
2009
2010         if (req->chain_outbuf == NULL) {
2011                 /*
2012                  * In req->chain_outbuf we collect all the replies. Start the
2013                  * chain by copying in the first reply.
2014                  *
2015                  * We do the realloc because later on we depend on
2016                  * talloc_get_size to determine the length of
2017                  * chain_outbuf. The reply_xxx routines might have
2018                  * over-allocated (reply_pipe_read_and_X used to be such an
2019                  * example).
2020                  */
2021                 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2022                         req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2023                 if (req->chain_outbuf == NULL) {
2024                         smb_panic("talloc failed");
2025                 }
2026                 req->outbuf = NULL;
2027         } else {
2028                 /*
2029                  * Update smb headers where subsequent chained commands
2030                  * may have updated them.
2031                  */
2032                 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
2033                 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
2034
2035                 if (!smb_splice_chain(&req->chain_outbuf,
2036                                       CVAL(req->outbuf, smb_com),
2037                                       CVAL(req->outbuf, smb_wct),
2038                                       (uint16_t *)(req->outbuf + smb_vwv),
2039                                       0, smb_buflen(req->outbuf),
2040                                       (uint8_t *)smb_buf(req->outbuf))) {
2041                         goto error;
2042                 }
2043                 TALLOC_FREE(req->outbuf);
2044         }
2045
2046         /*
2047          * We use the old request's vwv field to grab the next chained command
2048          * and offset into the chained fields.
2049          */
2050
2051         chain_cmd = CVAL(req->vwv+0, 0);
2052         chain_offset = SVAL(req->vwv+1, 0);
2053
2054         if (chain_cmd == 0xff) {
2055                 /*
2056                  * End of chain, no more requests from the client. So ship the
2057                  * replies.
2058                  */
2059                 smb_setlen((char *)(req->chain_outbuf),
2060                            talloc_get_size(req->chain_outbuf) - 4);
2061
2062                 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2063                                   true, req->seqnum+1,
2064                                   IS_CONN_ENCRYPTED(req->conn)
2065                                   ||req->encrypted,
2066                                   &req->pcd)) {
2067                         exit_server_cleanly("chain_reply: srv_send_smb "
2068                                             "failed.");
2069                 }
2070                 TALLOC_FREE(req->chain_outbuf);
2071                 req->done = true;
2072                 return;
2073         }
2074
2075         /* add a new perfcounter for this element of chain */
2076         SMB_PERFCOUNT_ADD(&req->pcd);
2077         SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2078         SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2079
2080         /*
2081          * Check if the client tries to fool us. The request so far uses the
2082          * space to the end of the byte buffer in the request just
2083          * processed. The chain_offset can't point into that area. If that was
2084          * the case, we could end up with an endless processing of the chain,
2085          * we would always handle the same request.
2086          */
2087
2088         already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
2089         if (chain_offset < already_used) {
2090                 goto error;
2091         }
2092
2093         /*
2094          * Next check: Make sure the chain offset does not point beyond the
2095          * overall smb request length.
2096          */
2097
2098         length_needed = chain_offset+1; /* wct */
2099         if (length_needed > smblen) {
2100                 goto error;
2101         }
2102
2103         /*
2104          * Now comes the pointer magic. Goal here is to set up req->vwv and
2105          * req->buf correctly again to be able to call the subsequent
2106          * switch_message(). The chain offset (the former vwv[1]) points at
2107          * the new wct field.
2108          */
2109
2110         wct = CVAL(smb_base(req->inbuf), chain_offset);
2111
2112         /*
2113          * Next consistency check: Make the new vwv array fits in the overall
2114          * smb request.
2115          */
2116
2117         length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2118         if (length_needed > smblen) {
2119                 goto error;
2120         }
2121         vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2122
2123         /*
2124          * Now grab the new byte buffer....
2125          */
2126
2127         buflen = SVAL(vwv+wct, 0);
2128
2129         /*
2130          * .. and check that it fits.
2131          */
2132
2133         length_needed += buflen;
2134         if (length_needed > smblen) {
2135                 goto error;
2136         }
2137         buf = (uint8_t *)(vwv+wct+1);
2138
2139         req->cmd = chain_cmd;
2140         req->wct = wct;
2141         req->vwv = vwv;
2142         req->buflen = buflen;
2143         req->buf = buf;
2144
2145         switch_message(chain_cmd, req, smblen);
2146
2147         if (req->outbuf == NULL) {
2148                 /*
2149                  * This happens if the chained command has suspended itself or
2150                  * if it has called srv_send_smb() itself.
2151                  */
2152                 return;
2153         }
2154
2155         /*
2156          * We end up here if the chained command was not itself chained or
2157          * suspended, but for example a close() command. We now need to splice
2158          * the chained commands' outbuf into the already built up chain_outbuf
2159          * and ship the result.
2160          */
2161         goto done;
2162
2163  error:
2164         /*
2165          * We end up here if there's any error in the chain syntax. Report a
2166          * DOS error, just like Windows does.
2167          */
2168         reply_force_doserror(req, ERRSRV, ERRerror);
2169         fixup_chain_error_packet(req);
2170
2171  done:
2172         /*
2173          * This scary statement intends to set the
2174          * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2175          * to the value req->outbuf carries
2176          */
2177         SSVAL(req->chain_outbuf, smb_flg2,
2178               (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2179               | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2180
2181         /*
2182          * Transfer the error codes from the subrequest to the main one
2183          */
2184         SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2185         SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2186
2187         if (!smb_splice_chain(&req->chain_outbuf,
2188                               CVAL(req->outbuf, smb_com),
2189                               CVAL(req->outbuf, smb_wct),
2190                               (uint16_t *)(req->outbuf + smb_vwv),
2191                               0, smb_buflen(req->outbuf),
2192                               (uint8_t *)smb_buf(req->outbuf))) {
2193                 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2194         }
2195         TALLOC_FREE(req->outbuf);
2196
2197         smb_setlen((char *)(req->chain_outbuf),
2198                    talloc_get_size(req->chain_outbuf) - 4);
2199
2200         show_msg((char *)(req->chain_outbuf));
2201
2202         if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2203                           true, req->seqnum+1,
2204                           IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2205                           &req->pcd)) {
2206                 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2207         }
2208         TALLOC_FREE(req->chain_outbuf);
2209         req->done = true;
2210 }
2211
2212 /****************************************************************************
2213  Check if services need reloading.
2214 ****************************************************************************/
2215
2216 static void check_reload(struct smbd_server_connection *sconn, time_t t)
2217 {
2218         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
2219
2220         if(last_smb_conf_reload_time == 0) {
2221                 last_smb_conf_reload_time = t;
2222                 /* Our printing subsystem might not be ready at smbd start up.
2223                    Then no printer is available till the first printers check
2224                    is performed.  A lower initial interval circumvents this. */
2225                 if ( printcap_cache_time > 60 )
2226                         last_printer_reload_time = t - printcap_cache_time + 60;
2227                 else
2228                         last_printer_reload_time = t;
2229         }
2230
2231         if (mypid != getpid()) { /* First time or fork happened meanwhile */
2232                 /* randomize over 60 second the printcap reload to avoid all
2233                  * process hitting cupsd at the same time */
2234                 int time_range = 60;
2235
2236                 last_printer_reload_time += random() % time_range;
2237                 mypid = getpid();
2238         }
2239
2240         if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2241                 reload_services(sconn->msg_ctx, sconn->sock, True);
2242                 last_smb_conf_reload_time = t;
2243         }
2244
2245         /* 'printcap cache time = 0' disable the feature */
2246
2247         if ( printcap_cache_time != 0 )
2248         { 
2249                 /* see if it's time to reload or if the clock has been set back */
2250
2251                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
2252                         || (t-last_printer_reload_time  < 0) ) 
2253                 {
2254                         DEBUG( 3,( "Printcap cache time expired.\n"));
2255                         reload_printers(sconn->msg_ctx);
2256                         last_printer_reload_time = t;
2257                 }
2258         }
2259 }
2260
2261 static bool fd_is_readable(int fd)
2262 {
2263         fd_set fds;
2264         struct timeval timeout = {0, };
2265         int ret;
2266
2267         FD_ZERO(&fds);
2268         FD_SET(fd, &fds);
2269
2270         ret = sys_select(fd+1, &fds, NULL, NULL, &timeout);
2271         if (ret == -1) {
2272                 return false;
2273         }
2274         return FD_ISSET(fd, &fds);
2275 }
2276
2277 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2278 {
2279         /* TODO: make write nonblocking */
2280 }
2281
2282 static void smbd_server_connection_read_handler(
2283         struct smbd_server_connection *conn, int fd)
2284 {
2285         uint8_t *inbuf = NULL;
2286         size_t inbuf_len = 0;
2287         size_t unread_bytes = 0;
2288         bool encrypted = false;
2289         TALLOC_CTX *mem_ctx = talloc_tos();
2290         NTSTATUS status;
2291         uint32_t seqnum;
2292
2293         bool from_client = (conn->sock == fd);
2294
2295         if (from_client) {
2296                 smbd_lock_socket(conn);
2297
2298                 if (!fd_is_readable(fd)) {
2299                         DEBUG(10,("the echo listener was faster\n"));
2300                         smbd_unlock_socket(conn);
2301                         return;
2302                 }
2303
2304                 /* TODO: make this completely nonblocking */
2305                 status = receive_smb_talloc(mem_ctx, fd,
2306                                             (char **)(void *)&inbuf,
2307                                             0, /* timeout */
2308                                             &unread_bytes,
2309                                             &encrypted,
2310                                             &inbuf_len, &seqnum,
2311                                             false /* trusted channel */);
2312                 smbd_unlock_socket(conn);
2313         } else {
2314                 /* TODO: make this completely nonblocking */
2315                 status = receive_smb_talloc(mem_ctx, fd,
2316                                             (char **)(void *)&inbuf,
2317                                             0, /* timeout */
2318                                             &unread_bytes,
2319                                             &encrypted,
2320                                             &inbuf_len, &seqnum,
2321                                             true /* trusted channel */);
2322         }
2323
2324         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2325                 goto process;
2326         }
2327         if (NT_STATUS_IS_ERR(status)) {
2328                 exit_server_cleanly("failed to receive smb request");
2329         }
2330         if (!NT_STATUS_IS_OK(status)) {
2331                 return;
2332         }
2333
2334 process:
2335         process_smb(conn, inbuf, inbuf_len, unread_bytes,
2336                     seqnum, encrypted, NULL);
2337 }
2338
2339 static void smbd_server_connection_handler(struct event_context *ev,
2340                                            struct fd_event *fde,
2341                                            uint16_t flags,
2342                                            void *private_data)
2343 {
2344         struct smbd_server_connection *conn = talloc_get_type(private_data,
2345                                               struct smbd_server_connection);
2346
2347         if (flags & EVENT_FD_WRITE) {
2348                 smbd_server_connection_write_handler(conn);
2349                 return;
2350         }
2351         if (flags & EVENT_FD_READ) {
2352                 smbd_server_connection_read_handler(conn, conn->sock);
2353                 return;
2354         }
2355 }
2356
2357 static void smbd_server_echo_handler(struct event_context *ev,
2358                                      struct fd_event *fde,
2359                                      uint16_t flags,
2360                                      void *private_data)
2361 {
2362         struct smbd_server_connection *conn = talloc_get_type(private_data,
2363                                               struct smbd_server_connection);
2364
2365         if (flags & EVENT_FD_WRITE) {
2366                 smbd_server_connection_write_handler(conn);
2367                 return;
2368         }
2369         if (flags & EVENT_FD_READ) {
2370                 smbd_server_connection_read_handler(
2371                         conn, conn->smb1.echo_handler.trusted_fd);
2372                 return;
2373         }
2374 }
2375
2376 /****************************************************************************
2377 received when we should release a specific IP
2378 ****************************************************************************/
2379 static void release_ip(const char *ip, void *priv)
2380 {
2381         const char *addr = (const char *)priv;
2382         const char *p = addr;
2383
2384         if (strncmp("::ffff:", addr, 7) == 0) {
2385                 p = addr + 7;
2386         }
2387
2388         if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2389                 /* we can't afford to do a clean exit - that involves
2390                    database writes, which would potentially mean we
2391                    are still running after the failover has finished -
2392                    we have to get rid of this process ID straight
2393                    away */
2394                 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2395                         ip));
2396                 /* note we must exit with non-zero status so the unclean handler gets
2397                    called in the parent, so that the brl database is tickled */
2398                 _exit(1);
2399         }
2400 }
2401
2402 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2403                            uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2404 {
2405         struct smbd_server_connection *sconn = talloc_get_type_abort(
2406                 private_data, struct smbd_server_connection);
2407
2408         release_ip((char *)data->data, sconn->client_id.addr);
2409 }
2410
2411 #ifdef CLUSTER_SUPPORT
2412 static int client_get_tcp_info(struct sockaddr_storage *server,
2413                                struct sockaddr_storage *client)
2414 {
2415         socklen_t length;
2416         if (server_fd == -1) {
2417                 return -1;
2418         }
2419         length = sizeof(*server);
2420         if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
2421                 return -1;
2422         }
2423         length = sizeof(*client);
2424         if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
2425                 return -1;
2426         }
2427         return 0;
2428 }
2429 #endif
2430
2431 /*
2432  * Send keepalive packets to our client
2433  */
2434 static bool keepalive_fn(const struct timeval *now, void *private_data)
2435 {
2436         struct smbd_server_connection *sconn = smbd_server_conn;
2437         bool ret;
2438
2439         if (sconn->using_smb2) {
2440                 /* Don't do keepalives on an SMB2 connection. */
2441                 return false;
2442         }
2443
2444         smbd_lock_socket(smbd_server_conn);
2445         ret = send_keepalive(sconn->sock);
2446         smbd_unlock_socket(smbd_server_conn);
2447
2448         if (!ret) {
2449                 char addr[INET6_ADDRSTRLEN];
2450                 /*
2451                  * Try and give an error message saying what
2452                  * client failed.
2453                  */
2454                 DEBUG(0, ("send_keepalive failed for client %s. "
2455                           "Error %s - exiting\n",
2456                           get_peer_addr(sconn->sock, addr, sizeof(addr)),
2457                           strerror(errno)));
2458                 return False;
2459         }
2460         return True;
2461 }
2462
2463 /*
2464  * Do the recurring check if we're idle
2465  */
2466 static bool deadtime_fn(const struct timeval *now, void *private_data)
2467 {
2468         struct smbd_server_connection *sconn =
2469                 (struct smbd_server_connection *)private_data;
2470
2471         if (sconn->using_smb2) {
2472                 /* TODO: implement real idle check */
2473                 if (sconn->smb2.sessions.list) {
2474                         return true;
2475                 }
2476                 DEBUG( 2, ( "Closing idle SMB2 connection\n" ) );
2477                 messaging_send(sconn->msg_ctx, procid_self(),
2478                                MSG_SHUTDOWN, &data_blob_null);
2479                 return false;
2480         }
2481
2482         if ((conn_num_open(sconn) == 0)
2483             || (conn_idle_all(sconn, now->tv_sec))) {
2484                 DEBUG( 2, ( "Closing idle SMB1 connection\n" ) );
2485                 messaging_send(sconn->msg_ctx, procid_self(),
2486                                MSG_SHUTDOWN, &data_blob_null);
2487                 return False;
2488         }
2489
2490         return True;
2491 }
2492
2493 /*
2494  * Do the recurring log file and smb.conf reload checks.
2495  */
2496
2497 static bool housekeeping_fn(const struct timeval *now, void *private_data)
2498 {
2499         struct smbd_server_connection *sconn = talloc_get_type_abort(
2500                 private_data, struct smbd_server_connection);
2501         change_to_root_user();
2502
2503         /* update printer queue caches if necessary */
2504         update_monitored_printq_cache(sconn->msg_ctx);
2505
2506         /* check if we need to reload services */
2507         check_reload(sconn, time(NULL));
2508
2509         /* Change machine password if neccessary. */
2510         attempt_machine_password_change();
2511
2512         /*
2513          * Force a log file check.
2514          */
2515         force_check_log_size();
2516         check_log_size();
2517         return true;
2518 }
2519
2520 static int create_unlink_tmp(const char *dir)
2521 {
2522         char *fname;
2523         int fd;
2524
2525         fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2526         if (fname == NULL) {
2527                 errno = ENOMEM;
2528                 return -1;
2529         }
2530         fd = mkstemp(fname);
2531         if (fd == -1) {
2532                 TALLOC_FREE(fname);
2533                 return -1;
2534         }
2535         if (unlink(fname) == -1) {
2536                 int sys_errno = errno;
2537                 close(fd);
2538                 TALLOC_FREE(fname);
2539                 errno = sys_errno;
2540                 return -1;
2541         }
2542         TALLOC_FREE(fname);
2543         return fd;
2544 }
2545
2546 struct smbd_echo_state {
2547         struct tevent_context *ev;
2548         struct iovec *pending;
2549         struct smbd_server_connection *sconn;
2550         int parent_pipe;
2551
2552         struct tevent_fd *parent_fde;
2553
2554         struct tevent_fd *read_fde;
2555         struct tevent_req *write_req;
2556 };
2557
2558 static void smbd_echo_writer_done(struct tevent_req *req);
2559
2560 static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2561 {
2562         int num_pending;
2563
2564         if (state->write_req != NULL) {
2565                 return;
2566         }
2567
2568         num_pending = talloc_array_length(state->pending);
2569         if (num_pending == 0) {
2570                 return;
2571         }
2572
2573         state->write_req = writev_send(state, state->ev, NULL,
2574                                        state->parent_pipe, false,
2575                                        state->pending, num_pending);
2576         if (state->write_req == NULL) {
2577                 DEBUG(1, ("writev_send failed\n"));
2578                 exit(1);
2579         }
2580
2581         talloc_steal(state->write_req, state->pending);
2582         state->pending = NULL;
2583
2584         tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2585                                 state);
2586 }
2587
2588 static void smbd_echo_writer_done(struct tevent_req *req)
2589 {
2590         struct smbd_echo_state *state = tevent_req_callback_data(
2591                 req, struct smbd_echo_state);
2592         ssize_t written;
2593         int err;
2594
2595         written = writev_recv(req, &err);
2596         TALLOC_FREE(req);
2597         state->write_req = NULL;
2598         if (written == -1) {
2599                 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2600                 exit(1);
2601         }
2602         DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2603         smbd_echo_activate_writer(state);
2604 }
2605
2606 static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2607                             uint32_t seqnum)
2608 {
2609         struct smb_request req;
2610         uint16_t num_replies;
2611         size_t out_len;
2612         char *outbuf;
2613         bool ok;
2614
2615         if (inbuf_len < smb_size) {
2616                 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2617                 return false;
2618         }
2619         if (!valid_smb_header(inbuf)) {
2620                 DEBUG(10, ("Got invalid SMB header\n"));
2621                 return false;
2622         }
2623
2624         if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2625                               seqnum)) {
2626                 return false;
2627         }
2628         req.inbuf = inbuf;
2629
2630         DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2631                    smb_messages[req.cmd].name
2632                    ? smb_messages[req.cmd].name : "unknown"));
2633
2634         if (req.cmd != SMBecho) {
2635                 return false;
2636         }
2637         if (req.wct < 1) {
2638                 return false;
2639         }
2640
2641         num_replies = SVAL(req.vwv+0, 0);
2642         if (num_replies != 1) {
2643                 /* Not a Windows "Hey, you're still there?" request */
2644                 return false;
2645         }
2646
2647         if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2648                            1, req.buflen)) {
2649                 DEBUG(10, ("create_outbuf failed\n"));
2650                 return false;
2651         }
2652         req.outbuf = (uint8_t *)outbuf;
2653
2654         SSVAL(req.outbuf, smb_vwv0, num_replies);
2655
2656         if (req.buflen > 0) {
2657                 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2658         }
2659
2660         out_len = smb_len(req.outbuf) + 4;
2661
2662         ok = srv_send_smb(req.sconn,
2663                           (char *)outbuf,
2664                           true, seqnum+1,
2665                           false, &req.pcd);
2666         TALLOC_FREE(outbuf);
2667         if (!ok) {
2668                 exit(1);
2669         }
2670
2671         return true;
2672 }
2673
2674 static void smbd_echo_exit(struct tevent_context *ev,
2675                            struct tevent_fd *fde, uint16_t flags,
2676                            void *private_data)
2677 {
2678         DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2679         exit(0);
2680 }
2681
2682 static void smbd_echo_reader(struct tevent_context *ev,
2683                              struct tevent_fd *fde, uint16_t flags,
2684                              void *private_data)
2685 {
2686         struct smbd_echo_state *state = talloc_get_type_abort(
2687                 private_data, struct smbd_echo_state);
2688         struct smbd_server_connection *sconn = state->sconn;
2689         size_t unread, num_pending;
2690         NTSTATUS status;
2691         struct iovec *tmp;
2692         size_t iov_len;
2693         uint32_t seqnum = 0;
2694         bool reply;
2695         bool ok;
2696         bool encrypted = false;
2697
2698         smb_msleep(1000);
2699
2700         ok = smbd_lock_socket_internal(sconn);
2701         if (!ok) {
2702                 DEBUG(0, ("%s: failed to lock socket\n",
2703                         __location__));
2704                 exit(1);
2705         }
2706
2707         if (!fd_is_readable(sconn->sock)) {
2708                 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2709                           (int)sys_getpid()));
2710                 ok = smbd_unlock_socket_internal(sconn);
2711                 if (!ok) {
2712                         DEBUG(1, ("%s: failed to unlock socket in\n",
2713                                 __location__));
2714                         exit(1);
2715                 }
2716                 return;
2717         }
2718
2719         num_pending = talloc_array_length(state->pending);
2720         tmp = talloc_realloc(state, state->pending, struct iovec,
2721                              num_pending+1);
2722         if (tmp == NULL) {
2723                 DEBUG(1, ("talloc_realloc failed\n"));
2724                 exit(1);
2725         }
2726         state->pending = tmp;
2727
2728         DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2729
2730         status = receive_smb_talloc(state->pending, sconn->sock,
2731                                     (char **)(void *)&state->pending[num_pending].iov_base,
2732                                     0 /* timeout */,
2733                                     &unread,
2734                                     &encrypted,
2735                                     &iov_len,
2736                                     &seqnum,
2737                                     false /* trusted_channel*/);
2738         if (!NT_STATUS_IS_OK(status)) {
2739                 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2740                           (int)sys_getpid(), nt_errstr(status)));
2741                 exit(1);
2742         }
2743         state->pending[num_pending].iov_len = iov_len;
2744
2745         ok = smbd_unlock_socket_internal(sconn);
2746         if (!ok) {
2747                 DEBUG(1, ("%s: failed to unlock socket in\n",
2748                         __location__));
2749                 exit(1);
2750         }
2751
2752         /*
2753          * place the seqnum in the packet so that the main process can reply
2754          * with signing
2755          */
2756         SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field, seqnum);
2757         SIVAL((uint8_t *)state->pending[num_pending].iov_base, smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2758
2759         reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2760                                 state->pending[num_pending].iov_len,
2761                                 seqnum);
2762         if (reply) {
2763                 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2764                 /* no check, shrinking by some bytes does not fail */
2765                 state->pending = talloc_realloc(state, state->pending,
2766                                                 struct iovec,
2767                                                 num_pending);
2768         } else {
2769                 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2770                 smbd_echo_activate_writer(state);
2771         }
2772 }
2773
2774 static void smbd_echo_loop(struct smbd_server_connection *sconn,
2775                            int parent_pipe)
2776 {
2777         struct smbd_echo_state *state;
2778
2779         state = talloc_zero(sconn, struct smbd_echo_state);
2780         if (state == NULL) {
2781                 DEBUG(1, ("talloc failed\n"));
2782                 return;
2783         }
2784         state->sconn = sconn;
2785         state->parent_pipe = parent_pipe;
2786         state->ev = s3_tevent_context_init(state);
2787         if (state->ev == NULL) {
2788                 DEBUG(1, ("tevent_context_init failed\n"));
2789                 TALLOC_FREE(state);
2790                 return;
2791         }
2792         state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2793                                         TEVENT_FD_READ, smbd_echo_exit,
2794                                         state);
2795         if (state->parent_fde == NULL) {
2796                 DEBUG(1, ("tevent_add_fd failed\n"));
2797                 TALLOC_FREE(state);
2798                 return;
2799         }
2800         state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2801                                         TEVENT_FD_READ, smbd_echo_reader,
2802                                         state);
2803         if (state->read_fde == NULL) {
2804                 DEBUG(1, ("tevent_add_fd failed\n"));
2805                 TALLOC_FREE(state);
2806                 return;
2807         }
2808
2809         while (true) {
2810                 if (tevent_loop_once(state->ev) == -1) {
2811                         DEBUG(1, ("tevent_loop_once failed: %s\n",
2812                                   strerror(errno)));
2813                         break;
2814                 }
2815         }
2816         TALLOC_FREE(state);
2817 }
2818
2819 /*
2820  * Handle SMBecho requests in a forked child process
2821  */
2822 static bool fork_echo_handler(struct smbd_server_connection *sconn)
2823 {
2824         int listener_pipe[2];
2825         int res;
2826         pid_t child;
2827
2828         res = pipe(listener_pipe);
2829         if (res == -1) {
2830                 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2831                 return false;
2832         }
2833         sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2834         if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2835                 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2836                 goto fail;
2837         }
2838
2839         child = sys_fork();
2840         if (child == 0) {
2841                 NTSTATUS status;
2842
2843                 close(listener_pipe[0]);
2844
2845                 status = reinit_after_fork(sconn->msg_ctx,
2846                                            smbd_event_context(),
2847                                            procid_self(), false);
2848                 if (!NT_STATUS_IS_OK(status)) {
2849                         DEBUG(1, ("reinit_after_fork failed: %s\n",
2850                                   nt_errstr(status)));
2851                         exit(1);
2852                 }
2853                 smbd_echo_loop(sconn, listener_pipe[1]);
2854                 exit(0);
2855         }
2856         close(listener_pipe[1]);
2857         listener_pipe[1] = -1;
2858         sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2859
2860         DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2861
2862         /*
2863          * Without smb signing this is the same as the normal smbd
2864          * listener. This needs to change once signing comes in.
2865          */
2866         sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2867                                         sconn,
2868                                         sconn->smb1.echo_handler.trusted_fd,
2869                                         EVENT_FD_READ,
2870                                         smbd_server_echo_handler,
2871                                         sconn);
2872         if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2873                 DEBUG(1, ("event_add_fd failed\n"));
2874                 goto fail;
2875         }
2876
2877         return true;
2878
2879 fail:
2880         if (listener_pipe[0] != -1) {
2881                 close(listener_pipe[0]);
2882         }
2883         if (listener_pipe[1] != -1) {
2884                 close(listener_pipe[1]);
2885         }
2886         sconn->smb1.echo_handler.trusted_fd = -1;
2887         if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2888                 close(sconn->smb1.echo_handler.socket_lock_fd);
2889         }
2890         sconn->smb1.echo_handler.trusted_fd = -1;
2891         sconn->smb1.echo_handler.socket_lock_fd = -1;
2892         return false;
2893 }
2894
2895 #if CLUSTER_SUPPORT
2896
2897 static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2898                                   struct sockaddr_storage *srv,
2899                                   struct sockaddr_storage *clnt)
2900 {
2901         struct ctdbd_connection *cconn;
2902         char tmp_addr[INET6_ADDRSTRLEN];
2903         char *addr;
2904
2905         cconn = messaging_ctdbd_connection();
2906         if (cconn == NULL) {
2907                 return NT_STATUS_NO_MEMORY;
2908         }
2909
2910         client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2911         addr = talloc_strdup(cconn, tmp_addr);
2912         if (addr == NULL) {
2913                 return NT_STATUS_NO_MEMORY;
2914         }
2915         return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2916 }
2917
2918 #endif
2919
2920 /****************************************************************************
2921  Process commands from the client
2922 ****************************************************************************/
2923
2924 void smbd_process(struct smbd_server_connection *sconn)
2925 {
2926         TALLOC_CTX *frame = talloc_stackframe();
2927         struct sockaddr_storage ss;
2928         struct sockaddr *sa = NULL;
2929         socklen_t sa_socklen;
2930         struct tsocket_address *local_address = NULL;
2931         struct tsocket_address *remote_address = NULL;
2932         const char *remaddr = NULL;
2933         int ret;
2934
2935         if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2936             lp_security() != SEC_SHARE &&
2937             !lp_async_smb_echo_handler()) {
2938                 /*
2939                  * We're not making the desion here,
2940                  * we're just allowing the client
2941                  * to decide between SMB1 and SMB2
2942                  * with the first negprot
2943                  * packet.
2944                  */
2945                 sconn->using_smb2 = true;
2946         }
2947
2948         /* Ensure child is set to blocking mode */
2949         set_blocking(sconn->sock,True);
2950
2951         set_socket_options(sconn->sock, "SO_KEEPALIVE");
2952         set_socket_options(sconn->sock, lp_socket_options());
2953
2954         sa = (struct sockaddr *)(void *)&ss;
2955         sa_socklen = sizeof(ss);
2956         ret = getpeername(sconn->sock, sa, &sa_socklen);
2957         if (ret != 0) {
2958                 int level = (errno == ENOTCONN)?2:0;
2959                 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2960                 exit_server_cleanly("getpeername() failed.\n");
2961         }
2962         ret = tsocket_address_bsd_from_sockaddr(sconn,
2963                                                 sa, sa_socklen,
2964                                                 &remote_address);
2965         if (ret != 0) {
2966                 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2967                         __location__, strerror(errno)));
2968                 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2969         }
2970
2971         sa = (struct sockaddr *)(void *)&ss;
2972         sa_socklen = sizeof(ss);
2973         ret = getsockname(sconn->sock, sa, &sa_socklen);
2974         if (ret != 0) {
2975                 int level = (errno == ENOTCONN)?2:0;
2976                 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2977                 exit_server_cleanly("getsockname() failed.\n");
2978         }
2979         ret = tsocket_address_bsd_from_sockaddr(sconn,
2980                                                 sa, sa_socklen,
2981                                                 &local_address);
2982         if (ret != 0) {
2983                 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2984                         __location__, strerror(errno)));
2985                 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2986         }
2987
2988         sconn->local_address = local_address;
2989         sconn->remote_address = remote_address;
2990
2991         if (tsocket_address_is_inet(remote_address, "ip")) {
2992                 remaddr = tsocket_address_inet_addr_string(
2993                                 sconn->remote_address,
2994                                 talloc_tos());
2995                 if (remaddr == NULL) {
2996
2997                 }
2998         } else {
2999                 remaddr = "0.0.0.0";
3000         }
3001
3002         /* this is needed so that we get decent entries
3003            in smbstatus for port 445 connects */
3004         set_remote_machine_name(remaddr, false);
3005         reload_services(sconn->msg_ctx, sconn->sock, true);
3006
3007         /*
3008          * Before the first packet, check the global hosts allow/ hosts deny
3009          * parameters before doing any parsing of packets passed to us by the
3010          * client. This prevents attacks on our parsing code from hosts not in
3011          * the hosts allow list.
3012          */
3013
3014         if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3015                           sconn->client_id.name,
3016                           sconn->client_id.addr)) {
3017                 /*
3018                  * send a negative session response "not listening on calling
3019                  * name"
3020                  */
3021                 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3022                 DEBUG( 1, ("Connection denied from %s to %s\n",
3023                            tsocket_address_string(remote_address, talloc_tos()),
3024                            tsocket_address_string(local_address, talloc_tos())));
3025                 (void)srv_send_smb(sconn,(char *)buf, false,
3026                                    0, false, NULL);
3027                 exit_server_cleanly("connection denied");
3028         }
3029
3030         DEBUG(10, ("Connection allowed from %s to %s\n",
3031                    tsocket_address_string(remote_address, talloc_tos()),
3032                    tsocket_address_string(local_address, talloc_tos())));
3033
3034         init_modules();
3035
3036         smb_perfcount_init();
3037
3038         if (!init_account_policy()) {
3039                 exit_server("Could not open account policy tdb.\n");
3040         }
3041
3042         if (*lp_rootdir()) {
3043                 if (chroot(lp_rootdir()) != 0) {
3044                         DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3045                         exit_server("Failed to chroot()");
3046                 }
3047                 if (chdir("/") == -1) {
3048                         DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3049                         exit_server("Failed to chroot()");
3050                 }
3051                 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3052         }
3053
3054         if (!srv_init_signing(sconn)) {
3055                 exit_server("Failed to init smb_signing");
3056         }
3057
3058         if (lp_async_smb_echo_handler() && !fork_echo_handler(sconn)) {
3059                 exit_server("Failed to fork echo handler");
3060         }
3061
3062         /* Setup oplocks */
3063         if (!init_oplocks(sconn->msg_ctx))
3064                 exit_server("Failed to init oplocks");
3065
3066         /* register our message handlers */
3067         messaging_register(sconn->msg_ctx, NULL,
3068                            MSG_SMB_FORCE_TDIS, msg_force_tdis);
3069         messaging_register(sconn->msg_ctx, sconn,
3070                            MSG_SMB_RELEASE_IP, msg_release_ip);
3071         messaging_register(sconn->msg_ctx, NULL,
3072                            MSG_SMB_CLOSE_FILE, msg_close_file);
3073
3074         /*
3075          * Use the default MSG_DEBUG handler to avoid rebroadcasting
3076          * MSGs to all child processes
3077          */
3078         messaging_deregister(sconn->msg_ctx,
3079                              MSG_DEBUG, NULL);
3080         messaging_register(sconn->msg_ctx, NULL,
3081                            MSG_DEBUG, debug_message);
3082
3083         if ((lp_keepalive() != 0)
3084             && !(event_add_idle(smbd_event_context(), NULL,
3085                                 timeval_set(lp_keepalive(), 0),
3086                                 "keepalive", keepalive_fn,
3087                                 NULL))) {
3088                 DEBUG(0, ("Could not add keepalive event\n"));
3089                 exit(1);
3090         }
3091
3092         if (!(event_add_idle(smbd_event_context(), NULL,
3093                              timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3094                              "deadtime", deadtime_fn, sconn))) {
3095                 DEBUG(0, ("Could not add deadtime event\n"));
3096                 exit(1);
3097         }
3098
3099         if (!(event_add_idle(smbd_event_context(), NULL,
3100                              timeval_set(SMBD_SELECT_TIMEOUT, 0),
3101                              "housekeeping", housekeeping_fn, sconn))) {
3102                 DEBUG(0, ("Could not add housekeeping event\n"));
3103                 exit(1);
3104         }
3105
3106 #ifdef CLUSTER_SUPPORT
3107
3108         if (lp_clustering()) {
3109                 /*
3110                  * We need to tell ctdb about our client's TCP
3111                  * connection, so that for failover ctdbd can send
3112                  * tickle acks, triggering a reconnection by the
3113                  * client.
3114                  */
3115
3116                 struct sockaddr_storage srv, clnt;
3117
3118                 if (client_get_tcp_info(&srv, &clnt) == 0) {
3119                         NTSTATUS status;
3120                         status = smbd_register_ips(sconn, &srv, &clnt);
3121                         if (!NT_STATUS_IS_OK(status)) {
3122                                 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3123                                           nt_errstr(status)));
3124                         }
3125                 } else
3126                 {
3127                         DEBUG(0,("Unable to get tcp info for "
3128                                  "CTDB_CONTROL_TCP_CLIENT: %s\n",
3129                                  strerror(errno)));
3130                 }
3131         }
3132
3133 #endif
3134
3135         sconn->nbt.got_session = false;
3136
3137         sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3138
3139         sconn->smb1.sessions.done_sesssetup = false;
3140         sconn->smb1.sessions.max_send = BUFFER_SIZE;
3141         sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3142         /* users from session setup */
3143         sconn->smb1.sessions.session_userlist = NULL;
3144         /* workgroup from session setup. */
3145         sconn->smb1.sessions.session_workgroup = NULL;
3146         /* this holds info on user ids that are already validated for this VC */
3147         sconn->smb1.sessions.validated_users = NULL;
3148         sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3149         sconn->smb1.sessions.num_validated_vuids = 0;
3150
3151         conn_init(sconn);
3152         if (!init_dptrs(sconn)) {
3153                 exit_server("init_dptrs() failed");
3154         }
3155
3156         sconn->smb1.fde = event_add_fd(smbd_event_context(),
3157                                                   sconn,
3158                                                   sconn->sock,
3159                                                   EVENT_FD_READ,
3160                                                   smbd_server_connection_handler,
3161                                                   sconn);
3162         if (!sconn->smb1.fde) {
3163                 exit_server("failed to create smbd_server_connection fde");
3164         }
3165
3166         TALLOC_FREE(frame);
3167
3168         while (True) {
3169                 NTSTATUS status;
3170
3171                 frame = talloc_stackframe_pool(8192);
3172
3173                 errno = 0;
3174
3175                 status = smbd_server_connection_loop_once(sconn);
3176                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3177                     !NT_STATUS_IS_OK(status)) {
3178                         DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3179                                   " exiting\n", nt_errstr(status)));
3180                         break;
3181                 }
3182
3183                 TALLOC_FREE(frame);
3184         }
3185
3186         exit_server_cleanly(NULL);
3187 }
3188
3189 bool req_is_in_chain(struct smb_request *req)
3190 {
3191         if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3192                 /*
3193                  * We're right now handling a subsequent request, so we must
3194                  * be in a chain
3195                  */
3196                 return true;
3197         }
3198
3199         if (!is_andx_req(req->cmd)) {
3200                 return false;
3201         }
3202
3203         if (req->wct < 2) {
3204                 /*
3205                  * Okay, an illegal request, but definitely not chained :-)
3206                  */
3207                 return false;
3208         }
3209
3210         return (CVAL(req->vwv+0, 0) != 0xFF);
3211 }