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