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