s3: Fix chained sesssetupAndX/tconn messages
[nivanova/samba-autobuild/.git] / source3 / smbd / process.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process incoming packets - main loop
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Volker Lendecke 2005-2007
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/globals.h"
23
24 extern bool global_machine_password_needs_changing;
25
26 static void construct_reply_common(struct smb_request *req, const char *inbuf,
27                                    char *outbuf);
28
29 /* Accessor function for smb_read_error for smbd functions. */
30
31 /****************************************************************************
32  Send an smb to a fd.
33 ****************************************************************************/
34
35 bool srv_send_smb(int fd, char *buffer,
36                   bool do_signing, uint32_t seqnum,
37                   bool do_encrypt,
38                   struct smb_perfcount_data *pcd)
39 {
40         size_t len = 0;
41         size_t nwritten=0;
42         ssize_t ret;
43         char *buf_out = buffer;
44
45         if (do_signing) {
46                 /* Sign the outgoing packet if required. */
47                 srv_calculate_sign_mac(smbd_server_conn, buf_out, seqnum);
48         }
49
50         if (do_encrypt) {
51                 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
52                 if (!NT_STATUS_IS_OK(status)) {
53                         DEBUG(0, ("send_smb: SMB encryption failed "
54                                 "on outgoing packet! Error %s\n",
55                                 nt_errstr(status) ));
56                         goto out;
57                 }
58         }
59
60         len = smb_len(buf_out) + 4;
61
62         ret = write_data(fd,buf_out+nwritten,len - nwritten);
63         if (ret <= 0) {
64                 DEBUG(0,("Error writing %d bytes to client. %d. (%s)\n",
65                          (int)len,(int)ret, strerror(errno) ));
66                 srv_free_enc_buffer(buf_out);
67                 goto out;
68         }
69
70         SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
71         srv_free_enc_buffer(buf_out);
72 out:
73         SMB_PERFCOUNT_END(pcd);
74         return true;
75 }
76
77 /*******************************************************************
78  Setup the word count and byte count for a smb message.
79 ********************************************************************/
80
81 int srv_set_message(char *buf,
82                         int num_words,
83                         int num_bytes,
84                         bool zero)
85 {
86         if (zero && (num_words || num_bytes)) {
87                 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
88         }
89         SCVAL(buf,smb_wct,num_words);
90         SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
91         smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
92         return (smb_size + num_words*2 + num_bytes);
93 }
94
95 static bool valid_smb_header(const uint8_t *inbuf)
96 {
97         if (is_encrypted_packet(inbuf)) {
98                 return true;
99         }
100         /*
101          * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
102          * but it just looks weird to call strncmp for this one.
103          */
104         return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
105 }
106
107 /* Socket functions for smbd packet processing. */
108
109 static bool valid_packet_size(size_t len)
110 {
111         /*
112          * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
113          * of header. Don't print the error if this fits.... JRA.
114          */
115
116         if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
117                 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
118                                         (unsigned long)len));
119                 return false;
120         }
121         return true;
122 }
123
124 static NTSTATUS read_packet_remainder(int fd, char *buffer,
125                                       unsigned int timeout, ssize_t len)
126 {
127         if (len <= 0) {
128                 return NT_STATUS_OK;
129         }
130
131         return read_socket_with_timeout(fd, buffer, len, len, timeout, NULL);
132 }
133
134 /****************************************************************************
135  Attempt a zerocopy writeX read. We know here that len > smb_size-4
136 ****************************************************************************/
137
138 /*
139  * Unfortunately, earlier versions of smbclient/libsmbclient
140  * don't send this "standard" writeX header. I've fixed this
141  * for 3.2 but we'll use the old method with earlier versions.
142  * Windows and CIFSFS at least use this standard size. Not
143  * sure about MacOSX.
144  */
145
146 #define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
147                                 (2*14) + /* word count (including bcc) */ \
148                                 1 /* pad byte */)
149
150 static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
151                                                     const char lenbuf[4],
152                                                     int fd, char **buffer,
153                                                     unsigned int timeout,
154                                                     size_t *p_unread,
155                                                     size_t *len_ret)
156 {
157         /* Size of a WRITEX call (+4 byte len). */
158         char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
159         ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
160         ssize_t toread;
161         NTSTATUS status;
162
163         memcpy(writeX_header, lenbuf, 4);
164
165         status = read_socket_with_timeout(
166                 fd, writeX_header + 4,
167                 STANDARD_WRITE_AND_X_HEADER_SIZE,
168                 STANDARD_WRITE_AND_X_HEADER_SIZE,
169                 timeout, NULL);
170
171         if (!NT_STATUS_IS_OK(status)) {
172                 return status;
173         }
174
175         /*
176          * Ok - now try and see if this is a possible
177          * valid writeX call.
178          */
179
180         if (is_valid_writeX_buffer((uint8_t *)writeX_header)) {
181                 /*
182                  * If the data offset is beyond what
183                  * we've read, drain the extra bytes.
184                  */
185                 uint16_t doff = SVAL(writeX_header,smb_vwv11);
186                 ssize_t newlen;
187
188                 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
189                         size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
190                         if (drain_socket(smbd_server_fd(), drain) != drain) {
191                                 smb_panic("receive_smb_raw_talloc_partial_read:"
192                                         " failed to drain pending bytes");
193                         }
194                 } else {
195                         doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
196                 }
197
198                 /* Spoof down the length and null out the bcc. */
199                 set_message_bcc(writeX_header, 0);
200                 newlen = smb_len(writeX_header);
201
202                 /* Copy the header we've written. */
203
204                 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
205                                 writeX_header,
206                                 sizeof(writeX_header));
207
208                 if (*buffer == NULL) {
209                         DEBUG(0, ("Could not allocate inbuf of length %d\n",
210                                   (int)sizeof(writeX_header)));
211                         return NT_STATUS_NO_MEMORY;
212                 }
213
214                 /* Work out the remaining bytes. */
215                 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
216                 *len_ret = newlen + 4;
217                 return NT_STATUS_OK;
218         }
219
220         if (!valid_packet_size(len)) {
221                 return NT_STATUS_INVALID_PARAMETER;
222         }
223
224         /*
225          * Not a valid writeX call. Just do the standard
226          * talloc and return.
227          */
228
229         *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
230
231         if (*buffer == NULL) {
232                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
233                           (int)len+4));
234                 return NT_STATUS_NO_MEMORY;
235         }
236
237         /* Copy in what we already read. */
238         memcpy(*buffer,
239                 writeX_header,
240                 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
241         toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
242
243         if(toread > 0) {
244                 status = read_packet_remainder(
245                         fd, (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
246                         timeout, toread);
247
248                 if (!NT_STATUS_IS_OK(status)) {
249                         DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
250                                    nt_errstr(status)));
251                         return status;
252                 }
253         }
254
255         *len_ret = len + 4;
256         return NT_STATUS_OK;
257 }
258
259 static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx, int fd,
260                                        char **buffer, unsigned int timeout,
261                                        size_t *p_unread, size_t *plen)
262 {
263         char lenbuf[4];
264         size_t len;
265         int min_recv_size = lp_min_receive_file_size();
266         NTSTATUS status;
267
268         *p_unread = 0;
269
270         status = read_smb_length_return_keepalive(fd, lenbuf, timeout, &len);
271         if (!NT_STATUS_IS_OK(status)) {
272                 DEBUG(10, ("receive_smb_raw: %s\n", nt_errstr(status)));
273                 return status;
274         }
275
276         if (CVAL(lenbuf,0) == 0 && min_recv_size &&
277             (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
278                 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
279             !srv_is_signing_active(smbd_server_conn)) {
280
281                 return receive_smb_raw_talloc_partial_read(
282                         mem_ctx, lenbuf, fd, buffer, timeout, p_unread, plen);
283         }
284
285         if (!valid_packet_size(len)) {
286                 return NT_STATUS_INVALID_PARAMETER;
287         }
288
289         /*
290          * The +4 here can't wrap, we've checked the length above already.
291          */
292
293         *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
294
295         if (*buffer == NULL) {
296                 DEBUG(0, ("Could not allocate inbuf of length %d\n",
297                           (int)len+4));
298                 return NT_STATUS_NO_MEMORY;
299         }
300
301         memcpy(*buffer, lenbuf, sizeof(lenbuf));
302
303         status = read_packet_remainder(fd, (*buffer)+4, timeout, len);
304         if (!NT_STATUS_IS_OK(status)) {
305                 return status;
306         }
307
308         *plen = len + 4;
309         return NT_STATUS_OK;
310 }
311
312 static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx, int fd,
313                                    char **buffer, unsigned int timeout,
314                                    size_t *p_unread, bool *p_encrypted,
315                                    size_t *p_len,
316                                    uint32_t *seqnum)
317 {
318         size_t len = 0;
319         NTSTATUS status;
320
321         *p_encrypted = false;
322
323         status = receive_smb_raw_talloc(mem_ctx, fd, buffer, timeout,
324                                         p_unread, &len);
325         if (!NT_STATUS_IS_OK(status)) {
326                 return status;
327         }
328
329         if (is_encrypted_packet((uint8_t *)*buffer)) {
330                 status = srv_decrypt_buffer(*buffer);
331                 if (!NT_STATUS_IS_OK(status)) {
332                         DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
333                                 "incoming packet! Error %s\n",
334                                 nt_errstr(status) ));
335                         return status;
336                 }
337                 *p_encrypted = true;
338         }
339
340         /* Check the incoming SMB signature. */
341         if (!srv_check_sign_mac(smbd_server_conn, *buffer, seqnum)) {
342                 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
343                           "incoming packet!\n"));
344                 return NT_STATUS_INVALID_NETWORK_RESPONSE;
345         }
346
347         *p_len = len;
348         return NT_STATUS_OK;
349 }
350
351 /*
352  * Initialize a struct smb_request from an inbuf
353  */
354
355 void init_smb_request(struct smb_request *req,
356                         const uint8 *inbuf,
357                         size_t unread_bytes,
358                         bool encrypted)
359 {
360         size_t req_size = smb_len(inbuf) + 4;
361         /* Ensure we have at least smb_size bytes. */
362         if (req_size < smb_size) {
363                 DEBUG(0,("init_smb_request: invalid request size %u\n",
364                         (unsigned int)req_size ));
365                 exit_server_cleanly("Invalid SMB request");
366         }
367         req->cmd    = CVAL(inbuf, smb_com);
368         req->flags2 = SVAL(inbuf, smb_flg2);
369         req->smbpid = SVAL(inbuf, smb_pid);
370         req->mid    = SVAL(inbuf, smb_mid);
371         req->seqnum = 0;
372         req->vuid   = SVAL(inbuf, smb_uid);
373         req->tid    = SVAL(inbuf, smb_tid);
374         req->wct    = CVAL(inbuf, smb_wct);
375         req->vwv    = (uint16_t *)(inbuf+smb_vwv);
376         req->buflen = smb_buflen(inbuf);
377         req->buf    = (const uint8_t *)smb_buf(inbuf);
378         req->unread_bytes = unread_bytes;
379         req->encrypted = encrypted;
380         req->conn = conn_find(req->tid);
381         req->chain_fsp = NULL;
382         req->chain_outbuf = NULL;
383         smb_init_perfcount_data(&req->pcd);
384
385         /* Ensure we have at least wct words and 2 bytes of bcc. */
386         if (smb_size + req->wct*2 > req_size) {
387                 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
388                         (unsigned int)req->wct,
389                         (unsigned int)req_size));
390                 exit_server_cleanly("Invalid SMB request");
391         }
392         /* Ensure bcc is correct. */
393         if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
394                 DEBUG(0,("init_smb_request: invalid bcc number %u "
395                         "(wct = %u, size %u)\n",
396                         (unsigned int)req->buflen,
397                         (unsigned int)req->wct,
398                         (unsigned int)req_size));
399                 exit_server_cleanly("Invalid SMB request");
400         }
401
402         req->outbuf = NULL;
403 }
404
405 static void process_smb(struct smbd_server_connection *conn,
406                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
407                         uint32_t seqnum, bool encrypted,
408                         struct smb_perfcount_data *deferred_pcd);
409
410 static void smbd_deferred_open_timer(struct event_context *ev,
411                                      struct timed_event *te,
412                                      struct timeval _tval,
413                                      void *private_data)
414 {
415         struct pending_message_list *msg = talloc_get_type(private_data,
416                                            struct pending_message_list);
417         TALLOC_CTX *mem_ctx = talloc_tos();
418         uint8_t *inbuf;
419
420         inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
421                                          msg->buf.length);
422         if (inbuf == NULL) {
423                 exit_server("smbd_deferred_open_timer: talloc failed\n");
424                 return;
425         }
426
427         /* We leave this message on the queue so the open code can
428            know this is a retry. */
429         DEBUG(5,("smbd_deferred_open_timer: trigger mid %u.\n",
430                 (unsigned int)SVAL(msg->buf.data,smb_mid)));
431
432         process_smb(smbd_server_conn, inbuf,
433                     msg->buf.length, 0,
434                     msg->seqnum, msg->encrypted, &msg->pcd);
435 }
436
437 /****************************************************************************
438  Function to push a message onto the tail of a linked list of smb messages ready
439  for processing.
440 ****************************************************************************/
441
442 static bool push_queued_message(struct smb_request *req,
443                                 struct timeval request_time,
444                                 struct timeval end_time,
445                                 char *private_data, size_t private_len)
446 {
447         int msg_len = smb_len(req->inbuf) + 4;
448         struct pending_message_list *msg;
449
450         msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
451
452         if(msg == NULL) {
453                 DEBUG(0,("push_message: malloc fail (1)\n"));
454                 return False;
455         }
456
457         msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
458         if(msg->buf.data == NULL) {
459                 DEBUG(0,("push_message: malloc fail (2)\n"));
460                 TALLOC_FREE(msg);
461                 return False;
462         }
463
464         msg->request_time = request_time;
465         msg->seqnum = req->seqnum;
466         msg->encrypted = req->encrypted;
467         SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
468
469         if (private_data) {
470                 msg->private_data = data_blob_talloc(msg, private_data,
471                                                      private_len);
472                 if (msg->private_data.data == NULL) {
473                         DEBUG(0,("push_message: malloc fail (3)\n"));
474                         TALLOC_FREE(msg);
475                         return False;
476                 }
477         }
478
479         msg->te = event_add_timed(smbd_event_context(),
480                                   msg,
481                                   end_time,
482                                   smbd_deferred_open_timer,
483                                   msg);
484         if (!msg->te) {
485                 DEBUG(0,("push_message: event_add_timed failed\n"));
486                 TALLOC_FREE(msg);
487                 return false;
488         }
489
490         DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
491
492         DEBUG(10,("push_message: pushed message length %u on "
493                   "deferred_open_queue\n", (unsigned int)msg_len));
494
495         return True;
496 }
497
498 /****************************************************************************
499  Function to delete a sharing violation open message by mid.
500 ****************************************************************************/
501
502 void remove_deferred_open_smb_message(uint16 mid)
503 {
504         struct pending_message_list *pml;
505
506         for (pml = deferred_open_queue; pml; pml = pml->next) {
507                 if (mid == SVAL(pml->buf.data,smb_mid)) {
508                         DEBUG(10,("remove_sharing_violation_open_smb_message: "
509                                   "deleting mid %u len %u\n",
510                                   (unsigned int)mid,
511                                   (unsigned int)pml->buf.length ));
512                         DLIST_REMOVE(deferred_open_queue, pml);
513                         TALLOC_FREE(pml);
514                         return;
515                 }
516         }
517 }
518
519 /****************************************************************************
520  Move a sharing violation open retry message to the front of the list and
521  schedule it for immediate processing.
522 ****************************************************************************/
523
524 void schedule_deferred_open_smb_message(uint16 mid)
525 {
526         struct pending_message_list *pml;
527         int i = 0;
528
529         for (pml = deferred_open_queue; pml; pml = pml->next) {
530                 uint16 msg_mid = SVAL(pml->buf.data,smb_mid);
531
532                 DEBUG(10,("schedule_deferred_open_smb_message: [%d] msg_mid = %u\n", i++,
533                         (unsigned int)msg_mid ));
534
535                 if (mid == msg_mid) {
536                         struct timed_event *te;
537
538                         DEBUG(10,("schedule_deferred_open_smb_message: scheduling mid %u\n",
539                                 mid ));
540
541                         te = event_add_timed(smbd_event_context(),
542                                              pml,
543                                              timeval_zero(),
544                                              smbd_deferred_open_timer,
545                                              pml);
546                         if (!te) {
547                                 DEBUG(10,("schedule_deferred_open_smb_message: "
548                                           "event_add_timed() failed, skipping mid %u\n",
549                                           mid ));
550                         }
551
552                         TALLOC_FREE(pml->te);
553                         pml->te = te;
554                         DLIST_PROMOTE(deferred_open_queue, pml);
555                         return;
556                 }
557         }
558
559         DEBUG(10,("schedule_deferred_open_smb_message: failed to find message mid %u\n",
560                 mid ));
561 }
562
563 /****************************************************************************
564  Return true if this mid is on the deferred queue.
565 ****************************************************************************/
566
567 bool open_was_deferred(uint16 mid)
568 {
569         struct pending_message_list *pml;
570
571         for (pml = deferred_open_queue; pml; pml = pml->next) {
572                 if (SVAL(pml->buf.data,smb_mid) == mid) {
573                         return True;
574                 }
575         }
576         return False;
577 }
578
579 /****************************************************************************
580  Return the message queued by this mid.
581 ****************************************************************************/
582
583 struct pending_message_list *get_open_deferred_message(uint16 mid)
584 {
585         struct pending_message_list *pml;
586
587         for (pml = deferred_open_queue; pml; pml = pml->next) {
588                 if (SVAL(pml->buf.data,smb_mid) == mid) {
589                         return pml;
590                 }
591         }
592         return NULL;
593 }
594
595 /****************************************************************************
596  Function to push a deferred open smb message onto a linked list of local smb
597  messages ready for processing.
598 ****************************************************************************/
599
600 bool push_deferred_smb_message(struct smb_request *req,
601                                struct timeval request_time,
602                                struct timeval timeout,
603                                char *private_data, size_t priv_len)
604 {
605         struct timeval end_time;
606
607         if (req->unread_bytes) {
608                 DEBUG(0,("push_deferred_smb_message: logic error ! "
609                         "unread_bytes = %u\n",
610                         (unsigned int)req->unread_bytes ));
611                 smb_panic("push_deferred_smb_message: "
612                         "logic error unread_bytes != 0" );
613         }
614
615         end_time = timeval_sum(&request_time, &timeout);
616
617         DEBUG(10,("push_deferred_open_smb_message: pushing message len %u mid %u "
618                   "timeout time [%u.%06u]\n",
619                   (unsigned int) smb_len(req->inbuf)+4, (unsigned int)req->mid,
620                   (unsigned int)end_time.tv_sec,
621                   (unsigned int)end_time.tv_usec));
622
623         return push_queued_message(req, request_time, end_time,
624                                    private_data, priv_len);
625 }
626
627 struct idle_event {
628         struct timed_event *te;
629         struct timeval interval;
630         char *name;
631         bool (*handler)(const struct timeval *now, void *private_data);
632         void *private_data;
633 };
634
635 static void smbd_idle_event_handler(struct event_context *ctx,
636                                     struct timed_event *te,
637                                     struct timeval now,
638                                     void *private_data)
639 {
640         struct idle_event *event =
641                 talloc_get_type_abort(private_data, struct idle_event);
642
643         TALLOC_FREE(event->te);
644
645         DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
646                   event->name, event->te));
647
648         if (!event->handler(&now, event->private_data)) {
649                 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
650                           event->name, event->te));
651                 /* Don't repeat, delete ourselves */
652                 TALLOC_FREE(event);
653                 return;
654         }
655
656         DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
657                   event->name, event->te));
658
659         event->te = event_add_timed(ctx, event,
660                                     timeval_sum(&now, &event->interval),
661                                     smbd_idle_event_handler, event);
662
663         /* We can't do much but fail here. */
664         SMB_ASSERT(event->te != NULL);
665 }
666
667 struct idle_event *event_add_idle(struct event_context *event_ctx,
668                                   TALLOC_CTX *mem_ctx,
669                                   struct timeval interval,
670                                   const char *name,
671                                   bool (*handler)(const struct timeval *now,
672                                                   void *private_data),
673                                   void *private_data)
674 {
675         struct idle_event *result;
676         struct timeval now = timeval_current();
677
678         result = TALLOC_P(mem_ctx, struct idle_event);
679         if (result == NULL) {
680                 DEBUG(0, ("talloc failed\n"));
681                 return NULL;
682         }
683
684         result->interval = interval;
685         result->handler = handler;
686         result->private_data = private_data;
687
688         if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
689                 DEBUG(0, ("talloc failed\n"));
690                 TALLOC_FREE(result);
691                 return NULL;
692         }
693
694         result->te = event_add_timed(event_ctx, result,
695                                      timeval_sum(&now, &interval),
696                                      smbd_idle_event_handler, result);
697         if (result->te == NULL) {
698                 DEBUG(0, ("event_add_timed failed\n"));
699                 TALLOC_FREE(result);
700                 return NULL;
701         }
702
703         DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
704         return result;
705 }
706
707 static void smbd_sig_term_handler(struct tevent_context *ev,
708                                   struct tevent_signal *se,
709                                   int signum,
710                                   int count,
711                                   void *siginfo,
712                                   void *private_data)
713 {
714         exit_server_cleanly("termination signal");
715 }
716
717 void smbd_setup_sig_term_handler(void)
718 {
719         struct tevent_signal *se;
720
721         se = tevent_add_signal(smbd_event_context(),
722                                smbd_event_context(),
723                                SIGTERM, 0,
724                                smbd_sig_term_handler,
725                                NULL);
726         if (!se) {
727                 exit_server("failed to setup SIGTERM handler");
728         }
729 }
730
731 static void smbd_sig_hup_handler(struct tevent_context *ev,
732                                   struct tevent_signal *se,
733                                   int signum,
734                                   int count,
735                                   void *siginfo,
736                                   void *private_data)
737 {
738         change_to_root_user();
739         DEBUG(1,("Reloading services after SIGHUP\n"));
740         reload_services(False);
741 }
742
743 void smbd_setup_sig_hup_handler(void)
744 {
745         struct tevent_signal *se;
746
747         se = tevent_add_signal(smbd_event_context(),
748                                smbd_event_context(),
749                                SIGHUP, 0,
750                                smbd_sig_hup_handler,
751                                NULL);
752         if (!se) {
753                 exit_server("failed to setup SIGHUP handler");
754         }
755 }
756
757 static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
758 {
759         fd_set r_fds, w_fds;
760         int selrtn;
761         struct timeval to;
762         int maxfd = 0;
763
764         to.tv_sec = SMBD_SELECT_TIMEOUT;
765         to.tv_usec = 0;
766
767         /*
768          * Setup the select fd sets.
769          */
770
771         FD_ZERO(&r_fds);
772         FD_ZERO(&w_fds);
773
774         /*
775          * Are there any timed events waiting ? If so, ensure we don't
776          * select for longer than it would take to wait for them.
777          */
778
779         {
780                 struct timeval now;
781                 GetTimeOfDay(&now);
782
783                 event_add_to_select_args(smbd_event_context(), &now,
784                                          &r_fds, &w_fds, &to, &maxfd);
785         }
786
787         /* Process a signal and timed events now... */
788         if (run_events(smbd_event_context(), 0, NULL, NULL)) {
789                 return NT_STATUS_RETRY;
790         }
791
792         {
793                 int sav;
794                 START_PROFILE(smbd_idle);
795
796                 selrtn = sys_select(maxfd+1,&r_fds,&w_fds,NULL,&to);
797                 sav = errno;
798
799                 END_PROFILE(smbd_idle);
800                 errno = sav;
801         }
802
803         if (run_events(smbd_event_context(), selrtn, &r_fds, &w_fds)) {
804                 return NT_STATUS_RETRY;
805         }
806
807         /* Check if error */
808         if (selrtn == -1) {
809                 /* something is wrong. Maybe the socket is dead? */
810                 return map_nt_error_from_unix(errno);
811         }
812
813         /* Did we timeout ? */
814         if (selrtn == 0) {
815                 return NT_STATUS_RETRY;
816         }
817
818         /* should not be reached */
819         return NT_STATUS_INTERNAL_ERROR;
820 }
821
822 /*
823  * Only allow 5 outstanding trans requests. We're allocating memory, so
824  * prevent a DoS.
825  */
826
827 NTSTATUS allow_new_trans(struct trans_state *list, int mid)
828 {
829         int count = 0;
830         for (; list != NULL; list = list->next) {
831
832                 if (list->mid == mid) {
833                         return NT_STATUS_INVALID_PARAMETER;
834                 }
835
836                 count += 1;
837         }
838         if (count > 5) {
839                 return NT_STATUS_INSUFFICIENT_RESOURCES;
840         }
841
842         return NT_STATUS_OK;
843 }
844
845 /*
846 These flags determine some of the permissions required to do an operation 
847
848 Note that I don't set NEED_WRITE on some write operations because they
849 are used by some brain-dead clients when printing, and I don't want to
850 force write permissions on print services.
851 */
852 #define AS_USER (1<<0)
853 #define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
854 #define TIME_INIT (1<<2)
855 #define CAN_IPC (1<<3) /* Must be paired with AS_USER */
856 #define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
857 #define DO_CHDIR (1<<6)
858
859 /* 
860    define a list of possible SMB messages and their corresponding
861    functions. Any message that has a NULL function is unimplemented -
862    please feel free to contribute implementations!
863 */
864 static const struct smb_message_struct {
865         const char *name;
866         void (*fn)(struct smb_request *req);
867         int flags;
868 } smb_messages[256] = {
869
870 /* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
871 /* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
872 /* 0x02 */ { "SMBopen",reply_open,AS_USER },
873 /* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
874 /* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
875 /* 0x05 */ { "SMBflush",reply_flush,AS_USER},
876 /* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
877 /* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
878 /* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
879 /* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
880 /* 0x0a */ { "SMBread",reply_read,AS_USER},
881 /* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
882 /* 0x0c */ { "SMBlock",reply_lock,AS_USER},
883 /* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
884 /* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
885 /* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
886 /* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
887 /* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
888 /* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
889 /* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
890 /* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
891 /* 0x15 */ { NULL, NULL, 0 },
892 /* 0x16 */ { NULL, NULL, 0 },
893 /* 0x17 */ { NULL, NULL, 0 },
894 /* 0x18 */ { NULL, NULL, 0 },
895 /* 0x19 */ { NULL, NULL, 0 },
896 /* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
897 /* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
898 /* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
899 /* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
900 /* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
901 /* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
902 /* 0x20 */ { "SMBwritec", NULL,0},
903 /* 0x21 */ { NULL, NULL, 0 },
904 /* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
905 /* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
906 /* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
907 /* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
908 /* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
909 /* 0x27 */ { "SMBioctl",reply_ioctl,0},
910 /* 0x28 */ { "SMBioctls", NULL,AS_USER},
911 /* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
912 /* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
913 /* 0x2b */ { "SMBecho",reply_echo,0},
914 /* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
915 /* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
916 /* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
917 /* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
918 /* 0x30 */ { NULL, NULL, 0 },
919 /* 0x31 */ { NULL, NULL, 0 },
920 /* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
921 /* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
922 /* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
923 /* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
924 /* 0x36 */ { NULL, NULL, 0 },
925 /* 0x37 */ { NULL, NULL, 0 },
926 /* 0x38 */ { NULL, NULL, 0 },
927 /* 0x39 */ { NULL, NULL, 0 },
928 /* 0x3a */ { NULL, NULL, 0 },
929 /* 0x3b */ { NULL, NULL, 0 },
930 /* 0x3c */ { NULL, NULL, 0 },
931 /* 0x3d */ { NULL, NULL, 0 },
932 /* 0x3e */ { NULL, NULL, 0 },
933 /* 0x3f */ { NULL, NULL, 0 },
934 /* 0x40 */ { NULL, NULL, 0 },
935 /* 0x41 */ { NULL, NULL, 0 },
936 /* 0x42 */ { NULL, NULL, 0 },
937 /* 0x43 */ { NULL, NULL, 0 },
938 /* 0x44 */ { NULL, NULL, 0 },
939 /* 0x45 */ { NULL, NULL, 0 },
940 /* 0x46 */ { NULL, NULL, 0 },
941 /* 0x47 */ { NULL, NULL, 0 },
942 /* 0x48 */ { NULL, NULL, 0 },
943 /* 0x49 */ { NULL, NULL, 0 },
944 /* 0x4a */ { NULL, NULL, 0 },
945 /* 0x4b */ { NULL, NULL, 0 },
946 /* 0x4c */ { NULL, NULL, 0 },
947 /* 0x4d */ { NULL, NULL, 0 },
948 /* 0x4e */ { NULL, NULL, 0 },
949 /* 0x4f */ { NULL, NULL, 0 },
950 /* 0x50 */ { NULL, NULL, 0 },
951 /* 0x51 */ { NULL, NULL, 0 },
952 /* 0x52 */ { NULL, NULL, 0 },
953 /* 0x53 */ { NULL, NULL, 0 },
954 /* 0x54 */ { NULL, NULL, 0 },
955 /* 0x55 */ { NULL, NULL, 0 },
956 /* 0x56 */ { NULL, NULL, 0 },
957 /* 0x57 */ { NULL, NULL, 0 },
958 /* 0x58 */ { NULL, NULL, 0 },
959 /* 0x59 */ { NULL, NULL, 0 },
960 /* 0x5a */ { NULL, NULL, 0 },
961 /* 0x5b */ { NULL, NULL, 0 },
962 /* 0x5c */ { NULL, NULL, 0 },
963 /* 0x5d */ { NULL, NULL, 0 },
964 /* 0x5e */ { NULL, NULL, 0 },
965 /* 0x5f */ { NULL, NULL, 0 },
966 /* 0x60 */ { NULL, NULL, 0 },
967 /* 0x61 */ { NULL, NULL, 0 },
968 /* 0x62 */ { NULL, NULL, 0 },
969 /* 0x63 */ { NULL, NULL, 0 },
970 /* 0x64 */ { NULL, NULL, 0 },
971 /* 0x65 */ { NULL, NULL, 0 },
972 /* 0x66 */ { NULL, NULL, 0 },
973 /* 0x67 */ { NULL, NULL, 0 },
974 /* 0x68 */ { NULL, NULL, 0 },
975 /* 0x69 */ { NULL, NULL, 0 },
976 /* 0x6a */ { NULL, NULL, 0 },
977 /* 0x6b */ { NULL, NULL, 0 },
978 /* 0x6c */ { NULL, NULL, 0 },
979 /* 0x6d */ { NULL, NULL, 0 },
980 /* 0x6e */ { NULL, NULL, 0 },
981 /* 0x6f */ { NULL, NULL, 0 },
982 /* 0x70 */ { "SMBtcon",reply_tcon,0},
983 /* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
984 /* 0x72 */ { "SMBnegprot",reply_negprot,0},
985 /* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
986 /* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
987 /* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
988 /* 0x76 */ { NULL, NULL, 0 },
989 /* 0x77 */ { NULL, NULL, 0 },
990 /* 0x78 */ { NULL, NULL, 0 },
991 /* 0x79 */ { NULL, NULL, 0 },
992 /* 0x7a */ { NULL, NULL, 0 },
993 /* 0x7b */ { NULL, NULL, 0 },
994 /* 0x7c */ { NULL, NULL, 0 },
995 /* 0x7d */ { NULL, NULL, 0 },
996 /* 0x7e */ { NULL, NULL, 0 },
997 /* 0x7f */ { NULL, NULL, 0 },
998 /* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
999 /* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1000 /* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1001 /* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1002 /* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1003 /* 0x85 */ { NULL, NULL, 0 },
1004 /* 0x86 */ { NULL, NULL, 0 },
1005 /* 0x87 */ { NULL, NULL, 0 },
1006 /* 0x88 */ { NULL, NULL, 0 },
1007 /* 0x89 */ { NULL, NULL, 0 },
1008 /* 0x8a */ { NULL, NULL, 0 },
1009 /* 0x8b */ { NULL, NULL, 0 },
1010 /* 0x8c */ { NULL, NULL, 0 },
1011 /* 0x8d */ { NULL, NULL, 0 },
1012 /* 0x8e */ { NULL, NULL, 0 },
1013 /* 0x8f */ { NULL, NULL, 0 },
1014 /* 0x90 */ { NULL, NULL, 0 },
1015 /* 0x91 */ { NULL, NULL, 0 },
1016 /* 0x92 */ { NULL, NULL, 0 },
1017 /* 0x93 */ { NULL, NULL, 0 },
1018 /* 0x94 */ { NULL, NULL, 0 },
1019 /* 0x95 */ { NULL, NULL, 0 },
1020 /* 0x96 */ { NULL, NULL, 0 },
1021 /* 0x97 */ { NULL, NULL, 0 },
1022 /* 0x98 */ { NULL, NULL, 0 },
1023 /* 0x99 */ { NULL, NULL, 0 },
1024 /* 0x9a */ { NULL, NULL, 0 },
1025 /* 0x9b */ { NULL, NULL, 0 },
1026 /* 0x9c */ { NULL, NULL, 0 },
1027 /* 0x9d */ { NULL, NULL, 0 },
1028 /* 0x9e */ { NULL, NULL, 0 },
1029 /* 0x9f */ { NULL, NULL, 0 },
1030 /* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1031 /* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1032 /* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1033 /* 0xa3 */ { NULL, NULL, 0 },
1034 /* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1035 /* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1036 /* 0xa6 */ { NULL, NULL, 0 },
1037 /* 0xa7 */ { NULL, NULL, 0 },
1038 /* 0xa8 */ { NULL, NULL, 0 },
1039 /* 0xa9 */ { NULL, NULL, 0 },
1040 /* 0xaa */ { NULL, NULL, 0 },
1041 /* 0xab */ { NULL, NULL, 0 },
1042 /* 0xac */ { NULL, NULL, 0 },
1043 /* 0xad */ { NULL, NULL, 0 },
1044 /* 0xae */ { NULL, NULL, 0 },
1045 /* 0xaf */ { NULL, NULL, 0 },
1046 /* 0xb0 */ { NULL, NULL, 0 },
1047 /* 0xb1 */ { NULL, NULL, 0 },
1048 /* 0xb2 */ { NULL, NULL, 0 },
1049 /* 0xb3 */ { NULL, NULL, 0 },
1050 /* 0xb4 */ { NULL, NULL, 0 },
1051 /* 0xb5 */ { NULL, NULL, 0 },
1052 /* 0xb6 */ { NULL, NULL, 0 },
1053 /* 0xb7 */ { NULL, NULL, 0 },
1054 /* 0xb8 */ { NULL, NULL, 0 },
1055 /* 0xb9 */ { NULL, NULL, 0 },
1056 /* 0xba */ { NULL, NULL, 0 },
1057 /* 0xbb */ { NULL, NULL, 0 },
1058 /* 0xbc */ { NULL, NULL, 0 },
1059 /* 0xbd */ { NULL, NULL, 0 },
1060 /* 0xbe */ { NULL, NULL, 0 },
1061 /* 0xbf */ { NULL, NULL, 0 },
1062 /* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1063 /* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1064 /* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1065 /* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1066 /* 0xc4 */ { NULL, NULL, 0 },
1067 /* 0xc5 */ { NULL, NULL, 0 },
1068 /* 0xc6 */ { NULL, NULL, 0 },
1069 /* 0xc7 */ { NULL, NULL, 0 },
1070 /* 0xc8 */ { NULL, NULL, 0 },
1071 /* 0xc9 */ { NULL, NULL, 0 },
1072 /* 0xca */ { NULL, NULL, 0 },
1073 /* 0xcb */ { NULL, NULL, 0 },
1074 /* 0xcc */ { NULL, NULL, 0 },
1075 /* 0xcd */ { NULL, NULL, 0 },
1076 /* 0xce */ { NULL, NULL, 0 },
1077 /* 0xcf */ { NULL, NULL, 0 },
1078 /* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1079 /* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1080 /* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1081 /* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1082 /* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1083 /* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1084 /* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1085 /* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1086 /* 0xd8 */ { NULL, NULL, 0 },
1087 /* 0xd9 */ { NULL, NULL, 0 },
1088 /* 0xda */ { NULL, NULL, 0 },
1089 /* 0xdb */ { NULL, NULL, 0 },
1090 /* 0xdc */ { NULL, NULL, 0 },
1091 /* 0xdd */ { NULL, NULL, 0 },
1092 /* 0xde */ { NULL, NULL, 0 },
1093 /* 0xdf */ { NULL, NULL, 0 },
1094 /* 0xe0 */ { NULL, NULL, 0 },
1095 /* 0xe1 */ { NULL, NULL, 0 },
1096 /* 0xe2 */ { NULL, NULL, 0 },
1097 /* 0xe3 */ { NULL, NULL, 0 },
1098 /* 0xe4 */ { NULL, NULL, 0 },
1099 /* 0xe5 */ { NULL, NULL, 0 },
1100 /* 0xe6 */ { NULL, NULL, 0 },
1101 /* 0xe7 */ { NULL, NULL, 0 },
1102 /* 0xe8 */ { NULL, NULL, 0 },
1103 /* 0xe9 */ { NULL, NULL, 0 },
1104 /* 0xea */ { NULL, NULL, 0 },
1105 /* 0xeb */ { NULL, NULL, 0 },
1106 /* 0xec */ { NULL, NULL, 0 },
1107 /* 0xed */ { NULL, NULL, 0 },
1108 /* 0xee */ { NULL, NULL, 0 },
1109 /* 0xef */ { NULL, NULL, 0 },
1110 /* 0xf0 */ { NULL, NULL, 0 },
1111 /* 0xf1 */ { NULL, NULL, 0 },
1112 /* 0xf2 */ { NULL, NULL, 0 },
1113 /* 0xf3 */ { NULL, NULL, 0 },
1114 /* 0xf4 */ { NULL, NULL, 0 },
1115 /* 0xf5 */ { NULL, NULL, 0 },
1116 /* 0xf6 */ { NULL, NULL, 0 },
1117 /* 0xf7 */ { NULL, NULL, 0 },
1118 /* 0xf8 */ { NULL, NULL, 0 },
1119 /* 0xf9 */ { NULL, NULL, 0 },
1120 /* 0xfa */ { NULL, NULL, 0 },
1121 /* 0xfb */ { NULL, NULL, 0 },
1122 /* 0xfc */ { NULL, NULL, 0 },
1123 /* 0xfd */ { NULL, NULL, 0 },
1124 /* 0xfe */ { NULL, NULL, 0 },
1125 /* 0xff */ { NULL, NULL, 0 }
1126
1127 };
1128
1129 /*******************************************************************
1130  allocate and initialize a reply packet
1131 ********************************************************************/
1132
1133 static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1134                           const char *inbuf, char **outbuf, uint8_t num_words,
1135                           uint32_t num_bytes)
1136 {
1137         /*
1138          * Protect against integer wrap
1139          */
1140         if ((num_bytes > 0xffffff)
1141             || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1142                 char *msg;
1143                 if (asprintf(&msg, "num_bytes too large: %u",
1144                              (unsigned)num_bytes) == -1) {
1145                         msg = CONST_DISCARD(char *, "num_bytes too large");
1146                 }
1147                 smb_panic(msg);
1148         }
1149
1150         *outbuf = TALLOC_ARRAY(mem_ctx, char,
1151                                smb_size + num_words*2 + num_bytes);
1152         if (*outbuf == NULL) {
1153                 return false;
1154         }
1155
1156         construct_reply_common(req, inbuf, *outbuf);
1157         srv_set_message(*outbuf, num_words, num_bytes, false);
1158         /*
1159          * Zero out the word area, the caller has to take care of the bcc area
1160          * himself
1161          */
1162         if (num_words != 0) {
1163                 memset(*outbuf + smb_vwv0, 0, num_words*2);
1164         }
1165
1166         return true;
1167 }
1168
1169 void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1170 {
1171         char *outbuf;
1172         if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1173                            num_bytes)) {
1174                 smb_panic("could not allocate output buffer\n");
1175         }
1176         req->outbuf = (uint8_t *)outbuf;
1177 }
1178
1179
1180 /*******************************************************************
1181  Dump a packet to a file.
1182 ********************************************************************/
1183
1184 static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1185 {
1186         int fd, i;
1187         char *fname = NULL;
1188         if (DEBUGLEVEL < 50) {
1189                 return;
1190         }
1191
1192         if (len < 4) len = smb_len(data)+4;
1193         for (i=1;i<100;i++) {
1194                 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1195                              type ? "req" : "resp") == -1) {
1196                         return;
1197                 }
1198                 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1199                 if (fd != -1 || errno != EEXIST) break;
1200         }
1201         if (fd != -1) {
1202                 ssize_t ret = write(fd, data, len);
1203                 if (ret != len)
1204                         DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1205                 close(fd);
1206                 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1207         }
1208         SAFE_FREE(fname);
1209 }
1210
1211 /****************************************************************************
1212  Prepare everything for calling the actual request function, and potentially
1213  call the request function via the "new" interface.
1214
1215  Return False if the "legacy" function needs to be called, everything is
1216  prepared.
1217
1218  Return True if we're done.
1219
1220  I know this API sucks, but it is the one with the least code change I could
1221  find.
1222 ****************************************************************************/
1223
1224 static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1225 {
1226         int flags;
1227         uint16 session_tag;
1228         connection_struct *conn = NULL;
1229
1230         errno = 0;
1231
1232         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1233          * so subtract 4 from it. */
1234         if (!valid_smb_header(req->inbuf)
1235             || (size < (smb_size - 4))) {
1236                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1237                          smb_len(req->inbuf)));
1238                 exit_server_cleanly("Non-SMB packet");
1239         }
1240
1241         if (smb_messages[type].fn == NULL) {
1242                 DEBUG(0,("Unknown message type %d!\n",type));
1243                 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1244                 reply_unknown_new(req, type);
1245                 return NULL;
1246         }
1247
1248         flags = smb_messages[type].flags;
1249
1250         /* In share mode security we must ignore the vuid. */
1251         session_tag = (lp_security() == SEC_SHARE)
1252                 ? UID_FIELD_INVALID : req->vuid;
1253         conn = req->conn;
1254
1255         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1256                  (int)sys_getpid(), (unsigned long)conn));
1257
1258         smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1259
1260         /* Ensure this value is replaced in the incoming packet. */
1261         SSVAL(req->inbuf,smb_uid,session_tag);
1262
1263         /*
1264          * Ensure the correct username is in current_user_info.  This is a
1265          * really ugly bugfix for problems with multiple session_setup_and_X's
1266          * being done and allowing %U and %G substitutions to work correctly.
1267          * There is a reason this code is done here, don't move it unless you
1268          * know what you're doing... :-).
1269          * JRA.
1270          */
1271
1272         if (session_tag != last_session_tag) {
1273                 user_struct *vuser = NULL;
1274
1275                 last_session_tag = session_tag;
1276                 if(session_tag != UID_FIELD_INVALID) {
1277                         vuser = get_valid_user_struct(session_tag);
1278                         if (vuser) {
1279                                 set_current_user_info(
1280                                         vuser->server_info->sanitized_username,
1281                                         vuser->server_info->unix_name,
1282                                         pdb_get_domain(vuser->server_info
1283                                                        ->sam_account));
1284                         }
1285                 }
1286         }
1287
1288         /* Does this call need to be run as the connected user? */
1289         if (flags & AS_USER) {
1290
1291                 /* Does this call need a valid tree connection? */
1292                 if (!conn) {
1293                         /*
1294                          * Amazingly, the error code depends on the command
1295                          * (from Samba4).
1296                          */
1297                         if (type == SMBntcreateX) {
1298                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1299                         } else {
1300                                 reply_doserror(req, ERRSRV, ERRinvnid);
1301                         }
1302                         return NULL;
1303                 }
1304
1305                 if (!change_to_user(conn,session_tag)) {
1306                         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1307                         remove_deferred_open_smb_message(req->mid);
1308                         return conn;
1309                 }
1310
1311                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1312
1313                 /* Does it need write permission? */
1314                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1315                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1316                         return conn;
1317                 }
1318
1319                 /* IPC services are limited */
1320                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1321                         reply_doserror(req, ERRSRV,ERRaccess);
1322                         return conn;
1323                 }
1324         } else {
1325                 /* This call needs to be run as root */
1326                 change_to_root_user();
1327         }
1328
1329         /* load service specific parameters */
1330         if (conn) {
1331                 if (req->encrypted) {
1332                         conn->encrypted_tid = true;
1333                         /* encrypted required from now on. */
1334                         conn->encrypt_level = Required;
1335                 } else if (ENCRYPTION_REQUIRED(conn)) {
1336                         if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1337                                 exit_server_cleanly("encryption required "
1338                                         "on connection");
1339                                 return conn;
1340                         }
1341                 }
1342
1343                 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1344                                          (flags & (AS_USER|DO_CHDIR)
1345                                           ?True:False))) {
1346                         reply_doserror(req, ERRSRV, ERRaccess);
1347                         return conn;
1348                 }
1349                 conn->num_smb_operations++;
1350         }
1351
1352         /* does this protocol need to be run as guest? */
1353         if ((flags & AS_GUEST)
1354             && (!change_to_guest() ||
1355                 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1356                               lp_hostsdeny(-1)))) {
1357                 reply_doserror(req, ERRSRV, ERRaccess);
1358                 return conn;
1359         }
1360
1361         smb_messages[type].fn(req);
1362         return req->conn;
1363 }
1364
1365 /****************************************************************************
1366  Construct a reply to the incoming packet.
1367 ****************************************************************************/
1368
1369 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1370                             uint32_t seqnum, bool encrypted,
1371                             struct smb_perfcount_data *deferred_pcd)
1372 {
1373         connection_struct *conn;
1374         struct smb_request *req;
1375
1376         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1377                 smb_panic("could not allocate smb_request");
1378         }
1379
1380         init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1381         req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
1382         req->seqnum = seqnum;
1383
1384         /* we popped this message off the queue - keep original perf data */
1385         if (deferred_pcd)
1386                 req->pcd = *deferred_pcd;
1387         else {
1388                 SMB_PERFCOUNT_START(&req->pcd);
1389                 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1390                 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1391         }
1392
1393         conn = switch_message(req->cmd, req, size);
1394
1395         if (req->unread_bytes) {
1396                 /* writeX failed. drain socket. */
1397                 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1398                                 req->unread_bytes) {
1399                         smb_panic("failed to drain pending bytes");
1400                 }
1401                 req->unread_bytes = 0;
1402         }
1403
1404         if (req->outbuf == NULL) {
1405                 return;
1406         }
1407
1408         if (CVAL(req->outbuf,0) == 0) {
1409                 show_msg((char *)req->outbuf);
1410         }
1411
1412         if (!srv_send_smb(smbd_server_fd(),
1413                         (char *)req->outbuf,
1414                         true, req->seqnum+1,
1415                         IS_CONN_ENCRYPTED(conn)||req->encrypted,
1416                         &req->pcd)) {
1417                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1418         }
1419
1420         TALLOC_FREE(req);
1421
1422         return;
1423 }
1424
1425 /****************************************************************************
1426  Process an smb from the client
1427 ****************************************************************************/
1428 static void process_smb(struct smbd_server_connection *conn,
1429                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
1430                         uint32_t seqnum, bool encrypted,
1431                         struct smb_perfcount_data *deferred_pcd)
1432 {
1433         int msg_type = CVAL(inbuf,0);
1434
1435         DO_PROFILE_INC(smb_count);
1436
1437         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1438                     smb_len(inbuf) ) );
1439         DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1440                                 (int)nread,
1441                                 (unsigned int)unread_bytes ));
1442
1443         if (msg_type != 0) {
1444                 /*
1445                  * NetBIOS session request, keepalive, etc.
1446                  */
1447                 reply_special((char *)inbuf);
1448                 goto done;
1449         }
1450
1451         show_msg((char *)inbuf);
1452
1453         construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1454         trans_num++;
1455
1456 done:
1457         conn->num_requests++;
1458
1459         /* The timeout_processing function isn't run nearly
1460            often enough to implement 'max log size' without
1461            overrunning the size of the file by many megabytes.
1462            This is especially true if we are running at debug
1463            level 10.  Checking every 50 SMBs is a nice
1464            tradeoff of performance vs log file size overrun. */
1465
1466         if ((conn->num_requests % 50) == 0 &&
1467             need_to_check_log_size()) {
1468                 change_to_root_user();
1469                 check_log_size();
1470         }
1471 }
1472
1473 /****************************************************************************
1474  Return a string containing the function name of a SMB command.
1475 ****************************************************************************/
1476
1477 const char *smb_fn_name(int type)
1478 {
1479         const char *unknown_name = "SMBunknown";
1480
1481         if (smb_messages[type].name == NULL)
1482                 return(unknown_name);
1483
1484         return(smb_messages[type].name);
1485 }
1486
1487 /****************************************************************************
1488  Helper functions for contruct_reply.
1489 ****************************************************************************/
1490
1491 void add_to_common_flags2(uint32 v)
1492 {
1493         common_flags2 |= v;
1494 }
1495
1496 void remove_from_common_flags2(uint32 v)
1497 {
1498         common_flags2 &= ~v;
1499 }
1500
1501 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1502                                    char *outbuf)
1503 {
1504         srv_set_message(outbuf,0,0,false);
1505         
1506         SCVAL(outbuf, smb_com, req->cmd);
1507         SIVAL(outbuf,smb_rcls,0);
1508         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1509         SSVAL(outbuf,smb_flg2,
1510                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1511                 common_flags2);
1512         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1513
1514         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1515         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1516         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1517         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1518 }
1519
1520 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1521 {
1522         construct_reply_common(req, (char *)req->inbuf, outbuf);
1523 }
1524
1525 /*
1526  * How many bytes have we already accumulated up to the current wct field
1527  * offset?
1528  */
1529
1530 size_t req_wct_ofs(struct smb_request *req)
1531 {
1532         size_t buf_size;
1533
1534         if (req->chain_outbuf == NULL) {
1535                 return smb_wct - 4;
1536         }
1537         buf_size = talloc_get_size(req->chain_outbuf);
1538         if ((buf_size % 4) != 0) {
1539                 buf_size += (4 - (buf_size % 4));
1540         }
1541         return buf_size - 4;
1542 }
1543
1544 /*
1545  * Hack around reply_nterror & friends not being aware of chained requests,
1546  * generating illegal (i.e. wct==0) chain replies.
1547  */
1548
1549 static void fixup_chain_error_packet(struct smb_request *req)
1550 {
1551         uint8_t *outbuf = req->outbuf;
1552         req->outbuf = NULL;
1553         reply_outbuf(req, 2, 0);
1554         memcpy(req->outbuf, outbuf, smb_wct);
1555         TALLOC_FREE(outbuf);
1556         SCVAL(req->outbuf, smb_vwv0, 0xff);
1557 }
1558
1559 /****************************************************************************
1560  Construct a chained reply and add it to the already made reply
1561 ****************************************************************************/
1562
1563 void chain_reply(struct smb_request *req)
1564 {
1565         size_t smblen = smb_len(req->inbuf);
1566         size_t already_used, length_needed;
1567         uint8_t chain_cmd;
1568         uint32_t chain_offset;  /* uint32_t to avoid overflow */
1569
1570         uint8_t wct;
1571         uint16_t *vwv;
1572         uint16_t buflen;
1573         uint8_t *buf;
1574
1575         if (IVAL(req->outbuf, smb_rcls) != 0) {
1576                 fixup_chain_error_packet(req);
1577         }
1578
1579         /*
1580          * Any of the AndX requests and replies have at least a wct of
1581          * 2. vwv[0] is the next command, vwv[1] is the offset from the
1582          * beginning of the SMB header to the next wct field.
1583          *
1584          * None of the AndX requests put anything valuable in vwv[0] and [1],
1585          * so we can overwrite it here to form the chain.
1586          */
1587
1588         if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1589                 goto error;
1590         }
1591
1592         /*
1593          * Here we assume that this is the end of the chain. For that we need
1594          * to set "next command" to 0xff and the offset to 0. If we later find
1595          * more commands in the chain, this will be overwritten again.
1596          */
1597
1598         SCVAL(req->outbuf, smb_vwv0, 0xff);
1599         SCVAL(req->outbuf, smb_vwv0+1, 0);
1600         SSVAL(req->outbuf, smb_vwv1, 0);
1601
1602         if (req->chain_outbuf == NULL) {
1603                 /*
1604                  * In req->chain_outbuf we collect all the replies. Start the
1605                  * chain by copying in the first reply.
1606                  *
1607                  * We do the realloc because later on we depend on
1608                  * talloc_get_size to determine the length of
1609                  * chain_outbuf. The reply_xxx routines might have
1610                  * over-allocated (reply_pipe_read_and_X used to be such an
1611                  * example).
1612                  */
1613                 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1614                         req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1615                 if (req->chain_outbuf == NULL) {
1616                         goto error;
1617                 }
1618                 req->outbuf = NULL;
1619         } else {
1620                 /*
1621                  * Update smb headers where subsequent chained commands
1622                  * may have updated them.
1623                  */
1624                 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1625                 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1626
1627                 if (!smb_splice_chain(&req->chain_outbuf,
1628                                       CVAL(req->outbuf, smb_com),
1629                                       CVAL(req->outbuf, smb_wct),
1630                                       (uint16_t *)(req->outbuf + smb_vwv),
1631                                       0, smb_buflen(req->outbuf),
1632                                       (uint8_t *)smb_buf(req->outbuf))) {
1633                         goto error;
1634                 }
1635                 TALLOC_FREE(req->outbuf);
1636         }
1637
1638         /*
1639          * We use the old request's vwv field to grab the next chained command
1640          * and offset into the chained fields.
1641          */
1642
1643         chain_cmd = CVAL(req->vwv+0, 0);
1644         chain_offset = SVAL(req->vwv+1, 0);
1645
1646         if (chain_cmd == 0xff) {
1647                 /*
1648                  * End of chain, no more requests from the client. So ship the
1649                  * replies.
1650                  */
1651                 smb_setlen((char *)(req->chain_outbuf),
1652                            talloc_get_size(req->chain_outbuf) - 4);
1653
1654                 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1655                                   true, req->seqnum+1,
1656                                   IS_CONN_ENCRYPTED(req->conn)
1657                                   ||req->encrypted,
1658                                   &req->pcd)) {
1659                         exit_server_cleanly("chain_reply: srv_send_smb "
1660                                             "failed.");
1661                 }
1662                 TALLOC_FREE(req);
1663
1664                 return;
1665         }
1666
1667         /* add a new perfcounter for this element of chain */
1668         SMB_PERFCOUNT_ADD(&req->pcd);
1669         SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1670         SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1671
1672         /*
1673          * Check if the client tries to fool us. The request so far uses the
1674          * space to the end of the byte buffer in the request just
1675          * processed. The chain_offset can't point into that area. If that was
1676          * the case, we could end up with an endless processing of the chain,
1677          * we would always handle the same request.
1678          */
1679
1680         already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1681         if (chain_offset < already_used) {
1682                 goto error;
1683         }
1684
1685         /*
1686          * Next check: Make sure the chain offset does not point beyond the
1687          * overall smb request length.
1688          */
1689
1690         length_needed = chain_offset+1; /* wct */
1691         if (length_needed > smblen) {
1692                 goto error;
1693         }
1694
1695         /*
1696          * Now comes the pointer magic. Goal here is to set up req->vwv and
1697          * req->buf correctly again to be able to call the subsequent
1698          * switch_message(). The chain offset (the former vwv[1]) points at
1699          * the new wct field.
1700          */
1701
1702         wct = CVAL(smb_base(req->inbuf), chain_offset);
1703
1704         /*
1705          * Next consistency check: Make the new vwv array fits in the overall
1706          * smb request.
1707          */
1708
1709         length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1710         if (length_needed > smblen) {
1711                 goto error;
1712         }
1713         vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1714
1715         /*
1716          * Now grab the new byte buffer....
1717          */
1718
1719         buflen = SVAL(vwv+wct, 0);
1720
1721         /*
1722          * .. and check that it fits.
1723          */
1724
1725         length_needed += buflen;
1726         if (length_needed > smblen) {
1727                 goto error;
1728         }
1729         buf = (uint8_t *)(vwv+wct+1);
1730
1731         req->cmd = chain_cmd;
1732         req->wct = wct;
1733         req->vwv = vwv;
1734         req->buflen = buflen;
1735         req->buf = buf;
1736
1737         switch_message(chain_cmd, req, smblen);
1738
1739         if (req->outbuf == NULL) {
1740                 /*
1741                  * This happens if the chained command has suspended itself or
1742                  * if it has called srv_send_smb() itself.
1743                  */
1744                 return;
1745         }
1746
1747         /*
1748          * We end up here if the chained command was not itself chained or
1749          * suspended, but for example a close() command. We now need to splice
1750          * the chained commands' outbuf into the already built up chain_outbuf
1751          * and ship the result.
1752          */
1753         goto done;
1754
1755  error:
1756         /*
1757          * We end up here if there's any error in the chain syntax. Report a
1758          * DOS error, just like Windows does.
1759          */
1760         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1761         fixup_chain_error_packet(req);
1762
1763  done:
1764         if (!smb_splice_chain(&req->chain_outbuf,
1765                               CVAL(req->outbuf, smb_com),
1766                               CVAL(req->outbuf, smb_wct),
1767                               (uint16_t *)(req->outbuf + smb_vwv),
1768                               0, smb_buflen(req->outbuf),
1769                               (uint8_t *)smb_buf(req->outbuf))) {
1770                 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1771         }
1772         TALLOC_FREE(req->outbuf);
1773
1774         smb_setlen((char *)(req->chain_outbuf),
1775                    talloc_get_size(req->chain_outbuf) - 4);
1776
1777         show_msg((char *)(req->chain_outbuf));
1778
1779         if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1780                           true, req->seqnum+1,
1781                           IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1782                           &req->pcd)) {
1783                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1784         }
1785         TALLOC_FREE(req);
1786 }
1787
1788 /****************************************************************************
1789  Check if services need reloading.
1790 ****************************************************************************/
1791
1792 void check_reload(time_t t)
1793 {
1794         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1795
1796         if(last_smb_conf_reload_time == 0) {
1797                 last_smb_conf_reload_time = t;
1798                 /* Our printing subsystem might not be ready at smbd start up.
1799                    Then no printer is available till the first printers check
1800                    is performed.  A lower initial interval circumvents this. */
1801                 if ( printcap_cache_time > 60 )
1802                         last_printer_reload_time = t - printcap_cache_time + 60;
1803                 else
1804                         last_printer_reload_time = t;
1805         }
1806
1807         if (mypid != getpid()) { /* First time or fork happened meanwhile */
1808                 /* randomize over 60 second the printcap reload to avoid all
1809                  * process hitting cupsd at the same time */
1810                 int time_range = 60;
1811
1812                 last_printer_reload_time += random() % time_range;
1813                 mypid = getpid();
1814         }
1815
1816         if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1817                 reload_services(True);
1818                 last_smb_conf_reload_time = t;
1819         }
1820
1821         /* 'printcap cache time = 0' disable the feature */
1822         
1823         if ( printcap_cache_time != 0 )
1824         { 
1825                 /* see if it's time to reload or if the clock has been set back */
1826                 
1827                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
1828                         || (t-last_printer_reload_time  < 0) ) 
1829                 {
1830                         DEBUG( 3,( "Printcap cache time expired.\n"));
1831                         reload_printers();
1832                         last_printer_reload_time = t;
1833                 }
1834         }
1835 }
1836
1837 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1838 {
1839         /* TODO: make write nonblocking */
1840 }
1841
1842 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1843 {
1844         uint8_t *inbuf = NULL;
1845         size_t inbuf_len = 0;
1846         size_t unread_bytes = 0;
1847         bool encrypted = false;
1848         TALLOC_CTX *mem_ctx = talloc_tos();
1849         NTSTATUS status;
1850         uint32_t seqnum;
1851
1852         /* TODO: make this completely nonblocking */
1853
1854         status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1855                                     (char **)(void *)&inbuf,
1856                                     0, /* timeout */
1857                                     &unread_bytes,
1858                                     &encrypted,
1859                                     &inbuf_len, &seqnum);
1860         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1861                 goto process;
1862         }
1863         if (NT_STATUS_IS_ERR(status)) {
1864                 exit_server_cleanly("failed to receive smb request");
1865         }
1866         if (!NT_STATUS_IS_OK(status)) {
1867                 return;
1868         }
1869
1870 process:
1871         process_smb(conn, inbuf, inbuf_len, unread_bytes,
1872                     seqnum, encrypted, NULL);
1873 }
1874
1875 static void smbd_server_connection_handler(struct event_context *ev,
1876                                            struct fd_event *fde,
1877                                            uint16_t flags,
1878                                            void *private_data)
1879 {
1880         struct smbd_server_connection *conn = talloc_get_type(private_data,
1881                                               struct smbd_server_connection);
1882
1883         if (flags & EVENT_FD_WRITE) {
1884                 smbd_server_connection_write_handler(conn);
1885         } else if (flags & EVENT_FD_READ) {
1886                 smbd_server_connection_read_handler(conn);
1887         }
1888 }
1889
1890
1891 /****************************************************************************
1892 received when we should release a specific IP
1893 ****************************************************************************/
1894 static void release_ip(const char *ip, void *priv)
1895 {
1896         char addr[INET6_ADDRSTRLEN];
1897         char *p = addr;
1898
1899         client_socket_addr(get_client_fd(),addr,sizeof(addr));
1900
1901         if (strncmp("::ffff:", addr, 7) == 0) {
1902                 p = addr + 7;
1903         }
1904
1905         if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1906                 /* we can't afford to do a clean exit - that involves
1907                    database writes, which would potentially mean we
1908                    are still running after the failover has finished -
1909                    we have to get rid of this process ID straight
1910                    away */
1911                 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1912                         ip));
1913                 /* note we must exit with non-zero status so the unclean handler gets
1914                    called in the parent, so that the brl database is tickled */
1915                 _exit(1);
1916         }
1917 }
1918
1919 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1920                            uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1921 {
1922         release_ip((char *)data->data, NULL);
1923 }
1924
1925 #ifdef CLUSTER_SUPPORT
1926 static int client_get_tcp_info(struct sockaddr_storage *server,
1927                                struct sockaddr_storage *client)
1928 {
1929         socklen_t length;
1930         if (server_fd == -1) {
1931                 return -1;
1932         }
1933         length = sizeof(*server);
1934         if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
1935                 return -1;
1936         }
1937         length = sizeof(*client);
1938         if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
1939                 return -1;
1940         }
1941         return 0;
1942 }
1943 #endif
1944
1945 /*
1946  * Send keepalive packets to our client
1947  */
1948 static bool keepalive_fn(const struct timeval *now, void *private_data)
1949 {
1950         if (!send_keepalive(smbd_server_fd())) {
1951                 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
1952                 return False;
1953         }
1954         return True;
1955 }
1956
1957 /*
1958  * Do the recurring check if we're idle
1959  */
1960 static bool deadtime_fn(const struct timeval *now, void *private_data)
1961 {
1962         if ((conn_num_open() == 0)
1963             || (conn_idle_all(now->tv_sec))) {
1964                 DEBUG( 2, ( "Closing idle connection\n" ) );
1965                 messaging_send(smbd_messaging_context(), procid_self(),
1966                                MSG_SHUTDOWN, &data_blob_null);
1967                 return False;
1968         }
1969
1970         return True;
1971 }
1972
1973 /*
1974  * Do the recurring log file and smb.conf reload checks.
1975  */
1976
1977 static bool housekeeping_fn(const struct timeval *now, void *private_data)
1978 {
1979         change_to_root_user();
1980
1981         /* update printer queue caches if necessary */
1982         update_monitored_printq_cache();
1983
1984         /* check if we need to reload services */
1985         check_reload(time(NULL));
1986
1987         /* Change machine password if neccessary. */
1988         attempt_machine_password_change();
1989
1990         /*
1991          * Force a log file check.
1992          */
1993         force_check_log_size();
1994         check_log_size();
1995         return true;
1996 }
1997
1998 /****************************************************************************
1999  Process commands from the client
2000 ****************************************************************************/
2001
2002 void smbd_process(void)
2003 {
2004         TALLOC_CTX *frame = talloc_stackframe();
2005         char remaddr[INET6_ADDRSTRLEN];
2006
2007         smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2008         if (!smbd_server_conn) {
2009                 exit_server("failed to create smbd_server_connection");
2010         }
2011
2012         /* Ensure child is set to blocking mode */
2013         set_blocking(smbd_server_fd(),True);
2014
2015         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2016         set_socket_options(smbd_server_fd(), lp_socket_options());
2017
2018         /* this is needed so that we get decent entries
2019            in smbstatus for port 445 connects */
2020         set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2021                                               remaddr,
2022                                               sizeof(remaddr)),
2023                                               false);
2024         reload_services(true);
2025
2026         /*
2027          * Before the first packet, check the global hosts allow/ hosts deny
2028          * parameters before doing any parsing of packets passed to us by the
2029          * client. This prevents attacks on our parsing code from hosts not in
2030          * the hosts allow list.
2031          */
2032
2033         if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2034                           lp_hostsdeny(-1))) {
2035                 char addr[INET6_ADDRSTRLEN];
2036
2037                 /*
2038                  * send a negative session response "not listening on calling
2039                  * name"
2040                  */
2041                 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2042                 DEBUG( 1, ("Connection denied from %s\n",
2043                            client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2044                 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2045                                    0, false, NULL);
2046                 exit_server_cleanly("connection denied");
2047         }
2048
2049         static_init_rpc;
2050
2051         init_modules();
2052
2053         smb_perfcount_init();
2054
2055         if (!init_account_policy()) {
2056                 exit_server("Could not open account policy tdb.\n");
2057         }
2058
2059         if (*lp_rootdir()) {
2060                 if (chroot(lp_rootdir()) != 0) {
2061                         DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2062                         exit_server("Failed to chroot()");
2063                 }
2064                 if (chdir("/") == -1) {
2065                         DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2066                         exit_server("Failed to chroot()");
2067                 }
2068                 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2069         }
2070
2071         if (!srv_init_signing(smbd_server_conn)) {
2072                 exit_server("Failed to init smb_signing");
2073         }
2074
2075         /* Setup oplocks */
2076         if (!init_oplocks(smbd_messaging_context()))
2077                 exit_server("Failed to init oplocks");
2078
2079         /* Setup aio signal handler. */
2080         initialize_async_io_handler();
2081
2082         /* register our message handlers */
2083         messaging_register(smbd_messaging_context(), NULL,
2084                            MSG_SMB_FORCE_TDIS, msg_force_tdis);
2085         messaging_register(smbd_messaging_context(), NULL,
2086                            MSG_SMB_RELEASE_IP, msg_release_ip);
2087         messaging_register(smbd_messaging_context(), NULL,
2088                            MSG_SMB_CLOSE_FILE, msg_close_file);
2089
2090         if ((lp_keepalive() != 0)
2091             && !(event_add_idle(smbd_event_context(), NULL,
2092                                 timeval_set(lp_keepalive(), 0),
2093                                 "keepalive", keepalive_fn,
2094                                 NULL))) {
2095                 DEBUG(0, ("Could not add keepalive event\n"));
2096                 exit(1);
2097         }
2098
2099         if (!(event_add_idle(smbd_event_context(), NULL,
2100                              timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2101                              "deadtime", deadtime_fn, NULL))) {
2102                 DEBUG(0, ("Could not add deadtime event\n"));
2103                 exit(1);
2104         }
2105
2106         if (!(event_add_idle(smbd_event_context(), NULL,
2107                              timeval_set(SMBD_SELECT_TIMEOUT, 0),
2108                              "housekeeping", housekeeping_fn, NULL))) {
2109                 DEBUG(0, ("Could not add housekeeping event\n"));
2110                 exit(1);
2111         }
2112
2113 #ifdef CLUSTER_SUPPORT
2114
2115         if (lp_clustering()) {
2116                 /*
2117                  * We need to tell ctdb about our client's TCP
2118                  * connection, so that for failover ctdbd can send
2119                  * tickle acks, triggering a reconnection by the
2120                  * client.
2121                  */
2122
2123                 struct sockaddr_storage srv, clnt;
2124
2125                 if (client_get_tcp_info(&srv, &clnt) == 0) {
2126
2127                         NTSTATUS status;
2128
2129                         status = ctdbd_register_ips(
2130                                 messaging_ctdbd_connection(),
2131                                 &srv, &clnt, release_ip, NULL);
2132
2133                         if (!NT_STATUS_IS_OK(status)) {
2134                                 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2135                                           nt_errstr(status)));
2136                         }
2137                 } else
2138                 {
2139                         DEBUG(0,("Unable to get tcp info for "
2140                                  "CTDB_CONTROL_TCP_CLIENT: %s\n",
2141                                  strerror(errno)));
2142                 }
2143         }
2144
2145 #endif
2146
2147         max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2148
2149         smbd_server_conn->fde = event_add_fd(smbd_event_context(),
2150                                              smbd_server_conn,
2151                                              smbd_server_fd(),
2152                                              EVENT_FD_READ,
2153                                              smbd_server_connection_handler,
2154                                              smbd_server_conn);
2155         if (!smbd_server_conn->fde) {
2156                 exit_server("failed to create smbd_server_connection fde");
2157         }
2158
2159         TALLOC_FREE(frame);
2160
2161         while (True) {
2162                 NTSTATUS status;
2163
2164                 frame = talloc_stackframe_pool(8192);
2165
2166                 errno = 0;
2167
2168                 status = smbd_server_connection_loop_once(smbd_server_conn);
2169                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2170                     !NT_STATUS_IS_OK(status)) {
2171                         DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2172                                   " exiting\n", nt_errstr(status)));
2173                         break;
2174                 }
2175
2176                 TALLOC_FREE(frame);
2177         }
2178
2179         exit_server_cleanly(NULL);
2180 }
2181
2182 bool req_is_in_chain(struct smb_request *req)
2183 {
2184         if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2185                 /*
2186                  * We're right now handling a subsequent request, so we must
2187                  * be in a chain
2188                  */
2189                 return true;
2190         }
2191
2192         if (!is_andx_req(req->cmd)) {
2193                 return false;
2194         }
2195
2196         if (req->wct < 2) {
2197                 /*
2198                  * Okay, an illegal request, but definitely not chained :-)
2199                  */
2200                 return false;
2201         }
2202
2203         return (CVAL(req->vwv+0, 0) != 0xFF);
2204 }