#include "../libcli/security/dom_sid.h"
#include "../libcli/security/security_token.h"
#include "lib/id_cache.h"
+#include "lib/sys_rw_data.h"
#include "serverid.h"
#include "system/threads.h"
struct deferred_open_record *open_rec;
};
-static void construct_reply_common(struct smb_request *req, const char *inbuf,
+static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
char *outbuf);
static struct pending_message_list *get_deferred_open_message_smb(
struct smbd_server_connection *sconn, uint64_t mid);
/* If it's still there and was processed, remove it. */
msg = get_deferred_open_message_smb(sconn, mid);
if (msg && msg->processed) {
- remove_deferred_open_message_smb(sconn, mid);
+ remove_deferred_open_message_smb(xconn, mid);
}
}
Function to delete a sharing violation open message by mid.
****************************************************************************/
-void remove_deferred_open_message_smb(struct smbd_server_connection *sconn,
+void remove_deferred_open_message_smb(struct smbXsrv_connection *xconn,
uint64_t mid)
{
+ struct smbd_server_connection *sconn = xconn->client->sconn;
struct pending_message_list *pml;
if (sconn->using_smb2) {
- remove_deferred_open_message_smb2(sconn, mid);
+ remove_deferred_open_message_smb2(xconn, mid);
return;
}
schedule it for immediate processing.
****************************************************************************/
-bool schedule_deferred_open_message_smb(struct smbd_server_connection *sconn,
+bool schedule_deferred_open_message_smb(struct smbXsrv_connection *xconn,
uint64_t mid)
{
+ struct smbd_server_connection *sconn = xconn->client->sconn;
struct pending_message_list *pml;
int i = 0;
if (sconn->using_smb2) {
- return schedule_deferred_open_message_smb2(sconn, mid);
+ return schedule_deferred_open_message_smb2(xconn, mid);
}
for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
Return true if this mid is on the deferred queue and was not yet processed.
****************************************************************************/
-bool open_was_deferred(struct smbd_server_connection *sconn, uint64_t mid)
+bool open_was_deferred(struct smbXsrv_connection *xconn, uint64_t mid)
{
+ struct smbd_server_connection *sconn = xconn->client->sconn;
struct pending_message_list *pml;
if (sconn->using_smb2) {
- return open_was_deferred_smb2(sconn, mid);
+ return open_was_deferred_smb2(xconn, mid);
}
for (pml = sconn->deferred_open_queue; pml; pml = pml->next) {
********************************************************************/
static bool create_outbuf(TALLOC_CTX *mem_ctx, struct smb_request *req,
- const char *inbuf, char **outbuf, uint8_t num_words,
- uint32_t num_bytes)
+ const uint8_t *inbuf, char **outbuf,
+ uint8_t num_words, uint32_t num_bytes)
{
size_t smb_len = MIN_SMB_SIZE + VWV(num_words) + num_bytes;
return false;
}
- construct_reply_common(req, inbuf, *outbuf);
+ construct_reply_common(req->cmd, inbuf, *outbuf);
srv_set_message(*outbuf, num_words, num_bytes, false);
/*
* Zero out the word area, the caller has to take care of the bcc area
void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
{
char *outbuf;
- if (!create_outbuf(req, req, (const char *)req->inbuf, &outbuf, num_words,
+ if (!create_outbuf(req, req, req->inbuf, &outbuf, num_words,
num_bytes)) {
smb_panic("could not allocate output buffer\n");
}
}
}
- if (session_tag != xconn->last_session_id) {
+ if (session_tag != xconn->client->last_session_id) {
struct user_struct *vuser = NULL;
- xconn->last_session_id = session_tag;
+ xconn->client->last_session_id = session_tag;
if (session) {
vuser = session->compat;
}
Construct a reply to the incoming packet.
****************************************************************************/
-static void construct_reply(struct smbd_server_connection *sconn,
+static void construct_reply(struct smbXsrv_connection *xconn,
char *inbuf, int size, size_t unread_bytes,
uint32_t seqnum, bool encrypted,
struct smb_perfcount_data *deferred_pcd)
{
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbd_server_connection *sconn = xconn->client->sconn;
struct smb_request *req;
if (!(req = talloc(talloc_tos(), struct smb_request))) {
smb_request_done(req);
}
-static void construct_reply_chain(struct smbd_server_connection *sconn,
+static void construct_reply_chain(struct smbXsrv_connection *xconn,
char *inbuf, int size, uint32_t seqnum,
bool encrypted,
struct smb_perfcount_data *deferred_pcd)
{
- struct smbXsrv_connection *xconn = sconn->conn;
struct smb_request **reqs = NULL;
struct smb_request *req;
unsigned num_reqs;
uint32_t seqnum, bool encrypted,
struct smb_perfcount_data *deferred_pcd)
{
- struct smbd_server_connection *sconn = xconn->sconn;
+ struct smbd_server_connection *sconn = xconn->client->sconn;
int msg_type = CVAL(inbuf,0);
- DO_PROFILE_INC(smb_count);
+ DO_PROFILE_INC(request);
DEBUG( 6, ( "got message type 0x%x of len 0x%x\n", msg_type,
smb_len(inbuf) ) );
show_msg((char *)inbuf);
if ((unread_bytes == 0) && smb1_is_chain(inbuf)) {
- construct_reply_chain(sconn, (char *)inbuf, nread,
+ construct_reply_chain(xconn, (char *)inbuf, nread,
seqnum, encrypted, deferred_pcd);
} else {
- construct_reply(sconn, (char *)inbuf, nread, unread_bytes,
+ construct_reply(xconn, (char *)inbuf, nread, unread_bytes,
seqnum, encrypted, deferred_pcd);
}
common_flags2 &= ~v;
}
-static void construct_reply_common(struct smb_request *req, const char *inbuf,
+static void construct_reply_common(uint8_t cmd, const uint8_t *inbuf,
char *outbuf)
{
uint16_t in_flags2 = SVAL(inbuf,smb_flg2);
srv_set_message(outbuf,0,0,false);
- SCVAL(outbuf, smb_com, req->cmd);
+ SCVAL(outbuf, smb_com, cmd);
SIVAL(outbuf,smb_rcls,0);
SCVAL(outbuf,smb_flg, FLAG_REPLY | (CVAL(inbuf,smb_flg) & FLAG_CASELESS_PATHNAMES));
SSVAL(outbuf,smb_flg2, out_flags2);
void construct_reply_common_req(struct smb_request *req, char *outbuf)
{
- construct_reply_common(req, (const char *)req->inbuf, outbuf);
+ construct_reply_common(req->cmd, req->inbuf, outbuf);
}
/**
unsigned i;
if (xconn != NULL) {
- sconn = xconn->sconn;
+ sconn = xconn->client->sconn;
}
state.mem_ctx = mem_ctx;
{
struct smbd_server_connection *sconn = talloc_get_type_abort(
private_data, struct smbd_server_connection);
- struct smbXsrv_connection *xconn = sconn->conn;
+ struct smbXsrv_connection *xconn = NULL;
bool ret;
if (sconn->using_smb2) {
return false;
}
+ /*
+ * With SMB1 we only have 1 connection
+ */
+ xconn = sconn->client->connections;
smbd_lock_socket(xconn);
ret = send_keepalive(xconn->transport.sock);
smbd_unlock_socket(xconn);
return false;
}
- if (!create_outbuf(talloc_tos(), &req, (const char *)req.inbuf, &outbuf,
+ if (!create_outbuf(talloc_tos(), &req, req.inbuf, &outbuf,
1, req.buflen)) {
DEBUG(10, ("create_outbuf failed\n"));
return false;
return NT_STATUS_OK;
}
+struct smbd_tevent_trace_state {
+ TALLOC_CTX *frame;
+ SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
+};
+
static void smbd_tevent_trace_callback(enum tevent_trace_point point,
void *private_data)
{
- struct smbXsrv_connection *conn =
- talloc_get_type_abort(private_data,
- struct smbXsrv_connection);
+ struct smbd_tevent_trace_state *state =
+ (struct smbd_tevent_trace_state *)private_data;
switch (point) {
case TEVENT_TRACE_BEFORE_WAIT:
- /*
- * This just removes compiler warning
- * without profile support
- */
- conn->smbd_idle_profstamp = 0;
- START_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
+ SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
break;
case TEVENT_TRACE_AFTER_WAIT:
- END_PROFILE_STAMP(smbd_idle, conn->smbd_idle_profstamp);
+ SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
break;
-#ifdef TEVENT_HAS_LOOP_ONCE_TRACE_POINTS
case TEVENT_TRACE_BEFORE_LOOP_ONCE:
+ TALLOC_FREE(state->frame);
+ state->frame = talloc_stackframe_pool(8192);
+ break;
case TEVENT_TRACE_AFTER_LOOP_ONCE:
+ TALLOC_FREE(state->frame);
break;
-#endif
}
+
+ errno = 0;
}
/**
return ret;
}
-/****************************************************************************
- Process commands from the client
-****************************************************************************/
-
-void smbd_process(struct tevent_context *ev_ctx,
- struct messaging_context *msg_ctx,
- int sock_fd,
- bool interactive)
+NTSTATUS smbd_add_connection(struct smbXsrv_client *client, int sock_fd,
+ struct smbXsrv_connection **_xconn)
{
TALLOC_CTX *frame = talloc_stackframe();
struct smbXsrv_connection *xconn;
- struct smbd_server_connection *sconn;
struct sockaddr_storage ss_srv;
void *sp_srv = (void *)&ss_srv;
struct sockaddr *sa_srv = (struct sockaddr *)sp_srv;
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;
+ char *p;
+ const char *rhost = NULL;
int ret;
int tmp;
- xconn = talloc_zero(ev_ctx, struct smbXsrv_connection);
+ *_xconn = NULL;
+
+ DO_PROFILE_INC(connect);
+
+ xconn = talloc_zero(client, struct smbXsrv_connection);
if (xconn == NULL) {
DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
- exit_server_cleanly("talloc_zero(struct smbXsrv_connection).\n");
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
}
+ talloc_steal(frame, xconn);
- xconn->ev_ctx = ev_ctx;
- xconn->msg_ctx = msg_ctx;
+ xconn->ev_ctx = client->ev_ctx;
+ xconn->msg_ctx = client->msg_ctx;
xconn->transport.sock = sock_fd;
smbd_echo_init(xconn);
-
- sconn = talloc_zero(xconn, struct smbd_server_connection);
- if (!sconn) {
- exit_server("failed to create smbd_server_connection");
- }
-
- xconn->sconn = sconn;
- sconn->conn = xconn;
-
- /*
- * TODO: remove this...:-)
- */
- global_smbXsrv_connection = xconn;
-
- sconn->ev_ctx = ev_ctx;
- sconn->msg_ctx = msg_ctx;
-
- if (!interactive) {
- smbd_setup_sig_term_handler(sconn);
- smbd_setup_sig_hup_handler(sconn);
-
- if (!serverid_register(messaging_server_id(msg_ctx),
- FLAG_MSG_GENERAL|FLAG_MSG_SMBD
- |FLAG_MSG_DBWRAP
- |FLAG_MSG_PRINT_GENERAL)) {
- exit_server_cleanly("Could not register myself in "
- "serverid.tdb");
- }
- }
-
- if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
- /*
- * We're not making the decision here,
- * we're just allowing the client
- * to decide between SMB1 and SMB2
- * with the first negprot
- * packet.
- */
- sconn->using_smb2 = true;
- }
+ xconn->protocol = PROTOCOL_NONE;
/* Ensure child is set to blocking mode */
set_blocking(sock_fd,True);
sa_socklen = sizeof(ss_clnt);
ret = getpeername(sock_fd, sa_clnt, &sa_socklen);
if (ret != 0) {
+ int saved_errno = errno;
int level = (errno == ENOTCONN)?2:0;
- DEBUG(level,("getpeername() failed - %s\n", strerror(errno)));
- exit_server_cleanly("getpeername() failed.\n");
+ DEBUG(level,("getpeername() failed - %s\n",
+ strerror(saved_errno)));
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix_common(saved_errno);
}
- ret = tsocket_address_bsd_from_sockaddr(sconn,
+ ret = tsocket_address_bsd_from_sockaddr(xconn,
sa_clnt, sa_socklen,
&remote_address);
if (ret != 0) {
+ int saved_errno = errno;
DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
- __location__, strerror(errno)));
- exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
+ __location__, strerror(saved_errno)));
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix_common(saved_errno);
}
sa_socklen = sizeof(ss_srv);
ret = getsockname(sock_fd, sa_srv, &sa_socklen);
if (ret != 0) {
+ int saved_errno = errno;
int level = (errno == ENOTCONN)?2:0;
- DEBUG(level,("getsockname() failed - %s\n", strerror(errno)));
- exit_server_cleanly("getsockname() failed.\n");
+ DEBUG(level,("getsockname() failed - %s\n",
+ strerror(saved_errno)));
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix_common(saved_errno);
}
- ret = tsocket_address_bsd_from_sockaddr(sconn,
+ ret = tsocket_address_bsd_from_sockaddr(xconn,
sa_srv, sa_socklen,
&local_address);
if (ret != 0) {
+ int saved_errno = errno;
DEBUG(0,("%s: tsocket_address_bsd_from_sockaddr remote failed - %s\n",
- __location__, strerror(errno)));
- exit_server_cleanly("tsocket_address_bsd_from_sockaddr remote failed.\n");
- }
-
- 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";
+ __location__, strerror(saved_errno)));
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix_common(saved_errno);
}
if (tsocket_address_is_inet(remote_address, "ip")) {
- remaddr = tsocket_address_inet_addr_string(
- sconn->remote_address,
- talloc_tos());
+ remaddr = tsocket_address_inet_addr_string(remote_address,
+ talloc_tos());
if (remaddr == NULL) {
DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
__location__, strerror(errno)));
- exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
}
} else {
remaddr = "0.0.0.0";
}
- /* this is needed so that we get decent entries
- in smbstatus for port 445 connects */
- set_remote_machine_name(remaddr, false);
- reload_services(sconn, conn_snum_used, true);
-
/*
* Before the first packet, check the global hosts allow/ hosts deny
* parameters before doing any parsing of packets passed to us by the
*/
ret = get_remote_hostname(remote_address,
- &rhost,
- talloc_tos());
+ &p, talloc_tos());
if (ret < 0) {
+ int saved_errno = errno;
DEBUG(0,("%s: get_remote_hostname failed - %s\n",
- __location__, strerror(errno)));
- exit_server_cleanly("get_remote_hostname failed.\n");
+ __location__, strerror(saved_errno)));
+ TALLOC_FREE(frame);
+ return map_nt_error_from_unix_common(saved_errno);
}
+ rhost = p;
if (strequal(rhost, "UNKNOWN")) {
- rhost = talloc_strdup(talloc_tos(), remaddr);
+ rhost = remaddr;
}
- sconn->remote_hostname = talloc_move(sconn, &rhost);
- sub_set_socket_ids(remaddr,
- sconn->remote_hostname,
- locaddr);
+ xconn->local_address = local_address;
+ xconn->remote_address = remote_address;
+ xconn->remote_hostname = talloc_strdup(xconn, rhost);
+ if (xconn->remote_hostname == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ if (!srv_init_signing(xconn)) {
+ DEBUG(0, ("Failed to init smb_signing\n"));
+ TALLOC_FREE(frame);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
if (!allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
- sconn->remote_hostname,
+ xconn->remote_hostname,
remaddr)) {
+ DEBUG( 1, ("Connection denied from %s to %s\n",
+ tsocket_address_string(remote_address, talloc_tos()),
+ tsocket_address_string(local_address, talloc_tos())));
+
+ /*
+ * We return a valid xconn
+ * so that the caller can return an error message
+ * to the client
+ */
+ client->connections = xconn;
+ xconn->client = client;
+ talloc_steal(client, xconn);
+
+ *_xconn = xconn;
+ TALLOC_FREE(frame);
+ return NT_STATUS_NETWORK_ACCESS_DENIED;
+ }
+
+ DEBUG(10, ("Connection allowed from %s to %s\n",
+ tsocket_address_string(remote_address, talloc_tos()),
+ tsocket_address_string(local_address, talloc_tos())));
+
+ if (lp_clustering()) {
+ /*
+ * We need to tell ctdb about our client's TCP
+ * connection, so that for failover ctdbd can send
+ * tickle acks, triggering a reconnection by the
+ * client.
+ */
+ NTSTATUS status;
+
+ status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("ctdbd_register_ips failed: %s\n",
+ nt_errstr(status)));
+ }
+ }
+
+ tmp = lp_max_xmit();
+ tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
+ tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
+
+ xconn->smb1.negprot.max_recv = tmp;
+
+ xconn->smb1.sessions.done_sesssetup = false;
+ xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
+
+ xconn->transport.fde = tevent_add_fd(client->ev_ctx,
+ xconn,
+ sock_fd,
+ TEVENT_FD_READ,
+ smbd_server_connection_handler,
+ xconn);
+ if (!xconn->transport.fde) {
+ TALLOC_FREE(frame);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ /* for now we only have one connection */
+ DLIST_ADD_END(client->connections, xconn, NULL);
+ xconn->client = client;
+ talloc_steal(client, xconn);
+
+ *_xconn = xconn;
+ TALLOC_FREE(frame);
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+ Process commands from the client
+****************************************************************************/
+
+void smbd_process(struct tevent_context *ev_ctx,
+ struct messaging_context *msg_ctx,
+ int sock_fd,
+ bool interactive)
+{
+ struct smbd_tevent_trace_state trace_state = {
+ .frame = talloc_stackframe(),
+ };
+ struct smbXsrv_client *client = NULL;
+ struct smbd_server_connection *sconn = NULL;
+ struct smbXsrv_connection *xconn = NULL;
+ const char *locaddr = NULL;
+ const char *remaddr = NULL;
+ int ret;
+ NTSTATUS status;
+
+ client = talloc_zero(ev_ctx, struct smbXsrv_client);
+ if (client == NULL) {
+ DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
+ exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
+ }
+
+ /*
+ * TODO: remove this...:-)
+ */
+ global_smbXsrv_client = client;
+
+ client->ev_ctx = ev_ctx;
+ client->msg_ctx = msg_ctx;
+
+ sconn = talloc_zero(client, struct smbd_server_connection);
+ if (sconn == NULL) {
+ exit_server("failed to create smbd_server_connection");
+ }
+
+ client->sconn = sconn;
+ sconn->client = client;
+
+ sconn->ev_ctx = ev_ctx;
+ sconn->msg_ctx = msg_ctx;
+
+ if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
+ /*
+ * We're not making the decision here,
+ * we're just allowing the client
+ * to decide between SMB1 and SMB2
+ * with the first negprot
+ * packet.
+ */
+ sconn->using_smb2 = true;
+ }
+
+ if (!interactive) {
+ smbd_setup_sig_term_handler(sconn);
+ smbd_setup_sig_hup_handler(sconn);
+
+ if (!serverid_register(messaging_server_id(msg_ctx),
+ FLAG_MSG_GENERAL|FLAG_MSG_SMBD
+ |FLAG_MSG_DBWRAP
+ |FLAG_MSG_PRINT_GENERAL)) {
+ exit_server_cleanly("Could not register myself in "
+ "serverid.tdb");
+ }
+ }
+
+ status = smbd_add_connection(client, sock_fd, &xconn);
+ if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_ACCESS_DENIED)) {
/*
* send a negative session response "not listening on calling
* name"
*/
unsigned char buf[5] = {0x83, 0, 0, 1, 0x81};
- DEBUG( 1, ("Connection denied from %s to %s\n",
- tsocket_address_string(remote_address, talloc_tos()),
- tsocket_address_string(local_address, talloc_tos())));
(void)srv_send_smb(xconn,(char *)buf, false,
0, false, NULL);
exit_server_cleanly("connection denied");
+ } else if (!NT_STATUS_IS_OK(status)) {
+ exit_server_cleanly(nt_errstr(status));
}
- DEBUG(10, ("Connection allowed from %s to %s\n",
- tsocket_address_string(remote_address, talloc_tos()),
- tsocket_address_string(local_address, talloc_tos())));
+ sconn->local_address =
+ tsocket_address_copy(xconn->local_address, sconn);
+ if (sconn->local_address == NULL) {
+ exit_server_cleanly("tsocket_address_copy() failed");
+ }
+ sconn->remote_address =
+ tsocket_address_copy(xconn->remote_address, sconn);
+ if (sconn->remote_address == NULL) {
+ exit_server_cleanly("tsocket_address_copy() failed");
+ }
+ sconn->remote_hostname =
+ talloc_strdup(sconn, xconn->remote_hostname);
+ if (sconn->remote_hostname == NULL) {
+ exit_server_cleanly("tsocket_strdup() failed");
+ }
+
+ if (tsocket_address_is_inet(sconn->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 remote failed - %s\n",
+ __location__, strerror(errno)));
+ exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
+ }
+ } else {
+ locaddr = "0.0.0.0";
+ }
+
+ if (tsocket_address_is_inet(sconn->remote_address, "ip")) {
+ remaddr = tsocket_address_inet_addr_string(
+ sconn->remote_address,
+ talloc_tos());
+ if (remaddr == NULL) {
+ DEBUG(0,("%s: tsocket_address_inet_addr_string remote failed - %s\n",
+ __location__, strerror(errno)));
+ exit_server_cleanly("tsocket_address_inet_addr_string remote failed.\n");
+ }
+ } else {
+ remaddr = "0.0.0.0";
+ }
+
+ /* this is needed so that we get decent entries
+ in smbstatus for port 445 connects */
+ set_remote_machine_name(remaddr, false);
+ reload_services(sconn, conn_snum_used, true);
+ sub_set_socket_ids(remaddr,
+ sconn->remote_hostname,
+ locaddr);
if (lp_preload_modules()) {
smb_load_modules(lp_preload_modules());
DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
}
- if (!srv_init_signing(xconn)) {
- exit_server("Failed to init smb_signing");
- }
-
if (!file_init(sconn)) {
exit_server("file_init() failed");
}
exit(1);
}
- if (lp_clustering()) {
- /*
- * We need to tell ctdb about our client's TCP
- * connection, so that for failover ctdbd can send
- * tickle acks, triggering a reconnection by the
- * client.
- */
- NTSTATUS status;
-
- status = smbd_register_ips(xconn, &ss_srv, &ss_clnt);
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(0, ("ctdbd_register_ips failed: %s\n",
- nt_errstr(status)));
- }
- }
-
- tmp = lp_max_xmit();
- tmp = MAX(tmp, SMB_BUFFER_SIZE_MIN);
- tmp = MIN(tmp, SMB_BUFFER_SIZE_MAX);
-
- xconn->smb1.negprot.max_recv = tmp;
-
- xconn->smb1.sessions.done_sesssetup = false;
- xconn->smb1.sessions.max_send = SMB_BUFFER_SIZE_MAX;
-
if (!init_dptrs(sconn)) {
exit_server("init_dptrs() failed");
}
- xconn->transport.fde = tevent_add_fd(ev_ctx,
- xconn,
- sock_fd,
- TEVENT_FD_READ,
- smbd_server_connection_handler,
- xconn);
- if (!xconn->transport.fde) {
- exit_server("failed to create smbd_server_connection fde");
- }
-
- sconn->conn->local_address = sconn->local_address;
- sconn->conn->remote_address = sconn->remote_address;
- sconn->conn->remote_hostname = sconn->remote_hostname;
- sconn->conn->protocol = PROTOCOL_NONE;
-
- TALLOC_FREE(frame);
-
- tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback, xconn);
+ TALLOC_FREE(trace_state.frame);
- while (True) {
- frame = talloc_stackframe_pool(8192);
+ tevent_set_trace_callback(ev_ctx, smbd_tevent_trace_callback,
+ &trace_state);
- errno = 0;
- if (tevent_loop_once(ev_ctx) == -1) {
- if (errno != EINTR) {
- DEBUG(3, ("tevent_loop_once failed: %s,"
- " exiting\n", strerror(errno) ));
- break;
- }
- }
-
- TALLOC_FREE(frame);
+ ret = tevent_loop_wait(ev_ctx);
+ if (ret != 0) {
+ DEBUG(1, ("tevent_loop_wait failed: %d, %s,"
+ " exiting\n", ret, strerror(errno)));
}
+ TALLOC_FREE(trace_state.frame);
+
exit_server_cleanly(NULL);
}