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