s3:smbd: move some session specific globals to struct smbd_server_connection
[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         struct smbd_server_connection *sconn = smbd_server_conn;
1230
1231         errno = 0;
1232
1233         /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1234          * so subtract 4 from it. */
1235         if (!valid_smb_header(req->inbuf)
1236             || (size < (smb_size - 4))) {
1237                 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1238                          smb_len(req->inbuf)));
1239                 exit_server_cleanly("Non-SMB packet");
1240         }
1241
1242         if (smb_messages[type].fn == NULL) {
1243                 DEBUG(0,("Unknown message type %d!\n",type));
1244                 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1245                 reply_unknown_new(req, type);
1246                 return NULL;
1247         }
1248
1249         flags = smb_messages[type].flags;
1250
1251         /* In share mode security we must ignore the vuid. */
1252         session_tag = (lp_security() == SEC_SHARE)
1253                 ? UID_FIELD_INVALID : req->vuid;
1254         conn = req->conn;
1255
1256         DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1257                  (int)sys_getpid(), (unsigned long)conn));
1258
1259         smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1260
1261         /* Ensure this value is replaced in the incoming packet. */
1262         SSVAL(req->inbuf,smb_uid,session_tag);
1263
1264         /*
1265          * Ensure the correct username is in current_user_info.  This is a
1266          * really ugly bugfix for problems with multiple session_setup_and_X's
1267          * being done and allowing %U and %G substitutions to work correctly.
1268          * There is a reason this code is done here, don't move it unless you
1269          * know what you're doing... :-).
1270          * JRA.
1271          */
1272
1273         if (session_tag != sconn->smb1.sessions.last_session_tag) {
1274                 user_struct *vuser = NULL;
1275
1276                 sconn->smb1.sessions.last_session_tag = session_tag;
1277                 if(session_tag != UID_FIELD_INVALID) {
1278                         vuser = get_valid_user_struct(session_tag);
1279                         if (vuser) {
1280                                 set_current_user_info(
1281                                         vuser->server_info->sanitized_username,
1282                                         vuser->server_info->unix_name,
1283                                         pdb_get_domain(vuser->server_info
1284                                                        ->sam_account));
1285                         }
1286                 }
1287         }
1288
1289         /* Does this call need to be run as the connected user? */
1290         if (flags & AS_USER) {
1291
1292                 /* Does this call need a valid tree connection? */
1293                 if (!conn) {
1294                         /*
1295                          * Amazingly, the error code depends on the command
1296                          * (from Samba4).
1297                          */
1298                         if (type == SMBntcreateX) {
1299                                 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1300                         } else {
1301                                 reply_doserror(req, ERRSRV, ERRinvnid);
1302                         }
1303                         return NULL;
1304                 }
1305
1306                 if (!change_to_user(conn,session_tag)) {
1307                         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRbaduid));
1308                         remove_deferred_open_smb_message(req->mid);
1309                         return conn;
1310                 }
1311
1312                 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1313
1314                 /* Does it need write permission? */
1315                 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1316                         reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1317                         return conn;
1318                 }
1319
1320                 /* IPC services are limited */
1321                 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1322                         reply_doserror(req, ERRSRV,ERRaccess);
1323                         return conn;
1324                 }
1325         } else {
1326                 /* This call needs to be run as root */
1327                 change_to_root_user();
1328         }
1329
1330         /* load service specific parameters */
1331         if (conn) {
1332                 if (req->encrypted) {
1333                         conn->encrypted_tid = true;
1334                         /* encrypted required from now on. */
1335                         conn->encrypt_level = Required;
1336                 } else if (ENCRYPTION_REQUIRED(conn)) {
1337                         if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1338                                 exit_server_cleanly("encryption required "
1339                                         "on connection");
1340                                 return conn;
1341                         }
1342                 }
1343
1344                 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1345                                          (flags & (AS_USER|DO_CHDIR)
1346                                           ?True:False))) {
1347                         reply_doserror(req, ERRSRV, ERRaccess);
1348                         return conn;
1349                 }
1350                 conn->num_smb_operations++;
1351         }
1352
1353         /* does this protocol need to be run as guest? */
1354         if ((flags & AS_GUEST)
1355             && (!change_to_guest() ||
1356                 !check_access(smbd_server_fd(), lp_hostsallow(-1),
1357                               lp_hostsdeny(-1)))) {
1358                 reply_doserror(req, ERRSRV, ERRaccess);
1359                 return conn;
1360         }
1361
1362         smb_messages[type].fn(req);
1363         return req->conn;
1364 }
1365
1366 /****************************************************************************
1367  Construct a reply to the incoming packet.
1368 ****************************************************************************/
1369
1370 static void construct_reply(char *inbuf, int size, size_t unread_bytes,
1371                             uint32_t seqnum, bool encrypted,
1372                             struct smb_perfcount_data *deferred_pcd)
1373 {
1374         connection_struct *conn;
1375         struct smb_request *req;
1376
1377         if (!(req = talloc(talloc_tos(), struct smb_request))) {
1378                 smb_panic("could not allocate smb_request");
1379         }
1380
1381         init_smb_request(req, (uint8 *)inbuf, unread_bytes, encrypted);
1382         req->inbuf  = (uint8_t *)talloc_move(req, &inbuf);
1383         req->seqnum = seqnum;
1384
1385         /* we popped this message off the queue - keep original perf data */
1386         if (deferred_pcd)
1387                 req->pcd = *deferred_pcd;
1388         else {
1389                 SMB_PERFCOUNT_START(&req->pcd);
1390                 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1391                 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1392         }
1393
1394         conn = switch_message(req->cmd, req, size);
1395
1396         if (req->unread_bytes) {
1397                 /* writeX failed. drain socket. */
1398                 if (drain_socket(smbd_server_fd(), req->unread_bytes) !=
1399                                 req->unread_bytes) {
1400                         smb_panic("failed to drain pending bytes");
1401                 }
1402                 req->unread_bytes = 0;
1403         }
1404
1405         if (req->outbuf == NULL) {
1406                 return;
1407         }
1408
1409         if (CVAL(req->outbuf,0) == 0) {
1410                 show_msg((char *)req->outbuf);
1411         }
1412
1413         if (!srv_send_smb(smbd_server_fd(),
1414                         (char *)req->outbuf,
1415                         true, req->seqnum+1,
1416                         IS_CONN_ENCRYPTED(conn)||req->encrypted,
1417                         &req->pcd)) {
1418                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1419         }
1420
1421         TALLOC_FREE(req);
1422
1423         return;
1424 }
1425
1426 /****************************************************************************
1427  Process an smb from the client
1428 ****************************************************************************/
1429 static void process_smb(struct smbd_server_connection *conn,
1430                         uint8_t *inbuf, size_t nread, size_t unread_bytes,
1431                         uint32_t seqnum, bool encrypted,
1432                         struct smb_perfcount_data *deferred_pcd)
1433 {
1434         int msg_type = CVAL(inbuf,0);
1435
1436         DO_PROFILE_INC(smb_count);
1437
1438         DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1439                     smb_len(inbuf) ) );
1440         DEBUG( 3, ( "Transaction %d of length %d (%u toread)\n", trans_num,
1441                                 (int)nread,
1442                                 (unsigned int)unread_bytes ));
1443
1444         if (msg_type != 0) {
1445                 /*
1446                  * NetBIOS session request, keepalive, etc.
1447                  */
1448                 reply_special((char *)inbuf);
1449                 goto done;
1450         }
1451
1452         if (smbd_server_conn->allow_smb2) {
1453                 if (smbd_is_smb2_header(inbuf, nread)) {
1454                         smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1455                         return;
1456                 }
1457                 smbd_server_conn->allow_smb2 = false;
1458         }
1459
1460         show_msg((char *)inbuf);
1461
1462         construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1463         trans_num++;
1464
1465 done:
1466         conn->smb1.num_requests++;
1467
1468         /* The timeout_processing function isn't run nearly
1469            often enough to implement 'max log size' without
1470            overrunning the size of the file by many megabytes.
1471            This is especially true if we are running at debug
1472            level 10.  Checking every 50 SMBs is a nice
1473            tradeoff of performance vs log file size overrun. */
1474
1475         if ((conn->smb1.num_requests % 50) == 0 &&
1476             need_to_check_log_size()) {
1477                 change_to_root_user();
1478                 check_log_size();
1479         }
1480 }
1481
1482 /****************************************************************************
1483  Return a string containing the function name of a SMB command.
1484 ****************************************************************************/
1485
1486 const char *smb_fn_name(int type)
1487 {
1488         const char *unknown_name = "SMBunknown";
1489
1490         if (smb_messages[type].name == NULL)
1491                 return(unknown_name);
1492
1493         return(smb_messages[type].name);
1494 }
1495
1496 /****************************************************************************
1497  Helper functions for contruct_reply.
1498 ****************************************************************************/
1499
1500 void add_to_common_flags2(uint32 v)
1501 {
1502         common_flags2 |= v;
1503 }
1504
1505 void remove_from_common_flags2(uint32 v)
1506 {
1507         common_flags2 &= ~v;
1508 }
1509
1510 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1511                                    char *outbuf)
1512 {
1513         srv_set_message(outbuf,0,0,false);
1514         
1515         SCVAL(outbuf, smb_com, req->cmd);
1516         SIVAL(outbuf,smb_rcls,0);
1517         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1518         SSVAL(outbuf,smb_flg2,
1519                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1520                 common_flags2);
1521         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1522
1523         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1524         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1525         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1526         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1527 }
1528
1529 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1530 {
1531         construct_reply_common(req, (char *)req->inbuf, outbuf);
1532 }
1533
1534 /*
1535  * How many bytes have we already accumulated up to the current wct field
1536  * offset?
1537  */
1538
1539 size_t req_wct_ofs(struct smb_request *req)
1540 {
1541         size_t buf_size;
1542
1543         if (req->chain_outbuf == NULL) {
1544                 return smb_wct - 4;
1545         }
1546         buf_size = talloc_get_size(req->chain_outbuf);
1547         if ((buf_size % 4) != 0) {
1548                 buf_size += (4 - (buf_size % 4));
1549         }
1550         return buf_size - 4;
1551 }
1552
1553 /*
1554  * Hack around reply_nterror & friends not being aware of chained requests,
1555  * generating illegal (i.e. wct==0) chain replies.
1556  */
1557
1558 static void fixup_chain_error_packet(struct smb_request *req)
1559 {
1560         uint8_t *outbuf = req->outbuf;
1561         req->outbuf = NULL;
1562         reply_outbuf(req, 2, 0);
1563         memcpy(req->outbuf, outbuf, smb_wct);
1564         TALLOC_FREE(outbuf);
1565         SCVAL(req->outbuf, smb_vwv0, 0xff);
1566 }
1567
1568 /****************************************************************************
1569  Construct a chained reply and add it to the already made reply
1570 ****************************************************************************/
1571
1572 void chain_reply(struct smb_request *req)
1573 {
1574         size_t smblen = smb_len(req->inbuf);
1575         size_t already_used, length_needed;
1576         uint8_t chain_cmd;
1577         uint32_t chain_offset;  /* uint32_t to avoid overflow */
1578
1579         uint8_t wct;
1580         uint16_t *vwv;
1581         uint16_t buflen;
1582         uint8_t *buf;
1583
1584         if (IVAL(req->outbuf, smb_rcls) != 0) {
1585                 fixup_chain_error_packet(req);
1586         }
1587
1588         /*
1589          * Any of the AndX requests and replies have at least a wct of
1590          * 2. vwv[0] is the next command, vwv[1] is the offset from the
1591          * beginning of the SMB header to the next wct field.
1592          *
1593          * None of the AndX requests put anything valuable in vwv[0] and [1],
1594          * so we can overwrite it here to form the chain.
1595          */
1596
1597         if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1598                 goto error;
1599         }
1600
1601         /*
1602          * Here we assume that this is the end of the chain. For that we need
1603          * to set "next command" to 0xff and the offset to 0. If we later find
1604          * more commands in the chain, this will be overwritten again.
1605          */
1606
1607         SCVAL(req->outbuf, smb_vwv0, 0xff);
1608         SCVAL(req->outbuf, smb_vwv0+1, 0);
1609         SSVAL(req->outbuf, smb_vwv1, 0);
1610
1611         if (req->chain_outbuf == NULL) {
1612                 /*
1613                  * In req->chain_outbuf we collect all the replies. Start the
1614                  * chain by copying in the first reply.
1615                  *
1616                  * We do the realloc because later on we depend on
1617                  * talloc_get_size to determine the length of
1618                  * chain_outbuf. The reply_xxx routines might have
1619                  * over-allocated (reply_pipe_read_and_X used to be such an
1620                  * example).
1621                  */
1622                 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1623                         req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1624                 if (req->chain_outbuf == NULL) {
1625                         goto error;
1626                 }
1627                 req->outbuf = NULL;
1628         } else {
1629                 /*
1630                  * Update smb headers where subsequent chained commands
1631                  * may have updated them.
1632                  */
1633                 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1634                 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1635
1636                 if (!smb_splice_chain(&req->chain_outbuf,
1637                                       CVAL(req->outbuf, smb_com),
1638                                       CVAL(req->outbuf, smb_wct),
1639                                       (uint16_t *)(req->outbuf + smb_vwv),
1640                                       0, smb_buflen(req->outbuf),
1641                                       (uint8_t *)smb_buf(req->outbuf))) {
1642                         goto error;
1643                 }
1644                 TALLOC_FREE(req->outbuf);
1645         }
1646
1647         /*
1648          * We use the old request's vwv field to grab the next chained command
1649          * and offset into the chained fields.
1650          */
1651
1652         chain_cmd = CVAL(req->vwv+0, 0);
1653         chain_offset = SVAL(req->vwv+1, 0);
1654
1655         if (chain_cmd == 0xff) {
1656                 /*
1657                  * End of chain, no more requests from the client. So ship the
1658                  * replies.
1659                  */
1660                 smb_setlen((char *)(req->chain_outbuf),
1661                            talloc_get_size(req->chain_outbuf) - 4);
1662
1663                 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1664                                   true, req->seqnum+1,
1665                                   IS_CONN_ENCRYPTED(req->conn)
1666                                   ||req->encrypted,
1667                                   &req->pcd)) {
1668                         exit_server_cleanly("chain_reply: srv_send_smb "
1669                                             "failed.");
1670                 }
1671                 TALLOC_FREE(req);
1672
1673                 return;
1674         }
1675
1676         /* add a new perfcounter for this element of chain */
1677         SMB_PERFCOUNT_ADD(&req->pcd);
1678         SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1679         SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1680
1681         /*
1682          * Check if the client tries to fool us. The request so far uses the
1683          * space to the end of the byte buffer in the request just
1684          * processed. The chain_offset can't point into that area. If that was
1685          * the case, we could end up with an endless processing of the chain,
1686          * we would always handle the same request.
1687          */
1688
1689         already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1690         if (chain_offset < already_used) {
1691                 goto error;
1692         }
1693
1694         /*
1695          * Next check: Make sure the chain offset does not point beyond the
1696          * overall smb request length.
1697          */
1698
1699         length_needed = chain_offset+1; /* wct */
1700         if (length_needed > smblen) {
1701                 goto error;
1702         }
1703
1704         /*
1705          * Now comes the pointer magic. Goal here is to set up req->vwv and
1706          * req->buf correctly again to be able to call the subsequent
1707          * switch_message(). The chain offset (the former vwv[1]) points at
1708          * the new wct field.
1709          */
1710
1711         wct = CVAL(smb_base(req->inbuf), chain_offset);
1712
1713         /*
1714          * Next consistency check: Make the new vwv array fits in the overall
1715          * smb request.
1716          */
1717
1718         length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1719         if (length_needed > smblen) {
1720                 goto error;
1721         }
1722         vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1723
1724         /*
1725          * Now grab the new byte buffer....
1726          */
1727
1728         buflen = SVAL(vwv+wct, 0);
1729
1730         /*
1731          * .. and check that it fits.
1732          */
1733
1734         length_needed += buflen;
1735         if (length_needed > smblen) {
1736                 goto error;
1737         }
1738         buf = (uint8_t *)(vwv+wct+1);
1739
1740         req->cmd = chain_cmd;
1741         req->wct = wct;
1742         req->vwv = vwv;
1743         req->buflen = buflen;
1744         req->buf = buf;
1745
1746         switch_message(chain_cmd, req, smblen);
1747
1748         if (req->outbuf == NULL) {
1749                 /*
1750                  * This happens if the chained command has suspended itself or
1751                  * if it has called srv_send_smb() itself.
1752                  */
1753                 return;
1754         }
1755
1756         /*
1757          * We end up here if the chained command was not itself chained or
1758          * suspended, but for example a close() command. We now need to splice
1759          * the chained commands' outbuf into the already built up chain_outbuf
1760          * and ship the result.
1761          */
1762         goto done;
1763
1764  error:
1765         /*
1766          * We end up here if there's any error in the chain syntax. Report a
1767          * DOS error, just like Windows does.
1768          */
1769         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1770         fixup_chain_error_packet(req);
1771
1772  done:
1773         if (!smb_splice_chain(&req->chain_outbuf,
1774                               CVAL(req->outbuf, smb_com),
1775                               CVAL(req->outbuf, smb_wct),
1776                               (uint16_t *)(req->outbuf + smb_vwv),
1777                               0, smb_buflen(req->outbuf),
1778                               (uint8_t *)smb_buf(req->outbuf))) {
1779                 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1780         }
1781         TALLOC_FREE(req->outbuf);
1782
1783         smb_setlen((char *)(req->chain_outbuf),
1784                    talloc_get_size(req->chain_outbuf) - 4);
1785
1786         show_msg((char *)(req->chain_outbuf));
1787
1788         if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1789                           true, req->seqnum+1,
1790                           IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1791                           &req->pcd)) {
1792                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1793         }
1794         TALLOC_FREE(req);
1795 }
1796
1797 /****************************************************************************
1798  Check if services need reloading.
1799 ****************************************************************************/
1800
1801 void check_reload(time_t t)
1802 {
1803         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1804
1805         if(last_smb_conf_reload_time == 0) {
1806                 last_smb_conf_reload_time = t;
1807                 /* Our printing subsystem might not be ready at smbd start up.
1808                    Then no printer is available till the first printers check
1809                    is performed.  A lower initial interval circumvents this. */
1810                 if ( printcap_cache_time > 60 )
1811                         last_printer_reload_time = t - printcap_cache_time + 60;
1812                 else
1813                         last_printer_reload_time = t;
1814         }
1815
1816         if (mypid != getpid()) { /* First time or fork happened meanwhile */
1817                 /* randomize over 60 second the printcap reload to avoid all
1818                  * process hitting cupsd at the same time */
1819                 int time_range = 60;
1820
1821                 last_printer_reload_time += random() % time_range;
1822                 mypid = getpid();
1823         }
1824
1825         if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1826                 reload_services(True);
1827                 last_smb_conf_reload_time = t;
1828         }
1829
1830         /* 'printcap cache time = 0' disable the feature */
1831         
1832         if ( printcap_cache_time != 0 )
1833         { 
1834                 /* see if it's time to reload or if the clock has been set back */
1835                 
1836                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
1837                         || (t-last_printer_reload_time  < 0) ) 
1838                 {
1839                         DEBUG( 3,( "Printcap cache time expired.\n"));
1840                         reload_printers();
1841                         last_printer_reload_time = t;
1842                 }
1843         }
1844 }
1845
1846 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1847 {
1848         /* TODO: make write nonblocking */
1849 }
1850
1851 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1852 {
1853         uint8_t *inbuf = NULL;
1854         size_t inbuf_len = 0;
1855         size_t unread_bytes = 0;
1856         bool encrypted = false;
1857         TALLOC_CTX *mem_ctx = talloc_tos();
1858         NTSTATUS status;
1859         uint32_t seqnum;
1860
1861         /* TODO: make this completely nonblocking */
1862
1863         status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1864                                     (char **)(void *)&inbuf,
1865                                     0, /* timeout */
1866                                     &unread_bytes,
1867                                     &encrypted,
1868                                     &inbuf_len, &seqnum);
1869         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1870                 goto process;
1871         }
1872         if (NT_STATUS_IS_ERR(status)) {
1873                 exit_server_cleanly("failed to receive smb request");
1874         }
1875         if (!NT_STATUS_IS_OK(status)) {
1876                 return;
1877         }
1878
1879 process:
1880         process_smb(conn, inbuf, inbuf_len, unread_bytes,
1881                     seqnum, encrypted, NULL);
1882 }
1883
1884 static void smbd_server_connection_handler(struct event_context *ev,
1885                                            struct fd_event *fde,
1886                                            uint16_t flags,
1887                                            void *private_data)
1888 {
1889         struct smbd_server_connection *conn = talloc_get_type(private_data,
1890                                               struct smbd_server_connection);
1891
1892         if (flags & EVENT_FD_WRITE) {
1893                 smbd_server_connection_write_handler(conn);
1894         } else if (flags & EVENT_FD_READ) {
1895                 smbd_server_connection_read_handler(conn);
1896         }
1897 }
1898
1899
1900 /****************************************************************************
1901 received when we should release a specific IP
1902 ****************************************************************************/
1903 static void release_ip(const char *ip, void *priv)
1904 {
1905         char addr[INET6_ADDRSTRLEN];
1906         char *p = addr;
1907
1908         client_socket_addr(get_client_fd(),addr,sizeof(addr));
1909
1910         if (strncmp("::ffff:", addr, 7) == 0) {
1911                 p = addr + 7;
1912         }
1913
1914         if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1915                 /* we can't afford to do a clean exit - that involves
1916                    database writes, which would potentially mean we
1917                    are still running after the failover has finished -
1918                    we have to get rid of this process ID straight
1919                    away */
1920                 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1921                         ip));
1922                 /* note we must exit with non-zero status so the unclean handler gets
1923                    called in the parent, so that the brl database is tickled */
1924                 _exit(1);
1925         }
1926 }
1927
1928 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1929                            uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1930 {
1931         release_ip((char *)data->data, NULL);
1932 }
1933
1934 #ifdef CLUSTER_SUPPORT
1935 static int client_get_tcp_info(struct sockaddr_storage *server,
1936                                struct sockaddr_storage *client)
1937 {
1938         socklen_t length;
1939         if (server_fd == -1) {
1940                 return -1;
1941         }
1942         length = sizeof(*server);
1943         if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
1944                 return -1;
1945         }
1946         length = sizeof(*client);
1947         if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
1948                 return -1;
1949         }
1950         return 0;
1951 }
1952 #endif
1953
1954 /*
1955  * Send keepalive packets to our client
1956  */
1957 static bool keepalive_fn(const struct timeval *now, void *private_data)
1958 {
1959         if (!send_keepalive(smbd_server_fd())) {
1960                 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
1961                 return False;
1962         }
1963         return True;
1964 }
1965
1966 /*
1967  * Do the recurring check if we're idle
1968  */
1969 static bool deadtime_fn(const struct timeval *now, void *private_data)
1970 {
1971         if ((conn_num_open() == 0)
1972             || (conn_idle_all(now->tv_sec))) {
1973                 DEBUG( 2, ( "Closing idle connection\n" ) );
1974                 messaging_send(smbd_messaging_context(), procid_self(),
1975                                MSG_SHUTDOWN, &data_blob_null);
1976                 return False;
1977         }
1978
1979         return True;
1980 }
1981
1982 /*
1983  * Do the recurring log file and smb.conf reload checks.
1984  */
1985
1986 static bool housekeeping_fn(const struct timeval *now, void *private_data)
1987 {
1988         change_to_root_user();
1989
1990         /* update printer queue caches if necessary */
1991         update_monitored_printq_cache();
1992
1993         /* check if we need to reload services */
1994         check_reload(time(NULL));
1995
1996         /* Change machine password if neccessary. */
1997         attempt_machine_password_change();
1998
1999         /*
2000          * Force a log file check.
2001          */
2002         force_check_log_size();
2003         check_log_size();
2004         return true;
2005 }
2006
2007 /****************************************************************************
2008  Process commands from the client
2009 ****************************************************************************/
2010
2011 void smbd_process(void)
2012 {
2013         TALLOC_CTX *frame = talloc_stackframe();
2014         char remaddr[INET6_ADDRSTRLEN];
2015
2016         smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2017         if (!smbd_server_conn) {
2018                 exit_server("failed to create smbd_server_connection");
2019         }
2020
2021         if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2022             lp_security() != SEC_SHARE) {
2023                 smbd_server_conn->allow_smb2 = true;
2024         }
2025
2026         /* Ensure child is set to blocking mode */
2027         set_blocking(smbd_server_fd(),True);
2028
2029         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2030         set_socket_options(smbd_server_fd(), lp_socket_options());
2031
2032         /* this is needed so that we get decent entries
2033            in smbstatus for port 445 connects */
2034         set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2035                                               remaddr,
2036                                               sizeof(remaddr)),
2037                                               false);
2038         reload_services(true);
2039
2040         /*
2041          * Before the first packet, check the global hosts allow/ hosts deny
2042          * parameters before doing any parsing of packets passed to us by the
2043          * client. This prevents attacks on our parsing code from hosts not in
2044          * the hosts allow list.
2045          */
2046
2047         if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2048                           lp_hostsdeny(-1))) {
2049                 char addr[INET6_ADDRSTRLEN];
2050
2051                 /*
2052                  * send a negative session response "not listening on calling
2053                  * name"
2054                  */
2055                 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2056                 DEBUG( 1, ("Connection denied from %s\n",
2057                            client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2058                 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2059                                    0, false, NULL);
2060                 exit_server_cleanly("connection denied");
2061         }
2062
2063         static_init_rpc;
2064
2065         init_modules();
2066
2067         smb_perfcount_init();
2068
2069         if (!init_account_policy()) {
2070                 exit_server("Could not open account policy tdb.\n");
2071         }
2072
2073         if (*lp_rootdir()) {
2074                 if (chroot(lp_rootdir()) != 0) {
2075                         DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2076                         exit_server("Failed to chroot()");
2077                 }
2078                 if (chdir("/") == -1) {
2079                         DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2080                         exit_server("Failed to chroot()");
2081                 }
2082                 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2083         }
2084
2085         if (!srv_init_signing(smbd_server_conn)) {
2086                 exit_server("Failed to init smb_signing");
2087         }
2088
2089         /* Setup oplocks */
2090         if (!init_oplocks(smbd_messaging_context()))
2091                 exit_server("Failed to init oplocks");
2092
2093         /* Setup aio signal handler. */
2094         initialize_async_io_handler();
2095
2096         /* register our message handlers */
2097         messaging_register(smbd_messaging_context(), NULL,
2098                            MSG_SMB_FORCE_TDIS, msg_force_tdis);
2099         messaging_register(smbd_messaging_context(), NULL,
2100                            MSG_SMB_RELEASE_IP, msg_release_ip);
2101         messaging_register(smbd_messaging_context(), NULL,
2102                            MSG_SMB_CLOSE_FILE, msg_close_file);
2103
2104         if ((lp_keepalive() != 0)
2105             && !(event_add_idle(smbd_event_context(), NULL,
2106                                 timeval_set(lp_keepalive(), 0),
2107                                 "keepalive", keepalive_fn,
2108                                 NULL))) {
2109                 DEBUG(0, ("Could not add keepalive event\n"));
2110                 exit(1);
2111         }
2112
2113         if (!(event_add_idle(smbd_event_context(), NULL,
2114                              timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2115                              "deadtime", deadtime_fn, NULL))) {
2116                 DEBUG(0, ("Could not add deadtime event\n"));
2117                 exit(1);
2118         }
2119
2120         if (!(event_add_idle(smbd_event_context(), NULL,
2121                              timeval_set(SMBD_SELECT_TIMEOUT, 0),
2122                              "housekeeping", housekeeping_fn, NULL))) {
2123                 DEBUG(0, ("Could not add housekeeping event\n"));
2124                 exit(1);
2125         }
2126
2127 #ifdef CLUSTER_SUPPORT
2128
2129         if (lp_clustering()) {
2130                 /*
2131                  * We need to tell ctdb about our client's TCP
2132                  * connection, so that for failover ctdbd can send
2133                  * tickle acks, triggering a reconnection by the
2134                  * client.
2135                  */
2136
2137                 struct sockaddr_storage srv, clnt;
2138
2139                 if (client_get_tcp_info(&srv, &clnt) == 0) {
2140
2141                         NTSTATUS status;
2142
2143                         status = ctdbd_register_ips(
2144                                 messaging_ctdbd_connection(),
2145                                 &srv, &clnt, release_ip, NULL);
2146
2147                         if (!NT_STATUS_IS_OK(status)) {
2148                                 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2149                                           nt_errstr(status)));
2150                         }
2151                 } else
2152                 {
2153                         DEBUG(0,("Unable to get tcp info for "
2154                                  "CTDB_CONTROL_TCP_CLIENT: %s\n",
2155                                  strerror(errno)));
2156                 }
2157         }
2158
2159 #endif
2160
2161         smbd_server_conn->nbt.got_session = false;
2162
2163         smbd_server_conn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2164
2165         smbd_server_conn->smb1.sessions.done_sesssetup = false;
2166         smbd_server_conn->smb1.sessions.max_send = BUFFER_SIZE;
2167         smbd_server_conn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
2168
2169         smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2170                                                   smbd_server_conn,
2171                                                   smbd_server_fd(),
2172                                                   EVENT_FD_READ,
2173                                                   smbd_server_connection_handler,
2174                                                   smbd_server_conn);
2175         if (!smbd_server_conn->smb1.fde) {
2176                 exit_server("failed to create smbd_server_connection fde");
2177         }
2178
2179         TALLOC_FREE(frame);
2180
2181         while (True) {
2182                 NTSTATUS status;
2183
2184                 frame = talloc_stackframe_pool(8192);
2185
2186                 errno = 0;
2187
2188                 status = smbd_server_connection_loop_once(smbd_server_conn);
2189                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2190                     !NT_STATUS_IS_OK(status)) {
2191                         DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2192                                   " exiting\n", nt_errstr(status)));
2193                         break;
2194                 }
2195
2196                 TALLOC_FREE(frame);
2197         }
2198
2199         exit_server_cleanly(NULL);
2200 }
2201
2202 bool req_is_in_chain(struct smb_request *req)
2203 {
2204         if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2205                 /*
2206                  * We're right now handling a subsequent request, so we must
2207                  * be in a chain
2208                  */
2209                 return true;
2210         }
2211
2212         if (!is_andx_req(req->cmd)) {
2213                 return false;
2214         }
2215
2216         if (req->wct < 2) {
2217                 /*
2218                  * Okay, an illegal request, but definitely not chained :-)
2219                  */
2220                 return false;
2221         }
2222
2223         return (CVAL(req->vwv+0, 0) != 0xFF);
2224 }