#include "passdb.h"
#include "auth.h"
#include "messages.h"
+#include "lib/messages_ctdb.h"
#include "smbprofile.h"
#include "rpc_server/spoolss/srv_spoolss_nt.h"
#include "libsmb/libsmb.h"
#include "../libcli/security/dom_sid.h"
#include "../libcli/security/security_token.h"
#include "lib/id_cache.h"
-#include "serverid.h"
+#include "lib/util/sys_rw_data.h"
#include "system/threads.h"
+#include "lib/pthreadpool/pthreadpool_tevent.h"
+#include "util_event.h"
/* Internal message queue for deferred opens. */
struct pending_message_list {
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);
#ifdef HAVE_ROBUST_MUTEXES
if (xconn->smb1.echo_handler.socket_mutex != NULL) {
- int ret = EINTR;
-
- while (ret == EINTR) {
- ret = pthread_mutex_unlock(
- xconn->smb1.echo_handler.socket_mutex);
- if (ret == 0) {
- break;
- }
- }
+ int ret;
+ ret = pthread_mutex_unlock(
+ xconn->smb1.echo_handler.socket_mutex);
if (ret != 0) {
DEBUG(1, ("pthread_mutex_unlock failed: %s\n",
strerror(ret)));
Setup the word count and byte count for a smb message.
********************************************************************/
-int srv_set_message(char *buf,
- int num_words,
- int num_bytes,
- bool zero)
+size_t srv_set_message(char *buf,
+ size_t num_words,
+ size_t num_bytes,
+ bool zero)
{
if (zero && (num_words || num_bytes)) {
memset(buf + smb_size,'\0',num_words*2 + num_bytes);
static bool init_smb_request(struct smb_request *req,
struct smbd_server_connection *sconn,
struct smbXsrv_connection *xconn,
- const uint8 *inbuf,
+ const uint8_t *inbuf,
size_t unread_bytes, bool encrypted,
uint32_t seqnum)
{
req->smb2req = NULL;
req->priv_paths = NULL;
req->chain = NULL;
+ req->posix_pathnames = lp_posix_pathnames();
smb_init_perfcount_data(&req->pcd);
/* Ensure we have at least wct words and 2 bytes of bcc. */
}
#endif
- DLIST_ADD_END(req->sconn->deferred_open_queue, msg,
- struct pending_message_list *);
+ DLIST_ADD_END(req->sconn->deferred_open_queue, msg);
DEBUG(10,("push_message: pushed message length %u on "
"deferred_open_queue\n", (unsigned int)msg_len));
"scheduling mid %llu\n",
(unsigned long long)mid ));
- te = tevent_add_timer(pml->sconn->ev_ctx,
+ /*
+ * smbd_deferred_open_timer() calls
+ * process_smb() to redispatch the request
+ * including the required impersonation.
+ *
+ * So we can just use the raw tevent_context.
+ */
+ te = tevent_add_timer(xconn->client->raw_ev_ctx,
pml,
timeval_zero(),
smbd_deferred_open_timer,
exit_server_cleanly("termination signal");
}
-void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
+static void smbd_setup_sig_term_handler(struct smbd_server_connection *sconn)
{
struct tevent_signal *se;
- se = tevent_add_signal(sconn->ev_ctx,
+ se = tevent_add_signal(sconn->root_ev_ctx,
sconn,
SIGTERM, 0,
smbd_sig_term_handler,
reload_services(sconn, conn_snum_used, false);
}
-void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
+static void smbd_setup_sig_hup_handler(struct smbd_server_connection *sconn)
{
struct tevent_signal *se;
- se = tevent_add_signal(sconn->ev_ctx,
+ se = tevent_add_signal(sconn->root_ev_ctx,
sconn,
SIGHUP, 0,
smbd_sig_hup_handler,
********************************************************************/
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
return true;
}
-void reply_outbuf(struct smb_request *req, uint8 num_words, uint32 num_bytes)
+void reply_outbuf(struct smb_request *req, uint8_t num_words, uint32_t 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");
}
TALLOC_FREE(fname);
}
+static void smb1srv_update_crypto_flags(struct smbXsrv_session *session,
+ struct smb_request *req,
+ uint8_t type,
+ bool *update_session_globalp,
+ bool *update_tcon_globalp)
+{
+ connection_struct *conn = req->conn;
+ struct smbXsrv_tcon *tcon = conn ? conn->tcon : NULL;
+ uint8_t encrypt_flag = SMBXSRV_PROCESSED_UNENCRYPTED_PACKET;
+ uint8_t sign_flag = SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+ bool update_session = false;
+ bool update_tcon = false;
+
+ if (req->encrypted) {
+ encrypt_flag = SMBXSRV_PROCESSED_ENCRYPTED_PACKET;
+ }
+
+ if (srv_is_signing_active(req->xconn)) {
+ sign_flag = SMBXSRV_PROCESSED_SIGNED_PACKET;
+ } else if ((type == SMBecho) || (type == SMBsesssetupX)) {
+ /*
+ * echo can be unsigned. Sesssion setup except final
+ * session setup response too
+ */
+ sign_flag &= ~SMBXSRV_PROCESSED_UNSIGNED_PACKET;
+ }
+
+ update_session |= smbXsrv_set_crypto_flag(
+ &session->global->encryption_flags, encrypt_flag);
+ update_session |= smbXsrv_set_crypto_flag(
+ &session->global->signing_flags, sign_flag);
+
+ if (tcon) {
+ update_tcon |= smbXsrv_set_crypto_flag(
+ &tcon->global->encryption_flags, encrypt_flag);
+ update_tcon |= smbXsrv_set_crypto_flag(
+ &tcon->global->signing_flags, sign_flag);
+ }
+
+ if (update_session) {
+ session->global->channels[0].encryption_cipher = SMB_ENCRYPTION_GSSAPI;
+ }
+
+ *update_session_globalp = update_session;
+ *update_tcon_globalp = update_tcon;
+ return;
+}
+
/****************************************************************************
Prepare everything for calling the actual request function, and potentially
call the request function via the "new" interface.
find.
****************************************************************************/
-static connection_struct *switch_message(uint8 type, struct smb_request *req)
+static connection_struct *switch_message(uint8_t type, struct smb_request *req)
{
int flags;
uint64_t session_tag;
errno = 0;
+ req->ev_ctx = NULL;
+
if (!xconn->smb1.negprot.done) {
switch (type) {
/*
}
}
- if (session_tag != xconn->client->last_session_id) {
- struct user_struct *vuser = NULL;
+ if (session != NULL && !(flags & AS_USER)) {
+ struct user_struct *vuser = session->compat;
- xconn->client->last_session_id = session_tag;
- if (session) {
- vuser = session->compat;
- }
+ /*
+ * change_to_user() implies set_current_user_info()
+ * and chdir_connect_service().
+ *
+ * So we only call set_current_user_info if
+ * we don't have AS_USER specified.
+ */
if (vuser) {
set_current_user_info(
vuser->session_info->unix_info->sanitized_username,
return NULL;
}
+ set_current_case_sensitive(conn, SVAL(req->inbuf,smb_flg));
+
+ /*
+ * change_to_user() implies set_current_user_info()
+ * and chdir_connect_service().
+ */
if (!change_to_user(conn,session_tag)) {
DEBUG(0, ("Error: Could not change to user. Removing "
"deferred open, mid=%llu.\n",
reply_nterror(req, NT_STATUS_ACCESS_DENIED);
return conn;
}
+
+ req->ev_ctx = conn->user_ev_ctx;
+ } else if (flags & AS_GUEST) {
+ /*
+ * Does this protocol need to be run as guest? (Only archane
+ * messenger service requests have this...)
+ */
+ if (!change_to_guest()) {
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return conn;
+ }
+
+ req->ev_ctx = req->sconn->guest_ev_ctx;
} else {
/* This call needs to be run as root */
change_to_root_user();
+
+ req->ev_ctx = req->sconn->root_ev_ctx;
}
/* load service specific parameters */
}
}
- if (!set_current_service(conn,SVAL(req->inbuf,smb_flg),
- (flags & (AS_USER|DO_CHDIR)
- ?True:False))) {
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return conn;
+ if (flags & DO_CHDIR) {
+ bool ok;
+
+ ok = chdir_current_service(conn);
+ if (!ok) {
+ reply_nterror(req, NT_STATUS_ACCESS_DENIED);
+ return conn;
+ }
}
conn->num_smb_operations++;
}
/*
- * Does this protocol need to be run as guest? (Only archane
- * messenger service requests have this...)
+ * Update encryption and signing state tracking flags that are
+ * used by smbstatus to display signing and encryption status.
*/
- if (flags & AS_GUEST) {
- char *raddr;
- bool ok;
-
- if (!change_to_guest()) {
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return conn;
- }
-
- raddr = tsocket_address_inet_addr_string(xconn->remote_address,
- talloc_tos());
- if (raddr == NULL) {
- reply_nterror(req, NT_STATUS_NO_MEMORY);
- return conn;
+ if (session != NULL) {
+ bool update_session_global = false;
+ bool update_tcon_global = false;
+
+ smb1srv_update_crypto_flags(session, req, type,
+ &update_session_global,
+ &update_tcon_global);
+
+ if (update_session_global) {
+ status = smbXsrv_session_update(session);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+ return conn;
+ }
}
- /*
- * Haven't we checked this in smbd_process already???
- */
-
- ok = allow_access(lp_hosts_deny(-1), lp_hosts_allow(-1),
- xconn->remote_hostname, raddr);
- TALLOC_FREE(raddr);
-
- if (!ok) {
- reply_nterror(req, NT_STATUS_ACCESS_DENIED);
- return conn;
+ if (update_tcon_global) {
+ status = smbXsrv_tcon_update(req->conn->tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ reply_nterror(req, NT_STATUS_UNSUCCESSFUL);
+ return conn;
+ }
}
}
smb_panic("could not allocate smb_request");
}
- if (!init_smb_request(req, sconn, xconn, (uint8 *)inbuf, unread_bytes,
+ if (!init_smb_request(req, sconn, xconn, (uint8_t *)inbuf, unread_bytes,
encrypted, seqnum)) {
exit_server_cleanly("Invalid SMB request");
}
unsigned num_reqs;
bool ok;
- ok = smb1_parse_chain(talloc_tos(), (uint8_t *)inbuf, xconn, encrypted,
+ ok = smb1_parse_chain(xconn, (uint8_t *)inbuf, xconn, encrypted,
seqnum, &reqs, &num_reqs);
if (!ok) {
char errbuf[smb_size];
next->vuid = SVAL(req->outbuf, smb_uid);
next->tid = SVAL(req->outbuf, smb_tid);
- status = smb1srv_tcon_lookup(req->xconn, req->tid,
+ status = smb1srv_tcon_lookup(req->xconn, next->tid,
now, &tcon);
+
if (NT_STATUS_IS_OK(status)) {
- req->conn = tcon->compat;
+ next->conn = tcon->compat;
} else {
- req->conn = NULL;
+ next->conn = NULL;
}
next->chain_fsp = req->chain_fsp;
next->inbuf = req->inbuf;
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) ) );
if (smbd_is_smb2_header(inbuf, nread)) {
const uint8_t *inpdu = inbuf + NBT_HDR_SIZE;
size_t pdulen = nread - NBT_HDR_SIZE;
- smbd_smb2_first_negprot(xconn, inpdu, pdulen);
+ smbd_smb2_process_negprot(xconn, 0, inpdu, pdulen);
return;
- } else if (nread >= smb_size && valid_smb_header(inbuf)
+ }
+ if (nread >= smb_size && valid_smb_header(inbuf)
&& CVAL(inbuf, smb_com) != 0x72) {
/* This is a non-negprot SMB1 packet.
Disable SMB2 from now on. */
Helper functions for contruct_reply.
****************************************************************************/
-void add_to_common_flags2(uint32 v)
+void add_to_common_flags2(uint32_t v)
{
common_flags2 |= v;
}
-void remove_from_common_flags2(uint32 v)
+void remove_from_common_flags2(uint32_t v)
{
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);
SSVAL(outbuf,smb_tid,SVAL(inbuf,smb_tid));
SSVAL(outbuf,smb_pid,SVAL(inbuf,smb_pid));
+ SSVAL(outbuf,smb_pidhigh,SVAL(inbuf,smb_pidhigh));
SSVAL(outbuf,smb_uid,SVAL(inbuf,smb_uid));
SSVAL(outbuf,smb_mid,SVAL(inbuf,smb_mid));
}
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);
}
/**
/****************************************************************************
received when we should release a specific IP
****************************************************************************/
-static bool release_ip(const char *ip, void *priv)
+static int release_ip(struct tevent_context *ev,
+ uint32_t src_vnn, uint32_t dst_vnn,
+ uint64_t dst_srvid,
+ const uint8_t *msg, size_t msglen,
+ void *private_data)
{
struct smbd_release_ip_state *state =
- talloc_get_type_abort(priv,
+ talloc_get_type_abort(private_data,
struct smbd_release_ip_state);
struct smbXsrv_connection *xconn = state->xconn;
+ const char *ip;
const char *addr = state->addr;
const char *p = addr;
+ if (msglen == 0) {
+ return 0;
+ }
+ if (msg[msglen-1] != '\0') {
+ return 0;
+ }
+
+ ip = (const char *)msg;
+
if (!NT_STATUS_IS_OK(xconn->transport.status)) {
/* avoid recursion */
- return false;
+ return 0;
}
if (strncmp("::ffff:", addr, 7) == 0) {
* as we might be called from within ctdbd_migrate(),
* we need to defer our action to the next event loop
*/
- tevent_schedule_immediate(state->im, xconn->ev_ctx,
- smbd_release_ip_immediate, state);
+ tevent_schedule_immediate(state->im,
+ xconn->client->raw_ev_ctx,
+ smbd_release_ip_immediate,
+ state);
/*
* Make sure we don't get any io on the connection.
*/
xconn->transport.status = NT_STATUS_ADDRESS_CLOSED;
- return true;
+ return EADDRNOTAVAIL;
}
- return false;
+ return 0;
}
static NTSTATUS smbd_register_ips(struct smbXsrv_connection *xconn,
{
struct smbd_release_ip_state *state;
struct ctdbd_connection *cconn;
+ int ret;
- cconn = messaging_ctdbd_connection();
+ cconn = messaging_ctdb_connection();
if (cconn == NULL) {
return NT_STATUS_NO_MEMORY;
}
return NT_STATUS_NO_MEMORY;
}
- return ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
+ ret = ctdbd_register_ips(cconn, srv, clnt, release_ip, state);
+ if (ret != 0) {
+ return map_nt_error_from_unix(ret);
+ }
+ return NT_STATUS_OK;
}
static void msg_kill_client_ip(struct messaging_context *msg_ctx,
const char *ip = (char *) data->data;
char *client_ip;
- DEBUG(10, ("Got kill request for client IP %s\n", ip));
+ DBG_DEBUG("Got kill request for client IP %s\n", ip);
client_ip = tsocket_address_inet_addr_string(sconn->remote_address,
talloc_tos());
}
if (strequal(ip, client_ip)) {
- DEBUG(1, ("Got kill client message for %s - "
- "exiting immediately\n", ip));
+ DBG_WARNING("Got kill client message for %s - "
+ "exiting immediately\n", ip);
exit_server_cleanly("Forced disconnect for client");
}
state->ev = ev;
state->xconn = xconn;
- subreq = wait_for_read_send(state, ev, xconn->transport.sock);
+ subreq = wait_for_read_send(state, ev, xconn->transport.sock, false);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
}
subreq = wait_for_read_send(state, state->ev,
- xconn->transport.sock);
+ xconn->transport.sock, false);
if (tevent_req_nomem(subreq, req)) {
return;
}
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;
}
state->xconn = xconn;
state->parent_pipe = parent_pipe;
- state->ev = s3_tevent_context_init(state);
+ state->ev = samba_tevent_context_init(state);
if (state->ev == NULL) {
- DEBUG(1, ("tevent_context_init failed\n"));
+ DEBUG(1, ("samba_tevent_context_init failed\n"));
TALLOC_FREE(state);
return;
}
close(listener_pipe[0]);
set_blocking(listener_pipe[1], false);
- status = reinit_after_fork(xconn->msg_ctx,
- xconn->ev_ctx,
- true);
+ status = smbd_reinit_after_fork(xconn->client->msg_ctx,
+ xconn->client->raw_ev_ctx,
+ true,
+ "smbd-echo");
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("reinit_after_fork failed: %s\n",
nt_errstr(status)));
exit(1);
}
+ initialize_password_db(true, xconn->client->raw_ev_ctx);
smbd_echo_loop(xconn, listener_pipe[1]);
exit(0);
}
* Without smb signing this is the same as the normal smbd
* listener. This needs to change once signing comes in.
*/
- xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(xconn->ev_ctx,
+ xconn->smb1.echo_handler.trusted_fde = tevent_add_fd(
+ xconn->client->raw_ev_ctx,
xconn,
xconn->smb1.echo_handler.trusted_fd,
TEVENT_FD_READ,
{
NTSTATUS status;
- set_Protocol(protocol);
conn->protocol = protocol;
+ if (conn->client->session_table != NULL) {
+ return NT_STATUS_OK;
+ }
+
if (protocol >= PROTOCOL_SMB2_02) {
status = smb2srv_session_table_init(conn);
if (!NT_STATUS_IS_OK(status)) {
+ conn->protocol = PROTOCOL_NONE;
return status;
}
status = smb2srv_open_table_init(conn);
if (!NT_STATUS_IS_OK(status)) {
+ conn->protocol = PROTOCOL_NONE;
return status;
}
} else {
status = smb1srv_session_table_init(conn);
if (!NT_STATUS_IS_OK(status)) {
+ conn->protocol = PROTOCOL_NONE;
return status;
}
status = smb1srv_tcon_table_init(conn);
if (!NT_STATUS_IS_OK(status)) {
+ conn->protocol = PROTOCOL_NONE;
return status;
}
status = smb1srv_open_table_init(conn);
if (!NT_STATUS_IS_OK(status)) {
+ conn->protocol = PROTOCOL_NONE;
return status;
}
}
+ set_Protocol(protocol);
return NT_STATUS_OK;
}
struct smbd_tevent_trace_state {
+ struct tevent_context *ev;
TALLOC_CTX *frame;
- uint64_t smbd_idle_profstamp;
+ SMBPROFILE_BASIC_ASYNC_STATE(profile_idle);
};
static void smbd_tevent_trace_callback(enum tevent_trace_point point,
switch (point) {
case TEVENT_TRACE_BEFORE_WAIT:
- /*
- * This just removes compiler warning
- * without profile support
- */
- state->smbd_idle_profstamp = 0;
- START_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
+ if (!smbprofile_dump_pending()) {
+ /*
+ * If there's no dump pending
+ * we don't want to schedule a new 1 sec timer.
+ *
+ * Instead we want to sleep as long as nothing happens.
+ */
+ smbprofile_dump_setup(NULL);
+ }
+ SMBPROFILE_BASIC_ASYNC_START(idle, profile_p, state->profile_idle);
break;
case TEVENT_TRACE_AFTER_WAIT:
- END_PROFILE_STAMP(smbd_idle, state->smbd_idle_profstamp);
+ SMBPROFILE_BASIC_ASYNC_END(state->profile_idle);
+ if (!smbprofile_dump_pending()) {
+ /*
+ * We need to flush our state after sleeping
+ * (hopefully a long time).
+ */
+ smbprofile_dump();
+ /*
+ * future profiling events should trigger timers
+ * on our main event context.
+ */
+ smbprofile_dump_setup(state->ev);
+ }
break;
case TEVENT_TRACE_BEFORE_LOOP_ONCE:
TALLOC_FREE(state->frame);
*_xconn = NULL;
+ DO_PROFILE_INC(connect);
+
xconn = talloc_zero(client, struct smbXsrv_connection);
if (xconn == NULL) {
DEBUG(0,("talloc_zero(struct smbXsrv_connection)\n"));
}
talloc_steal(frame, xconn);
- xconn->ev_ctx = client->ev_ctx;
- xconn->msg_ctx = client->msg_ctx;
xconn->transport.sock = sock_fd;
smbd_echo_init(xconn);
xconn->protocol = PROTOCOL_NONE;
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->transport.fde = tevent_add_fd(client->raw_ev_ctx,
xconn,
sock_fd,
TEVENT_FD_READ,
}
/* for now we only have one connection */
- DLIST_ADD_END(client->connections, xconn, NULL);
+ DLIST_ADD_END(client->connections, xconn);
xconn->client = client;
talloc_steal(client, xconn);
bool interactive)
{
struct smbd_tevent_trace_state trace_state = {
+ .ev = ev_ctx,
.frame = talloc_stackframe(),
};
struct smbXsrv_client *client = NULL;
const char *remaddr = NULL;
int ret;
NTSTATUS status;
+ struct timeval tv = timeval_current();
+ NTTIME now = timeval_to_nttime(&tv);
+ char *chroot_dir = NULL;
+ int rc;
- client = talloc_zero(ev_ctx, struct smbXsrv_client);
- if (client == NULL) {
- DEBUG(0,("talloc_zero(struct smbXsrv_client)\n"));
+ status = smbXsrv_client_create(ev_ctx, ev_ctx, msg_ctx, now, &client);
+ if (!NT_STATUS_IS_OK(status)) {
+ DBG_ERR("smbXsrv_client_create(): %s\n", nt_errstr(status));
exit_server_cleanly("talloc_zero(struct smbXsrv_client).\n");
}
*/
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");
sconn->client = client;
sconn->ev_ctx = ev_ctx;
+ sconn->raw_ev_ctx = ev_ctx;
+ sconn->root_ev_ctx = ev_ctx;
+ sconn->guest_ev_ctx = ev_ctx;
sconn->msg_ctx = msg_ctx;
+ ret = pthreadpool_tevent_init(sconn, lp_aio_max_threads(),
+ &sconn->pool);
+ if (ret != 0) {
+ exit_server("pthreadpool_tevent_init() failed.");
+ }
+
if (lp_server_max_protocol() >= PROTOCOL_SMB2_02) {
/*
* We're not making the decision here,
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);
locaddr);
if (lp_preload_modules()) {
- smb_load_modules(lp_preload_modules());
+ smb_load_all_modules_absoute_path(lp_preload_modules());
}
smb_perfcount_init();
exit_server("Could not open account policy tdb.\n");
}
- if (*lp_root_directory(talloc_tos())) {
- if (chroot(lp_root_directory(talloc_tos())) != 0) {
- DEBUG(0,("Failed to change root to %s\n",
- lp_root_directory(talloc_tos())));
- exit_server("Failed to chroot()");
+ chroot_dir = lp_root_directory(talloc_tos());
+ if (chroot_dir[0] != '\0') {
+ rc = chdir(chroot_dir);
+ if (rc != 0) {
+ DBG_ERR("Failed to chdir to %s\n", chroot_dir);
+ exit_server("Failed to chdir()");
}
- if (chdir("/") == -1) {
- DEBUG(0,("Failed to chdir to / on chroot to %s\n", lp_root_directory(talloc_tos())));
+
+ rc = chroot(chroot_dir);
+ if (rc != 0) {
+ DBG_ERR("Failed to change root to %s\n", chroot_dir);
exit_server("Failed to chroot()");
}
- DEBUG(0,("Changed root to %s\n", lp_root_directory(talloc_tos())));
+ DBG_WARNING("Changed root to %s\n", chroot_dir);
+
+ TALLOC_FREE(chroot_dir);
}
if (!file_init(sconn)) {
ID_CACHE_KILL, smbd_id_cache_kill);
messaging_deregister(sconn->msg_ctx,
- MSG_SMB_CONF_UPDATED, sconn->ev_ctx);
+ MSG_SMB_CONF_UPDATED, sconn->raw_ev_ctx);
messaging_register(sconn->msg_ctx, sconn,
MSG_SMB_CONF_UPDATED, smbd_conf_updated);
exit(1);
}
+ smbprofile_dump_setup(ev_ctx);
+
if (!init_dptrs(sconn)) {
exit_server("init_dptrs() failed");
}