extern bool global_machine_password_needs_changing;
+/* Internal message queue for deferred opens. */
+struct pending_message_list {
+ struct pending_message_list *next, *prev;
+ struct timeval request_time; /* When was this first issued? */
+ struct smbd_server_connection *sconn;
+ struct timed_event *te;
+ struct smb_perfcount_data pcd;
+ uint32_t seqnum;
+ bool encrypted;
+ bool processed;
+ DATA_BLOB buf;
+ DATA_BLOB private_data;
+};
+
static void construct_reply_common(struct smb_request *req, const char *inbuf,
char *outbuf);
static struct pending_message_list *get_deferred_open_message_smb(
}
if (do_encrypt) {
- NTSTATUS status = srv_encrypt_buffer(buffer, &buf_out);
+ NTSTATUS status = srv_encrypt_buffer(sconn, buffer, &buf_out);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("send_smb: SMB encryption failed "
"on outgoing packet! Error %s\n",
get_peer_addr(sconn->sock, addr, sizeof(addr)),
(int)ret, strerror(errno) ));
- srv_free_enc_buffer(buf_out);
+ srv_free_enc_buffer(sconn, buf_out);
goto out;
}
SMB_PERFCOUNT_SET_MSGLEN_OUT(pcd, len);
- srv_free_enc_buffer(buf_out);
+ srv_free_enc_buffer(sconn, buf_out);
out:
SMB_PERFCOUNT_END(pcd);
status = receive_smb_raw_talloc(mem_ctx, sconn, sock, buffer, timeout,
p_unread, &len);
if (!NT_STATUS_IS_OK(status)) {
- DEBUG(1, ("read_smb_length_return_keepalive failed for "
- "client %s read error = %s.\n",
- tsocket_address_string(sconn->remote_address,
- talloc_tos()),
- nt_errstr(status)));
+ DEBUG(NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)?5:1,
+ ("receive_smb_raw_talloc failed for client %s "
+ "read error = %s.\n",
+ tsocket_address_string(sconn->remote_address,
+ talloc_tos()),
+ nt_errstr(status)) );
return status;
}
if (is_encrypted_packet(sconn, (uint8_t *)*buffer)) {
- status = srv_decrypt_buffer(*buffer);
+ status = srv_decrypt_buffer(sconn, *buffer);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("receive_smb_talloc: SMB decryption failed on "
"incoming packet! Error %s\n",
{
struct pending_message_list *msg = talloc_get_type(private_data,
struct pending_message_list);
+ struct smbd_server_connection *sconn = msg->sconn;
TALLOC_CTX *mem_ctx = talloc_tos();
uint64_t mid = (uint64_t)SVAL(msg->buf.data,smb_mid);
uint8_t *inbuf;
* re-processed in error. */
msg->processed = true;
- process_smb(smbd_server_conn, inbuf,
+ process_smb(sconn, inbuf,
msg->buf.length, 0,
msg->seqnum, msg->encrypted, &msg->pcd);
/* If it's still there and was processed, remove it. */
- msg = get_deferred_open_message_smb(smbd_server_conn, mid);
+ msg = get_deferred_open_message_smb(sconn, mid);
if (msg && msg->processed) {
- remove_deferred_open_message_smb(smbd_server_conn, mid);
+ remove_deferred_open_message_smb(sconn, mid);
}
}
DEBUG(0,("push_message: malloc fail (1)\n"));
return False;
}
+ msg->sconn = req->sconn;
msg->buf = data_blob_talloc(msg, req->inbuf, msg_len);
if(msg->buf.data == NULL) {
}
}
- msg->te = event_add_timed(server_event_context(),
- msg,
- end_time,
- smbd_deferred_open_timer,
- msg);
+ msg->te = tevent_add_timer(msg->sconn->ev_ctx,
+ msg,
+ end_time,
+ smbd_deferred_open_timer,
+ msg);
if (!msg->te) {
DEBUG(0,("push_message: event_add_timed failed\n"));
TALLOC_FREE(msg);
"scheduling mid %llu\n",
(unsigned long long)mid ));
- te = event_add_timed(server_event_context(),
- pml,
- timeval_zero(),
- smbd_deferred_open_timer,
- pml);
+ te = tevent_add_timer(pml->sconn->ev_ctx,
+ pml,
+ timeval_zero(),
+ smbd_deferred_open_timer,
+ pml);
if (!te) {
DEBUG(10,("schedule_deferred_open_message_smb: "
"event_add_timed() failed, "
{
struct pending_message_list *pml;
- if (smbd_server_conn->using_smb2) {
+ if (smbreq->sconn->using_smb2) {
return get_deferred_open_message_state_smb2(smbreq->smb2req,
p_request_time,
pp_state);
static void construct_reply_common(struct smb_request *req, const char *inbuf,
char *outbuf)
{
+ uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
+ uint16_t out_flags2 = common_flags2;
+
+ out_flags2 |= in_flags2 & FLAGS2_UNICODE_STRINGS;
+ out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES;
+ out_flags2 |= in_flags2 & FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
+
srv_set_message(outbuf,0,0,false);
SCVAL(outbuf, smb_com, req->cmd);
SIVAL(outbuf,smb_rcls,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
- SSVAL(outbuf,smb_flg2,
- (SVAL(inbuf,smb_flg2) & FLAGS2_UNICODE_STRINGS) |
- common_flags2);
+ SSVAL(outbuf,smb_flg2, out_flags2);
memset(outbuf+smb_pidhigh,'\0',(smb_tid-smb_pidhigh));
+ memcpy(outbuf+smb_ss_field, inbuf+smb_ss_field, 8);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
NTSTATUS status;
uint32_t seqnum;
- bool from_client = (sconn->sock == fd);
+ bool from_client;
+
+ if (lp_async_smb_echo_handler()
+ && fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
+ /*
+ * This is the super-ugly hack to prefer the packets
+ * forwarded by the echo handler over the ones by the
+ * client directly
+ */
+ fd = sconn->smb1.echo_handler.trusted_fd;
+ }
+
+ from_client = (sconn->sock == fd);
if (from_client) {
smbd_lock_socket(sconn);
- if (lp_async_smb_echo_handler()) {
-
- if (fd_is_readable(sconn->smb1.echo_handler.trusted_fd)) {
- /*
- * This is the super-ugly hack to
- * prefer the packets forwarded by the
- * echo handler over the ones by the
- * client directly
- */
- fd = sconn->smb1.echo_handler.trusted_fd;
- } else if (!fd_is_readable(fd)) {
- DEBUG(10,("the echo listener was faster\n"));
- smbd_unlock_socket(sconn);
- return;
- }
+ if (!fd_is_readable(fd)) {
+ DEBUG(10,("the echo listener was faster\n"));
+ smbd_unlock_socket(sconn);
+ return;
}
+ }
+
+ /* TODO: make this completely nonblocking */
+ status = receive_smb_talloc(mem_ctx, sconn, fd,
+ (char **)(void *)&inbuf,
+ 0, /* timeout */
+ &unread_bytes,
+ &encrypted,
+ &inbuf_len, &seqnum,
+ false /* trusted channel */);
- /* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, sconn, fd,
- (char **)(void *)&inbuf,
- 0, /* timeout */
- &unread_bytes,
- &encrypted,
- &inbuf_len, &seqnum,
- false /* trusted channel */);
+ if (from_client) {
smbd_unlock_socket(sconn);
- } else {
- /* TODO: make this completely nonblocking */
- status = receive_smb_talloc(mem_ctx, sconn, fd,
- (char **)(void *)&inbuf,
- 0, /* timeout */
- &unread_bytes,
- &encrypted,
- &inbuf_len, &seqnum,
- true /* trusted channel */);
}
if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
*/
static bool keepalive_fn(const struct timeval *now, void *private_data)
{
- struct smbd_server_connection *sconn = smbd_server_conn;
+ struct smbd_server_connection *sconn = talloc_get_type_abort(
+ private_data, struct smbd_server_connection);
bool ret;
if (sconn->using_smb2) {
return false;
}
- smbd_lock_socket(smbd_server_conn);
+ smbd_lock_socket(sconn);
ret = send_keepalive(sconn->sock);
- smbd_unlock_socket(smbd_server_conn);
+ smbd_unlock_socket(sconn);
if (!ret) {
char addr[INET6_ADDRSTRLEN];
smbd_echo_activate_writer(state);
}
-static bool smbd_echo_reply(uint8_t *inbuf, size_t inbuf_len,
+static bool smbd_echo_reply(struct smbd_echo_state *state,
+ uint8_t *inbuf, size_t inbuf_len,
uint32_t seqnum)
{
struct smb_request req;
DEBUG(10, ("Got short packet: %d bytes\n", (int)inbuf_len));
return false;
}
- if (!valid_smb_header(smbd_server_conn, inbuf)) {
+ if (!valid_smb_header(state->sconn, inbuf)) {
DEBUG(10, ("Got invalid SMB header\n"));
return false;
}
- if (!init_smb_request(&req, smbd_server_conn, inbuf, 0, false,
+ if (!init_smb_request(&req, state->sconn, inbuf, 0, false,
seqnum)) {
return false;
}
exit(1);
}
- reply = smbd_echo_reply((uint8_t *)buf, buflen, seqnum);
+ reply = smbd_echo_reply(state, (uint8_t *)buf, buflen, seqnum);
if (!reply) {
size_t num_pending;
struct iovec *tmp;
set_blocking(listener_pipe[1], false);
status = reinit_after_fork(sconn->msg_ctx,
- server_event_context(),
+ sconn->ev_ctx,
procid_self(), false);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("reinit_after_fork failed: %s\n",
* Without smb signing this is the same as the normal smbd
* listener. This needs to change once signing comes in.
*/
- sconn->smb1.echo_handler.trusted_fde = event_add_fd(server_event_context(),
+ sconn->smb1.echo_handler.trusted_fde = tevent_add_fd(sconn->ev_ctx,
sconn,
sconn->smb1.echo_handler.trusted_fd,
- EVENT_FD_READ,
+ TEVENT_FD_READ,
smbd_server_echo_handler,
sconn);
if (sconn->smb1.echo_handler.trusted_fde == NULL) {
socklen_t sa_socklen;
struct tsocket_address *local_address = NULL;
struct tsocket_address *remote_address = NULL;
+ const char *locaddr = NULL;
const char *remaddr = NULL;
char *rhost;
int ret;
sconn->local_address = local_address;
sconn->remote_address = remote_address;
+ if (tsocket_address_is_inet(local_address, "ip")) {
+ locaddr = tsocket_address_inet_addr_string(
+ sconn->local_address,
+ talloc_tos());
+ if (locaddr == NULL) {
+ DEBUG(0,("%s: tsocket_address_inet_addr_string local failed - %s\n",
+ __location__, strerror(errno)));
+ exit_server_cleanly("tsocket_address_inet_addr_string local failed.\n");
+ }
+ } else {
+ locaddr = "0.0.0.0";
+ }
+
if (tsocket_address_is_inet(remote_address, "ip")) {
remaddr = tsocket_address_inet_addr_string(
sconn->remote_address,
}
sconn->remote_hostname = talloc_move(sconn, &rhost);
+ sub_set_socket_ids(remaddr,
+ sconn->remote_hostname,
+ locaddr);
+
if (!allow_access(lp_hostsdeny(-1), lp_hostsallow(-1),
sconn->remote_hostname,
remaddr)) {
/* register our message handlers */
messaging_register(sconn->msg_ctx, NULL,
MSG_SMB_FORCE_TDIS, msg_force_tdis);
- messaging_register(sconn->msg_ctx, NULL,
+ messaging_register(sconn->msg_ctx, sconn,
MSG_SMB_CLOSE_FILE, msg_close_file);
/*
&& !(event_add_idle(ev_ctx, NULL,
timeval_set(lp_keepalive(), 0),
"keepalive", keepalive_fn,
- NULL))) {
+ sconn))) {
DEBUG(0, ("Could not add keepalive event\n"));
exit(1);
}