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

Last change on this file since 751 was 751, checked in by Silvan Scherrer, 13 years ago

Samba Server: updated trunk to 3.6.9

File size: 87.2 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(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 void smbd_sig_term_handler(struct tevent_context *ev,
928 struct tevent_signal *se,
929 int signum,
930 int count,
931 void *siginfo,
932 void *private_data)
933{
934 exit_server_cleanly("termination signal");
935}
936
937void smbd_setup_sig_term_handler(void)
938{
939 struct tevent_signal *se;
940
941 se = tevent_add_signal(smbd_event_context(),
942 smbd_event_context(),
943 SIGTERM, 0,
944 smbd_sig_term_handler,
945 NULL);
946 if (!se) {
947 exit_server("failed to setup SIGTERM handler");
948 }
949}
950
951static void smbd_sig_hup_handler(struct tevent_context *ev,
952 struct tevent_signal *se,
953 int signum,
954 int count,
955 void *siginfo,
956 void *private_data)
957{
958 struct messaging_context *msg_ctx = talloc_get_type_abort(
959 private_data, struct messaging_context);
960 change_to_root_user();
961 DEBUG(1,("Reloading services after SIGHUP\n"));
962 reload_services(msg_ctx, smbd_server_conn->sock, False);
963 if (am_parent) {
964 pcap_cache_reload(ev, msg_ctx, &reload_pcap_change_notify);
965 }
966}
967
968void smbd_setup_sig_hup_handler(struct tevent_context *ev,
969 struct messaging_context *msg_ctx)
970{
971 struct tevent_signal *se;
972
973 se = tevent_add_signal(ev, ev, SIGHUP, 0, smbd_sig_hup_handler,
974 msg_ctx);
975 if (!se) {
976 exit_server("failed to setup SIGHUP handler");
977 }
978}
979
980static NTSTATUS smbd_server_connection_loop_once(struct smbd_server_connection *conn)
981{
982 int timeout;
983 int num_pfds = 0;
984 int ret;
985 bool retry;
986
987 timeout = SMBD_SELECT_TIMEOUT * 1000;
988
989 /*
990 * Are there any timed events waiting ? If so, ensure we don't
991 * select for longer than it would take to wait for them.
992 */
993
994 event_add_to_poll_args(smbd_event_context(), conn,
995 &conn->pfds, &num_pfds, &timeout);
996
997 /* Process a signal and timed events now... */
998 if (run_events_poll(smbd_event_context(), 0, NULL, 0)) {
999 return NT_STATUS_RETRY;
1000 }
1001
1002 {
1003 int sav;
1004 START_PROFILE(smbd_idle);
1005
1006 ret = sys_poll(conn->pfds, num_pfds, timeout);
1007 sav = errno;
1008
1009 END_PROFILE(smbd_idle);
1010 errno = sav;
1011 }
1012
1013 if (ret == -1) {
1014 if (errno == EINTR) {
1015 return NT_STATUS_RETRY;
1016 }
1017 return map_nt_error_from_unix(errno);
1018 }
1019
1020 retry = run_events_poll(smbd_event_context(), ret, conn->pfds,
1021 num_pfds);
1022 if (retry) {
1023 return NT_STATUS_RETRY;
1024 }
1025
1026 /* Did we timeout ? */
1027 if (ret == 0) {
1028 return NT_STATUS_RETRY;
1029 }
1030
1031 /* should not be reached */
1032 return NT_STATUS_INTERNAL_ERROR;
1033}
1034
1035/*
1036 * Only allow 5 outstanding trans requests. We're allocating memory, so
1037 * prevent a DoS.
1038 */
1039
1040NTSTATUS allow_new_trans(struct trans_state *list, uint64_t mid)
1041{
1042 int count = 0;
1043 for (; list != NULL; list = list->next) {
1044
1045 if (list->mid == mid) {
1046 return NT_STATUS_INVALID_PARAMETER;
1047 }
1048
1049 count += 1;
1050 }
1051 if (count > 5) {
1052 return NT_STATUS_INSUFFICIENT_RESOURCES;
1053 }
1054
1055 return NT_STATUS_OK;
1056}
1057
1058/*
1059These flags determine some of the permissions required to do an operation
1060
1061Note that I don't set NEED_WRITE on some write operations because they
1062are used by some brain-dead clients when printing, and I don't want to
1063force write permissions on print services.
1064*/
1065#define AS_USER (1<<0)
1066#define NEED_WRITE (1<<1) /* Must be paired with AS_USER */
1067#define TIME_INIT (1<<2)
1068#define CAN_IPC (1<<3) /* Must be paired with AS_USER */
1069#define AS_GUEST (1<<5) /* Must *NOT* be paired with AS_USER */
1070#define DO_CHDIR (1<<6)
1071
1072/*
1073 define a list of possible SMB messages and their corresponding
1074 functions. Any message that has a NULL function is unimplemented -
1075 please feel free to contribute implementations!
1076*/
1077static const struct smb_message_struct {
1078 const char *name;
1079 void (*fn)(struct smb_request *req);
1080 int flags;
1081} smb_messages[256] = {
1082
1083/* 0x00 */ { "SMBmkdir",reply_mkdir,AS_USER | NEED_WRITE},
1084/* 0x01 */ { "SMBrmdir",reply_rmdir,AS_USER | NEED_WRITE},
1085/* 0x02 */ { "SMBopen",reply_open,AS_USER },
1086/* 0x03 */ { "SMBcreate",reply_mknew,AS_USER},
1087/* 0x04 */ { "SMBclose",reply_close,AS_USER | CAN_IPC },
1088/* 0x05 */ { "SMBflush",reply_flush,AS_USER},
1089/* 0x06 */ { "SMBunlink",reply_unlink,AS_USER | NEED_WRITE },
1090/* 0x07 */ { "SMBmv",reply_mv,AS_USER | NEED_WRITE },
1091/* 0x08 */ { "SMBgetatr",reply_getatr,AS_USER},
1092/* 0x09 */ { "SMBsetatr",reply_setatr,AS_USER | NEED_WRITE},
1093/* 0x0a */ { "SMBread",reply_read,AS_USER},
1094/* 0x0b */ { "SMBwrite",reply_write,AS_USER | CAN_IPC },
1095/* 0x0c */ { "SMBlock",reply_lock,AS_USER},
1096/* 0x0d */ { "SMBunlock",reply_unlock,AS_USER},
1097/* 0x0e */ { "SMBctemp",reply_ctemp,AS_USER },
1098/* 0x0f */ { "SMBmknew",reply_mknew,AS_USER},
1099/* 0x10 */ { "SMBcheckpath",reply_checkpath,AS_USER},
1100/* 0x11 */ { "SMBexit",reply_exit,DO_CHDIR},
1101/* 0x12 */ { "SMBlseek",reply_lseek,AS_USER},
1102/* 0x13 */ { "SMBlockread",reply_lockread,AS_USER},
1103/* 0x14 */ { "SMBwriteunlock",reply_writeunlock,AS_USER},
1104/* 0x15 */ { NULL, NULL, 0 },
1105/* 0x16 */ { NULL, NULL, 0 },
1106/* 0x17 */ { NULL, NULL, 0 },
1107/* 0x18 */ { NULL, NULL, 0 },
1108/* 0x19 */ { NULL, NULL, 0 },
1109/* 0x1a */ { "SMBreadbraw",reply_readbraw,AS_USER},
1110/* 0x1b */ { "SMBreadBmpx",reply_readbmpx,AS_USER},
1111/* 0x1c */ { "SMBreadBs",reply_readbs,AS_USER },
1112/* 0x1d */ { "SMBwritebraw",reply_writebraw,AS_USER},
1113/* 0x1e */ { "SMBwriteBmpx",reply_writebmpx,AS_USER},
1114/* 0x1f */ { "SMBwriteBs",reply_writebs,AS_USER},
1115/* 0x20 */ { "SMBwritec", NULL,0},
1116/* 0x21 */ { NULL, NULL, 0 },
1117/* 0x22 */ { "SMBsetattrE",reply_setattrE,AS_USER | NEED_WRITE },
1118/* 0x23 */ { "SMBgetattrE",reply_getattrE,AS_USER },
1119/* 0x24 */ { "SMBlockingX",reply_lockingX,AS_USER },
1120/* 0x25 */ { "SMBtrans",reply_trans,AS_USER | CAN_IPC },
1121/* 0x26 */ { "SMBtranss",reply_transs,AS_USER | CAN_IPC},
1122/* 0x27 */ { "SMBioctl",reply_ioctl,0},
1123/* 0x28 */ { "SMBioctls", NULL,AS_USER},
1124/* 0x29 */ { "SMBcopy",reply_copy,AS_USER | NEED_WRITE },
1125/* 0x2a */ { "SMBmove", NULL,AS_USER | NEED_WRITE },
1126/* 0x2b */ { "SMBecho",reply_echo,0},
1127/* 0x2c */ { "SMBwriteclose",reply_writeclose,AS_USER},
1128/* 0x2d */ { "SMBopenX",reply_open_and_X,AS_USER | CAN_IPC },
1129/* 0x2e */ { "SMBreadX",reply_read_and_X,AS_USER | CAN_IPC },
1130/* 0x2f */ { "SMBwriteX",reply_write_and_X,AS_USER | CAN_IPC },
1131/* 0x30 */ { NULL, NULL, 0 },
1132/* 0x31 */ { NULL, NULL, 0 },
1133/* 0x32 */ { "SMBtrans2",reply_trans2, AS_USER | CAN_IPC },
1134/* 0x33 */ { "SMBtranss2",reply_transs2, AS_USER | CAN_IPC },
1135/* 0x34 */ { "SMBfindclose",reply_findclose,AS_USER},
1136/* 0x35 */ { "SMBfindnclose",reply_findnclose,AS_USER},
1137/* 0x36 */ { NULL, NULL, 0 },
1138/* 0x37 */ { NULL, NULL, 0 },
1139/* 0x38 */ { NULL, NULL, 0 },
1140/* 0x39 */ { NULL, NULL, 0 },
1141/* 0x3a */ { NULL, NULL, 0 },
1142/* 0x3b */ { NULL, NULL, 0 },
1143/* 0x3c */ { NULL, NULL, 0 },
1144/* 0x3d */ { NULL, NULL, 0 },
1145/* 0x3e */ { NULL, NULL, 0 },
1146/* 0x3f */ { NULL, NULL, 0 },
1147/* 0x40 */ { NULL, NULL, 0 },
1148/* 0x41 */ { NULL, NULL, 0 },
1149/* 0x42 */ { NULL, NULL, 0 },
1150/* 0x43 */ { NULL, NULL, 0 },
1151/* 0x44 */ { NULL, NULL, 0 },
1152/* 0x45 */ { NULL, NULL, 0 },
1153/* 0x46 */ { NULL, NULL, 0 },
1154/* 0x47 */ { NULL, NULL, 0 },
1155/* 0x48 */ { NULL, NULL, 0 },
1156/* 0x49 */ { NULL, NULL, 0 },
1157/* 0x4a */ { NULL, NULL, 0 },
1158/* 0x4b */ { NULL, NULL, 0 },
1159/* 0x4c */ { NULL, NULL, 0 },
1160/* 0x4d */ { NULL, NULL, 0 },
1161/* 0x4e */ { NULL, NULL, 0 },
1162/* 0x4f */ { NULL, NULL, 0 },
1163/* 0x50 */ { NULL, NULL, 0 },
1164/* 0x51 */ { NULL, NULL, 0 },
1165/* 0x52 */ { NULL, NULL, 0 },
1166/* 0x53 */ { NULL, NULL, 0 },
1167/* 0x54 */ { NULL, NULL, 0 },
1168/* 0x55 */ { NULL, NULL, 0 },
1169/* 0x56 */ { NULL, NULL, 0 },
1170/* 0x57 */ { NULL, NULL, 0 },
1171/* 0x58 */ { NULL, NULL, 0 },
1172/* 0x59 */ { NULL, NULL, 0 },
1173/* 0x5a */ { NULL, NULL, 0 },
1174/* 0x5b */ { NULL, NULL, 0 },
1175/* 0x5c */ { NULL, NULL, 0 },
1176/* 0x5d */ { NULL, NULL, 0 },
1177/* 0x5e */ { NULL, NULL, 0 },
1178/* 0x5f */ { NULL, NULL, 0 },
1179/* 0x60 */ { NULL, NULL, 0 },
1180/* 0x61 */ { NULL, NULL, 0 },
1181/* 0x62 */ { NULL, NULL, 0 },
1182/* 0x63 */ { NULL, NULL, 0 },
1183/* 0x64 */ { NULL, NULL, 0 },
1184/* 0x65 */ { NULL, NULL, 0 },
1185/* 0x66 */ { NULL, NULL, 0 },
1186/* 0x67 */ { NULL, NULL, 0 },
1187/* 0x68 */ { NULL, NULL, 0 },
1188/* 0x69 */ { NULL, NULL, 0 },
1189/* 0x6a */ { NULL, NULL, 0 },
1190/* 0x6b */ { NULL, NULL, 0 },
1191/* 0x6c */ { NULL, NULL, 0 },
1192/* 0x6d */ { NULL, NULL, 0 },
1193/* 0x6e */ { NULL, NULL, 0 },
1194/* 0x6f */ { NULL, NULL, 0 },
1195/* 0x70 */ { "SMBtcon",reply_tcon,0},
1196/* 0x71 */ { "SMBtdis",reply_tdis,DO_CHDIR},
1197/* 0x72 */ { "SMBnegprot",reply_negprot,0},
1198/* 0x73 */ { "SMBsesssetupX",reply_sesssetup_and_X,0},
1199/* 0x74 */ { "SMBulogoffX",reply_ulogoffX, 0}, /* ulogoff doesn't give a valid TID */
1200/* 0x75 */ { "SMBtconX",reply_tcon_and_X,0},
1201/* 0x76 */ { NULL, NULL, 0 },
1202/* 0x77 */ { NULL, NULL, 0 },
1203/* 0x78 */ { NULL, NULL, 0 },
1204/* 0x79 */ { NULL, NULL, 0 },
1205/* 0x7a */ { NULL, NULL, 0 },
1206/* 0x7b */ { NULL, NULL, 0 },
1207/* 0x7c */ { NULL, NULL, 0 },
1208/* 0x7d */ { NULL, NULL, 0 },
1209/* 0x7e */ { NULL, NULL, 0 },
1210/* 0x7f */ { NULL, NULL, 0 },
1211/* 0x80 */ { "SMBdskattr",reply_dskattr,AS_USER},
1212/* 0x81 */ { "SMBsearch",reply_search,AS_USER},
1213/* 0x82 */ { "SMBffirst",reply_search,AS_USER},
1214/* 0x83 */ { "SMBfunique",reply_search,AS_USER},
1215/* 0x84 */ { "SMBfclose",reply_fclose,AS_USER},
1216/* 0x85 */ { NULL, NULL, 0 },
1217/* 0x86 */ { NULL, NULL, 0 },
1218/* 0x87 */ { NULL, NULL, 0 },
1219/* 0x88 */ { NULL, NULL, 0 },
1220/* 0x89 */ { NULL, NULL, 0 },
1221/* 0x8a */ { NULL, NULL, 0 },
1222/* 0x8b */ { NULL, NULL, 0 },
1223/* 0x8c */ { NULL, NULL, 0 },
1224/* 0x8d */ { NULL, NULL, 0 },
1225/* 0x8e */ { NULL, NULL, 0 },
1226/* 0x8f */ { NULL, NULL, 0 },
1227/* 0x90 */ { NULL, NULL, 0 },
1228/* 0x91 */ { NULL, NULL, 0 },
1229/* 0x92 */ { NULL, NULL, 0 },
1230/* 0x93 */ { NULL, NULL, 0 },
1231/* 0x94 */ { NULL, NULL, 0 },
1232/* 0x95 */ { NULL, NULL, 0 },
1233/* 0x96 */ { NULL, NULL, 0 },
1234/* 0x97 */ { NULL, NULL, 0 },
1235/* 0x98 */ { NULL, NULL, 0 },
1236/* 0x99 */ { NULL, NULL, 0 },
1237/* 0x9a */ { NULL, NULL, 0 },
1238/* 0x9b */ { NULL, NULL, 0 },
1239/* 0x9c */ { NULL, NULL, 0 },
1240/* 0x9d */ { NULL, NULL, 0 },
1241/* 0x9e */ { NULL, NULL, 0 },
1242/* 0x9f */ { NULL, NULL, 0 },
1243/* 0xa0 */ { "SMBnttrans",reply_nttrans, AS_USER | CAN_IPC },
1244/* 0xa1 */ { "SMBnttranss",reply_nttranss, AS_USER | CAN_IPC },
1245/* 0xa2 */ { "SMBntcreateX",reply_ntcreate_and_X, AS_USER | CAN_IPC },
1246/* 0xa3 */ { NULL, NULL, 0 },
1247/* 0xa4 */ { "SMBntcancel",reply_ntcancel, 0 },
1248/* 0xa5 */ { "SMBntrename",reply_ntrename, AS_USER | NEED_WRITE },
1249/* 0xa6 */ { NULL, NULL, 0 },
1250/* 0xa7 */ { NULL, NULL, 0 },
1251/* 0xa8 */ { NULL, NULL, 0 },
1252/* 0xa9 */ { NULL, NULL, 0 },
1253/* 0xaa */ { NULL, NULL, 0 },
1254/* 0xab */ { NULL, NULL, 0 },
1255/* 0xac */ { NULL, NULL, 0 },
1256/* 0xad */ { NULL, NULL, 0 },
1257/* 0xae */ { NULL, NULL, 0 },
1258/* 0xaf */ { NULL, NULL, 0 },
1259/* 0xb0 */ { NULL, NULL, 0 },
1260/* 0xb1 */ { NULL, NULL, 0 },
1261/* 0xb2 */ { NULL, NULL, 0 },
1262/* 0xb3 */ { NULL, NULL, 0 },
1263/* 0xb4 */ { NULL, NULL, 0 },
1264/* 0xb5 */ { NULL, NULL, 0 },
1265/* 0xb6 */ { NULL, NULL, 0 },
1266/* 0xb7 */ { NULL, NULL, 0 },
1267/* 0xb8 */ { NULL, NULL, 0 },
1268/* 0xb9 */ { NULL, NULL, 0 },
1269/* 0xba */ { NULL, NULL, 0 },
1270/* 0xbb */ { NULL, NULL, 0 },
1271/* 0xbc */ { NULL, NULL, 0 },
1272/* 0xbd */ { NULL, NULL, 0 },
1273/* 0xbe */ { NULL, NULL, 0 },
1274/* 0xbf */ { NULL, NULL, 0 },
1275/* 0xc0 */ { "SMBsplopen",reply_printopen,AS_USER},
1276/* 0xc1 */ { "SMBsplwr",reply_printwrite,AS_USER},
1277/* 0xc2 */ { "SMBsplclose",reply_printclose,AS_USER},
1278/* 0xc3 */ { "SMBsplretq",reply_printqueue,AS_USER},
1279/* 0xc4 */ { NULL, NULL, 0 },
1280/* 0xc5 */ { NULL, NULL, 0 },
1281/* 0xc6 */ { NULL, NULL, 0 },
1282/* 0xc7 */ { NULL, NULL, 0 },
1283/* 0xc8 */ { NULL, NULL, 0 },
1284/* 0xc9 */ { NULL, NULL, 0 },
1285/* 0xca */ { NULL, NULL, 0 },
1286/* 0xcb */ { NULL, NULL, 0 },
1287/* 0xcc */ { NULL, NULL, 0 },
1288/* 0xcd */ { NULL, NULL, 0 },
1289/* 0xce */ { NULL, NULL, 0 },
1290/* 0xcf */ { NULL, NULL, 0 },
1291/* 0xd0 */ { "SMBsends",reply_sends,AS_GUEST},
1292/* 0xd1 */ { "SMBsendb", NULL,AS_GUEST},
1293/* 0xd2 */ { "SMBfwdname", NULL,AS_GUEST},
1294/* 0xd3 */ { "SMBcancelf", NULL,AS_GUEST},
1295/* 0xd4 */ { "SMBgetmac", NULL,AS_GUEST},
1296/* 0xd5 */ { "SMBsendstrt",reply_sendstrt,AS_GUEST},
1297/* 0xd6 */ { "SMBsendend",reply_sendend,AS_GUEST},
1298/* 0xd7 */ { "SMBsendtxt",reply_sendtxt,AS_GUEST},
1299/* 0xd8 */ { NULL, NULL, 0 },
1300/* 0xd9 */ { NULL, NULL, 0 },
1301/* 0xda */ { NULL, NULL, 0 },
1302/* 0xdb */ { NULL, NULL, 0 },
1303/* 0xdc */ { NULL, NULL, 0 },
1304/* 0xdd */ { NULL, NULL, 0 },
1305/* 0xde */ { NULL, NULL, 0 },
1306/* 0xdf */ { NULL, NULL, 0 },
1307/* 0xe0 */ { NULL, NULL, 0 },
1308/* 0xe1 */ { NULL, NULL, 0 },
1309/* 0xe2 */ { NULL, NULL, 0 },
1310/* 0xe3 */ { NULL, NULL, 0 },
1311/* 0xe4 */ { NULL, NULL, 0 },
1312/* 0xe5 */ { NULL, NULL, 0 },
1313/* 0xe6 */ { NULL, NULL, 0 },
1314/* 0xe7 */ { NULL, NULL, 0 },
1315/* 0xe8 */ { NULL, NULL, 0 },
1316/* 0xe9 */ { NULL, NULL, 0 },
1317/* 0xea */ { NULL, NULL, 0 },
1318/* 0xeb */ { NULL, NULL, 0 },
1319/* 0xec */ { NULL, NULL, 0 },
1320/* 0xed */ { NULL, NULL, 0 },
1321/* 0xee */ { NULL, NULL, 0 },
1322/* 0xef */ { NULL, NULL, 0 },
1323/* 0xf0 */ { NULL, NULL, 0 },
1324/* 0xf1 */ { NULL, NULL, 0 },
1325/* 0xf2 */ { NULL, NULL, 0 },
1326/* 0xf3 */ { NULL, NULL, 0 },
1327/* 0xf4 */ { NULL, NULL, 0 },
1328/* 0xf5 */ { NULL, NULL, 0 },
1329/* 0xf6 */ { NULL, NULL, 0 },
1330/* 0xf7 */ { NULL, NULL, 0 },
1331/* 0xf8 */ { NULL, NULL, 0 },
1332/* 0xf9 */ { NULL, NULL, 0 },
1333/* 0xfa */ { NULL, NULL, 0 },
1334/* 0xfb */ { NULL, NULL, 0 },
1335/* 0xfc */ { NULL, NULL, 0 },
1336/* 0xfd */ { NULL, NULL, 0 },
1337/* 0xfe */ { NULL, NULL, 0 },
1338/* 0xff */ { NULL, NULL, 0 }
1339
1340};
1341
1342/*******************************************************************
1343 allocate and initialize a reply packet
1344********************************************************************/
1345
1346static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
1347 const char *inbuf, char **outbuf, uint8_t num_words,
1348 uint32_t num_bytes)
1349{
1350 /*
1351 * Protect against integer wrap
1352 */
1353 if ((num_bytes > 0xffffff)
1354 || ((num_bytes + smb_size + num_words*2) > 0xffffff)) {
1355 char *msg;
1356 if (asprintf(&msg, "num_bytes too large: %u",
1357 (unsigned)num_bytes) == -1) {
1358 msg = CONST_DISCARD(char *, "num_bytes too large");
1359 }
1360 smb_panic(msg);
1361 }
1362
1363 *outbuf = TALLOC_ARRAY(mem_ctx, char,
1364 smb_size + num_words*2 + num_bytes);
1365 if (*outbuf == NULL) {
1366 return false;
1367 }
1368
1369 construct_reply_common(req, inbuf, *outbuf);
1370 srv_set_message(*outbuf, num_words, num_bytes, false);
1371 /*
1372 * Zero out the word area, the caller has to take care of the bcc area
1373 * himself
1374 */
1375 if (num_words != 0) {
1376 memset(*outbuf + smb_vwv0, 0, num_words*2);
1377 }
1378
1379 return true;
1380}
1381
1382void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
1383{
1384 char *outbuf;
1385 if (!create_outbuf(req, req, (char *)req->inbuf, &outbuf, num_words,
1386 num_bytes)) {
1387 smb_panic("could not allocate output buffer\n");
1388 }
1389 req->outbuf = (uint8_t *)outbuf;
1390}
1391
1392
1393/*******************************************************************
1394 Dump a packet to a file.
1395********************************************************************/
1396
1397static void smb_dump(const char *name, int type, const char *data, ssize_t len)
1398{
1399 int fd, i;
1400 char *fname = NULL;
1401 if (DEBUGLEVEL < 50) {
1402 return;
1403 }
1404
1405 if (len < 4) len = smb_len(data)+4;
1406 for (i=1;i<100;i++) {
1407 if (asprintf(&fname, "/tmp/%s.%d.%s", name, i,
1408 type ? "req" : "resp") == -1) {
1409 return;
1410 }
1411 fd = open(fname, O_WRONLY|O_CREAT|O_EXCL, 0644);
1412 if (fd != -1 || errno != EEXIST) break;
1413 }
1414 if (fd != -1) {
1415 ssize_t ret = write(fd, data, len);
1416 if (ret != len)
1417 DEBUG(0,("smb_dump: problem: write returned %d\n", (int)ret ));
1418 close(fd);
1419 DEBUG(0,("created %s len %lu\n", fname, (unsigned long)len));
1420 }
1421 SAFE_FREE(fname);
1422}
1423
1424/****************************************************************************
1425 Prepare everything for calling the actual request function, and potentially
1426 call the request function via the "new" interface.
1427
1428 Return False if the "legacy" function needs to be called, everything is
1429 prepared.
1430
1431 Return True if we're done.
1432
1433 I know this API sucks, but it is the one with the least code change I could
1434 find.
1435****************************************************************************/
1436
1437static connection_struct *switch_message(uint8 type, struct smb_request *req, int size)
1438{
1439 int flags;
1440 uint16 session_tag;
1441 connection_struct *conn = NULL;
1442 struct smbd_server_connection *sconn = req->sconn;
1443
1444 errno = 0;
1445
1446 /* Make sure this is an SMB packet. smb_size contains NetBIOS header
1447 * so subtract 4 from it. */
1448 if ((size < (smb_size - 4)) ||
1449 !valid_smb_header(req->inbuf)) {
1450 DEBUG(2,("Non-SMB packet of length %d. Terminating server\n",
1451 smb_len(req->inbuf)));
1452 exit_server_cleanly("Non-SMB packet");
1453 }
1454
1455 if (smb_messages[type].fn == NULL) {
1456 DEBUG(0,("Unknown message type %d!\n",type));
1457 smb_dump("Unknown", 1, (char *)req->inbuf, size);
1458 reply_unknown_new(req, type);
1459 return NULL;
1460 }
1461
1462 flags = smb_messages[type].flags;
1463
1464 /* In share mode security we must ignore the vuid. */
1465 session_tag = (lp_security() == SEC_SHARE)
1466 ? UID_FIELD_INVALID : req->vuid;
1467 conn = req->conn;
1468
1469 DEBUG(3,("switch message %s (pid %d) conn 0x%lx\n", smb_fn_name(type),
1470 (int)sys_getpid(), (unsigned long)conn));
1471
1472 smb_dump(smb_fn_name(type), 1, (char *)req->inbuf, size);
1473
1474 /* Ensure this value is replaced in the incoming packet. */
1475 SSVAL(req->inbuf,smb_uid,session_tag);
1476
1477 /*
1478 * Ensure the correct username is in current_user_info. This is a
1479 * really ugly bugfix for problems with multiple session_setup_and_X's
1480 * being done and allowing %U and %G substitutions to work correctly.
1481 * There is a reason this code is done here, don't move it unless you
1482 * know what you're doing... :-).
1483 * JRA.
1484 */
1485
1486 if (session_tag != sconn->smb1.sessions.last_session_tag) {
1487 user_struct *vuser = NULL;
1488
1489 sconn->smb1.sessions.last_session_tag = session_tag;
1490 if(session_tag != UID_FIELD_INVALID) {
1491 vuser = get_valid_user_struct(sconn, session_tag);
1492 if (vuser) {
1493 set_current_user_info(
1494 vuser->session_info->sanitized_username,
1495 vuser->session_info->unix_name,
1496 vuser->session_info->info3->base.domain.string);
1497 }
1498 }
1499 }
1500
1501 /* Does this call need to be run as the connected user? */
1502 if (flags & AS_USER) {
1503
1504 /* Does this call need a valid tree connection? */
1505 if (!conn) {
1506 /*
1507 * Amazingly, the error code depends on the command
1508 * (from Samba4).
1509 */
1510 if (type == SMBntcreateX) {
1511 reply_nterror(req, NT_STATUS_INVALID_HANDLE);
1512 } else {
1513 reply_nterror(req, NT_STATUS_NETWORK_NAME_DELETED);
1514 }
1515 return NULL;
1516 }
1517
1518 if (!change_to_user(conn,session_tag)) {
1519 DEBUG(0, ("Error: Could not change to user. Removing "
1520 "deferred open, mid=%llu.\n",
1521 (unsigned long long)req->mid));
1522 reply_force_doserror(req, ERRSRV, ERRbaduid);
1523 return conn;
1524 }
1525
1526 /* All NEED_WRITE and CAN_IPC flags must also have AS_USER. */
1527
1528 /* Does it need write permission? */
1529 if ((flags & NEED_WRITE) && !CAN_WRITE(conn)) {
1530 reply_nterror(req, NT_STATUS_MEDIA_WRITE_PROTECTED);
1531 return conn;
1532 }
1533
1534 /* IPC services are limited */
1535 if (IS_IPC(conn) && !(flags & CAN_IPC)) {
1536 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1537 return conn;
1538 }
1539 } else {
1540 /* This call needs to be run as root */
1541 change_to_root_user();
1542 }
1543
1544 /* load service specific parameters */
1545 if (conn) {
1546 if (req->encrypted) {
1547 conn->encrypted_tid = true;
1548 /* encrypted required from now on. */
1549 conn->encrypt_level = Required;
1550 } else if (ENCRYPTION_REQUIRED(conn)) {
1551 if (req->cmd != SMBtrans2 && req->cmd != SMBtranss2) {
1552 exit_server_cleanly("encryption required "
1553 "on connection");
1554 return conn;
1555 }
1556 }
1557
1558 if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
1559 (flags & (AS_USER|DO_CHDIR)
1560 ?True:False))) {
1561 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1562 return conn;
1563 }
1564 conn->num_smb_operations++;
1565 }
1566
1567 /* does this protocol need to be run as guest? */
1568 if ((flags & AS_GUEST)
1569 && (!change_to_guest() ||
1570 !allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
1571 sconn->client_id.name,
1572 sconn->client_id.addr))) {
1573 reply_nterror(req, NT_STATUS_ACCESS_DENIED);
1574 return conn;
1575 }
1576
1577 smb_messages[type].fn(req);
1578 return req->conn;
1579}
1580
1581/****************************************************************************
1582 Construct a reply to the incoming packet.
1583****************************************************************************/
1584
1585static void construct_reply(struct smbd_server_connection *sconn,
1586 char *inbuf, int size, size_t unread_bytes,
1587 uint32_t seqnum, bool encrypted,
1588 struct smb_perfcount_data *deferred_pcd)
1589{
1590 connection_struct *conn;
1591 struct smb_request *req;
1592
1593 if (!(req = talloc(talloc_tos(), struct smb_request))) {
1594 smb_panic("could not allocate smb_request");
1595 }
1596
1597 if (!init_smb_request(req, sconn, (uint8 *)inbuf, unread_bytes,
1598 encrypted, seqnum)) {
1599 exit_server_cleanly("Invalid SMB request");
1600 }
1601
1602 req->inbuf = (uint8_t *)talloc_move(req, &inbuf);
1603
1604 /* we popped this message off the queue - keep original perf data */
1605 if (deferred_pcd)
1606 req->pcd = *deferred_pcd;
1607 else {
1608 SMB_PERFCOUNT_START(&req->pcd);
1609 SMB_PERFCOUNT_SET_OP(&req->pcd, req->cmd);
1610 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, size);
1611 }
1612
1613 conn = switch_message(req->cmd, req, size);
1614
1615 if (req->unread_bytes) {
1616 /* writeX failed. drain socket. */
1617 if (drain_socket(req->sconn->sock, req->unread_bytes) !=
1618 req->unread_bytes) {
1619 smb_panic("failed to drain pending bytes");
1620 }
1621 req->unread_bytes = 0;
1622 }
1623
1624 if (req->done) {
1625 TALLOC_FREE(req);
1626 return;
1627 }
1628
1629 if (req->outbuf == NULL) {
1630 return;
1631 }
1632
1633 if (CVAL(req->outbuf,0) == 0) {
1634 show_msg((char *)req->outbuf);
1635 }
1636
1637 if (!srv_send_smb(req->sconn,
1638 (char *)req->outbuf,
1639 true, req->seqnum+1,
1640 IS_CONN_ENCRYPTED(conn)||req->encrypted,
1641 &req->pcd)) {
1642 exit_server_cleanly("construct_reply: srv_send_smb failed.");
1643 }
1644
1645 TALLOC_FREE(req);
1646
1647 return;
1648}
1649
1650/****************************************************************************
1651 Process an smb from the client
1652****************************************************************************/
1653static void process_smb(struct smbd_server_connection *sconn,
1654 uint8_t *inbuf, size_t nread, size_t unread_bytes,
1655 uint32_t seqnum, bool encrypted,
1656 struct smb_perfcount_data *deferred_pcd)
1657{
1658 int msg_type = CVAL(inbuf,0);
1659
1660 DO_PROFILE_INC(smb_count);
1661
1662 DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
1663 smb_len(inbuf) ) );
1664 DEBUG(3, ("Transaction %d of length %d (%u toread)\n",
1665 sconn->trans_num, (int)nread, (unsigned int)unread_bytes));
1666
1667 if (msg_type != 0) {
1668 /*
1669 * NetBIOS session request, keepalive, etc.
1670 */
1671 reply_special(sconn, (char *)inbuf, nread);
1672 goto done;
1673 }
1674
1675 if (sconn->using_smb2) {
1676 /* At this point we're not really using smb2,
1677 * we make the decision here.. */
1678 if (smbd_is_smb2_header(inbuf, nread)) {
1679 smbd_smb2_first_negprot(sconn, inbuf, nread);
1680 return;
1681 } else if (nread >= smb_size && valid_smb_header(inbuf)
1682 && CVAL(inbuf, smb_com) != 0x72) {
1683 /* This is a non-negprot SMB1 packet.
1684 Disable SMB2 from now on. */
1685 sconn->using_smb2 = false;
1686 }
1687 }
1688
1689 show_msg((char *)inbuf);
1690
1691 construct_reply(sconn, (char *)inbuf, nread, unread_bytes, seqnum,
1692 encrypted, deferred_pcd);
1693 sconn->trans_num++;
1694
1695done:
1696 sconn->num_requests++;
1697
1698 /* The timeout_processing function isn't run nearly
1699 often enough to implement 'max log size' without
1700 overrunning the size of the file by many megabytes.
1701 This is especially true if we are running at debug
1702 level 10. Checking every 50 SMBs is a nice
1703 tradeoff of performance vs log file size overrun. */
1704
1705 if ((sconn->num_requests % 50) == 0 &&
1706 need_to_check_log_size()) {
1707 change_to_root_user();
1708 check_log_size();
1709 }
1710}
1711
1712/****************************************************************************
1713 Return a string containing the function name of a SMB command.
1714****************************************************************************/
1715
1716const char *smb_fn_name(int type)
1717{
1718 const char *unknown_name = "SMBunknown";
1719
1720 if (smb_messages[type].name == NULL)
1721 return(unknown_name);
1722
1723 return(smb_messages[type].name);
1724}
1725
1726/****************************************************************************
1727 Helper functions for contruct_reply.
1728****************************************************************************/
1729
1730void add_to_common_flags2(uint32 v)
1731{
1732 common_flags2 |= v;
1733}
1734
1735void remove_from_common_flags2(uint32 v)
1736{
1737 common_flags2 &= ~v;
1738}
1739
1740static void construct_reply_common(struct smb_request *req, const char *inbuf,
1741 char *outbuf)
1742{
1743 srv_set_message(outbuf,0,0,false);
1744
1745 SCVAL(outbuf, smb_com, req->cmd);
1746 SIVAL(outbuf,smb_rcls,0);
1747 SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
1748 SSVAL(outbuf,smb_flg2,
1749 (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
1750 common_flags2);
1751 memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
1752
1753 SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
1754 SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
1755 SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
1756 SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
1757}
1758
1759void construct_reply_common_req(struct smb_request *req, char *outbuf)
1760{
1761 construct_reply_common(req, (char *)req->inbuf, outbuf);
1762}
1763
1764/*
1765 * How many bytes have we already accumulated up to the current wct field
1766 * offset?
1767 */
1768
1769size_t req_wct_ofs(struct smb_request *req)
1770{
1771 size_t buf_size;
1772
1773 if (req->chain_outbuf == NULL) {
1774 return smb_wct - 4;
1775 }
1776 buf_size = talloc_get_size(req->chain_outbuf);
1777 if ((buf_size % 4) != 0) {
1778 buf_size += (4 - (buf_size % 4));
1779 }
1780 return buf_size - 4;
1781}
1782
1783/*
1784 * Hack around reply_nterror & friends not being aware of chained requests,
1785 * generating illegal (i.e. wct==0) chain replies.
1786 */
1787
1788static void fixup_chain_error_packet(struct smb_request *req)
1789{
1790 uint8_t *outbuf = req->outbuf;
1791 req->outbuf = NULL;
1792 reply_outbuf(req, 2, 0);
1793 memcpy(req->outbuf, outbuf, smb_wct);
1794 TALLOC_FREE(outbuf);
1795 SCVAL(req->outbuf, smb_vwv0, 0xff);
1796}
1797
1798/**
1799 * @brief Find the smb_cmd offset of the last command pushed
1800 * @param[in] buf The buffer we're building up
1801 * @retval Where can we put our next andx cmd?
1802 *
1803 * While chaining requests, the "next" request we're looking at needs to put
1804 * its SMB_Command before the data the previous request already built up added
1805 * to the chain. Find the offset to the place where we have to put our cmd.
1806 */
1807
1808static bool find_andx_cmd_ofs(uint8_t *buf, size_t *pofs)
1809{
1810 uint8_t cmd;
1811 size_t ofs;
1812
1813 cmd = CVAL(buf, smb_com);
1814
1815 SMB_ASSERT(is_andx_req(cmd));
1816
1817 ofs = smb_vwv0;
1818
1819 while (CVAL(buf, ofs) != 0xff) {
1820
1821 if (!is_andx_req(CVAL(buf, ofs))) {
1822 return false;
1823 }
1824
1825 /*
1826 * ofs is from start of smb header, so add the 4 length
1827 * bytes. The next cmd is right after the wct field.
1828 */
1829 ofs = SVAL(buf, ofs+2) + 4 + 1;
1830
1831 SMB_ASSERT(ofs+4 < talloc_get_size(buf));
1832 }
1833
1834 *pofs = ofs;
1835 return true;
1836}
1837
1838/**
1839 * @brief Do the smb chaining at a buffer level
1840 * @param[in] poutbuf Pointer to the talloc'ed buffer to be modified
1841 * @param[in] smb_command The command that we want to issue
1842 * @param[in] wct How many words?
1843 * @param[in] vwv The words, already in network order
1844 * @param[in] bytes_alignment How shall we align "bytes"?
1845 * @param[in] num_bytes How many bytes?
1846 * @param[in] bytes The data the request ships
1847 *
1848 * smb_splice_chain() adds the vwv and bytes to the request already present in
1849 * *poutbuf.
1850 */
1851
1852static bool smb_splice_chain(uint8_t **poutbuf, uint8_t smb_command,
1853 uint8_t wct, const uint16_t *vwv,
1854 size_t bytes_alignment,
1855 uint32_t num_bytes, const uint8_t *bytes)
1856{
1857 uint8_t *outbuf;
1858 size_t old_size, new_size;
1859 size_t ofs;
1860 size_t chain_padding = 0;
1861 size_t bytes_padding = 0;
1862 bool first_request;
1863
1864 old_size = talloc_get_size(*poutbuf);
1865
1866 /*
1867 * old_size == smb_wct means we're pushing the first request in for
1868 * libsmb/
1869 */
1870
1871 first_request = (old_size == smb_wct);
1872
1873 if (!first_request && ((old_size % 4) != 0)) {
1874 /*
1875 * Align the wct field of subsequent requests to a 4-byte
1876 * boundary
1877 */
1878 chain_padding = 4 - (old_size % 4);
1879 }
1880
1881 /*
1882 * After the old request comes the new wct field (1 byte), the vwv's
1883 * and the num_bytes field. After at we might need to align the bytes
1884 * given to us to "bytes_alignment", increasing the num_bytes value.
1885 */
1886
1887 new_size = old_size + chain_padding + 1 + wct * sizeof(uint16_t) + 2;
1888
1889 if ((bytes_alignment != 0) && ((new_size % bytes_alignment) != 0)) {
1890 bytes_padding = bytes_alignment - (new_size % bytes_alignment);
1891 }
1892
1893 new_size += bytes_padding + num_bytes;
1894
1895 if ((smb_command != SMBwriteX) && (new_size > 0xffff)) {
1896 DEBUG(1, ("splice_chain: %u bytes won't fit\n",
1897 (unsigned)new_size));
1898 return false;
1899 }
1900
1901 outbuf = TALLOC_REALLOC_ARRAY(NULL, *poutbuf, uint8_t, new_size);
1902 if (outbuf == NULL) {
1903 DEBUG(0, ("talloc failed\n"));
1904 return false;
1905 }
1906 *poutbuf = outbuf;
1907
1908 if (first_request) {
1909 SCVAL(outbuf, smb_com, smb_command);
1910 } else {
1911 size_t andx_cmd_ofs;
1912
1913 if (!find_andx_cmd_ofs(outbuf, &andx_cmd_ofs)) {
1914 DEBUG(1, ("invalid command chain\n"));
1915 *poutbuf = TALLOC_REALLOC_ARRAY(
1916 NULL, *poutbuf, uint8_t, old_size);
1917 return false;
1918 }
1919
1920 if (chain_padding != 0) {
1921 memset(outbuf + old_size, 0, chain_padding);
1922 old_size += chain_padding;
1923 }
1924
1925 SCVAL(outbuf, andx_cmd_ofs, smb_command);
1926 SSVAL(outbuf, andx_cmd_ofs + 2, old_size - 4);
1927 }
1928
1929 ofs = old_size;
1930
1931 /*
1932 * Push the chained request:
1933 *
1934 * wct field
1935 */
1936
1937 SCVAL(outbuf, ofs, wct);
1938 ofs += 1;
1939
1940 /*
1941 * vwv array
1942 */
1943
1944 memcpy(outbuf + ofs, vwv, sizeof(uint16_t) * wct);
1945 ofs += sizeof(uint16_t) * wct;
1946
1947 /*
1948 * bcc (byte count)
1949 */
1950
1951 SSVAL(outbuf, ofs, num_bytes + bytes_padding);
1952 ofs += sizeof(uint16_t);
1953
1954 /*
1955 * padding
1956 */
1957
1958 if (bytes_padding != 0) {
1959 memset(outbuf + ofs, 0, bytes_padding);
1960 ofs += bytes_padding;
1961 }
1962
1963 /*
1964 * The bytes field
1965 */
1966
1967 memcpy(outbuf + ofs, bytes, num_bytes);
1968
1969 return true;
1970}
1971
1972/****************************************************************************
1973 Construct a chained reply and add it to the already made reply
1974****************************************************************************/
1975
1976void chain_reply(struct smb_request *req)
1977{
1978 size_t smblen = smb_len(req->inbuf);
1979 size_t already_used, length_needed;
1980 uint8_t chain_cmd;
1981 uint32_t chain_offset; /* uint32_t to avoid overflow */
1982
1983 uint8_t wct;
1984 uint16_t *vwv;
1985 uint16_t buflen;
1986 uint8_t *buf;
1987
1988 if (IVAL(req->outbuf, smb_rcls) != 0) {
1989 fixup_chain_error_packet(req);
1990 }
1991
1992 /*
1993 * Any of the AndX requests and replies have at least a wct of
1994 * 2. vwv[0] is the next command, vwv[1] is the offset from the
1995 * beginning of the SMB header to the next wct field.
1996 *
1997 * None of the AndX requests put anything valuable in vwv[0] and [1],
1998 * so we can overwrite it here to form the chain.
1999 */
2000
2001 if ((req->wct < 2) || (CVAL(req->outbuf, smb_wct) < 2)) {
2002 if (req->chain_outbuf == NULL) {
2003 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2004 req, req->outbuf, uint8_t,
2005 smb_len(req->outbuf) + 4);
2006 if (req->chain_outbuf == NULL) {
2007 smb_panic("talloc failed");
2008 }
2009 }
2010 req->outbuf = NULL;
2011 goto error;
2012 }
2013
2014 /*
2015 * Here we assume that this is the end of the chain. For that we need
2016 * to set "next command" to 0xff and the offset to 0. If we later find
2017 * more commands in the chain, this will be overwritten again.
2018 */
2019
2020 SCVAL(req->outbuf, smb_vwv0, 0xff);
2021 SCVAL(req->outbuf, smb_vwv0+1, 0);
2022 SSVAL(req->outbuf, smb_vwv1, 0);
2023
2024 if (req->chain_outbuf == NULL) {
2025 /*
2026 * In req->chain_outbuf we collect all the replies. Start the
2027 * chain by copying in the first reply.
2028 *
2029 * We do the realloc because later on we depend on
2030 * talloc_get_size to determine the length of
2031 * chain_outbuf. The reply_xxx routines might have
2032 * over-allocated (reply_pipe_read_and_X used to be such an
2033 * example).
2034 */
2035 req->chain_outbuf = TALLOC_REALLOC_ARRAY(
2036 req, req->outbuf, uint8_t, smb_len(req->outbuf) + 4);
2037 if (req->chain_outbuf == NULL) {
2038 smb_panic("talloc failed");
2039 }
2040 req->outbuf = NULL;
2041 } else {
2042 /*
2043 * Update smb headers where subsequent chained commands
2044 * may have updated them.
2045 */
2046 SSVAL(req->chain_outbuf, smb_tid, SVAL(req->outbuf, smb_tid));
2047 SSVAL(req->chain_outbuf, smb_uid, SVAL(req->outbuf, smb_uid));
2048
2049 if (!smb_splice_chain(&req->chain_outbuf,
2050 CVAL(req->outbuf, smb_com),
2051 CVAL(req->outbuf, smb_wct),
2052 (uint16_t *)(req->outbuf + smb_vwv),
2053 0, smb_buflen(req->outbuf),
2054 (uint8_t *)smb_buf(req->outbuf))) {
2055 goto error;
2056 }
2057 TALLOC_FREE(req->outbuf);
2058 }
2059
2060 /*
2061 * We use the old request's vwv field to grab the next chained command
2062 * and offset into the chained fields.
2063 */
2064
2065 chain_cmd = CVAL(req->vwv+0, 0);
2066 chain_offset = SVAL(req->vwv+1, 0);
2067
2068 if (chain_cmd == 0xff) {
2069 /*
2070 * End of chain, no more requests from the client. So ship the
2071 * replies.
2072 */
2073 smb_setlen((char *)(req->chain_outbuf),
2074 talloc_get_size(req->chain_outbuf) - 4);
2075
2076 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2077 true, req->seqnum+1,
2078 IS_CONN_ENCRYPTED(req->conn)
2079 ||req->encrypted,
2080 &req->pcd)) {
2081 exit_server_cleanly("chain_reply: srv_send_smb "
2082 "failed.");
2083 }
2084 TALLOC_FREE(req->chain_outbuf);
2085 req->done = true;
2086 return;
2087 }
2088
2089 /* add a new perfcounter for this element of chain */
2090 SMB_PERFCOUNT_ADD(&req->pcd);
2091 SMB_PERFCOUNT_SET_OP(&req->pcd, chain_cmd);
2092 SMB_PERFCOUNT_SET_MSGLEN_IN(&req->pcd, smblen);
2093
2094 /*
2095 * Check if the client tries to fool us. The chain offset
2096 * needs to point beyond the current request in the chain, it
2097 * needs to strictly grow. Otherwise we might be tricked into
2098 * an endless loop always processing the same request over and
2099 * over again. We used to assume that vwv and the byte buffer
2100 * array in a chain are always attached, but OS/2 the
2101 * Write&X/Read&X chain puts the Read&X vwv array right behind
2102 * the Write&X vwv chain. The Write&X bcc array is put behind
2103 * the Read&X vwv array. So now we check whether the chain
2104 * offset points strictly behind the previous vwv
2105 * array. req->buf points right after the vwv array of the
2106 * previous request. See
2107 * https://bugzilla.samba.org/show_bug.cgi?id=8360 for more
2108 * information.
2109 */
2110
2111 already_used = PTR_DIFF(req->buf, smb_base(req->inbuf));
2112 if (chain_offset <= already_used) {
2113 goto error;
2114 }
2115
2116 /*
2117 * Next check: Make sure the chain offset does not point beyond the
2118 * overall smb request length.
2119 */
2120
2121 length_needed = chain_offset+1; /* wct */
2122 if (length_needed > smblen) {
2123 goto error;
2124 }
2125
2126 /*
2127 * Now comes the pointer magic. Goal here is to set up req->vwv and
2128 * req->buf correctly again to be able to call the subsequent
2129 * switch_message(). The chain offset (the former vwv[1]) points at
2130 * the new wct field.
2131 */
2132
2133 wct = CVAL(smb_base(req->inbuf), chain_offset);
2134
2135 /*
2136 * Next consistency check: Make the new vwv array fits in the overall
2137 * smb request.
2138 */
2139
2140 length_needed += (wct+1)*sizeof(uint16_t); /* vwv+buflen */
2141 if (length_needed > smblen) {
2142 goto error;
2143 }
2144 vwv = (uint16_t *)(smb_base(req->inbuf) + chain_offset + 1);
2145
2146 /*
2147 * Now grab the new byte buffer....
2148 */
2149
2150 buflen = SVAL(vwv+wct, 0);
2151
2152 /*
2153 * .. and check that it fits.
2154 */
2155
2156 length_needed += buflen;
2157 if (length_needed > smblen) {
2158 goto error;
2159 }
2160 buf = (uint8_t *)(vwv+wct+1);
2161
2162 req->cmd = chain_cmd;
2163 req->wct = wct;
2164 req->vwv = vwv;
2165 req->buflen = buflen;
2166 req->buf = buf;
2167
2168 switch_message(chain_cmd, req, smblen);
2169
2170 if (req->outbuf == NULL) {
2171 /*
2172 * This happens if the chained command has suspended itself or
2173 * if it has called srv_send_smb() itself.
2174 */
2175 return;
2176 }
2177
2178 /*
2179 * We end up here if the chained command was not itself chained or
2180 * suspended, but for example a close() command. We now need to splice
2181 * the chained commands' outbuf into the already built up chain_outbuf
2182 * and ship the result.
2183 */
2184 goto done;
2185
2186 error:
2187 /*
2188 * We end up here if there's any error in the chain syntax. Report a
2189 * DOS error, just like Windows does.
2190 */
2191 reply_force_doserror(req, ERRSRV, ERRerror);
2192 fixup_chain_error_packet(req);
2193
2194 done:
2195 /*
2196 * This scary statement intends to set the
2197 * FLAGS2_32_BIT_ERROR_CODES flg2 field in req->chain_outbuf
2198 * to the value req->outbuf carries
2199 */
2200 SSVAL(req->chain_outbuf, smb_flg2,
2201 (SVAL(req->chain_outbuf, smb_flg2) & ~FLAGS2_32_BIT_ERROR_CODES)
2202 | (SVAL(req->outbuf, smb_flg2) & FLAGS2_32_BIT_ERROR_CODES));
2203
2204 /*
2205 * Transfer the error codes from the subrequest to the main one
2206 */
2207 SSVAL(req->chain_outbuf, smb_rcls, SVAL(req->outbuf, smb_rcls));
2208 SSVAL(req->chain_outbuf, smb_err, SVAL(req->outbuf, smb_err));
2209
2210 if (!smb_splice_chain(&req->chain_outbuf,
2211 CVAL(req->outbuf, smb_com),
2212 CVAL(req->outbuf, smb_wct),
2213 (uint16_t *)(req->outbuf + smb_vwv),
2214 0, smb_buflen(req->outbuf),
2215 (uint8_t *)smb_buf(req->outbuf))) {
2216 exit_server_cleanly("chain_reply: smb_splice_chain failed\n");
2217 }
2218 TALLOC_FREE(req->outbuf);
2219
2220 smb_setlen((char *)(req->chain_outbuf),
2221 talloc_get_size(req->chain_outbuf) - 4);
2222
2223 show_msg((char *)(req->chain_outbuf));
2224
2225 if (!srv_send_smb(req->sconn, (char *)req->chain_outbuf,
2226 true, req->seqnum+1,
2227 IS_CONN_ENCRYPTED(req->conn)||req->encrypted,
2228 &req->pcd)) {
2229 exit_server_cleanly("chain_reply: srv_send_smb failed.");
2230 }
2231 TALLOC_FREE(req->chain_outbuf);
2232 req->done = true;
2233}
2234
2235/****************************************************************************
2236 Check if services need reloading.
2237****************************************************************************/
2238
2239static void check_reload(struct smbd_server_connection *sconn, time_t t)
2240{
2241
2242 if (last_smb_conf_reload_time == 0) {
2243 last_smb_conf_reload_time = t;
2244 }
2245
2246 if (t >= last_smb_conf_reload_time+SMBD_RELOAD_CHECK) {
2247 reload_services(sconn->msg_ctx, sconn->sock, True);
2248 last_smb_conf_reload_time = t;
2249 }
2250}
2251
2252static bool fd_is_readable(int fd)
2253{
2254 int ret, revents;
2255
2256 ret = poll_one_fd(fd, POLLIN|POLLHUP, 0, &revents);
2257
2258 return ((ret > 0) && ((revents & (POLLIN|POLLHUP|POLLERR)) != 0));
2259
2260}
2261
2262static void smbd_server_connection_write_handler(struct smbd_server_connection *conn)
2263{
2264 /* TODO: make write nonblocking */
2265}
2266
2267static void smbd_server_connection_read_handler(
2268 struct smbd_server_connection *conn, int fd)
2269{
2270 uint8_t *inbuf = NULL;
2271 size_t inbuf_len = 0;
2272 size_t unread_bytes = 0;
2273 bool encrypted = false;
2274 TALLOC_CTX *mem_ctx = talloc_tos();
2275 NTSTATUS status;
2276 uint32_t seqnum;
2277
2278 bool from_client = (conn->sock == fd);
2279
2280 if (from_client) {
2281 smbd_lock_socket(conn);
2282
2283 if (lp_async_smb_echo_handler() && !fd_is_readable(fd)) {
2284 DEBUG(10,("the echo listener was faster\n"));
2285 smbd_unlock_socket(conn);
2286 return;
2287 }
2288
2289 /* TODO: make this completely nonblocking */
2290 status = receive_smb_talloc(mem_ctx, conn, fd,
2291 (char **)(void *)&inbuf,
2292 0, /* timeout */
2293 &unread_bytes,
2294 &encrypted,
2295 &inbuf_len, &seqnum,
2296 false /* trusted channel */);
2297 smbd_unlock_socket(conn);
2298 } else {
2299 /* TODO: make this completely nonblocking */
2300 status = receive_smb_talloc(mem_ctx, conn, fd,
2301 (char **)(void *)&inbuf,
2302 0, /* timeout */
2303 &unread_bytes,
2304 &encrypted,
2305 &inbuf_len, &seqnum,
2306 true /* trusted channel */);
2307 }
2308
2309 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
2310 goto process;
2311 }
2312 if (NT_STATUS_IS_ERR(status)) {
2313 exit_server_cleanly("failed to receive smb request");
2314 }
2315 if (!NT_STATUS_IS_OK(status)) {
2316 return;
2317 }
2318
2319process:
2320 process_smb(conn, inbuf, inbuf_len, unread_bytes,
2321 seqnum, encrypted, NULL);
2322}
2323
2324static void smbd_server_connection_handler(struct event_context *ev,
2325 struct fd_event *fde,
2326 uint16_t flags,
2327 void *private_data)
2328{
2329 struct smbd_server_connection *conn = talloc_get_type(private_data,
2330 struct smbd_server_connection);
2331
2332 if (flags & EVENT_FD_WRITE) {
2333 smbd_server_connection_write_handler(conn);
2334 return;
2335 }
2336 if (flags & EVENT_FD_READ) {
2337 smbd_server_connection_read_handler(conn, conn->sock);
2338 return;
2339 }
2340}
2341
2342static void smbd_server_echo_handler(struct event_context *ev,
2343 struct fd_event *fde,
2344 uint16_t flags,
2345 void *private_data)
2346{
2347 struct smbd_server_connection *conn = talloc_get_type(private_data,
2348 struct smbd_server_connection);
2349
2350 if (flags & EVENT_FD_WRITE) {
2351 smbd_server_connection_write_handler(conn);
2352 return;
2353 }
2354 if (flags & EVENT_FD_READ) {
2355 smbd_server_connection_read_handler(
2356 conn, conn->smb1.echo_handler.trusted_fd);
2357 return;
2358 }
2359}
2360
2361/****************************************************************************
2362received when we should release a specific IP
2363****************************************************************************/
2364static void release_ip(const char *ip, void *priv)
2365{
2366 const char *addr = (const char *)priv;
2367 const char *p = addr;
2368
2369 if (strncmp("::ffff:", addr, 7) == 0) {
2370 p = addr + 7;
2371 }
2372
2373 DEBUG(10, ("Got release IP message for %s, "
2374 "our address is %s\n", ip, p));
2375
2376 if ((strcmp(p, ip) == 0) || ((p != addr) && strcmp(addr, ip) == 0)) {
2377 /* we can't afford to do a clean exit - that involves
2378 database writes, which would potentially mean we
2379 are still running after the failover has finished -
2380 we have to get rid of this process ID straight
2381 away */
2382 DEBUG(0,("Got release IP message for our IP %s - exiting immediately\n",
2383 ip));
2384 /* note we must exit with non-zero status so the unclean handler gets
2385 called in the parent, so that the brl database is tickled */
2386 _exit(1);
2387 }
2388}
2389
2390static void msg_release_ip(struct messaging_context *msg_ctx, void *private_data,
2391 uint32_t msg_type, struct server_id server_id, DATA_BLOB *data)
2392{
2393 struct smbd_server_connection *sconn = talloc_get_type_abort(
2394 private_data, struct smbd_server_connection);
2395
2396 release_ip((char *)data->data, sconn->client_id.addr);
2397}
2398
2399#ifdef CLUSTER_SUPPORT
2400static int client_get_tcp_info(int sock, struct sockaddr_storage *server,
2401 struct sockaddr_storage *client)
2402{
2403 socklen_t length;
2404 length = sizeof(*server);
2405 if (getsockname(sock, (struct sockaddr *)server, &length) != 0) {
2406 return -1;
2407 }
2408 length = sizeof(*client);
2409 if (getpeername(sock, (struct sockaddr *)client, &length) != 0) {
2410 return -1;
2411 }
2412 return 0;
2413}
2414#endif
2415
2416/*
2417 * Send keepalive packets to our client
2418 */
2419static bool keepalive_fn(const struct timeval *now, void *private_data)
2420{
2421 struct smbd_server_connection *sconn = smbd_server_conn;
2422 bool ret;
2423
2424 if (sconn->using_smb2) {
2425 /* Don't do keepalives on an SMB2 connection. */
2426 return false;
2427 }
2428
2429 smbd_lock_socket(smbd_server_conn);
2430 ret = send_keepalive(sconn->sock);
2431 smbd_unlock_socket(smbd_server_conn);
2432
2433 if (!ret) {
2434 char addr[INET6_ADDRSTRLEN];
2435 /*
2436 * Try and give an error message saying what
2437 * client failed.
2438 */
2439 DEBUG(0, ("send_keepalive failed for client %s. "
2440 "Error %s - exiting\n",
2441 get_peer_addr(sconn->sock, addr, sizeof(addr)),
2442 strerror(errno)));
2443 return False;
2444 }
2445 return True;
2446}
2447
2448/*
2449 * Do the recurring check if we're idle
2450 */
2451static bool deadtime_fn(const struct timeval *now, void *private_data)
2452{
2453 struct smbd_server_connection *sconn =
2454 (struct smbd_server_connection *)private_data;
2455
2456 if ((conn_num_open(sconn) == 0)
2457 || (conn_idle_all(sconn, now->tv_sec))) {
2458 DEBUG( 2, ( "Closing idle connection\n" ) );
2459 messaging_send(sconn->msg_ctx,
2460 messaging_server_id(sconn->msg_ctx),
2461 MSG_SHUTDOWN, &data_blob_null);
2462 return False;
2463 }
2464
2465 return True;
2466}
2467
2468/*
2469 * Do the recurring log file and smb.conf reload checks.
2470 */
2471
2472static bool housekeeping_fn(const struct timeval *now, void *private_data)
2473{
2474 struct smbd_server_connection *sconn = talloc_get_type_abort(
2475 private_data, struct smbd_server_connection);
2476
2477 DEBUG(5, ("housekeeping\n"));
2478
2479 change_to_root_user();
2480
2481 /* update printer queue caches if necessary */
2482 update_monitored_printq_cache(sconn->msg_ctx);
2483
2484 /* check if we need to reload services */
2485 check_reload(sconn, time_mono(NULL));
2486
2487 /* Change machine password if neccessary. */
2488 attempt_machine_password_change();
2489
2490 /*
2491 * Force a log file check.
2492 */
2493 force_check_log_size();
2494 check_log_size();
2495 return true;
2496}
2497
2498static int create_unlink_tmp(const char *dir)
2499{
2500 char *fname;
2501 int fd;
2502
2503 fname = talloc_asprintf(talloc_tos(), "%s/listenerlock_XXXXXX", dir);
2504 if (fname == NULL) {
2505 errno = ENOMEM;
2506 return -1;
2507 }
2508 fd = mkstemp(fname);
2509 if (fd == -1) {
2510 TALLOC_FREE(fname);
2511 return -1;
2512 }
2513 if (unlink(fname) == -1) {
2514 int sys_errno = errno;
2515 close(fd);
2516 TALLOC_FREE(fname);
2517 errno = sys_errno;
2518 return -1;
2519 }
2520 TALLOC_FREE(fname);
2521 return fd;
2522}
2523
2524struct smbd_echo_state {
2525 struct tevent_context *ev;
2526 struct iovec *pending;
2527 struct smbd_server_connection *sconn;
2528 int parent_pipe;
2529
2530 struct tevent_fd *parent_fde;
2531
2532 struct tevent_fd *read_fde;
2533 struct tevent_req *write_req;
2534};
2535
2536static void smbd_echo_writer_done(struct tevent_req *req);
2537
2538static void smbd_echo_activate_writer(struct smbd_echo_state *state)
2539{
2540 int num_pending;
2541
2542 if (state->write_req != NULL) {
2543 return;
2544 }
2545
2546 num_pending = talloc_array_length(state->pending);
2547 if (num_pending == 0) {
2548 return;
2549 }
2550
2551 state->write_req = writev_send(state, state->ev, NULL,
2552 state->parent_pipe, false,
2553 state->pending, num_pending);
2554 if (state->write_req == NULL) {
2555 DEBUG(1, ("writev_send failed\n"));
2556 exit(1);
2557 }
2558
2559 talloc_steal(state->write_req, state->pending);
2560 state->pending = NULL;
2561
2562 tevent_req_set_callback(state->write_req, smbd_echo_writer_done,
2563 state);
2564}
2565
2566static void smbd_echo_writer_done(struct tevent_req *req)
2567{
2568 struct smbd_echo_state *state = tevent_req_callback_data(
2569 req, struct smbd_echo_state);
2570 ssize_t written;
2571 int err;
2572
2573 written = writev_recv(req, &err);
2574 TALLOC_FREE(req);
2575 state->write_req = NULL;
2576 if (written == -1) {
2577 DEBUG(1, ("writev to parent failed: %s\n", strerror(err)));
2578 exit(1);
2579 }
2580 DEBUG(10,("echo_handler[%d]: forwarded pdu to main\n", (int)sys_getpid()));
2581 smbd_echo_activate_writer(state);
2582}
2583
2584static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
2585 uint32_t seqnum)
2586{
2587 struct smb_request req;
2588 uint16_t num_replies;
2589 size_t out_len;
2590 char *outbuf;
2591 bool ok;
2592
2593 if ((inbuf_len == 4) && (CVAL(inbuf, 0) == SMBkeepalive)) {
2594 DEBUG(10, ("Got netbios keepalive\n"));
2595 /*
2596 * Just swallow it
2597 */
2598 return true;
2599 }
2600
2601 if (inbuf_len < smb_size) {
2602 DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
2603 return false;
2604 }
2605 if (!valid_smb_header(inbuf)) {
2606 DEBUG(10, ("Got invalid SMB header\n"));
2607 return false;
2608 }
2609
2610 if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
2611 seqnum)) {
2612 return false;
2613 }
2614 req.inbuf = inbuf;
2615
2616 DEBUG(10, ("smbecho handler got cmd %d (%s)\n", (int)req.cmd,
2617 smb_messages[req.cmd].name
2618 ? smb_messages[req.cmd].name : "unknown"));
2619
2620 if (req.cmd != SMBecho) {
2621 return false;
2622 }
2623 if (req.wct < 1) {
2624 return false;
2625 }
2626
2627 num_replies = SVAL(req.vwv+0, 0);
2628 if (num_replies != 1) {
2629 /* Not a Windows "Hey, you're still there?" request */
2630 return false;
2631 }
2632
2633 if (!create_outbuf(talloc_tos(), &req, (char *)req.inbuf, &outbuf,
2634 1, req.buflen)) {
2635 DEBUG(10, ("create_outbuf failed\n"));
2636 return false;
2637 }
2638 req.outbuf = (uint8_t *)outbuf;
2639
2640 SSVAL(req.outbuf, smb_vwv0, num_replies);
2641
2642 if (req.buflen > 0) {
2643 memcpy(smb_buf(req.outbuf), req.buf, req.buflen);
2644 }
2645
2646 out_len = smb_len(req.outbuf) + 4;
2647
2648 ok = srv_send_smb(req.sconn,
2649 (char *)outbuf,
2650 true, seqnum+1,
2651 false, &req.pcd);
2652 TALLOC_FREE(outbuf);
2653 if (!ok) {
2654 exit(1);
2655 }
2656
2657 return true;
2658}
2659
2660static void smbd_echo_exit(struct tevent_context *ev,
2661 struct tevent_fd *fde, uint16_t flags,
2662 void *private_data)
2663{
2664 DEBUG(2, ("smbd_echo_exit: lost connection to parent\n"));
2665 exit(0);
2666}
2667
2668static void smbd_echo_reader(struct tevent_context *ev,
2669 struct tevent_fd *fde, uint16_t flags,
2670 void *private_data)
2671{
2672 struct smbd_echo_state *state = talloc_get_type_abort(
2673 private_data, struct smbd_echo_state);
2674 struct smbd_server_connection *sconn = state->sconn;
2675 size_t unread, num_pending;
2676 NTSTATUS status;
2677 struct iovec *tmp;
2678 size_t iov_len;
2679 uint32_t seqnum = 0;
2680 bool reply;
2681 bool ok;
2682 bool encrypted = false;
2683
2684 smb_msleep(1000);
2685
2686 ok = smbd_lock_socket_internal(sconn);
2687 if (!ok) {
2688 DEBUG(0, ("%s: failed to lock socket\n",
2689 __location__));
2690 exit(1);
2691 }
2692
2693 if (!fd_is_readable(sconn->sock)) {
2694 DEBUG(10,("echo_handler[%d] the parent smbd was faster\n",
2695 (int)sys_getpid()));
2696 ok = smbd_unlock_socket_internal(sconn);
2697 if (!ok) {
2698 DEBUG(1, ("%s: failed to unlock socket in\n",
2699 __location__));
2700 exit(1);
2701 }
2702 return;
2703 }
2704
2705 num_pending = talloc_array_length(state->pending);
2706 tmp = talloc_realloc(state, state->pending, struct iovec,
2707 num_pending+1);
2708 if (tmp == NULL) {
2709 DEBUG(1, ("talloc_realloc failed\n"));
2710 exit(1);
2711 }
2712 state->pending = tmp;
2713
2714 DEBUG(10,("echo_handler[%d]: reading pdu\n", (int)sys_getpid()));
2715
2716 status = receive_smb_talloc(state->pending, sconn, sconn->sock,
2717 (char **)(void *)&state->pending[num_pending].iov_base,
2718 0 /* timeout */,
2719 &unread,
2720 &encrypted,
2721 &iov_len,
2722 &seqnum,
2723 false /* trusted_channel*/);
2724 if (!NT_STATUS_IS_OK(status)) {
2725 DEBUG(1, ("echo_handler[%d]: receive_smb_raw_talloc failed: %s\n",
2726 (int)sys_getpid(), nt_errstr(status)));
2727 exit(1);
2728 }
2729 state->pending[num_pending].iov_len = iov_len;
2730
2731 ok = smbd_unlock_socket_internal(sconn);
2732 if (!ok) {
2733 DEBUG(1, ("%s: failed to unlock socket in\n",
2734 __location__));
2735 exit(1);
2736 }
2737
2738 reply = smbd_echo_reply((uint8_t *)state->pending[num_pending].iov_base,
2739 state->pending[num_pending].iov_len,
2740 seqnum);
2741 if (reply) {
2742 DEBUG(10,("echo_handler[%d]: replied to client\n", (int)sys_getpid()));
2743 /* no check, shrinking by some bytes does not fail */
2744 state->pending = talloc_realloc(state, state->pending,
2745 struct iovec,
2746 num_pending);
2747 return;
2748 }
2749
2750 if (state->pending[num_pending].iov_len >= smb_size) {
2751 /*
2752 * place the seqnum in the packet so that the main process
2753 * can reply with signing
2754 */
2755 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2756 smb_ss_field, seqnum);
2757 SIVAL((uint8_t *)state->pending[num_pending].iov_base,
2758 smb_ss_field+4, NT_STATUS_V(NT_STATUS_OK));
2759 }
2760
2761 DEBUG(10,("echo_handler[%d]: forward to main\n", (int)sys_getpid()));
2762 smbd_echo_activate_writer(state);
2763}
2764
2765static void smbd_echo_loop(struct smbd_server_connection *sconn,
2766 int parent_pipe)
2767{
2768 struct smbd_echo_state *state;
2769
2770 state = talloc_zero(sconn, struct smbd_echo_state);
2771 if (state == NULL) {
2772 DEBUG(1, ("talloc failed\n"));
2773 return;
2774 }
2775 state->sconn = sconn;
2776 state->parent_pipe = parent_pipe;
2777 state->ev = s3_tevent_context_init(state);
2778 if (state->ev == NULL) {
2779 DEBUG(1, ("tevent_context_init failed\n"));
2780 TALLOC_FREE(state);
2781 return;
2782 }
2783 state->parent_fde = tevent_add_fd(state->ev, state, parent_pipe,
2784 TEVENT_FD_READ, smbd_echo_exit,
2785 state);
2786 if (state->parent_fde == NULL) {
2787 DEBUG(1, ("tevent_add_fd failed\n"));
2788 TALLOC_FREE(state);
2789 return;
2790 }
2791 state->read_fde = tevent_add_fd(state->ev, state, sconn->sock,
2792 TEVENT_FD_READ, smbd_echo_reader,
2793 state);
2794 if (state->read_fde == NULL) {
2795 DEBUG(1, ("tevent_add_fd failed\n"));
2796 TALLOC_FREE(state);
2797 return;
2798 }
2799
2800 while (true) {
2801 if (tevent_loop_once(state->ev) == -1) {
2802 DEBUG(1, ("tevent_loop_once failed: %s\n",
2803 strerror(errno)));
2804 break;
2805 }
2806 }
2807 TALLOC_FREE(state);
2808}
2809
2810/*
2811 * Handle SMBecho requests in a forked child process
2812 */
2813bool fork_echo_handler(struct smbd_server_connection *sconn)
2814{
2815 int listener_pipe[2];
2816 int res;
2817 pid_t child;
2818
2819 res = pipe(listener_pipe);
2820 if (res == -1) {
2821 DEBUG(1, ("pipe() failed: %s\n", strerror(errno)));
2822 return false;
2823 }
2824 sconn->smb1.echo_handler.socket_lock_fd = create_unlink_tmp(lp_lockdir());
2825 if (sconn->smb1.echo_handler.socket_lock_fd == -1) {
2826 DEBUG(1, ("Could not create lock fd: %s\n", strerror(errno)));
2827 goto fail;
2828 }
2829
2830 child = sys_fork();
2831 if (child == 0) {
2832 NTSTATUS status;
2833
2834 close(listener_pipe[0]);
2835 set_blocking(listener_pipe[1], false);
2836
2837 status = reinit_after_fork(sconn->msg_ctx,
2838 smbd_event_context(),
2839 procid_self(), false);
2840 if (!NT_STATUS_IS_OK(status)) {
2841 DEBUG(1, ("reinit_after_fork failed: %s\n",
2842 nt_errstr(status)));
2843 exit(1);
2844 }
2845 smbd_echo_loop(sconn, listener_pipe[1]);
2846 exit(0);
2847 }
2848 close(listener_pipe[1]);
2849 listener_pipe[1] = -1;
2850 sconn->smb1.echo_handler.trusted_fd = listener_pipe[0];
2851
2852 DEBUG(10,("fork_echo_handler: main[%d] echo_child[%d]\n", (int)sys_getpid(), child));
2853
2854 /*
2855 * Without smb signing this is the same as the normal smbd
2856 * listener. This needs to change once signing comes in.
2857 */
2858 sconn->smb1.echo_handler.trusted_fde = event_add_fd(smbd_event_context(),
2859 sconn,
2860 sconn->smb1.echo_handler.trusted_fd,
2861 EVENT_FD_READ,
2862 smbd_server_echo_handler,
2863 sconn);
2864 if (sconn->smb1.echo_handler.trusted_fde == NULL) {
2865 DEBUG(1, ("event_add_fd failed\n"));
2866 goto fail;
2867 }
2868
2869 return true;
2870
2871fail:
2872 if (listener_pipe[0] != -1) {
2873 close(listener_pipe[0]);
2874 }
2875 if (listener_pipe[1] != -1) {
2876 close(listener_pipe[1]);
2877 }
2878 sconn->smb1.echo_handler.trusted_fd = -1;
2879 if (sconn->smb1.echo_handler.socket_lock_fd != -1) {
2880 close(sconn->smb1.echo_handler.socket_lock_fd);
2881 }
2882 sconn->smb1.echo_handler.trusted_fd = -1;
2883 sconn->smb1.echo_handler.socket_lock_fd = -1;
2884 return false;
2885}
2886
2887#if CLUSTER_SUPPORT
2888
2889static NTSTATUS smbd_register_ips(struct smbd_server_connection *sconn,
2890 struct sockaddr_storage *srv,
2891 struct sockaddr_storage *clnt)
2892{
2893 struct ctdbd_connection *cconn;
2894 char tmp_addr[INET6_ADDRSTRLEN];
2895 char *addr;
2896
2897 cconn = messaging_ctdbd_connection();
2898 if (cconn == NULL) {
2899 return NT_STATUS_NO_MEMORY;
2900 }
2901
2902 client_socket_addr(sconn->sock, tmp_addr, sizeof(tmp_addr));
2903 addr = talloc_strdup(cconn, tmp_addr);
2904 if (addr == NULL) {
2905 return NT_STATUS_NO_MEMORY;
2906 }
2907 return ctdbd_register_ips(cconn, srv, clnt, release_ip, addr);
2908}
2909
2910#endif
2911
2912/****************************************************************************
2913 Process commands from the client
2914****************************************************************************/
2915
2916void smbd_process(struct smbd_server_connection *sconn)
2917{
2918 TALLOC_CTX *frame = talloc_stackframe();
2919 struct sockaddr_storage ss;
2920 struct sockaddr *sa = NULL;
2921 socklen_t sa_socklen;
2922 struct tsocket_address *local_address = NULL;
2923 struct tsocket_address *remote_address = NULL;
2924 const char *remaddr = NULL;
2925 int ret;
2926
2927 if (lp_maxprotocol() == PROTOCOL_SMB2) {
2928 /*
2929 * We're not making the decision here,
2930 * we're just allowing the client
2931 * to decide between SMB1 and SMB2
2932 * with the first negprot
2933 * packet.
2934 */
2935 sconn->using_smb2 = true;
2936 }
2937
2938 /* Ensure child is set to blocking mode */
2939 set_blocking(sconn->sock,True);
2940
2941 set_socket_options(sconn->sock, "SO_KEEPALIVE");
2942 set_socket_options(sconn->sock, lp_socket_options());
2943
2944 sa = (struct sockaddr *)(void *)&ss;
2945 sa_socklen = sizeof(ss);
2946 ret = getpeername(sconn->sock, sa, &sa_socklen);
2947 if (ret != 0) {
2948 int level = (errno == ENOTCONN)?2:0;
2949 DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
2950 exit_server_cleanly("getpeername() failed.\n");
2951 }
2952 ret = tsocket_address_bsd_from_sockaddr(sconn,
2953 sa, sa_socklen,
2954 &remote_address);
2955 if (ret != 0) {
2956 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2957 __location__, strerror(errno)));
2958 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2959 }
2960
2961 sa = (struct sockaddr *)(void *)&ss;
2962 sa_socklen = sizeof(ss);
2963 ret = getsockname(sconn->sock, sa, &sa_socklen);
2964 if (ret != 0) {
2965 int level = (errno == ENOTCONN)?2:0;
2966 DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
2967 exit_server_cleanly("getsockname() failed.\n");
2968 }
2969 ret = tsocket_address_bsd_from_sockaddr(sconn,
2970 sa, sa_socklen,
2971 &local_address);
2972 if (ret != 0) {
2973 DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
2974 __location__, strerror(errno)));
2975 exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
2976 }
2977
2978 sconn->local_address = local_address;
2979 sconn->remote_address = remote_address;
2980
2981 if (tsocket_address_is_inet(remote_address, "ip")) {
2982 remaddr = tsocket_address_inet_addr_string(
2983 sconn->remote_address,
2984 talloc_tos());
2985 if (remaddr == NULL) {
2986
2987 }
2988 } else {
2989 remaddr = "0.0.0.0";
2990 }
2991
2992 /* this is needed so that we get decent entries
2993 in smbstatus for port 445 connects */
2994 set_remote_machine_name(remaddr, false);
2995 reload_services(sconn->msg_ctx, sconn->sock, true);
2996
2997 /*
2998 * Before the first packet, check the global hosts allow/ hosts deny
2999 * parameters before doing any parsing of packets passed to us by the
3000 * client. This prevents attacks on our parsing code from hosts not in
3001 * the hosts allow list.
3002 */
3003
3004 if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
3005 sconn->client_id.name,
3006 sconn->client_id.addr)) {
3007 /*
3008 * send a negative session response "not listening on calling
3009 * name"
3010 */
3011 unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
3012 DEBUG( 1, ("Connection denied from %s to %s\n",
3013 tsocket_address_string(remote_address, talloc_tos()),
3014 tsocket_address_string(local_address, talloc_tos())));
3015 (void)srv_send_smb(sconn,(char *)buf, false,
3016 0, false, NULL);
3017 exit_server_cleanly("connection denied");
3018 }
3019
3020 DEBUG(10, ("Connection allowed from %s to %s\n",
3021 tsocket_address_string(remote_address, talloc_tos()),
3022 tsocket_address_string(local_address, talloc_tos())));
3023
3024 init_modules();
3025
3026 smb_perfcount_init();
3027
3028 if (!init_account_policy()) {
3029 exit_server("Could not open account policy tdb.\n");
3030 }
3031
3032 if (*lp_rootdir()) {
3033 if (chroot(lp_rootdir()) != 0) {
3034 DEBUG(0,("Failed to change root to %s\n", lp_rootdir()));
3035 exit_server("Failed to chroot()");
3036 }
3037 if (chdir("/") == -1) {
3038 DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_rootdir()));
3039 exit_server("Failed to chroot()");
3040 }
3041 DEBUG(0,("Changed root to %s\n", lp_rootdir()));
3042 }
3043
3044 if (!srv_init_signing(sconn)) {
3045 exit_server("Failed to init smb_signing");
3046 }
3047
3048 /* Setup oplocks */
3049 if (!init_oplocks(sconn->msg_ctx))
3050 exit_server("Failed to init oplocks");
3051
3052 /* register our message handlers */
3053 messaging_register(sconn->msg_ctx, NULL,
3054 MSG_SMB_FORCE_TDIS, msg_force_tdis);
3055 messaging_register(sconn->msg_ctx, sconn,
3056 MSG_SMB_RELEASE_IP, msg_release_ip);
3057 messaging_register(sconn->msg_ctx, NULL,
3058 MSG_SMB_CLOSE_FILE, msg_close_file);
3059
3060 /*
3061 * Use the default MSG_DEBUG handler to avoid rebroadcasting
3062 * MSGs to all child processes
3063 */
3064 messaging_deregister(sconn->msg_ctx,
3065 MSG_DEBUG, NULL);
3066 messaging_register(sconn->msg_ctx, NULL,
3067 MSG_DEBUG, debug_message);
3068
3069 if ((lp_keepalive() != 0)
3070 && !(event_add_idle(smbd_event_context(), NULL,
3071 timeval_set(lp_keepalive(), 0),
3072 "keepalive", keepalive_fn,
3073 NULL))) {
3074 DEBUG(0, ("Could not add keepalive event\n"));
3075 exit(1);
3076 }
3077
3078 if (!(event_add_idle(smbd_event_context(), NULL,
3079 timeval_set(IDLE_CLOSED_TIMEOUT, 0),
3080 "deadtime", deadtime_fn, sconn))) {
3081 DEBUG(0, ("Could not add deadtime event\n"));
3082 exit(1);
3083 }
3084
3085 if (!(event_add_idle(smbd_event_context(), NULL,
3086 timeval_set(SMBD_HOUSEKEEPING_INTERVAL, 0),
3087 "housekeeping", housekeeping_fn, sconn))) {
3088 DEBUG(0, ("Could not add housekeeping event\n"));
3089 exit(1);
3090 }
3091
3092#ifdef CLUSTER_SUPPORT
3093
3094 if (lp_clustering()) {
3095 /*
3096 * We need to tell ctdb about our client's TCP
3097 * connection, so that for failover ctdbd can send
3098 * tickle acks, triggering a reconnection by the
3099 * client.
3100 */
3101
3102 struct sockaddr_storage srv, clnt;
3103
3104 if (client_get_tcp_info(sconn->sock, &srv, &clnt) == 0) {
3105 NTSTATUS status;
3106 status = smbd_register_ips(sconn, &srv, &clnt);
3107 if (!NT_STATUS_IS_OK(status)) {
3108 DEBUG(0, ("ctdbd_register_ips failed: %s\n",
3109 nt_errstr(status)));
3110 }
3111 } else
3112 {
3113 DEBUG(0,("Unable to get tcp info for "
3114 "CTDB_CONTROL_TCP_CLIENT: %s\n",
3115 strerror(errno)));
3116 }
3117 }
3118
3119#endif
3120
3121 sconn->nbt.got_session = false;
3122
3123 sconn->smb1.negprot.max_recv = MIN(lp_maxxmit(),BUFFER_SIZE);
3124
3125 sconn->smb1.sessions.done_sesssetup = false;
3126 sconn->smb1.sessions.max_send = BUFFER_SIZE;
3127 sconn->smb1.sessions.last_session_tag = UID_FIELD_INVALID;
3128 /* users from session setup */
3129 sconn->smb1.sessions.session_userlist = NULL;
3130 /* workgroup from session setup. */
3131 sconn->smb1.sessions.session_workgroup = NULL;
3132 /* this holds info on user ids that are already validated for this VC */
3133 sconn->smb1.sessions.validated_users = NULL;
3134 sconn->smb1.sessions.next_vuid = VUID_OFFSET;
3135 sconn->smb1.sessions.num_validated_vuids = 0;
3136
3137 conn_init(sconn);
3138 if (!init_dptrs(sconn)) {
3139 exit_server("init_dptrs() failed");
3140 }
3141
3142 sconn->smb1.fde = event_add_fd(smbd_event_context(),
3143 sconn,
3144 sconn->sock,
3145 EVENT_FD_READ,
3146 smbd_server_connection_handler,
3147 sconn);
3148 if (!sconn->smb1.fde) {
3149 exit_server("failed to create smbd_server_connection fde");
3150 }
3151
3152 TALLOC_FREE(frame);
3153
3154 while (True) {
3155 NTSTATUS status;
3156
3157 frame = talloc_stackframe_pool(8192);
3158
3159 errno = 0;
3160
3161 status = smbd_server_connection_loop_once(sconn);
3162 if (!NT_STATUS_EQUAL(status, NT_STATUS_RETRY) &&
3163 !NT_STATUS_IS_OK(status)) {
3164 DEBUG(3, ("smbd_server_connection_loop_once failed: %s,"
3165 " exiting\n", nt_errstr(status)));
3166 break;
3167 }
3168
3169 TALLOC_FREE(frame);
3170 }
3171
3172 exit_server_cleanly(NULL);
3173}
3174
3175bool req_is_in_chain(struct smb_request *req)
3176{
3177 if (req->vwv != (uint16_t *)(req->inbuf+smb_vwv)) {
3178 /*
3179 * We're right now handling a subsequent request, so we must
3180 * be in a chain
3181 */
3182 return true;
3183 }
3184
3185 if (!is_andx_req(req->cmd)) {
3186 return false;
3187 }
3188
3189 if (req->wct < 2) {
3190 /*
3191 * Okay, an illegal request, but definitely not chained :-)
3192 */
3193 return false;
3194 }
3195
3196 return (CVAL(req->vwv+0, 0) != 0xFF);
3197}
Note: See TracBrowser for help on using the repository browser.