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