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