s3:smbd: move pending_auth_data list to struct smbd_server_connection
[kai/samba.git] / source3 / smbd / process.c
1 /* 
2    Unix SMB/CIFS implementation.
3    process incoming packets - main loop
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Volker Lendecke 2005-2007
6    
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 3 of the License, or
10    (at your option) any later version.
11    
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16    
17    You should have received a copy of the GNU General Public License
18    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "includes.h"
22 #include "smbd/globals.h"
23
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         if (smbd_server_conn->allow_smb2) {
1452                 if (smbd_is_smb2_header(inbuf, nread)) {
1453                         smbd_smb2_first_negprot(smbd_server_conn, inbuf, nread);
1454                         return;
1455                 }
1456                 smbd_server_conn->allow_smb2 = false;
1457         }
1458
1459         show_msg((char *)inbuf);
1460
1461         construct_reply((char *)inbuf,nread,unread_bytes,seqnum,encrypted,deferred_pcd);
1462         trans_num++;
1463
1464 done:
1465         conn->smb1.num_requests++;
1466
1467         /* The timeout_processing function isn't run nearly
1468            often enough to implement 'max log size' without
1469            overrunning the size of the file by many megabytes.
1470            This is especially true if we are running at debug
1471            level 10.  Checking every 50 SMBs is a nice
1472            tradeoff of performance vs log file size overrun. */
1473
1474         if ((conn->smb1.num_requests % 50) == 0 &&
1475             need_to_check_log_size()) {
1476                 change_to_root_user();
1477                 check_log_size();
1478         }
1479 }
1480
1481 /****************************************************************************
1482  Return a string containing the function name of a SMB command.
1483 ****************************************************************************/
1484
1485 const char *smb_fn_name(int type)
1486 {
1487         const char *unknown_name = "SMBunknown";
1488
1489         if (smb_messages[type].name == NULL)
1490                 return(unknown_name);
1491
1492         return(smb_messages[type].name);
1493 }
1494
1495 /****************************************************************************
1496  Helper functions for contruct_reply.
1497 ****************************************************************************/
1498
1499 void add_to_common_flags2(uint32 v)
1500 {
1501         common_flags2 |= v;
1502 }
1503
1504 void remove_from_common_flags2(uint32 v)
1505 {
1506         common_flags2 &= ~v;
1507 }
1508
1509 static void construct_reply_common(struct smb_request *req, const char *inbuf,
1510                                    char *outbuf)
1511 {
1512         srv_set_message(outbuf,0,0,false);
1513         
1514         SCVAL(outbuf, smb_com, req->cmd);
1515         SIVAL(outbuf,smb_rcls,0);
1516         SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES)); 
1517         SSVAL(outbuf,smb_flg2,
1518                 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1519                 common_flags2);
1520         memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1521
1522         SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1523         SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1524         SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1525         SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1526 }
1527
1528 void construct_reply_common_req(struct smb_request *req, char *outbuf)
1529 {
1530         construct_reply_common(req, (char *)req->inbuf, outbuf);
1531 }
1532
1533 /*
1534  * How many bytes have we already accumulated up to the current wct field
1535  * offset?
1536  */
1537
1538 size_t req_wct_ofs(struct smb_request *req)
1539 {
1540         size_t buf_size;
1541
1542         if (req->chain_outbuf == NULL) {
1543                 return smb_wct - 4;
1544         }
1545         buf_size = talloc_get_size(req->chain_outbuf);
1546         if ((buf_size % 4) != 0) {
1547                 buf_size += (4 - (buf_size % 4));
1548         }
1549         return buf_size - 4;
1550 }
1551
1552 /*
1553  * Hack around reply_nterror & friends not being aware of chained requests,
1554  * generating illegal (i.e. wct==0) chain replies.
1555  */
1556
1557 static void fixup_chain_error_packet(struct smb_request *req)
1558 {
1559         uint8_t *outbuf = req->outbuf;
1560         req->outbuf = NULL;
1561         reply_outbuf(req, 2, 0);
1562         memcpy(req->outbuf, outbuf, smb_wct);
1563         TALLOC_FREE(outbuf);
1564         SCVAL(req->outbuf, smb_vwv0, 0xff);
1565 }
1566
1567 /****************************************************************************
1568  Construct a chained reply and add it to the already made reply
1569 ****************************************************************************/
1570
1571 void chain_reply(struct smb_request *req)
1572 {
1573         size_t smblen = smb_len(req->inbuf);
1574         size_t already_used, length_needed;
1575         uint8_t chain_cmd;
1576         uint32_t chain_offset;  /* uint32_t to avoid overflow */
1577
1578         uint8_t wct;
1579         uint16_t *vwv;
1580         uint16_t buflen;
1581         uint8_t *buf;
1582
1583         if (IVAL(req->outbuf, smb_rcls) != 0) {
1584                 fixup_chain_error_packet(req);
1585         }
1586
1587         /*
1588          * Any of the AndX requests and replies have at least a wct of
1589          * 2. vwv[0] is the next command, vwv[1] is the offset from the
1590          * beginning of the SMB header to the next wct field.
1591          *
1592          * None of the AndX requests put anything valuable in vwv[0] and [1],
1593          * so we can overwrite it here to form the chain.
1594          */
1595
1596         if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1597                 goto error;
1598         }
1599
1600         /*
1601          * Here we assume that this is the end of the chain. For that we need
1602          * to set "next command" to 0xff and the offset to 0. If we later find
1603          * more commands in the chain, this will be overwritten again.
1604          */
1605
1606         SCVAL(req->outbuf, smb_vwv0, 0xff);
1607         SCVAL(req->outbuf, smb_vwv0+1, 0);
1608         SSVAL(req->outbuf, smb_vwv1, 0);
1609
1610         if (req->chain_outbuf == NULL) {
1611                 /*
1612                  * In req->chain_outbuf we collect all the replies. Start the
1613                  * chain by copying in the first reply.
1614                  *
1615                  * We do the realloc because later on we depend on
1616                  * talloc_get_size to determine the length of
1617                  * chain_outbuf. The reply_xxx routines might have
1618                  * over-allocated (reply_pipe_read_and_X used to be such an
1619                  * example).
1620                  */
1621                 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1622                         req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
1623                 if (req->chain_outbuf == NULL) {
1624                         goto error;
1625                 }
1626                 req->outbuf = NULL;
1627         } else {
1628                 /*
1629                  * Update smb headers where subsequent chained commands
1630                  * may have updated them.
1631                  */
1632                 SCVAL(req->chain_outbuf, smb_tid, CVAL(req->outbuf, smb_tid));
1633                 SCVAL(req->chain_outbuf, smb_uid, CVAL(req->outbuf, smb_uid));
1634
1635                 if (!smb_splice_chain(&req->chain_outbuf,
1636                                       CVAL(req->outbuf, smb_com),
1637                                       CVAL(req->outbuf, smb_wct),
1638                                       (uint16_t *)(req->outbuf + smb_vwv),
1639                                       0, smb_buflen(req->outbuf),
1640                                       (uint8_t *)smb_buf(req->outbuf))) {
1641                         goto error;
1642                 }
1643                 TALLOC_FREE(req->outbuf);
1644         }
1645
1646         /*
1647          * We use the old request's vwv field to grab the next chained command
1648          * and offset into the chained fields.
1649          */
1650
1651         chain_cmd = CVAL(req->vwv+0, 0);
1652         chain_offset = SVAL(req->vwv+1, 0);
1653
1654         if (chain_cmd == 0xff) {
1655                 /*
1656                  * End of chain, no more requests from the client. So ship the
1657                  * replies.
1658                  */
1659                 smb_setlen((char *)(req->chain_outbuf),
1660                            talloc_get_size(req->chain_outbuf) - 4);
1661
1662                 if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1663                                   true, req->seqnum+1,
1664                                   IS_CONN_ENCRYPTED(req->conn)
1665                                   ||req->encrypted,
1666                                   &req->pcd)) {
1667                         exit_server_cleanly("chain_reply: srv_send_smb "
1668                                             "failed.");
1669                 }
1670                 TALLOC_FREE(req);
1671
1672                 return;
1673         }
1674
1675         /* add a new perfcounter for this element of chain */
1676         SMB_PERFCOUNT_ADD(&req->pcd);
1677         SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
1678         SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
1679
1680         /*
1681          * Check if the client tries to fool us. The request so far uses the
1682          * space to the end of the byte buffer in the request just
1683          * processed. The chain_offset can't point into that area. If that was
1684          * the case, we could end up with an endless processing of the chain,
1685          * we would always handle the same request.
1686          */
1687
1688         already_used = PTR_DIFF(req->buf+req->buflen, smb_base(req->inbuf));
1689         if (chain_offset < already_used) {
1690                 goto error;
1691         }
1692
1693         /*
1694          * Next check: Make sure the chain offset does not point beyond the
1695          * overall smb request length.
1696          */
1697
1698         length_needed = chain_offset+1; /* wct */
1699         if (length_needed > smblen) {
1700                 goto error;
1701         }
1702
1703         /*
1704          * Now comes the pointer magic. Goal here is to set up req->vwv and
1705          * req->buf correctly again to be able to call the subsequent
1706          * switch_message(). The chain offset (the former vwv[1]) points at
1707          * the new wct field.
1708          */
1709
1710         wct = CVAL(smb_base(req->inbuf), chain_offset);
1711
1712         /*
1713          * Next consistency check: Make the new vwv array fits in the overall
1714          * smb request.
1715          */
1716
1717         length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
1718         if (length_needed > smblen) {
1719                 goto error;
1720         }
1721         vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
1722
1723         /*
1724          * Now grab the new byte buffer....
1725          */
1726
1727         buflen = SVAL(vwv+wct, 0);
1728
1729         /*
1730          * .. and check that it fits.
1731          */
1732
1733         length_needed += buflen;
1734         if (length_needed > smblen) {
1735                 goto error;
1736         }
1737         buf = (uint8_t *)(vwv+wct+1);
1738
1739         req->cmd = chain_cmd;
1740         req->wct = wct;
1741         req->vwv = vwv;
1742         req->buflen = buflen;
1743         req->buf = buf;
1744
1745         switch_message(chain_cmd, req, smblen);
1746
1747         if (req->outbuf == NULL) {
1748                 /*
1749                  * This happens if the chained command has suspended itself or
1750                  * if it has called srv_send_smb() itself.
1751                  */
1752                 return;
1753         }
1754
1755         /*
1756          * We end up here if the chained command was not itself chained or
1757          * suspended, but for example a close() command. We now need to splice
1758          * the chained commands' outbuf into the already built up chain_outbuf
1759          * and ship the result.
1760          */
1761         goto done;
1762
1763  error:
1764         /*
1765          * We end up here if there's any error in the chain syntax. Report a
1766          * DOS error, just like Windows does.
1767          */
1768         reply_nterror(req, NT_STATUS_DOS(ERRSRV, ERRerror));
1769         fixup_chain_error_packet(req);
1770
1771  done:
1772         if (!smb_splice_chain(&req->chain_outbuf,
1773                               CVAL(req->outbuf, smb_com),
1774                               CVAL(req->outbuf, smb_wct),
1775                               (uint16_t *)(req->outbuf + smb_vwv),
1776                               0, smb_buflen(req->outbuf),
1777                               (uint8_t *)smb_buf(req->outbuf))) {
1778                 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
1779         }
1780         TALLOC_FREE(req->outbuf);
1781
1782         smb_setlen((char *)(req->chain_outbuf),
1783                    talloc_get_size(req->chain_outbuf) - 4);
1784
1785         show_msg((char *)(req->chain_outbuf));
1786
1787         if (!srv_send_smb(smbd_server_fd(), (char *)req->chain_outbuf,
1788                           true, req->seqnum+1,
1789                           IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
1790                           &req->pcd)) {
1791                 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1792         }
1793         TALLOC_FREE(req);
1794 }
1795
1796 /****************************************************************************
1797  Check if services need reloading.
1798 ****************************************************************************/
1799
1800 void check_reload(time_t t)
1801 {
1802         time_t printcap_cache_time = (time_t)lp_printcap_cache_time();
1803
1804         if(last_smb_conf_reload_time == 0) {
1805                 last_smb_conf_reload_time = t;
1806                 /* Our printing subsystem might not be ready at smbd start up.
1807                    Then no printer is available till the first printers check
1808                    is performed.  A lower initial interval circumvents this. */
1809                 if ( printcap_cache_time > 60 )
1810                         last_printer_reload_time = t - printcap_cache_time + 60;
1811                 else
1812                         last_printer_reload_time = t;
1813         }
1814
1815         if (mypid != getpid()) { /* First time or fork happened meanwhile */
1816                 /* randomize over 60 second the printcap reload to avoid all
1817                  * process hitting cupsd at the same time */
1818                 int time_range = 60;
1819
1820                 last_printer_reload_time += random() % time_range;
1821                 mypid = getpid();
1822         }
1823
1824         if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
1825                 reload_services(True);
1826                 last_smb_conf_reload_time = t;
1827         }
1828
1829         /* 'printcap cache time = 0' disable the feature */
1830         
1831         if ( printcap_cache_time != 0 )
1832         { 
1833                 /* see if it's time to reload or if the clock has been set back */
1834                 
1835                 if ( (t >= last_printer_reload_time+printcap_cache_time) 
1836                         || (t-last_printer_reload_time  < 0) ) 
1837                 {
1838                         DEBUG( 3,( "Printcap cache time expired.\n"));
1839                         reload_printers();
1840                         last_printer_reload_time = t;
1841                 }
1842         }
1843 }
1844
1845 static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
1846 {
1847         /* TODO: make write nonblocking */
1848 }
1849
1850 static void smbd_server_connection_read_handler(struct smbd_server_connection *conn)
1851 {
1852         uint8_t *inbuf = NULL;
1853         size_t inbuf_len = 0;
1854         size_t unread_bytes = 0;
1855         bool encrypted = false;
1856         TALLOC_CTX *mem_ctx = talloc_tos();
1857         NTSTATUS status;
1858         uint32_t seqnum;
1859
1860         /* TODO: make this completely nonblocking */
1861
1862         status = receive_smb_talloc(mem_ctx, smbd_server_fd(),
1863                                     (char **)(void *)&inbuf,
1864                                     0, /* timeout */
1865                                     &unread_bytes,
1866                                     &encrypted,
1867                                     &inbuf_len, &seqnum);
1868         if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
1869                 goto process;
1870         }
1871         if (NT_STATUS_IS_ERR(status)) {
1872                 exit_server_cleanly("failed to receive smb request");
1873         }
1874         if (!NT_STATUS_IS_OK(status)) {
1875                 return;
1876         }
1877
1878 process:
1879         process_smb(conn, inbuf, inbuf_len, unread_bytes,
1880                     seqnum, encrypted, NULL);
1881 }
1882
1883 static void smbd_server_connection_handler(struct event_context *ev,
1884                                            struct fd_event *fde,
1885                                            uint16_t flags,
1886                                            void *private_data)
1887 {
1888         struct smbd_server_connection *conn = talloc_get_type(private_data,
1889                                               struct smbd_server_connection);
1890
1891         if (flags & EVENT_FD_WRITE) {
1892                 smbd_server_connection_write_handler(conn);
1893         } else if (flags & EVENT_FD_READ) {
1894                 smbd_server_connection_read_handler(conn);
1895         }
1896 }
1897
1898
1899 /****************************************************************************
1900 received when we should release a specific IP
1901 ****************************************************************************/
1902 static void release_ip(const char *ip, void *priv)
1903 {
1904         char addr[INET6_ADDRSTRLEN];
1905         char *p = addr;
1906
1907         client_socket_addr(get_client_fd(),addr,sizeof(addr));
1908
1909         if (strncmp("::ffff:", addr, 7) == 0) {
1910                 p = addr + 7;
1911         }
1912
1913         if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
1914                 /* we can't afford to do a clean exit - that involves
1915                    database writes, which would potentially mean we
1916                    are still running after the failover has finished -
1917                    we have to get rid of this process ID straight
1918                    away */
1919                 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
1920                         ip));
1921                 /* note we must exit with non-zero status so the unclean handler gets
1922                    called in the parent, so that the brl database is tickled */
1923                 _exit(1);
1924         }
1925 }
1926
1927 static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
1928                            uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
1929 {
1930         release_ip((char *)data->data, NULL);
1931 }
1932
1933 #ifdef CLUSTER_SUPPORT
1934 static int client_get_tcp_info(struct sockaddr_storage *server,
1935                                struct sockaddr_storage *client)
1936 {
1937         socklen_t length;
1938         if (server_fd == -1) {
1939                 return -1;
1940         }
1941         length = sizeof(*server);
1942         if (getsockname(server_fd, (struct sockaddr *)server, &length) != 0) {
1943                 return -1;
1944         }
1945         length = sizeof(*client);
1946         if (getpeername(server_fd, (struct sockaddr *)client, &length) != 0) {
1947                 return -1;
1948         }
1949         return 0;
1950 }
1951 #endif
1952
1953 /*
1954  * Send keepalive packets to our client
1955  */
1956 static bool keepalive_fn(const struct timeval *now, void *private_data)
1957 {
1958         if (!send_keepalive(smbd_server_fd())) {
1959                 DEBUG( 2, ( "Keepalive failed - exiting.\n" ) );
1960                 return False;
1961         }
1962         return True;
1963 }
1964
1965 /*
1966  * Do the recurring check if we're idle
1967  */
1968 static bool deadtime_fn(const struct timeval *now, void *private_data)
1969 {
1970         if ((conn_num_open() == 0)
1971             || (conn_idle_all(now->tv_sec))) {
1972                 DEBUG( 2, ( "Closing idle connection\n" ) );
1973                 messaging_send(smbd_messaging_context(), procid_self(),
1974                                MSG_SHUTDOWN, &data_blob_null);
1975                 return False;
1976         }
1977
1978         return True;
1979 }
1980
1981 /*
1982  * Do the recurring log file and smb.conf reload checks.
1983  */
1984
1985 static bool housekeeping_fn(const struct timeval *now, void *private_data)
1986 {
1987         change_to_root_user();
1988
1989         /* update printer queue caches if necessary */
1990         update_monitored_printq_cache();
1991
1992         /* check if we need to reload services */
1993         check_reload(time(NULL));
1994
1995         /* Change machine password if neccessary. */
1996         attempt_machine_password_change();
1997
1998         /*
1999          * Force a log file check.
2000          */
2001         force_check_log_size();
2002         check_log_size();
2003         return true;
2004 }
2005
2006 /****************************************************************************
2007  Process commands from the client
2008 ****************************************************************************/
2009
2010 void smbd_process(void)
2011 {
2012         TALLOC_CTX *frame = talloc_stackframe();
2013         char remaddr[INET6_ADDRSTRLEN];
2014
2015         smbd_server_conn = talloc_zero(smbd_event_context(), struct smbd_server_connection);
2016         if (!smbd_server_conn) {
2017                 exit_server("failed to create smbd_server_connection");
2018         }
2019
2020         if (lp_maxprotocol() == PROTOCOL_SMB2 &&
2021             lp_security() != SEC_SHARE) {
2022                 smbd_server_conn->allow_smb2 = true;
2023         }
2024
2025         /* Ensure child is set to blocking mode */
2026         set_blocking(smbd_server_fd(),True);
2027
2028         set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");
2029         set_socket_options(smbd_server_fd(), lp_socket_options());
2030
2031         /* this is needed so that we get decent entries
2032            in smbstatus for port 445 connects */
2033         set_remote_machine_name(get_peer_addr(smbd_server_fd(),
2034                                               remaddr,
2035                                               sizeof(remaddr)),
2036                                               false);
2037         reload_services(true);
2038
2039         /*
2040          * Before the first packet, check the global hosts allow/ hosts deny
2041          * parameters before doing any parsing of packets passed to us by the
2042          * client. This prevents attacks on our parsing code from hosts not in
2043          * the hosts allow list.
2044          */
2045
2046         if (!check_access(smbd_server_fd(), lp_hostsallow(-1),
2047                           lp_hostsdeny(-1))) {
2048                 char addr[INET6_ADDRSTRLEN];
2049
2050                 /*
2051                  * send a negative session response "not listening on calling
2052                  * name"
2053                  */
2054                 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2055                 DEBUG( 1, ("Connection denied from %s\n",
2056                            client_addr(get_client_fd(),addr,sizeof(addr)) ) );
2057                 (void)srv_send_smb(smbd_server_fd(),(char *)buf, false,
2058                                    0, false, NULL);
2059                 exit_server_cleanly("connection denied");
2060         }
2061
2062         static_init_rpc;
2063
2064         init_modules();
2065
2066         smb_perfcount_init();
2067
2068         if (!init_account_policy()) {
2069                 exit_server("Could not open account policy tdb.\n");
2070         }
2071
2072         if (*lp_rootdir()) {
2073                 if (chroot(lp_rootdir()) != 0) {
2074                         DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2075                         exit_server("Failed to chroot()");
2076                 }
2077                 if (chdir("/") == -1) {
2078                         DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2079                         exit_server("Failed to chroot()");
2080                 }
2081                 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2082         }
2083
2084         if (!srv_init_signing(smbd_server_conn)) {
2085                 exit_server("Failed to init smb_signing");
2086         }
2087
2088         /* Setup oplocks */
2089         if (!init_oplocks(smbd_messaging_context()))
2090                 exit_server("Failed to init oplocks");
2091
2092         /* Setup aio signal handler. */
2093         initialize_async_io_handler();
2094
2095         /* register our message handlers */
2096         messaging_register(smbd_messaging_context(), NULL,
2097                            MSG_SMB_FORCE_TDIS, msg_force_tdis);
2098         messaging_register(smbd_messaging_context(), NULL,
2099                            MSG_SMB_RELEASE_IP, msg_release_ip);
2100         messaging_register(smbd_messaging_context(), NULL,
2101                            MSG_SMB_CLOSE_FILE, msg_close_file);
2102
2103         if ((lp_keepalive() != 0)
2104             && !(event_add_idle(smbd_event_context(), NULL,
2105                                 timeval_set(lp_keepalive(), 0),
2106                                 "keepalive", keepalive_fn,
2107                                 NULL))) {
2108                 DEBUG(0, ("Could not add keepalive event\n"));
2109                 exit(1);
2110         }
2111
2112         if (!(event_add_idle(smbd_event_context(), NULL,
2113                              timeval_set(IDLE_CLOSED_TIMEOUT, 0),
2114                              "deadtime", deadtime_fn, NULL))) {
2115                 DEBUG(0, ("Could not add deadtime event\n"));
2116                 exit(1);
2117         }
2118
2119         if (!(event_add_idle(smbd_event_context(), NULL,
2120                              timeval_set(SMBD_SELECT_TIMEOUT, 0),
2121                              "housekeeping", housekeeping_fn, NULL))) {
2122                 DEBUG(0, ("Could not add housekeeping event\n"));
2123                 exit(1);
2124         }
2125
2126 #ifdef CLUSTER_SUPPORT
2127
2128         if (lp_clustering()) {
2129                 /*
2130                  * We need to tell ctdb about our client's TCP
2131                  * connection, so that for failover ctdbd can send
2132                  * tickle acks, triggering a reconnection by the
2133                  * client.
2134                  */
2135
2136                 struct sockaddr_storage srv, clnt;
2137
2138                 if (client_get_tcp_info(&srv, &clnt) == 0) {
2139
2140                         NTSTATUS status;
2141
2142                         status = ctdbd_register_ips(
2143                                 messaging_ctdbd_connection(),
2144                                 &srv, &clnt, release_ip, NULL);
2145
2146                         if (!NT_STATUS_IS_OK(status)) {
2147                                 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
2148                                           nt_errstr(status)));
2149                         }
2150                 } else
2151                 {
2152                         DEBUG(0,("Unable to get tcp info for "
2153                                  "CTDB_CONTROL_TCP_CLIENT: %s\n",
2154                                  strerror(errno)));
2155                 }
2156         }
2157
2158 #endif
2159
2160         max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
2161
2162         smbd_server_conn->smb1.fde = event_add_fd(smbd_event_context(),
2163                                                   smbd_server_conn,
2164                                                   smbd_server_fd(),
2165                                                   EVENT_FD_READ,
2166                                                   smbd_server_connection_handler,
2167                                                   smbd_server_conn);
2168         if (!smbd_server_conn->smb1.fde) {
2169                 exit_server("failed to create smbd_server_connection fde");
2170         }
2171
2172         TALLOC_FREE(frame);
2173
2174         while (True) {
2175                 NTSTATUS status;
2176
2177                 frame = talloc_stackframe_pool(8192);
2178
2179                 errno = 0;
2180
2181                 status = smbd_server_connection_loop_once(smbd_server_conn);
2182                 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
2183                     !NT_STATUS_IS_OK(status)) {
2184                         DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
2185                                   " exiting\n", nt_errstr(status)));
2186                         break;
2187                 }
2188
2189                 TALLOC_FREE(frame);
2190         }
2191
2192         exit_server_cleanly(NULL);
2193 }
2194
2195 bool req_is_in_chain(struct smb_request *req)
2196 {
2197         if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
2198                 /*
2199                  * We're right now handling a subsequent request, so we must
2200                  * be in a chain
2201                  */
2202                 return true;
2203         }
2204
2205         if (!is_andx_req(req->cmd)) {
2206                 return false;
2207         }
2208
2209         if (req->wct < 2) {
2210                 /*
2211                  * Okay, an illegal request, but definitely not chained :-)
2212                  */
2213                 return false;
2214         }
2215
2216         return (CVAL(req->vwv+0, 0) != 0xFF);
2217 }