source: trunk/server/source3/smbd/process.c@ 862

Last change on this file since 862 was 862, checked in by Silvan Scherrer, 11 years ago

Samba Server: update trunk to 3.6.23

File size: 82.8 KB
Line 
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 "../lib/tsocket/tsocket.h"
23#include "system/filesys.h"
24#include "smbd/smbd.h"
25#include "smbd/globals.h"
26#include "librpc/gen_ndr/netlogon.h"
27#include "../lib/async_req/async_sock.h"
28#include "ctdbd_conn.h"
29#include "../lib/util/select.h"
30#include "printing/pcap.h"
31#include "system/select.h"
32#include "passdb.h"
33#include "auth.h"
34#include "messages.h"
35#include "smbprofile.h"
36#include "rpc_server/spoolss/srv_spoolss_nt.h"
37#include "libsmb/libsmb.h"
38#ifdef __OS2__
39#define pipe(A) os2_pipe(A)
40#endif
41
42extern bool global_machine_password_needs_changing;
43
44static void construct_reply_common(struct smb_request *req, const char *inbuf,
45 char *outbuf);
46static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid);
47
48static bool smbd_lock_socket_internal(struct smbd_server_connection *sconn)
49{
50 bool ok;
51
52 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
53 return true;
54 }
55
56 sconn->smb1.echo_handler.ref_count++;
57
58 if (sconn->smb1.echo_handler.ref_count > 1) {
59 return true;
60 }
61
62 DEBUG(10,("pid[%d] wait for socket lock\n", (int)sys_getpid()));
63
64 do {
65 ok = fcntl_lock(
66 sconn->smb1.echo_handler.socket_lock_fd,
67 SMB_F_SETLKW, 0, 0, F_WRLCK);
68 } while (!ok && (errno == EINTR));
69
70 if (!ok) {
71 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
72 return false;
73 }
74
75 DEBUG(10,("pid[%d] got for socket lock\n", (int)sys_getpid()));
76
77 return true;
78}
79
80void smbd_lock_socket(struct smbd_server_connection *sconn)
81{
82 if (!smbd_lock_socket_internal(sconn)) {
83 exit_server_cleanly("failed to lock socket");
84 }
85}
86
87static bool smbd_unlock_socket_internal(struct smbd_server_connection *sconn)
88{
89 bool ok;
90
91 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
92 return true;
93 }
94
95 sconn->smb1.echo_handler.ref_count--;
96
97 if (sconn->smb1.echo_handler.ref_count > 0) {
98 return true;
99 }
100
101 do {
102 ok = fcntl_lock(
103 sconn->smb1.echo_handler.socket_lock_fd,
104 SMB_F_SETLKW, 0, 0, F_UNLCK);
105 } while (!ok && (errno == EINTR));
106
107 if (!ok) {
108 DEBUG(1, ("fcntl_lock failed: %s\n", strerror(errno)));
109 return false;
110 }
111
112 DEBUG(10,("pid[%d] unlocked socket\n", (int)sys_getpid()));
113
114 return true;
115}
116
117void smbd_unlock_socket(struct smbd_server_connection *sconn)
118{
119 if (!smbd_unlock_socket_internal(sconn)) {
120 exit_server_cleanly("failed to unlock socket");
121 }
122}
123
124/* Accessor function for smb_read_error for smbd functions. */
125
126/****************************************************************************
127 Send an smb to a fd.
128****************************************************************************/
129
130bool srv_send_smb(struct smbd_server_connection *sconn, char *buffer,
131 bool do_signing, uint32_t seqnum,
132 bool do_encrypt,
133 struct smb_perfcount_data *pcd)
134{
135 size_t len = 0;
136 size_t nwritten=0;
137 ssize_t ret;
138 char *buf_out = buffer;
139
140 smbd_lock_socket(sconn);
141
142 if (do_signing) {
143 /* Sign the outgoing packet if required. */
144 srv_calculate_sign_mac(sconn, buf_out, seqnum);
145 }
146
147 if (do_encrypt) {
148 NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
149 if (!NT_STATUS_IS_OK(status)) {
150 DEBUG(0, ("send_smb: SMB encryption failed "
151 "on outgoing packet! Error %s\n",
152 nt_errstr(status) ));
153 goto out;
154 }
155 }
156
157 len = smb_len_large(buf_out) + 4;
158
159 ret = write_data(sconn->sock, buf_out+nwritten, len - nwritten);
160 if (ret <= 0) {
161
162 char addr[INET6_ADDRSTRLEN];
163 /*
164 * Try and give an error message saying what
165 * client failed.
166 */
167 DEBUG(1,("pid[%d] Error writing %d bytes to client %s. %d. (%s)\n",
168 (int)sys_getpid(), (int)len,
169 get_peer_addr(sconn->sock, addr, sizeof(addr)),
170 (int)ret, strerror(errno) ));
171
172 srv_free_enc_buffer(buf_out);
173 goto out;
174 }
175
176 SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
177 srv_free_enc_buffer(buf_out);
178out:
179 SMB_PERFCOUNT_END(pcd);
180
181 smbd_unlock_socket(sconn);
182 return true;
183}
184
185/*******************************************************************
186 Setup the word count and byte count for a smb message.
187********************************************************************/
188
189int srv_set_message(char *buf,
190 int num_words,
191 int num_bytes,
192 bool zero)
193{
194 if (zero && (num_words || num_bytes)) {
195 memset(buf + smb_size,'\0',num_words*2 + num_bytes);
196 }
197 SCVAL(buf,smb_wct,num_words);
198 SSVAL(buf,smb_vwv + num_words*SIZEOFWORD,num_bytes);
199 smb_setlen(buf,(smb_size + num_words*2 + num_bytes - 4));
200 return (smb_size + num_words*2 + num_bytes);
201}
202
203static bool valid_smb_header(const uint8_t *inbuf)
204{
205 if (is_encrypted_packet(inbuf)) {
206 return true;
207 }
208 /*
209 * This used to be (strncmp(smb_base(inbuf),"\377SMB",4) == 0)
210 * but it just looks weird to call strncmp for this one.
211 */
212 return (IVAL(smb_base(inbuf), 0) == 0x424D53FF);
213}
214
215/* Socket functions for smbd packet processing. */
216
217static bool valid_packet_size(size_t len)
218{
219 /*
220 * A WRITEX with CAP_LARGE_WRITEX can be 64k worth of data plus 65 bytes
221 * of header. Don't print the error if this fits.... JRA.
222 */
223
224 if (len > (BUFFER_SIZE + LARGE_WRITEX_HDR_SIZE)) {
225 DEBUG(0,("Invalid packet length! (%lu bytes).\n",
226 (unsigned long)len));
227 return false;
228 }
229 return true;
230}
231
232static NTSTATUS read_packet_remainder(int fd, char *buffer,
233 unsigned int timeout, ssize_t len)
234{
235 NTSTATUS status;
236
237 if (len <= 0) {
238 return NT_STATUS_OK;
239 }
240
241 status = read_fd_with_timeout(fd, buffer, len, len, timeout, NULL);
242 if (!NT_STATUS_IS_OK(status)) {
243 char addr[INET6_ADDRSTRLEN];
244 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
245 "error = %s.\n",
246 get_peer_addr(fd, addr, sizeof(addr)),
247 nt_errstr(status)));
248 }
249 return status;
250}
251
252/****************************************************************************
253 Attempt a zerocopy writeX read. We know here that len > smb_size-4
254****************************************************************************/
255
256/*
257 * Unfortunately, earlier versions of smbclient/libsmbclient
258 * don't send this "standard" writeX header. I've fixed this
259 * for 3.2 but we'll use the old method with earlier versions.
260 * Windows and CIFSFS at least use this standard size. Not
261 * sure about MacOSX.
262 */
263
264#define STANDARD_WRITE_AND_X_HEADER_SIZE (smb_size - 4 + /* basic header */ \
265 (2*14) + /* word count (including bcc) */ \
266 1 /* pad byte */)
267
268static NTSTATUS receive_smb_raw_talloc_partial_read(TALLOC_CTX *mem_ctx,
269 const char lenbuf[4],
270 struct smbd_server_connection *sconn,
271 int sock,
272 char **buffer,
273 unsigned int timeout,
274 size_t *p_unread,
275 size_t *len_ret)
276{
277 /* Size of a WRITEX call (+4 byte len). */
278 char writeX_header[4 + STANDARD_WRITE_AND_X_HEADER_SIZE];
279 ssize_t len = smb_len_large(lenbuf); /* Could be a UNIX large writeX. */
280 ssize_t toread;
281 NTSTATUS status;
282
283 memcpy(writeX_header, lenbuf, 4);
284
285 status = read_fd_with_timeout(
286 sock, writeX_header + 4,
287 STANDARD_WRITE_AND_X_HEADER_SIZE,
288 STANDARD_WRITE_AND_X_HEADER_SIZE,
289 timeout, NULL);
290
291 if (!NT_STATUS_IS_OK(status)) {
292 DEBUG(0, ("read_fd_with_timeout failed for client %s read "
293 "error = %s.\n", sconn->client_id.addr,
294 nt_errstr(status)));
295 return status;
296 }
297
298 /*
299 * Ok - now try and see if this is a possible
300 * valid writeX call.
301 */
302
303 if (is_valid_writeX_buffer(sconn, (uint8_t *)writeX_header)) {
304 /*
305 * If the data offset is beyond what
306 * we've read, drain the extra bytes.
307 */
308 uint16_t doff = SVAL(writeX_header,smb_vwv11);
309 ssize_t newlen;
310
311 if (doff > STANDARD_WRITE_AND_X_HEADER_SIZE) {
312 size_t drain = doff - STANDARD_WRITE_AND_X_HEADER_SIZE;
313 if (drain_socket(sock, drain) != drain) {
314 smb_panic("receive_smb_raw_talloc_partial_read:"
315 " failed to drain pending bytes");
316 }
317 } else {
318 doff = STANDARD_WRITE_AND_X_HEADER_SIZE;
319 }
320
321 /* Spoof down the length and null out the bcc. */
322 set_message_bcc(writeX_header, 0);
323 newlen = smb_len(writeX_header);
324
325 /* Copy the header we've written. */
326
327 *buffer = (char *)TALLOC_MEMDUP(mem_ctx,
328 writeX_header,
329 sizeof(writeX_header));
330
331 if (*buffer == NULL) {
332 DEBUG(0, ("Could not allocate inbuf of length %d\n",
333 (int)sizeof(writeX_header)));
334 return NT_STATUS_NO_MEMORY;
335 }
336
337 /* Work out the remaining bytes. */
338 *p_unread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
339 *len_ret = newlen + 4;
340 return NT_STATUS_OK;
341 }
342
343 if (!valid_packet_size(len)) {
344 return NT_STATUS_INVALID_PARAMETER;
345 }
346
347 /*
348 * Not a valid writeX call. Just do the standard
349 * talloc and return.
350 */
351
352 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
353
354 if (*buffer == NULL) {
355 DEBUG(0, ("Could not allocate inbuf of length %d\n",
356 (int)len+4));
357 return NT_STATUS_NO_MEMORY;
358 }
359
360 /* Copy in what we already read. */
361 memcpy(*buffer,
362 writeX_header,
363 4 + STANDARD_WRITE_AND_X_HEADER_SIZE);
364 toread = len - STANDARD_WRITE_AND_X_HEADER_SIZE;
365
366 if(toread > 0) {
367 status = read_packet_remainder(
368 sock,
369 (*buffer) + 4 + STANDARD_WRITE_AND_X_HEADER_SIZE,
370 timeout, toread);
371
372 if (!NT_STATUS_IS_OK(status)) {
373 DEBUG(10, ("receive_smb_raw_talloc_partial_read: %s\n",
374 nt_errstr(status)));
375 return status;
376 }
377 }
378
379 *len_ret = len + 4;
380 return NT_STATUS_OK;
381}
382
383static NTSTATUS receive_smb_raw_talloc(TALLOC_CTX *mem_ctx,
384 struct smbd_server_connection *sconn,
385 int sock,
386 char **buffer, unsigned int timeout,
387 size_t *p_unread, size_t *plen)
388{
389 char lenbuf[4];
390 size_t len;
391 int min_recv_size = lp_min_receive_file_size();
392 NTSTATUS status;
393
394 *p_unread = 0;
395
396 status = read_smb_length_return_keepalive(sock, lenbuf, timeout,
397 &len);
398 if (!NT_STATUS_IS_OK(status)) {
399 return status;
400 }
401
402 if (CVAL(lenbuf,0) == 0 && min_recv_size &&
403 (smb_len_large(lenbuf) > /* Could be a UNIX large writeX. */
404 (min_recv_size + STANDARD_WRITE_AND_X_HEADER_SIZE)) &&
405 !srv_is_signing_active(sconn) &&
406 sconn->smb1.echo_handler.trusted_fde == NULL) {
407
408 return receive_smb_raw_talloc_partial_read(
409 mem_ctx, lenbuf, sconn, sock, buffer, timeout,
410 p_unread, plen);
411 }
412
413 if (!valid_packet_size(len)) {
414 return NT_STATUS_INVALID_PARAMETER;
415 }
416
417 /*
418 * The +4 here can't wrap, we've checked the length above already.
419 */
420
421 *buffer = TALLOC_ARRAY(mem_ctx, char, len+4);
422
423 if (*buffer == NULL) {
424 DEBUG(0, ("Could not allocate inbuf of length %d\n",
425 (int)len+4));
426 return NT_STATUS_NO_MEMORY;
427 }
428
429 memcpy(*buffer, lenbuf, sizeof(lenbuf));
430
431 status = read_packet_remainder(sock, (*buffer)+4, timeout, len);
432 if (!NT_STATUS_IS_OK(status)) {
433 return status;
434 }
435
436 *plen = len + 4;
437 return NT_STATUS_OK;
438}
439
440static NTSTATUS receive_smb_talloc(TALLOC_CTX *mem_ctx,
441 struct smbd_server_connection *sconn,
442 int sock,
443 char **buffer, unsigned int timeout,
444 size_t *p_unread, bool *p_encrypted,
445 size_t *p_len,
446 uint32_t *seqnum,
447 bool trusted_channel)
448{
449 size_t len = 0;
450 NTSTATUS status;
451
452 *p_encrypted = false;
453
454 status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
455 p_unread, &len);
456 if (!NT_STATUS_IS_OK(status)) {
457 DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
458 ("receive_smb_raw_talloc failed for client %s "
459 "read error = %s.\n",
460 sconn->client_id.addr, nt_errstr(status)));
461 return status;
462 }
463
464 if (is_encrypted_packet((uint8_t *)*buffer)) {
465 status = srv_decrypt_buffer(*buffer);
466 if (!NT_STATUS_IS_OK(status)) {
467 DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
468 "incoming packet! Error %s\n",
469 nt_errstr(status) ));
470 return status;
471 }
472 *p_encrypted = true;
473 }
474
475 /* Check the incoming SMB signature. */
476 if (!srv_check_sign_mac(sconn, *buffer, seqnum, trusted_channel)) {
477 DEBUG(0, ("receive_smb: SMB Signature verification failed on "
478 "incoming packet!\n"));
479 return NT_STATUS_INVALID_NETWORK_RESPONSE;
480 }
481
482 *p_len = len;
483 return NT_STATUS_OK;
484}
485
486/*
487 * Initialize a struct smb_request from an inbuf
488 */
489
490static bool init_smb_request(struct smb_request *req,
491 struct smbd_server_connection *sconn,
492 const uint8 *inbuf,
493 size_t unread_bytes, bool encrypted,
494 uint32_t seqnum)
495{
496 size_t req_size = smb_len(inbuf) + 4;
497 /* Ensure we have at least smb_size bytes. */
498 if (req_size < smb_size) {
499 DEBUG(0,("init_smb_request: invalid request size %u\n",
500 (unsigned int)req_size ));
501 return false;
502 }
503 req->cmd = CVAL(inbuf, smb_com);
504 req->flags2 = SVAL(inbuf, smb_flg2);
505 req->smbpid = SVAL(inbuf, smb_pid);
506 req->mid = (uint64_t)SVAL(inbuf, smb_mid);
507 req->seqnum = seqnum;
508 req->vuid = SVAL(inbuf, smb_uid);
509 req->tid = SVAL(inbuf, smb_tid);
510 req->wct = CVAL(inbuf, smb_wct);
511 req->vwv = (uint16_t *)(inbuf+smb_vwv);
512 req->buflen = smb_buflen(inbuf);
513 req->buf = (const uint8_t *)smb_buf(inbuf);
514 req->unread_bytes = unread_bytes;
515 req->encrypted = encrypted;
516 req->sconn = sconn;
517 req->conn = conn_find(sconn,req->tid);
518 req->chain_fsp = NULL;
519 req->chain_outbuf = NULL;
520 req->done = false;
521 req->smb2req = NULL;
522 smb_init_perfcount_data(&req->pcd);
523
524 /* Ensure we have at least wct words and 2 bytes of bcc. */
525 if (smb_size + req->wct*2 > req_size) {
526 DEBUG(0,("init_smb_request: invalid wct number %u (size %u)\n",
527 (unsigned int)req->wct,
528 (unsigned int)req_size));
529 return false;
530 }
531 /* Ensure bcc is correct. */
532 if (((uint8 *)smb_buf(inbuf)) + req->buflen > inbuf + req_size) {
533 DEBUG(0,("init_smb_request: invalid bcc number %u "
534 "(wct = %u, size %u)\n",
535 (unsigned int)req->buflen,
536 (unsigned int)req->wct,
537 (unsigned int)req_size));
538 return false;
539 }
540
541 req->outbuf = NULL;
542 return true;
543}
544
545static void process_smb(struct smbd_server_connection *conn,
546 uint8_t *inbuf, size_t nread, size_t unread_bytes,
547 uint32_t seqnum, bool encrypted,
548 struct smb_perfcount_data *deferred_pcd);
549
550static void smbd_deferred_open_timer(struct event_context *ev,
551 struct timed_event *te,
552 struct timeval _tval,
553 void *private_data)
554{
555 struct pending_message_list *msg = talloc_get_type(private_data,
556 struct pending_message_list);
557 TALLOC_CTX *mem_ctx = talloc_tos();
558 uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
559 uint8_t *inbuf;
560
561 inbuf = (uint8_t *)talloc_memdup(mem_ctx, msg->buf.data,
562 msg->buf.length);
563 if (inbuf == NULL) {
564 exit_server("smbd_deferred_open_timer: talloc failed\n");
565 return;
566 }
567
568 /* We leave this message on the queue so the open code can
569 know this is a retry. */
570 DEBUG(5,("smbd_deferred_open_timer: trigger mid %llu.\n",
571 (unsigned long long)mid ));
572
573 /* Mark the message as processed so this is not
574 * re-processed in error. */
575 msg->processed = true;
576
577 process_smb(smbd_server_conn, inbuf,
578 msg->buf.length, 0,
579 msg->seqnum, msg->encrypted, &msg->pcd);
580
581 /* If it's still there and was processed, remove it. */
582 msg = get_deferred_open_message_smb(mid);
583 if (msg && msg->processed) {
584 remove_deferred_open_message_smb(mid);
585 }
586}
587
588/****************************************************************************
589 Function to push a message onto the tail of a linked list of smb messages ready
590 for processing.
591****************************************************************************/
592
593static bool push_queued_message(struct smb_request *req,
594 struct timeval request_time,
595 struct timeval end_time,
596 char *private_data, size_t private_len)
597{
598 int msg_len = smb_len(req->inbuf) + 4;
599 struct pending_message_list *msg;
600
601 msg = TALLOC_ZERO_P(NULL, struct pending_message_list);
602
603 if(msg == NULL) {
604 DEBUG(0,("push_message: malloc fail (1)\n"));
605 return False;
606 }
607
608 msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
609 if(msg->buf.data == NULL) {
610 DEBUG(0,("push_message: malloc fail (2)\n"));
611 TALLOC_FREE(msg);
612 return False;
613 }
614
615 msg->request_time = request_time;
616 msg->seqnum = req->seqnum;
617 msg->encrypted = req->encrypted;
618 msg->processed = false;
619 SMB_PERFCOUNT_DEFER_OP(&req->pcd, &msg->pcd);
620
621 if (private_data) {
622 msg->private_data = data_blob_talloc(msg, private_data,
623 private_len);
624 if (msg->private_data.data == NULL) {
625 DEBUG(0,("push_message: malloc fail (3)\n"));
626 TALLOC_FREE(msg);
627 return False;
628 }
629 }
630
631 msg->te = event_add_timed(smbd_event_context(),
632 msg,
633 end_time,
634 smbd_deferred_open_timer,
635 msg);
636 if (!msg->te) {
637 DEBUG(0,("push_message: event_add_timed failed\n"));
638 TALLOC_FREE(msg);
639 return false;
640 }
641
642 DLIST_ADD_END(deferred_open_queue, msg, struct pending_message_list *);
643
644 DEBUG(10,("push_message: pushed message length %u on "
645 "deferred_open_queue\n", (unsigned int)msg_len));
646
647 return True;
648}
649
650/****************************************************************************
651 Function to delete a sharing violation open message by mid.
652****************************************************************************/
653
654void remove_deferred_open_message_smb(uint64_t mid)
655{
656 struct pending_message_list *pml;
657
658 if (smbd_server_conn->using_smb2) {
659 remove_deferred_open_message_smb2(smbd_server_conn, mid);
660 return;
661 }
662
663 for (pml = deferred_open_queue; pml; pml = pml->next) {
664 if (mid == (uint64_t)SVAL(pml->buf.data,smb_mid)) {
665 DEBUG(10,("remove_deferred_open_message_smb: "
666 "deleting mid %llu len %u\n",
667 (unsigned long long)mid,
668 (unsigned int)pml->buf.length ));
669 DLIST_REMOVE(deferred_open_queue, pml);
670 TALLOC_FREE(pml);
671 return;
672 }
673 }
674}
675
676/****************************************************************************
677 Move a sharing violation open retry message to the front of the list and
678 schedule it for immediate processing.
679****************************************************************************/
680
681void schedule_deferred_open_message_smb(uint64_t mid)
682{
683 struct pending_message_list *pml;
684 int i = 0;
685
686 if (smbd_server_conn->using_smb2) {
687 schedule_deferred_open_message_smb2(smbd_server_conn, mid);
688 return;
689 }
690
691 for (pml = deferred_open_queue; pml; pml = pml->next) {
692 uint64_t msg_mid = (uint64_t)SVAL(pml->buf.data,smb_mid);
693
694 DEBUG(10,("schedule_deferred_open_message_smb: [%d] "
695 "msg_mid = %llu\n",
696 i++,
697 (unsigned long long)msg_mid ));
698
699 if (mid == msg_mid) {
700 struct timed_event *te;
701
702 if (pml->processed) {
703 /* A processed message should not be
704 * rescheduled. */
705 DEBUG(0,("schedule_deferred_open_message_smb: LOGIC ERROR "
706 "message mid %llu was already processed\n",
707 (unsigned long long)msg_mid ));
708 continue;
709 }
710
711 DEBUG(10,("schedule_deferred_open_message_smb: "
712 "scheduling mid %llu\n",
713 (unsigned long long)mid ));
714
715 te = event_add_timed(smbd_event_context(),
716 pml,
717 timeval_zero(),
718 smbd_deferred_open_timer,
719 pml);
720 if (!te) {
721 DEBUG(10,("schedule_deferred_open_message_smb: "
722 "event_add_timed() failed, "
723 "skipping mid %llu\n",
724 (unsigned long long)msg_mid ));
725 }
726
727 TALLOC_FREE(pml->te);
728 pml->te = te;
729 DLIST_PROMOTE(deferred_open_queue, pml);
730 return;
731 }
732 }
733
734 DEBUG(10,("schedule_deferred_open_message_smb: failed to "
735 "find message mid %llu\n",
736 (unsigned long long)mid ));
737}
738
739/****************************************************************************
740 Return true if this mid is on the deferred queue and was not yet processed.
741****************************************************************************/
742
743bool open_was_deferred(uint64_t mid)
744{
745 struct pending_message_list *pml;
746
747 if (smbd_server_conn->using_smb2) {
748 return open_was_deferred_smb2(smbd_server_conn, mid);
749 }
750
751 for (pml = deferred_open_queue; pml; pml = pml->next) {
752 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid && !pml->processed) {
753 return True;
754 }
755 }
756 return False;
757}
758
759/****************************************************************************
760 Return the message queued by this mid.
761****************************************************************************/
762
763static struct pending_message_list *get_deferred_open_message_smb(uint64_t mid)
764{
765 struct pending_message_list *pml;
766
767 for (pml = deferred_open_queue; pml; pml = pml->next) {
768 if (((uint64_t)SVAL(pml->buf.data,smb_mid)) == mid) {
769 return pml;
770 }
771 }
772 return NULL;
773}
774
775/****************************************************************************
776 Get the state data queued by this mid.
777****************************************************************************/
778
779bool get_deferred_open_message_state(struct smb_request *smbreq,
780 struct timeval *p_request_time,
781 void **pp_state)
782{
783 struct pending_message_list *pml;
784
785 if (smbd_server_conn->using_smb2) {
786 return get_deferred_open_message_state_smb2(smbreq->smb2req,
787 p_request_time,
788 pp_state);
789 }
790
791 pml = get_deferred_open_message_smb(smbreq->mid);
792 if (!pml) {
793 return false;
794 }
795 if (p_request_time) {
796 *p_request_time = pml->request_time;
797 }
798 if (pp_state) {
799 *pp_state = (void *)pml->private_data.data;
800 }
801 return true;
802}
803
804/****************************************************************************
805 Function to push a deferred open smb message onto a linked list of local smb
806 messages ready for processing.
807****************************************************************************/
808
809bool push_deferred_open_message_smb(struct smb_request *req,
810 struct timeval request_time,
811 struct timeval timeout,
812 struct file_id id,
813 char *private_data, size_t priv_len)
814{
815 struct timeval end_time;
816
817 if (req->smb2req) {
818 return push_deferred_open_message_smb2(req->smb2req,
819 request_time,
820 timeout,
821 id,
822 private_data,
823 priv_len);
824 }
825
826 if (req->unread_bytes) {
827 DEBUG(0,("push_deferred_open_message_smb: logic error ! "
828 "unread_bytes = %u\n",
829 (unsigned int)req->unread_bytes ));
830 smb_panic("push_deferred_open_message_smb: "
831 "logic error unread_bytes != 0" );
832 }
833
834 end_time = timeval_sum(&request_time, &timeout);
835
836 DEBUG(10,("push_deferred_open_message_smb: pushing message "
837 "len %u mid %llu timeout time [%u.%06u]\n",
838 (unsigned int) smb_len(req->inbuf)+4,
839 (unsigned long long)req->mid,
840 (unsigned int)end_time.tv_sec,
841 (unsigned int)end_time.tv_usec));
842
843 return push_queued_message(req, request_time, end_time,
844 private_data, priv_len);
845}
846
847struct idle_event {
848 struct timed_event *te;
849 struct timeval interval;
850 char *name;
851 bool (*handler)(const struct timeval *now, void *private_data);
852 void *private_data;
853};
854
855static void smbd_idle_event_handler(struct event_context *ctx,
856 struct timed_event *te,
857 struct timeval now,
858 void *private_data)
859{
860 struct idle_event *event =
861 talloc_get_type_abort(private_data, struct idle_event);
862
863 TALLOC_FREE(event->te);
864
865 DEBUG(10,("smbd_idle_event_handler: %s %p called\n",
866 event->name, event->te));
867
868 if (!event->handler(&now, event->private_data)) {
869 DEBUG(10,("smbd_idle_event_handler: %s %p stopped\n",
870 event->name, event->te));
871 /* Don't repeat, delete ourselves */
872 TALLOC_FREE(event);
873 return;
874 }
875
876 DEBUG(10,("smbd_idle_event_handler: %s %p rescheduled\n",
877 event->name, event->te));
878
879 event->te = event_add_timed(ctx, event,
880 timeval_sum(&now, &event->interval),
881 smbd_idle_event_handler, event);
882
883 /* We can't do much but fail here. */
884 SMB_ASSERT(event->te != NULL);
885}
886
887struct idle_event *event_add_idle(struct event_context *event_ctx,
888 TALLOC_CTX *mem_ctx,
889 struct timeval interval,
890 const char *name,
891 bool (*handler)(const struct timeval *now,
892 void *private_data),
893 void *private_data)
894{
895 struct idle_event *result;
896 struct timeval now = timeval_current();
897
898 result = TALLOC_P(mem_ctx, struct idle_event);
899 if (result == NULL) {
900 DEBUG(0, ("talloc failed\n"));
901 return NULL;
902 }
903
904 result->interval = interval;
905 result->handler = handler;
906 result->private_data = private_data;
907
908 if (!(result->name = talloc_asprintf(result, "idle_evt(%s)", name))) {
909 DEBUG(0, ("talloc failed\n"));
910 TALLOC_FREE(result);
911 return NULL;
912 }
913
914 result->te = event_add_timed(event_ctx, result,
915 timeval_sum(&now, &interval),
916 smbd_idle_event_handler, result);
917 if (result->te == NULL) {
918 DEBUG(0, ("event_add_timed failed\n"));
919 TALLOC_FREE(result);
920 return NULL;
921 }
922
923 DEBUG(10,("event_add_idle: %s %p\n", result->name, result->te));
924 return result;
925}
926
927static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
928{
929 int timeout;
930 int num_pfds = 0;
931 int ret;
932 bool retry;
933
934 timeout = SMBD_SELECT_TIMEOUT * 1000;
935
936 /*
937 * Are there any timed events waiting ? If so, ensure we don't
938 * select for longer than it would take to wait for them.
939 */
940
941 event_add_to_poll_args(smbd_event_context(), conn,
942 &conn->pfds, &num_pfds, &timeout);
943
944 /* Process a signal and timed events now... */
945 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
946 return NT_STATUS_RETRY;
947 }
948
949 {
950 int sav;
951 START_PROFILE(smbd_idle);
952
953 ret = sys_poll(conn->pfds, num_pfds, timeout);
954 sav = errno;
955
956 END_PROFILE(smbd_idle);
957 errno = sav;
958 }
959
960 if (ret == -1) {
961 if (errno == EINTR) {
962 return NT_STATUS_RETRY;
963 }
964 return map_nt_error_from_unix(errno);
965 }
966
967 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
968 num_pfds);
969 if (retry) {
970 return NT_STATUS_RETRY;
971 }
972
973 /* Did we timeout ? */
974 if (ret == 0) {
975 return NT_STATUS_RETRY;
976 }
977
978 /* should not be reached */
979 return NT_STATUS_INTERNAL_ERROR;
980}
981
982/*
983 * Only allow 5 outstanding trans requests. We're allocating memory, so
984 * prevent a DoS.
985 */
986
987NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
988{
989 int count = 0;
990 for (; list != NULL; list = list->next) {
991
992 if (list->mid == mid) {
993 return NT_STATUS_INVALID_PARAMETER;
994 }
995
996 count += 1;
997 }
998 if (count > 5) {
999 return NT_STATUS_INSUFFICIENT_RESOURCES;
1000 }
1001
1002 return NT_STATUS_OK;
1003}
1004
1005/*
1006These flags determine some of the permissions required to do an operation
1007
1008Note that I don't set NEED_WRITE on some write operations because they
1009are used by some brain-dead clients when printing, and I don't want to
1010force write permissions on print services.
1011*/
1012#define AS_USER (1<<0)
1013#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1014#define TIME_INIT (1<<2)
1015#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1016#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1017#define DO_CHDIR (1<<6)
1018
1019/*
1020 define a list of possible SMB messages and their corresponding
1021 functions. Any message that has a NULL function is unimplemented -
1022 please feel free to contribute implementations!
1023*/
1024static const struct smb_message_struct {
1025 const char *name;
1026 void (*fn)(struct smb_request *req);
1027 int flags;
1028} smb_messages[256] = {
1029
1030/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1031/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1032/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1033/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1034/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1035/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1036/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1037/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1038/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1039/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1040/* 0x0a */ { "SMBread",reply_read,AS_USER},
1041/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1042/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1043/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1044/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1045/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1046/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1047/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1048/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1049/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1050/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1051/* 0x15 */ { NULL, NULL, 0 },
1052/* 0x16 */ { NULL, NULL, 0 },
1053/* 0x17 */ { NULL, NULL, 0 },
1054/* 0x18 */ { NULL, NULL, 0 },
1055/* 0x19 */ { NULL, NULL, 0 },
1056/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1057/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1058/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1059/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1060/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1061/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1062/* 0x20 */ { "SMBwritec", NULL,0},
1063/* 0x21 */ { NULL, NULL, 0 },
1064/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1065/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1066/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1067/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1068/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1069/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1070/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1071/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1072/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1073/* 0x2b */ { "SMBecho",reply_echo,0},
1074/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1075/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1076/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1077/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1078/* 0x30 */ { NULL, NULL, 0 },
1079/* 0x31 */ { NULL, NULL, 0 },
1080/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1081/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1082/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1083/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1084/* 0x36 */ { NULL, NULL, 0 },
1085/* 0x37 */ { NULL, NULL, 0 },
1086/* 0x38 */ { NULL, NULL, 0 },
1087/* 0x39 */ { NULL, NULL, 0 },
1088/* 0x3a */ { NULL, NULL, 0 },
1089/* 0x3b */ { NULL, NULL, 0 },
1090/* 0x3c */ { NULL, NULL, 0 },
1091/* 0x3d */ { NULL, NULL, 0 },
1092/* 0x3e */ { NULL, NULL, 0 },
1093/* 0x3f */ { NULL, NULL, 0 },
1094/* 0x40 */ { NULL, NULL, 0 },
1095/* 0x41 */ { NULL, NULL, 0 },
1096/* 0x42 */ { NULL, NULL, 0 },
1097/* 0x43 */ { NULL, NULL, 0 },
1098/* 0x44 */ { NULL, NULL, 0 },
1099/* 0x45 */ { NULL, NULL, 0 },
1100/* 0x46 */ { NULL, NULL, 0 },
1101/* 0x47 */ { NULL, NULL, 0 },
1102/* 0x48 */ { NULL, NULL, 0 },
1103/* 0x49 */ { NULL, NULL, 0 },
1104/* 0x4a */ { NULL, NULL, 0 },
1105/* 0x4b */ { NULL, NULL, 0 },
1106/* 0x4c */ { NULL, NULL, 0 },
1107/* 0x4d */ { NULL, NULL, 0 },
1108/* 0x4e */ { NULL, NULL, 0 },
1109/* 0x4f */ { NULL, NULL, 0 },
1110/* 0x50 */ { NULL, NULL, 0 },
1111/* 0x51 */ { NULL, NULL, 0 },
1112/* 0x52 */ { NULL, NULL, 0 },
1113/* 0x53 */ { NULL, NULL, 0 },
1114/* 0x54 */ { NULL, NULL, 0 },
1115/* 0x55 */ { NULL, NULL, 0 },
1116/* 0x56 */ { NULL, NULL, 0 },
1117/* 0x57 */ { NULL, NULL, 0 },
1118/* 0x58 */ { NULL, NULL, 0 },
1119/* 0x59 */ { NULL, NULL, 0 },
1120/* 0x5a */ { NULL, NULL, 0 },
1121/* 0x5b */ { NULL, NULL, 0 },
1122/* 0x5c */ { NULL, NULL, 0 },
1123/* 0x5d */ { NULL, NULL, 0 },
1124/* 0x5e */ { NULL, NULL, 0 },
1125/* 0x5f */ { NULL, NULL, 0 },
1126/* 0x60 */ { NULL, NULL, 0 },
1127/* 0x61 */ { NULL, NULL, 0 },
1128/* 0x62 */ { NULL, NULL, 0 },
1129/* 0x63 */ { NULL, NULL, 0 },
1130/* 0x64 */ { NULL, NULL, 0 },
1131/* 0x65 */ { NULL, NULL, 0 },
1132/* 0x66 */ { NULL, NULL, 0 },
1133/* 0x67 */ { NULL, NULL, 0 },
1134/* 0x68 */ { NULL, NULL, 0 },
1135/* 0x69 */ { NULL, NULL, 0 },
1136/* 0x6a */ { NULL, NULL, 0 },
1137/* 0x6b */ { NULL, NULL, 0 },
1138/* 0x6c */ { NULL, NULL, 0 },
1139/* 0x6d */ { NULL, NULL, 0 },
1140/* 0x6e */ { NULL, NULL, 0 },
1141/* 0x6f */ { NULL, NULL, 0 },
1142/* 0x70 */ { "SMBtcon",reply_tcon,0},
1143/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1144/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1145/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1146/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1147/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1148/* 0x76 */ { NULL, NULL, 0 },
1149/* 0x77 */ { NULL, NULL, 0 },
1150/* 0x78 */ { NULL, NULL, 0 },
1151/* 0x79 */ { NULL, NULL, 0 },
1152/* 0x7a */ { NULL, NULL, 0 },
1153/* 0x7b */ { NULL, NULL, 0 },
1154/* 0x7c */ { NULL, NULL, 0 },
1155/* 0x7d */ { NULL, NULL, 0 },
1156/* 0x7e */ { NULL, NULL, 0 },
1157/* 0x7f */ { NULL, NULL, 0 },
1158/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1159/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1160/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1161/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1162/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1163/* 0x85 */ { NULL, NULL, 0 },
1164/* 0x86 */ { NULL, NULL, 0 },
1165/* 0x87 */ { NULL, NULL, 0 },
1166/* 0x88 */ { NULL, NULL, 0 },
1167/* 0x89 */ { NULL, NULL, 0 },
1168/* 0x8a */ { NULL, NULL, 0 },
1169/* 0x8b */ { NULL, NULL, 0 },
1170/* 0x8c */ { NULL, NULL, 0 },
1171/* 0x8d */ { NULL, NULL, 0 },
1172/* 0x8e */ { NULL, NULL, 0 },
1173/* 0x8f */ { NULL, NULL, 0 },
1174/* 0x90 */ { NULL, NULL, 0 },
1175/* 0x91 */ { NULL, NULL, 0 },
1176/* 0x92 */ { NULL, NULL, 0 },
1177/* 0x93 */ { NULL, NULL, 0 },
1178/* 0x94 */ { NULL, NULL, 0 },
1179/* 0x95 */ { NULL, NULL, 0 },
1180/* 0x96 */ { NULL, NULL, 0 },
1181/* 0x97 */ { NULL, NULL, 0 },
1182/* 0x98 */ { NULL, NULL, 0 },
1183/* 0x99 */ { NULL, NULL, 0 },
1184/* 0x9a */ { NULL, NULL, 0 },
1185/* 0x9b */ { NULL, NULL, 0 },
1186/* 0x9c */ { NULL, NULL, 0 },
1187/* 0x9d */ { NULL, NULL, 0 },
1188/* 0x9e */ { NULL, NULL, 0 },
1189/* 0x9f */ { NULL, NULL, 0 },
1190/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1191/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1192/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1193/* 0xa3 */ { NULL, NULL, 0 },
1194/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1195/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1196/* 0xa6 */ { NULL, NULL, 0 },
1197/* 0xa7 */ { NULL, NULL, 0 },
1198/* 0xa8 */ { NULL, NULL, 0 },
1199/* 0xa9 */ { NULL, NULL, 0 },
1200/* 0xaa */ { NULL, NULL, 0 },
1201/* 0xab */ { NULL, NULL, 0 },
1202/* 0xac */ { NULL, NULL, 0 },
1203/* 0xad */ { NULL, NULL, 0 },
1204/* 0xae */ { NULL, NULL, 0 },
1205/* 0xaf */ { NULL, NULL, 0 },
1206/* 0xb0 */ { NULL, NULL, 0 },
1207/* 0xb1 */ { NULL, NULL, 0 },
1208/* 0xb2 */ { NULL, NULL, 0 },
1209/* 0xb3 */ { NULL, NULL, 0 },
1210/* 0xb4 */ { NULL, NULL, 0 },
1211/* 0xb5 */ { NULL, NULL, 0 },
1212/* 0xb6 */ { NULL, NULL, 0 },
1213/* 0xb7 */ { NULL, NULL, 0 },
1214/* 0xb8 */ { NULL, NULL, 0 },
1215/* 0xb9 */ { NULL, NULL, 0 },
1216/* 0xba */ { NULL, NULL, 0 },
1217/* 0xbb */ { NULL, NULL, 0 },
1218/* 0xbc */ { NULL, NULL, 0 },
1219/* 0xbd */ { NULL, NULL, 0 },
1220/* 0xbe */ { NULL, NULL, 0 },
1221/* 0xbf */ { NULL, NULL, 0 },
1222/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1223/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1224/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1225/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1226/* 0xc4 */ { NULL, NULL, 0 },
1227/* 0xc5 */ { NULL, NULL, 0 },
1228/* 0xc6 */ { NULL, NULL, 0 },
1229/* 0xc7 */ { NULL, NULL, 0 },
1230/* 0xc8 */ { NULL, NULL, 0 },
1231/* 0xc9 */ { NULL, NULL, 0 },
1232/* 0xca */ { NULL, NULL, 0 },
1233/* 0xcb */ { NULL, NULL, 0 },
1234/* 0xcc */ { NULL, NULL, 0 },
1235/* 0xcd */ { NULL, NULL, 0 },
1236/* 0xce */ { NULL, NULL, 0 },
1237/* 0xcf */ { NULL, NULL, 0 },
1238/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1239/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1240/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1241/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1242/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1243/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1244/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1245/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1246/* 0xd8 */ { NULL, NULL, 0 },
1247/* 0xd9 */ { NULL, NULL, 0 },
1248/* 0xda */ { NULL, NULL, 0 },
1249/* 0xdb */ { NULL, NULL, 0 },
1250/* 0xdc */ { NULL, NULL, 0 },
1251/* 0xdd */ { NULL, NULL, 0 },
1252/* 0xde */ { NULL, NULL, 0 },
1253/* 0xdf */ { NULL, NULL, 0 },
1254/* 0xe0 */ { NULL, NULL, 0 },
1255/* 0xe1 */ { NULL, NULL, 0 },
1256/* 0xe2 */ { NULL, NULL, 0 },
1257/* 0xe3 */ { NULL, NULL, 0 },
1258/* 0xe4 */ { NULL, NULL, 0 },
1259/* 0xe5 */ { NULL, NULL, 0 },
1260/* 0xe6 */ { NULL, NULL, 0 },
1261/* 0xe7 */ { NULL, NULL, 0 },
1262/* 0xe8 */ { NULL, NULL, 0 },
1263/* 0xe9 */ { NULL, NULL, 0 },
1264/* 0xea */ { NULL, NULL, 0 },
1265/* 0xeb */ { NULL, NULL, 0 },
1266/* 0xec */ { NULL, NULL, 0 },
1267/* 0xed */ { NULL, NULL, 0 },
1268/* 0xee */ { NULL, NULL, 0 },
1269/* 0xef */ { NULL, NULL, 0 },
1270/* 0xf0 */ { NULL, NULL, 0 },
1271/* 0xf1 */ { NULL, NULL, 0 },
1272/* 0xf2 */ { NULL, NULL, 0 },
1273/* 0xf3 */ { NULL, NULL, 0 },
1274/* 0xf4 */ { NULL, NULL, 0 },
1275/* 0xf5 */ { NULL, NULL, 0 },
1276/* 0xf6 */ { NULL, NULL, 0 },
1277/* 0xf7 */ { NULL, NULL, 0 },
1278/* 0xf8 */ { NULL, NULL, 0 },
1279/* 0xf9 */ { NULL, NULL, 0 },
1280/* 0xfa */ { NULL, NULL, 0 },
1281/* 0xfb */ { NULL, NULL, 0 },
1282/* 0xfc */ { NULL, NULL, 0 },
1283/* 0xfd */ { NULL, NULL, 0 },
1284/* 0xfe */ { NULL, NULL, 0 },
1285/* 0xff */ { NULL, NULL, 0 }
1286
1287};
1288
1289/*******************************************************************
1290 allocate and initialize a reply packet
1291********************************************************************/
1292
1293static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1294 const char *inbuf, char **outbuf, uint8_t num_words,
1295 uint32_t num_bytes)
1296{
1297 /*
1298 * Protect against integer wrap
1299 */
1300 if ((num_bytes > 0xffffff)
1301 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1302 char *msg;
1303 if (asprintf(&msg, "num_bytes too large: %u",
1304 (unsigned)num_bytes) == -1) {
1305 msg = CONST_DISCARD(char *, "num_bytes too large");
1306 }
1307 smb_panic(msg);
1308 }
1309
1310 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1311 smb_size + num_words*2 + num_bytes);
1312 if (*outbuf == NULL) {
1313 return false;
1314 }
1315
1316 construct_reply_common(req, inbuf, *outbuf);
1317 srv_set_message(*outbuf, num_words, num_bytes, false);
1318 /*
1319 * Zero out the word area, the caller has to take care of the bcc area
1320 * himself
1321 */
1322 if (num_words != 0) {
1323 memset(*outbuf + smb_vwv0, 0, num_words*2);
1324 }
1325
1326 return true;
1327}
1328
1329void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1330{
1331 char *outbuf;
1332 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1333 num_bytes)) {
1334 smb_panic("could not allocate output buffer\n");
1335 }
1336 req->outbuf = (uint8_t *)outbuf;
1337}
1338
1339
1340/*******************************************************************
1341 Dump a packet to a file.
1342********************************************************************/
1343
1344static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1345{
1346 int fd, i;
1347 char *fname = NULL;
1348 if (DEBUGLEVEL < 50) {
1349 return;
1350 }
1351
1352 if (len < 4) len = smb_len(data)+4;
1353 for (i=1;i<100;i++) {
1354 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1355 type ? "req" : "resp") == -1) {
1356 return;
1357 }
1358 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1359 if (fd != -1 || errno != EEXIST) break;
1360 }
1361 if (fd != -1) {
1362 ssize_t ret = write(fd, data, len);
1363 if (ret != len)
1364 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1365 close(fd);
1366 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1367 }
1368 SAFE_FREE(fname);
1369}
1370
1371/****************************************************************************
1372 Prepare everything for calling the actual request function, and potentially
1373 call the request function via the "new" interface.
1374
1375 Return False if the "legacy" function needs to be called, everything is
1376 prepared.
1377
1378 Return True if we're done.
1379
1380 I know this API sucks, but it is the one with the least code change I could
1381 find.
1382****************************************************************************/
1383
1384static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1385{
1386 int flags;
1387 uint16 session_tag;
1388 connection_struct *conn = NULL;
1389 struct smbd_server_connection *sconn = req->sconn;
1390
1391 errno = 0;
1392
1393 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1394 * so subtract 4 from it. */
1395 if ((size < (smb_size - 4)) ||
1396 !valid_smb_header(req->inbuf)) {
1397 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1398 smb_len(req->inbuf)));
1399 exit_server_cleanly("Non-SMB packet");
1400 }
1401
1402 if (smb_messages[type].fn == NULL) {
1403 DEBUG(0,("Unknown message type %d!\n",type));
1404 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1405 reply_unknown_new(req, type);
1406 return NULL;
1407 }
1408
1409 flags = smb_messages[type].flags;
1410
1411 /* In share mode security we must ignore the vuid. */
1412 session_tag = (lp_security() == SEC_SHARE)
1413 ? UID_FIELD_INVALID : req->vuid;
1414 conn = req->conn;
1415
1416 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1417 (int)sys_getpid(), (unsigned long)conn));
1418
1419 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1420
1421 /* Ensure this value is replaced in the incoming packet. */
1422 SSVAL(req->inbuf,smb_uid,session_tag);
1423
1424 /*
1425 * Ensure the correct username is in current_user_info. This is a
1426 * really ugly bugfix for problems with multiple session_setup_and_X's
1427 * being done and allowing %U and %G substitutions to work correctly.
1428 * There is a reason this code is done here, don't move it unless you
1429 * know what you're doing... :-).
1430 * JRA.
1431 */
1432
1433 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1434 user_struct *vuser = NULL;
1435
1436 sconn->smb1.sessions.last_session_tag = session_tag;
1437 if(session_tag != UID_FIELD_INVALID) {
1438 vuser = get_valid_user_struct(sconn, session_tag);
1439 if (vuser) {
1440 set_current_user_info(
1441 vuser->session_info->sanitized_username,
1442 vuser->session_info->unix_name,
1443 vuser->session_info->info3->base.domain.string);
1444 }
1445 }
1446 }
1447
1448 /* Does this call need to be run as the connected user? */
1449 if (flags & AS_USER) {
1450
1451 /* Does this call need a valid tree connection? */
1452 if (!conn) {
1453 /*
1454 * Amazingly, the error code depends on the command
1455 * (from Samba4).
1456 */
1457 if (type == SMBntcreateX) {
1458 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1459 } else {
1460 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1461 }
1462 return NULL;
1463 }
1464
1465 if (!change_to_user(conn,session_tag)) {
1466 DEBUG(0, ("Error: Could not change to user. Removing "
1467 "deferred open, mid=%llu.\n",
1468 (unsigned long long)req->mid));
1469 reply_force_doserror(req, ERRSRV, ERRbaduid);
1470 return conn;
1471 }
1472
1473 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1474
1475 /* Does it need write permission? */
1476 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1477 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1478 return conn;
1479 }
1480
1481 /* IPC services are limited */
1482 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1483 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1484 return conn;
1485 }
1486 } else {
1487 /* This call needs to be run as root */
1488 change_to_root_user();
1489 }
1490
1491 /* load service specific parameters */
1492 if (conn) {
1493 if (req->encrypted) {
1494 conn->encrypted_tid = true;
1495 /* encrypted required from now on. */
1496 conn->encrypt_level = Required;
1497 } else if (ENCRYPTION_REQUIRED(conn)) {
1498 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1499 exit_server_cleanly("encryption required "
1500 "on connection");
1501 return conn;
1502 }
1503 }
1504
1505 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1506 (flags & (AS_USER|DO_CHDIR)
1507 ?True:False))) {
1508 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1509 return conn;
1510 }
1511 conn->num_smb_operations++;
1512 }
1513
1514 /* does this protocol need to be run as guest? */
1515 if ((flags & AS_GUEST)
1516 && (!change_to_guest() ||
1517 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1518 sconn->client_id.name,
1519 sconn->client_id.addr))) {
1520 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1521 return conn;
1522 }
1523
1524 smb_messages[type].fn(req);
1525 return req->conn;
1526}
1527
1528/****************************************************************************
1529 Construct a reply to the incoming packet.
1530****************************************************************************/
1531
1532static void construct_reply(struct smbd_server_connection *sconn,
1533 char *inbuf, int size, size_t unread_bytes,
1534 uint32_t seqnum, bool encrypted,
1535 struct smb_perfcount_data *deferred_pcd)
1536{
1537 connection_struct *conn;
1538 struct smb_request *req;
1539
1540 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1541 smb_panic("could not allocate smb_request");
1542 }
1543
1544 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1545 encrypted, seqnum)) {
1546 exit_server_cleanly("Invalid SMB request");
1547 }
1548
1549 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1550
1551 /* we popped this message off the queue - keep original perf data */
1552 if (deferred_pcd)
1553 req->pcd = *deferred_pcd;
1554 else {
1555 SMB_PERFCOUNT_START(&req->pcd);
1556 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1557 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1558 }
1559
1560 conn = switch_message(req->cmd, req, size);
1561
1562 if (req->unread_bytes) {
1563 /* writeX failed. drain socket. */
1564 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1565 req->unread_bytes) {
1566 smb_panic("failed to drain pending bytes");
1567 }
1568 req->unread_bytes = 0;
1569 }
1570
1571 if (req->done) {
1572 TALLOC_FREE(req);
1573 return;
1574 }
1575
1576 if (req->outbuf == NULL) {
1577 return;
1578 }
1579
1580 if (CVAL(req->outbuf,0) == 0) {
1581 show_msg((char *)req->outbuf);
1582 }
1583
1584 if (!srv_send_smb(req->sconn,
1585 (char *)req->outbuf,
1586 true, req->seqnum+1,
1587 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1588 &req->pcd)) {
1589 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1590 }
1591
1592 TALLOC_FREE(req);
1593
1594 return;
1595}
1596
1597/****************************************************************************
1598 Process an smb from the client
1599****************************************************************************/
1600static void process_smb(struct smbd_server_connection *sconn,
1601 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1602 uint32_t seqnum, bool encrypted,
1603 struct smb_perfcount_data *deferred_pcd)
1604{
1605 int msg_type = CVAL(inbuf,0);
1606
1607 DO_PROFILE_INC(smb_count);
1608
1609 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1610 smb_len(inbuf) ) );
1611 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1612 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1613
1614 if (msg_type != 0) {
1615 /*
1616 * NetBIOS session request, keepalive, etc.
1617 */
1618 reply_special(sconn, (char *)inbuf, nread);
1619 goto done;
1620 }
1621
1622 if (sconn->using_smb2) {
1623 /* At this point we're not really using smb2,
1624 * we make the decision here.. */
1625 if (smbd_is_smb2_header(inbuf, nread)) {
1626 smbd_smb2_first_negprot(sconn, inbuf, nread);
1627 return;
1628 } else if (nread >= smb_size && valid_smb_header(inbuf)
1629 && CVAL(inbuf, smb_com) != 0x72) {
1630 /* This is a non-negprot SMB1 packet.
1631 Disable SMB2 from now on. */
1632 sconn->using_smb2 = false;
1633 }
1634 }
1635
1636 show_msg((char *)inbuf);
1637
1638 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1639 encrypted, deferred_pcd);
1640 sconn->trans_num++;
1641
1642done:
1643 sconn->num_requests++;
1644
1645 /* The timeout_processing function isn't run nearly
1646 often enough to implement 'max log size' without
1647 overrunning the size of the file by many megabytes.
1648 This is especially true if we are running at debug
1649 level 10. Checking every 50 SMBs is a nice
1650 tradeoff of performance vs log file size overrun. */
1651
1652 if ((sconn->num_requests % 50) == 0 &&
1653 need_to_check_log_size()) {
1654 change_to_root_user();
1655 check_log_size();
1656 }
1657}
1658
1659/****************************************************************************
1660 Return a string containing the function name of a SMB command.
1661****************************************************************************/
1662
1663const char *smb_fn_name(int type)
1664{
1665 const char *unknown_name = "SMBunknown";
1666
1667 if (smb_messages[type].name == NULL)
1668 return(unknown_name);
1669
1670 return(smb_messages[type].name);
1671}
1672
1673/****************************************************************************
1674 Helper functions for contruct_reply.
1675****************************************************************************/
1676
1677void add_to_common_flags2(uint32 v)
1678{
1679 common_flags2 |= v;
1680}
1681
1682void remove_from_common_flags2(uint32 v)
1683{
1684 common_flags2 &= ~v;
1685}
1686
1687static void construct_reply_common(struct smb_request *req, const char *inbuf,
1688 char *outbuf)
1689{
1690 srv_set_message(outbuf,0,0,false);
1691
1692 SCVAL(outbuf, smb_com, req->cmd);
1693 SIVAL(outbuf,smb_rcls,0);
1694 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1695 SSVAL(outbuf,smb_flg2,
1696 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1697 common_flags2);
1698 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1699
1700 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1701 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1702 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1703 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1704}
1705
1706void construct_reply_common_req(struct smb_request *req, char *outbuf)
1707{
1708 construct_reply_common(req, (char *)req->inbuf, outbuf);
1709}
1710
1711/*
1712 * How many bytes have we already accumulated up to the current wct field
1713 * offset?
1714 */
1715
1716size_t req_wct_ofs(struct smb_request *req)
1717{
1718 size_t buf_size;
1719
1720 if (req->chain_outbuf == NULL) {
1721 return smb_wct - 4;
1722 }
1723 buf_size = talloc_get_size(req->chain_outbuf);
1724 if ((buf_size % 4) != 0) {
1725 buf_size += (4 - (buf_size % 4));
1726 }
1727 return buf_size - 4;
1728}
1729
1730/*
1731 * Hack around reply_nterror & friends not being aware of chained requests,
1732 * generating illegal (i.e. wct==0) chain replies.
1733 */
1734
1735static void fixup_chain_error_packet(struct smb_request *req)
1736{
1737 uint8_t *outbuf = req->outbuf;
1738 req->outbuf = NULL;
1739 reply_outbuf(req, 2, 0);
1740 memcpy(req->outbuf, outbuf, smb_wct);
1741 TALLOC_FREE(outbuf);
1742 SCVAL(req->outbuf, smb_vwv0, 0xff);
1743}
1744
1745/**
1746 * @brief Find the smb_cmd offset of the last command pushed
1747 * @param[in] buf The buffer we're building up
1748 * @retval Where can we put our next andx cmd?
1749 *
1750 * While chaining requests, the "next" request we're looking at needs to put
1751 * its SMB_Command before the data the previous request already built up added
1752 * to the chain. Find the offset to the place where we have to put our cmd.
1753 */
1754
1755static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1756{
1757 uint8_t cmd;
1758 size_t ofs;
1759
1760 cmd = CVAL(buf, smb_com);
1761
1762 SMB_ASSERT(is_andx_req(cmd));
1763
1764 ofs = smb_vwv0;
1765
1766 while (CVAL(buf, ofs) != 0xff) {
1767
1768 if (!is_andx_req(CVAL(buf, ofs))) {
1769 return false;
1770 }
1771
1772 /*
1773 * ofs is from start of smb header, so add the 4 length
1774 * bytes. The next cmd is right after the wct field.
1775 */
1776 ofs = SVAL(buf, ofs+2) + 4 + 1;
1777
1778 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1779 }
1780
1781 *pofs = ofs;
1782 return true;
1783}
1784
1785/**
1786 * @brief Do the smb chaining at a buffer level
1787 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1788 * @param[in] smb_command The command that we want to issue
1789 * @param[in] wct How many words?
1790 * @param[in] vwv The words, already in network order
1791 * @param[in] bytes_alignment How shall we align "bytes"?
1792 * @param[in] num_bytes How many bytes?
1793 * @param[in] bytes The data the request ships
1794 *
1795 * smb_splice_chain() adds the vwv and bytes to the request already present in
1796 * *poutbuf.
1797 */
1798
1799static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1800 uint8_t wct, const uint16_t *vwv,
1801 size_t bytes_alignment,
1802 uint32_t num_bytes, const uint8_t *bytes)
1803{
1804 uint8_t *outbuf;
1805 size_t old_size, new_size;
1806 size_t ofs;
1807 size_t chain_padding = 0;
1808 size_t bytes_padding = 0;
1809 bool first_request;
1810
1811 old_size = talloc_get_size(*poutbuf);
1812
1813 /*
1814 * old_size == smb_wct means we're pushing the first request in for
1815 * libsmb/
1816 */
1817
1818 first_request = (old_size == smb_wct);
1819
1820 if (!first_request && ((old_size % 4) != 0)) {
1821 /*
1822 * Align the wct field of subsequent requests to a 4-byte
1823 * boundary
1824 */
1825 chain_padding = 4 - (old_size % 4);
1826 }
1827
1828 /*
1829 * After the old request comes the new wct field (1 byte), the vwv's
1830 * and the num_bytes field. After at we might need to align the bytes
1831 * given to us to "bytes_alignment", increasing the num_bytes value.
1832 */
1833
1834 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1835
1836 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1837 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1838 }
1839
1840 new_size += bytes_padding + num_bytes;
1841
1842 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1843 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1844 (unsigned)new_size));
1845 return false;
1846 }
1847
1848 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1849 if (outbuf == NULL) {
1850 DEBUG(0, ("talloc failed\n"));
1851 return false;
1852 }
1853 *poutbuf = outbuf;
1854
1855 if (first_request) {
1856 SCVAL(outbuf, smb_com, smb_command);
1857 } else {
1858 size_t andx_cmd_ofs;
1859
1860 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1861 DEBUG(1, ("invalid command chain\n"));
1862 *poutbuf = TALLOC_REALLOC_ARRAY(
1863 NULL, *poutbuf, uint8_t, old_size);
1864 return false;
1865 }
1866
1867 if (chain_padding != 0) {
1868 memset(outbuf + old_size, 0, chain_padding);
1869 old_size += chain_padding;
1870 }
1871
1872 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1873 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1874 }
1875
1876 ofs = old_size;
1877
1878 /*
1879 * Push the chained request:
1880 *
1881 * wct field
1882 */
1883
1884 SCVAL(outbuf, ofs, wct);
1885 ofs += 1;
1886
1887 /*
1888 * vwv array
1889 */
1890
1891 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1892 ofs += sizeof(uint16_t) * wct;
1893
1894 /*
1895 * bcc (byte count)
1896 */
1897
1898 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1899 ofs += sizeof(uint16_t);
1900
1901 /*
1902 * padding
1903 */
1904
1905 if (bytes_padding != 0) {
1906 memset(outbuf + ofs, 0, bytes_padding);
1907 ofs += bytes_padding;
1908 }
1909
1910 /*
1911 * The bytes field
1912 */
1913
1914 memcpy(outbuf + ofs, bytes, num_bytes);
1915
1916 return true;
1917}
1918
1919/****************************************************************************
1920 Construct a chained reply and add it to the already made reply
1921****************************************************************************/
1922
1923void chain_reply(struct smb_request *req)
1924{
1925 size_t smblen = smb_len(req->inbuf);
1926 size_t already_used, length_needed;
1927 uint8_t chain_cmd;
1928 uint32_t chain_offset; /* uint32_t to avoid overflow */
1929
1930 uint8_t wct;
1931 uint16_t *vwv;
1932 uint16_t buflen;
1933 uint8_t *buf;
1934
1935 if (IVAL(req->outbuf, smb_rcls) != 0) {
1936 fixup_chain_error_packet(req);
1937 }
1938
1939 /*
1940 * Any of the AndX requests and replies have at least a wct of
1941 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1942 * beginning of the SMB header to the next wct field.
1943 *
1944 * None of the AndX requests put anything valuable in vwv[0] and [1],
1945 * so we can overwrite it here to form the chain.
1946 */
1947
1948 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
1949 if (req->chain_outbuf == NULL) {
1950 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1951 req, req->outbuf, uint8_t,
1952 smb_len(req->outbuf) + 4);
1953 if (req->chain_outbuf == NULL) {
1954 smb_panic("talloc failed");
1955 }
1956 }
1957 req->outbuf = NULL;
1958 goto error;
1959 }
1960
1961 /*
1962 * Here we assume that this is the end of the chain. For that we need
1963 * to set "next command" to 0xff and the offset to 0. If we later find
1964 * more commands in the chain, this will be overwritten again.
1965 */
1966
1967 SCVAL(req->outbuf, smb_vwv0, 0xff);
1968 SCVAL(req->outbuf, smb_vwv0+1, 0);
1969 SSVAL(req->outbuf, smb_vwv1, 0);
1970
1971 if (req->chain_outbuf == NULL) {
1972 /*
1973 * In req->chain_outbuf we collect all the replies. Start the
1974 * chain by copying in the first reply.
1975 *
1976 * We do the realloc because later on we depend on
1977 * talloc_get_size to determine the length of
1978 * chain_outbuf. The reply_xxx routines might have
1979 * over-allocated (reply_pipe_read_and_X used to be such an
1980 * example).
1981 */
1982 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
1983 req, req->outbuf, uint8_t,
1984 smb_len_large(req->outbuf) + 4);
1985 if (req->chain_outbuf == NULL) {
1986 smb_panic("talloc failed");
1987 }
1988 req->outbuf = NULL;
1989 } else {
1990 /*
1991 * Update smb headers where subsequent chained commands
1992 * may have updated them.
1993 */
1994 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
1995 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
1996
1997 if (!smb_splice_chain(&req->chain_outbuf,
1998 CVAL(req->outbuf, smb_com),
1999 CVAL(req->outbuf, smb_wct),
2000 (uint16_t *)(req->outbuf + smb_vwv),
2001 0, smb_buflen(req->outbuf),
2002 (uint8_t *)smb_buf(req->outbuf))) {
2003 goto error;
2004 }
2005 TALLOC_FREE(req->outbuf);
2006 }
2007
2008 /*
2009 * We use the old request's vwv field to grab the next chained command
2010 * and offset into the chained fields.
2011 */
2012
2013 chain_cmd = CVAL(req->vwv+0, 0);
2014 chain_offset = SVAL(req->vwv+1, 0);
2015
2016 if (chain_cmd == 0xff) {
2017 /*
2018 * End of chain, no more requests from the client. So ship the
2019 * replies.
2020 */
2021 smb_setlen((char *)(req->chain_outbuf),
2022 talloc_get_size(req->chain_outbuf) - 4);
2023
2024 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2025 true, req->seqnum+1,
2026 IS_CONN_ENCRYPTED(req->conn)
2027 ||req->encrypted,
2028 &req->pcd)) {
2029 exit_server_cleanly("chain_reply: srv_send_smb "
2030 "failed.");
2031 }
2032 TALLOC_FREE(req->chain_outbuf);
2033 req->done = true;
2034 return;
2035 }
2036
2037 /* add a new perfcounter for this element of chain */
2038 SMB_PERFCOUNT_ADD(&req->pcd);
2039 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2040 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2041
2042 /*
2043 * Check if the client tries to fool us. The chain offset
2044 * needs to point beyond the current request in the chain, it
2045 * needs to strictly grow. Otherwise we might be tricked into
2046 * an endless loop always processing the same request over and
2047 * over again. We used to assume that vwv and the byte buffer
2048 * array in a chain are always attached, but OS/2 the
2049 * Write&X/Read&X chain puts the Read&X vwv array right behind
2050 * the Write&X vwv chain. The Write&X bcc array is put behind
2051 * the Read&X vwv array. So now we check whether the chain
2052 * offset points strictly behind the previous vwv
2053 * array. req->buf points right after the vwv array of the
2054 * previous request. See
2055 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2056 * information.
2057 */
2058
2059 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2060 if (chain_offset <= already_used) {
2061 goto error;
2062 }
2063
2064 /*
2065 * Next check: Make sure the chain offset does not point beyond the
2066 * overall smb request length.
2067 */
2068
2069 length_needed = chain_offset+1; /* wct */
2070 if (length_needed > smblen) {
2071 goto error;
2072 }
2073
2074 /*
2075 * Now comes the pointer magic. Goal here is to set up req->vwv and
2076 * req->buf correctly again to be able to call the subsequent
2077 * switch_message(). The chain offset (the former vwv[1]) points at
2078 * the new wct field.
2079 */
2080
2081 wct = CVAL(smb_base(req->inbuf), chain_offset);
2082
2083 /*
2084 * Next consistency check: Make the new vwv array fits in the overall
2085 * smb request.
2086 */
2087
2088 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2089 if (length_needed > smblen) {
2090 goto error;
2091 }
2092 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2093
2094 /*
2095 * Now grab the new byte buffer....
2096 */
2097
2098 buflen = SVAL(vwv+wct, 0);
2099
2100 /*
2101 * .. and check that it fits.
2102 */
2103
2104 length_needed += buflen;
2105 if (length_needed > smblen) {
2106 goto error;
2107 }
2108 buf = (uint8_t *)(vwv+wct+1);
2109
2110 req->cmd = chain_cmd;
2111 req->wct = wct;
2112 req->vwv = vwv;
2113 req->buflen = buflen;
2114 req->buf = buf;
2115
2116 switch_message(chain_cmd, req, smblen);
2117
2118 if (req->outbuf == NULL) {
2119 /*
2120 * This happens if the chained command has suspended itself or
2121 * if it has called srv_send_smb() itself.
2122 */
2123 return;
2124 }
2125
2126 /*
2127 * We end up here if the chained command was not itself chained or
2128 * suspended, but for example a close() command. We now need to splice
2129 * the chained commands' outbuf into the already built up chain_outbuf
2130 * and ship the result.
2131 */
2132 goto done;
2133
2134 error:
2135 /*
2136 * We end up here if there's any error in the chain syntax. Report a
2137 * DOS error, just like Windows does.
2138 */
2139 reply_force_doserror(req, ERRSRV, ERRerror);
2140 fixup_chain_error_packet(req);
2141
2142 done:
2143 /*
2144 * This scary statement intends to set the
2145 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2146 * to the value req->outbuf carries
2147 */
2148 SSVAL(req->chain_outbuf, smb_flg2,
2149 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2150 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2151
2152 /*
2153 * Transfer the error codes from the subrequest to the main one
2154 */
2155 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2156 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2157
2158 if (!smb_splice_chain(&req->chain_outbuf,
2159 CVAL(req->outbuf, smb_com),
2160 CVAL(req->outbuf, smb_wct),
2161 (uint16_t *)(req->outbuf + smb_vwv),
2162 0, smb_buflen(req->outbuf),
2163 (uint8_t *)smb_buf(req->outbuf))) {
2164 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2165 }
2166 TALLOC_FREE(req->outbuf);
2167
2168 smb_setlen((char *)(req->chain_outbuf),
2169 talloc_get_size(req->chain_outbuf) - 4);
2170
2171 show_msg((char *)(req->chain_outbuf));
2172
2173 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2174 true, req->seqnum+1,
2175 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2176 &req->pcd)) {
2177 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2178 }
2179 TALLOC_FREE(req->chain_outbuf);
2180 req->done = true;
2181}
2182
2183/****************************************************************************
2184 Check if services need reloading.
2185****************************************************************************/
2186
2187static void check_reload(struct smbd_server_connection *sconn, time_t t)
2188{
2189
2190 if (last_smb_conf_reload_time == 0) {
2191 last_smb_conf_reload_time = t;
2192 }
2193
2194 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2195 reload_services(sconn->msg_ctx, sconn->sock, True);
2196 last_smb_conf_reload_time = t;
2197 }
2198}
2199
2200static bool fd_is_readable(int fd)
2201{
2202 int ret, revents;
2203
2204 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2205
2206 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2207
2208}
2209
2210static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2211{
2212 /* TODO: make write nonblocking */
2213}
2214
2215static void smbd_server_connection_read_handler(
2216 struct smbd_server_connection *conn, int fd)
2217{
2218 uint8_t *inbuf = NULL;
2219 size_t inbuf_len = 0;
2220 size_t unread_bytes = 0;
2221 bool encrypted = false;
2222 TALLOC_CTX *mem_ctx = talloc_tos();
2223 NTSTATUS status;
2224 uint32_t seqnum;
2225
2226 bool from_client = (conn->sock == fd);
2227
2228 if (from_client) {
2229 smbd_lock_socket(conn);
2230
2231 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2232 DEBUG(10,("the echo listener was faster\n"));
2233 smbd_unlock_socket(conn);
2234 return;
2235 }
2236
2237 /* TODO: make this completely nonblocking */
2238 status = receive_smb_talloc(mem_ctx, conn, fd,
2239 (char **)(void *)&inbuf,
2240 0, /* timeout */
2241 &unread_bytes,
2242 &encrypted,
2243 &inbuf_len, &seqnum,
2244 false /* trusted channel */);
2245 smbd_unlock_socket(conn);
2246 } else {
2247 /* TODO: make this completely nonblocking */
2248 status = receive_smb_talloc(mem_ctx, conn, fd,
2249 (char **)(void *)&inbuf,
2250 0, /* timeout */
2251 &unread_bytes,
2252 &encrypted,
2253 &inbuf_len, &seqnum,
2254 true /* trusted channel */);
2255 }
2256
2257 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2258 goto process;
2259 }
2260 if (NT_STATUS_IS_ERR(status)) {
2261 exit_server_cleanly("failed to receive smb request");
2262 }
2263 if (!NT_STATUS_IS_OK(status)) {
2264 return;
2265 }
2266
2267process:
2268 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2269 seqnum, encrypted, NULL);
2270}
2271
2272static void smbd_server_connection_handler(struct event_context *ev,
2273 struct fd_event *fde,
2274 uint16_t flags,
2275 void *private_data)
2276{
2277 struct smbd_server_connection *conn = talloc_get_type(private_data,
2278 struct smbd_server_connection);
2279
2280 if (flags & EVENT_FD_WRITE) {
2281 smbd_server_connection_write_handler(conn);
2282 return;
2283 }
2284 if (flags & EVENT_FD_READ) {
2285 smbd_server_connection_read_handler(conn, conn->sock);
2286 return;
2287 }
2288}
2289
2290static void smbd_server_echo_handler(struct event_context *ev,
2291 struct fd_event *fde,
2292 uint16_t flags,
2293 void *private_data)
2294{
2295 struct smbd_server_connection *conn = talloc_get_type(private_data,
2296 struct smbd_server_connection);
2297
2298 if (flags & EVENT_FD_WRITE) {
2299 smbd_server_connection_write_handler(conn);
2300 return;
2301 }
2302 if (flags & EVENT_FD_READ) {
2303 smbd_server_connection_read_handler(
2304 conn, conn->smb1.echo_handler.trusted_fd);
2305 return;
2306 }
2307}
2308
2309/****************************************************************************
2310received when we should release a specific IP
2311****************************************************************************/
2312static void release_ip(const char *ip, void *priv)
2313{
2314 const char *addr = (const char *)priv;
2315 const char *p = addr;
2316
2317 if (strncmp("::ffff:", addr, 7) == 0) {
2318 p = addr + 7;
2319 }
2320
2321 DEBUG(10, ("Got release IP message for %s, "
2322 "our address is %s\n", ip, p));
2323
2324 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2325 /* we can't afford to do a clean exit - that involves
2326 database writes, which would potentially mean we
2327 are still running after the failover has finished -
2328 we have to get rid of this process ID straight
2329 away */
2330 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2331 ip));
2332 /* note we must exit with non-zero status so the unclean handler gets
2333 called in the parent, so that the brl database is tickled */
2334 _exit(1);
2335 }
2336}
2337
2338static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2339 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2340{
2341 struct smbd_server_connection *sconn = talloc_get_type_abort(
2342 private_data, struct smbd_server_connection);
2343
2344 release_ip((char *)data->data, sconn->client_id.addr);
2345}
2346
2347#ifdef CLUSTER_SUPPORT
2348static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2349 struct sockaddr_storage *client)
2350{
2351 socklen_t length;
2352 length = sizeof(*server);
2353 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2354 return -1;
2355 }
2356 length = sizeof(*client);
2357 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2358 return -1;
2359 }
2360 return 0;
2361}
2362#endif
2363
2364/*
2365 * Send keepalive packets to our client
2366 */
2367static bool keepalive_fn(const struct timeval *now, void *private_data)
2368{
2369 struct smbd_server_connection *sconn = smbd_server_conn;
2370 bool ret;
2371
2372 if (sconn->using_smb2) {
2373 /* Don't do keepalives on an SMB2 connection. */
2374 return false;
2375 }
2376
2377 smbd_lock_socket(smbd_server_conn);
2378 ret = send_keepalive(sconn->sock);
2379 smbd_unlock_socket(smbd_server_conn);
2380
2381 if (!ret) {
2382 char addr[INET6_ADDRSTRLEN];
2383 /*
2384 * Try and give an error message saying what
2385 * client failed.
2386 */
2387 DEBUG(0, ("send_keepalive failed for client %s. "
2388 "Error %s - exiting\n",
2389 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2390 strerror(errno)));
2391 return False;
2392 }
2393 return True;
2394}
2395
2396/*
2397 * Do the recurring check if we're idle
2398 */
2399static bool deadtime_fn(const struct timeval *now, void *private_data)
2400{
2401 struct smbd_server_connection *sconn =
2402 (struct smbd_server_connection *)private_data;
2403
2404 if ((conn_num_open(sconn) == 0)
2405 || (conn_idle_all(sconn, now->tv_sec))) {
2406 DEBUG( 2, ( "Closing idle connection\n" ) );
2407 messaging_send(sconn->msg_ctx,
2408 messaging_server_id(sconn->msg_ctx),
2409 MSG_SHUTDOWN, &data_blob_null);
2410 return False;
2411 }
2412
2413 return True;
2414}
2415
2416/*
2417 * Do the recurring log file and smb.conf reload checks.
2418 */
2419
2420static bool housekeeping_fn(const struct timeval *now, void *private_data)
2421{
2422 struct smbd_server_connection *sconn = talloc_get_type_abort(
2423 private_data, struct smbd_server_connection);
2424
2425 DEBUG(5, ("housekeeping\n"));
2426
2427 change_to_root_user();
2428
2429 /* update printer queue caches if necessary */
2430 update_monitored_printq_cache(sconn->msg_ctx);
2431
2432 /* check if we need to reload services */
2433 check_reload(sconn, time_mono(NULL));
2434
2435 /* Change machine password if neccessary. */
2436 attempt_machine_password_change();
2437
2438 /*
2439 * Force a log file check.
2440 */
2441 force_check_log_size();
2442 check_log_size();
2443 return true;
2444}
2445
2446static int create_unlink_tmp(const char *dir)
2447{
2448 char *fname;
2449 int fd;
2450
2451 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2452 if (fname == NULL) {
2453 errno = ENOMEM;
2454 return -1;
2455 }
2456 fd = mkstemp(fname);
2457 if (fd == -1) {
2458 TALLOC_FREE(fname);
2459 return -1;
2460 }
2461 if (unlink(fname) == -1) {
2462 int sys_errno = errno;
2463 close(fd);
2464 TALLOC_FREE(fname);
2465 errno = sys_errno;
2466 return -1;
2467 }
2468 TALLOC_FREE(fname);
2469 return fd;
2470}
2471
2472struct smbd_echo_state {
2473 struct tevent_context *ev;
2474 struct iovec *pending;
2475 struct smbd_server_connection *sconn;
2476 int parent_pipe;
2477
2478 struct tevent_fd *parent_fde;
2479
2480 struct tevent_fd *read_fde;
2481 struct tevent_req *write_req;
2482};
2483
2484static void smbd_echo_writer_done(struct tevent_req *req);
2485
2486static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2487{
2488 int num_pending;
2489
2490 if (state->write_req != NULL) {
2491 return;
2492 }
2493
2494 num_pending = talloc_array_length(state->pending);
2495 if (num_pending == 0) {
2496 return;
2497 }
2498
2499 state->write_req = writev_send(state, state->ev, NULL,
2500 state->parent_pipe, false,
2501 state->pending, num_pending);
2502 if (state->write_req == NULL) {
2503 DEBUG(1, ("writev_send failed\n"));
2504 exit(1);
2505 }
2506
2507 talloc_steal(state->write_req, state->pending);
2508 state->pending = NULL;
2509
2510 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2511 state);
2512}
2513
2514static void smbd_echo_writer_done(struct tevent_req *req)
2515{
2516 struct smbd_echo_state *state = tevent_req_callback_data(
2517 req, struct smbd_echo_state);
2518 ssize_t written;
2519 int err;
2520
2521 written = writev_recv(req, &err);
2522 TALLOC_FREE(req);
2523 state->write_req = NULL;
2524 if (written == -1) {
2525 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2526 exit(1);
2527 }
2528 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2529 smbd_echo_activate_writer(state);
2530}
2531
2532static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2533 uint32_t seqnum)
2534{
2535 struct smb_request req;
2536 uint16_t num_replies;
2537 size_t out_len;
2538 char *outbuf;
2539 bool ok;
2540
2541 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2542 DEBUG(10, ("Got netbios keepalive\n"));
2543 /*
2544 * Just swallow it
2545 */
2546 return true;
2547 }
2548
2549 if (inbuf_len < smb_size) {
2550 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2551 return false;
2552 }
2553 if (!valid_smb_header(inbuf)) {
2554 DEBUG(10, ("Got invalid SMB header\n"));
2555 return false;
2556 }
2557
2558 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2559 seqnum)) {
2560 return false;
2561 }
2562 req.inbuf = inbuf;
2563
2564 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2565 smb_messages[req.cmd].name
2566 ? smb_messages[req.cmd].name : "unknown"));
2567
2568 if (req.cmd != SMBecho) {
2569 return false;
2570 }
2571 if (req.wct < 1) {
2572 return false;
2573 }
2574
2575 num_replies = SVAL(req.vwv+0, 0);
2576 if (num_replies != 1) {
2577 /* Not a Windows "Hey, you're still there?" request */
2578 return false;
2579 }
2580
2581 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2582 1, req.buflen)) {
2583 DEBUG(10, ("create_outbuf failed\n"));
2584 return false;
2585 }
2586 req.outbuf = (uint8_t *)outbuf;
2587
2588 SSVAL(req.outbuf, smb_vwv0, num_replies);
2589
2590 if (req.buflen > 0) {
2591 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2592 }
2593
2594 out_len = smb_len(req.outbuf) + 4;
2595
2596 ok = srv_send_smb(req.sconn,
2597 (char *)outbuf,
2598 true, seqnum+1,
2599 false, &req.pcd);
2600 TALLOC_FREE(outbuf);
2601 if (!ok) {
2602 exit(1);
2603 }
2604
2605 return true;
2606}
2607
2608static void smbd_echo_exit(struct tevent_context *ev,
2609 struct tevent_fd *fde, uint16_t flags,
2610 void *private_data)
2611{
2612 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2613 exit(0);
2614}
2615
2616static void smbd_echo_reader(struct tevent_context *ev,
2617 struct tevent_fd *fde, uint16_t flags,
2618 void *private_data)
2619{
2620 struct smbd_echo_state *state = talloc_get_type_abort(
2621 private_data, struct smbd_echo_state);
2622 struct smbd_server_connection *sconn = state->sconn;
2623 size_t unread, num_pending;
2624 NTSTATUS status;
2625 struct iovec *tmp;
2626 size_t iov_len;
2627 uint32_t seqnum = 0;
2628 bool reply;
2629 bool ok;
2630 bool encrypted = false;
2631
2632 smb_msleep(1000);
2633
2634 ok = smbd_lock_socket_internal(sconn);
2635 if (!ok) {
2636 DEBUG(0, ("%s: failed to lock socket\n",
2637 __location__));
2638 exit(1);
2639 }
2640
2641 if (!fd_is_readable(sconn->sock)) {
2642 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2643 (int)sys_getpid()));
2644 ok = smbd_unlock_socket_internal(sconn);
2645 if (!ok) {
2646 DEBUG(1, ("%s: failed to unlock socket in\n",
2647 __location__));
2648 exit(1);
2649 }
2650 return;
2651 }
2652
2653 num_pending = talloc_array_length(state->pending);
2654 tmp = talloc_realloc(state, state->pending, struct iovec,
2655 num_pending+1);
2656 if (tmp == NULL) {
2657 DEBUG(1, ("talloc_realloc failed\n"));
2658 exit(1);
2659 }
2660 state->pending = tmp;
2661
2662 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2663
2664 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2665 (char **)(void *)&state->pending[num_pending].iov_base,
2666 0 /* timeout */,
2667 &unread,
2668 &encrypted,
2669 &iov_len,
2670 &seqnum,
2671 false /* trusted_channel*/);
2672 if (!NT_STATUS_IS_OK(status)) {
2673 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2674 (int)sys_getpid(), nt_errstr(status)));
2675 exit(1);
2676 }
2677 state->pending[num_pending].iov_len = iov_len;
2678
2679 ok = smbd_unlock_socket_internal(sconn);
2680 if (!ok) {
2681 DEBUG(1, ("%s: failed to unlock socket in\n",
2682 __location__));
2683 exit(1);
2684 }
2685
2686 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2687 state->pending[num_pending].iov_len,
2688 seqnum);
2689 if (reply) {
2690 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2691 /* no check, shrinking by some bytes does not fail */
2692 state->pending = talloc_realloc(state, state->pending,
2693 struct iovec,
2694 num_pending);
2695 return;
2696 }
2697
2698 if (state->pending[num_pending].iov_len >= smb_size) {
2699 /*
2700 * place the seqnum in the packet so that the main process
2701 * can reply with signing
2702 */
2703 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2704 smb_ss_field, seqnum);
2705 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2706 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2707 }
2708
2709 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2710 smbd_echo_activate_writer(state);
2711}
2712
2713static void smbd_echo_loop(struct smbd_server_connection *sconn,
2714 int parent_pipe)
2715{
2716 struct smbd_echo_state *state;
2717
2718 state = talloc_zero(sconn, struct smbd_echo_state);
2719 if (state == NULL) {
2720 DEBUG(1, ("talloc failed\n"));
2721 return;
2722 }
2723 state->sconn = sconn;
2724 state->parent_pipe = parent_pipe;
2725 state->ev = s3_tevent_context_init(state);
2726 if (state->ev == NULL) {
2727 DEBUG(1, ("tevent_context_init failed\n"));
2728 TALLOC_FREE(state);
2729 return;
2730 }
2731 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2732 TEVENT_FD_READ, smbd_echo_exit,
2733 state);
2734 if (state->parent_fde == NULL) {
2735 DEBUG(1, ("tevent_add_fd failed\n"));
2736 TALLOC_FREE(state);
2737 return;
2738 }
2739 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2740 TEVENT_FD_READ, smbd_echo_reader,
2741 state);
2742 if (state->read_fde == NULL) {
2743 DEBUG(1, ("tevent_add_fd failed\n"));
2744 TALLOC_FREE(state);
2745 return;
2746 }
2747
2748 while (true) {
2749 if (tevent_loop_once(state->ev) == -1) {
2750 DEBUG(1, ("tevent_loop_once failed: %s\n",
2751 strerror(errno)));
2752 break;
2753 }
2754 }
2755 TALLOC_FREE(state);
2756}
2757
2758/*
2759 * Handle SMBecho requests in a forked child process
2760 */
2761bool fork_echo_handler(struct smbd_server_connection *sconn)
2762{
2763 int listener_pipe[2];
2764 int res;
2765 pid_t child;
2766
2767 res = pipe(listener_pipe);
2768 if (res == -1) {
2769 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2770 return false;
2771 }
2772 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2773 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2774 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2775 goto fail;
2776 }
2777
2778 child = sys_fork();
2779 if (child == 0) {
2780 NTSTATUS status;
2781
2782 close(listener_pipe[0]);
2783 set_blocking(listener_pipe[1], false);
2784
2785 status = reinit_after_fork(sconn->msg_ctx,
2786 smbd_event_context(),
2787 procid_self(), false);
2788 if (!NT_STATUS_IS_OK(status)) {
2789 DEBUG(1, ("reinit_after_fork failed: %s\n",
2790 nt_errstr(status)));
2791 exit(1);
2792 }
2793 smbd_echo_loop(sconn, listener_pipe[1]);
2794 exit(0);
2795 }
2796 close(listener_pipe[1]);
2797 listener_pipe[1] = -1;
2798 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2799
2800 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2801
2802 /*
2803 * Without smb signing this is the same as the normal smbd
2804 * listener. This needs to change once signing comes in.
2805 */
2806 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2807 sconn,
2808 sconn->smb1.echo_handler.trusted_fd,
2809 EVENT_FD_READ,
2810 smbd_server_echo_handler,
2811 sconn);
2812 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2813 DEBUG(1, ("event_add_fd failed\n"));
2814 goto fail;
2815 }
2816
2817 return true;
2818
2819fail:
2820 if (listener_pipe[0] != -1) {
2821 close(listener_pipe[0]);
2822 }
2823 if (listener_pipe[1] != -1) {
2824 close(listener_pipe[1]);
2825 }
2826 sconn->smb1.echo_handler.trusted_fd = -1;
2827 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2828 close(sconn->smb1.echo_handler.socket_lock_fd);
2829 }
2830 sconn->smb1.echo_handler.trusted_fd = -1;
2831 sconn->smb1.echo_handler.socket_lock_fd = -1;
2832 return false;
2833}
2834
2835#if CLUSTER_SUPPORT
2836
2837static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2838 struct sockaddr_storage *srv,
2839 struct sockaddr_storage *clnt)
2840{
2841 struct ctdbd_connection *cconn;
2842 char tmp_addr[INET6_ADDRSTRLEN];
2843 char *addr;
2844
2845 cconn = messaging_ctdbd_connection();
2846 if (cconn == NULL) {
2847 return NT_STATUS_NO_MEMORY;
2848 }
2849
2850 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2851 addr = talloc_strdup(cconn, tmp_addr);
2852 if (addr == NULL) {
2853 return NT_STATUS_NO_MEMORY;
2854 }
2855 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2856}
2857
2858#endif
2859
2860/****************************************************************************
2861 Process commands from the client
2862****************************************************************************/
2863
2864void smbd_process(struct smbd_server_connection *sconn)
2865{
2866 TALLOC_CTX *frame = talloc_stackframe();
2867 struct sockaddr_storage ss;
2868 struct sockaddr *sa = NULL;
2869 socklen_t sa_socklen;
2870 struct tsocket_address *local_address = NULL;
2871 struct tsocket_address *remote_address = NULL;
2872 const char *remaddr = NULL;
2873 int ret;
2874
2875 if (lp_maxprotocol() == PROTOCOL_SMB2) {
2876 /*
2877 * We're not making the decision here,
2878 * we're just allowing the client
2879 * to decide between SMB1 and SMB2
2880 * with the first negprot
2881 * packet.
2882 */
2883 sconn->using_smb2 = true;
2884 }
2885
2886 /* Ensure child is set to blocking mode */
2887 set_blocking(sconn->sock,True);
2888
2889 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2890 set_socket_options(sconn->sock, lp_socket_options());
2891
2892 sa = (struct sockaddr *)(void *)&ss;
2893 sa_socklen = sizeof(ss);
2894 ret = getpeername(sconn->sock, sa, &sa_socklen);
2895 if (ret != 0) {
2896 int level = (errno == ENOTCONN)?2:0;
2897 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2898 exit_server_cleanly("getpeername() failed.\n");
2899 }
2900 ret = tsocket_address_bsd_from_sockaddr(sconn,
2901 sa, sa_socklen,
2902 &remote_address);
2903 if (ret != 0) {
2904 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2905 __location__, strerror(errno)));
2906 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2907 }
2908
2909 sa = (struct sockaddr *)(void *)&ss;
2910 sa_socklen = sizeof(ss);
2911 ret = getsockname(sconn->sock, sa, &sa_socklen);
2912 if (ret != 0) {
2913 int level = (errno == ENOTCONN)?2:0;
2914 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2915 exit_server_cleanly("getsockname() failed.\n");
2916 }
2917 ret = tsocket_address_bsd_from_sockaddr(sconn,
2918 sa, sa_socklen,
2919 &local_address);
2920 if (ret != 0) {
2921 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2922 __location__, strerror(errno)));
2923 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2924 }
2925
2926 sconn->local_address = local_address;
2927 sconn->remote_address = remote_address;
2928
2929 if (tsocket_address_is_inet(remote_address, "ip")) {
2930 remaddr = tsocket_address_inet_addr_string(
2931 sconn->remote_address,
2932 talloc_tos());
2933 if (remaddr == NULL) {
2934
2935 }
2936 } else {
2937 remaddr = "0.0.0.0";
2938 }
2939
2940 /* this is needed so that we get decent entries
2941 in smbstatus for port 445 connects */
2942 set_remote_machine_name(remaddr, false);
2943 reload_services(sconn->msg_ctx, sconn->sock, true);
2944
2945 /*
2946 * Before the first packet, check the global hosts allow/ hosts deny
2947 * parameters before doing any parsing of packets passed to us by the
2948 * client. This prevents attacks on our parsing code from hosts not in
2949 * the hosts allow list.
2950 */
2951
2952 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
2953 sconn->client_id.name,
2954 sconn->client_id.addr)) {
2955 /*
2956 * send a negative session response "not listening on calling
2957 * name"
2958 */
2959 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
2960 DEBUG( 1, ("Connection denied from %s to %s\n",
2961 tsocket_address_string(remote_address, talloc_tos()),
2962 tsocket_address_string(local_address, talloc_tos())));
2963 (void)srv_send_smb(sconn,(char *)buf, false,
2964 0, false, NULL);
2965 exit_server_cleanly("connection denied");
2966 }
2967
2968 DEBUG(10, ("Connection allowed from %s to %s\n",
2969 tsocket_address_string(remote_address, talloc_tos()),
2970 tsocket_address_string(local_address, talloc_tos())));
2971
2972 init_modules();
2973
2974 smb_perfcount_init();
2975
2976 if (!init_account_policy()) {
2977 exit_server("Could not open account policy tdb.\n");
2978 }
2979
2980 if (*lp_rootdir()) {
2981 if (chroot(lp_rootdir()) != 0) {
2982 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
2983 exit_server("Failed to chroot()");
2984 }
2985 if (chdir("/") == -1) {
2986 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
2987 exit_server("Failed to chroot()");
2988 }
2989 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
2990 }
2991
2992 if (!srv_init_signing(sconn)) {
2993 exit_server("Failed to init smb_signing");
2994 }
2995
2996 /* Setup oplocks */
2997 if (!init_oplocks(sconn->msg_ctx))
2998 exit_server("Failed to init oplocks");
2999
3000 /* register our message handlers */
3001 messaging_register(sconn->msg_ctx, NULL,
3002 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3003 messaging_register(sconn->msg_ctx, sconn,
3004 MSG_SMB_RELEASE_IP, msg_release_ip);
3005 messaging_register(sconn->msg_ctx, NULL,
3006 MSG_SMB_CLOSE_FILE, msg_close_file);
3007
3008 /*
3009 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3010 * MSGs to all child processes
3011 */
3012 messaging_deregister(sconn->msg_ctx,
3013 MSG_DEBUG, NULL);
3014 messaging_register(sconn->msg_ctx, NULL,
3015 MSG_DEBUG, debug_message);
3016
3017 if ((lp_keepalive() != 0)
3018 && !(event_add_idle(smbd_event_context(), NULL,
3019 timeval_set(lp_keepalive(), 0),
3020 "keepalive", keepalive_fn,
3021 NULL))) {
3022 DEBUG(0, ("Could not add keepalive event\n"));
3023 exit(1);
3024 }
3025
3026 if (!(event_add_idle(smbd_event_context(), NULL,
3027 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3028 "deadtime", deadtime_fn, sconn))) {
3029 DEBUG(0, ("Could not add deadtime event\n"));
3030 exit(1);
3031 }
3032
3033 if (!(event_add_idle(smbd_event_context(), NULL,
3034 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3035 "housekeeping", housekeeping_fn, sconn))) {
3036 DEBUG(0, ("Could not add housekeeping event\n"));
3037 exit(1);
3038 }
3039
3040#ifdef CLUSTER_SUPPORT
3041
3042 if (lp_clustering()) {
3043 /*
3044 * We need to tell ctdb about our client's TCP
3045 * connection, so that for failover ctdbd can send
3046 * tickle acks, triggering a reconnection by the
3047 * client.
3048 */
3049
3050 struct sockaddr_storage srv, clnt;
3051
3052 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3053 NTSTATUS status;
3054 status = smbd_register_ips(sconn, &srv, &clnt);
3055 if (!NT_STATUS_IS_OK(status)) {
3056 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3057 nt_errstr(status)));
3058 }
3059 } else
3060 {
3061 DEBUG(0,("Unable to get tcp info for "
3062 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3063 strerror(errno)));
3064 }
3065 }
3066
3067#endif
3068
3069 sconn->nbt.got_session = false;
3070
3071 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3072
3073 sconn->smb1.sessions.done_sesssetup = false;
3074 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3075 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3076 /* users from session setup */
3077 sconn->smb1.sessions.session_userlist = NULL;
3078 /* workgroup from session setup. */
3079 sconn->smb1.sessions.session_workgroup = NULL;
3080 /* this holds info on user ids that are already validated for this VC */
3081 sconn->smb1.sessions.validated_users = NULL;
3082 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3083 sconn->smb1.sessions.num_validated_vuids = 0;
3084
3085 conn_init(sconn);
3086 if (!init_dptrs(sconn)) {
3087 exit_server("init_dptrs() failed");
3088 }
3089
3090 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3091 sconn,
3092 sconn->sock,
3093 EVENT_FD_READ,
3094 smbd_server_connection_handler,
3095 sconn);
3096 if (!sconn->smb1.fde) {
3097 exit_server("failed to create smbd_server_connection fde");
3098 }
3099
3100 TALLOC_FREE(frame);
3101
3102 while (True) {
3103 NTSTATUS status;
3104
3105 frame = talloc_stackframe_pool(8192);
3106
3107 errno = 0;
3108
3109 status = smbd_server_connection_loop_once(sconn);
3110 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3111 !NT_STATUS_IS_OK(status)) {
3112 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3113 " exiting\n", nt_errstr(status)));
3114 break;
3115 }
3116
3117 TALLOC_FREE(frame);
3118 }
3119
3120 exit_server_cleanly(NULL);
3121}
3122
3123bool req_is_in_chain(struct smb_request *req)
3124{
3125 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3126 /*
3127 * We're right now handling a subsequent request, so we must
3128 * be in a chain
3129 */
3130 return true;
3131 }
3132
3133 if (!is_andx_req(req->cmd)) {
3134 return false;
3135 }
3136
3137 if (req->wct < 2) {
3138 /*
3139 * Okay, an illegal request, but definitely not chained :-)
3140 */
3141 return false;
3142 }
3143
3144 return (CVAL(req->vwv+0, 0) != 0xFF);
3145}
Note: See TracBrowser for help on using the repository browser.