1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-24 10:50:22 +03:00

s3:smbd: make use of smbXsrv_tcon and smbXsrv_session for smb2

The removes the protocol specific smbd_smb2_session and
smbd_smb2_tcon.

Pair-Programmed-With: Michael Adam <obnox@samba.org>

metze
This commit is contained in:
Stefan Metzmacher 2012-03-27 11:09:05 +02:00
parent ef408e5068
commit 463b308f16
20 changed files with 179 additions and 274 deletions

View File

@ -280,6 +280,7 @@ struct share_params {
typedef struct connection_struct {
struct connection_struct *next, *prev;
struct smbd_server_connection *sconn; /* can be NULL */
struct smbXsrv_tcon0 *tcon; /* for now NULL for SMB1 */
uint32_t cnum; /* an index passed over the wire */
struct share_params *params;
bool force_user;

View File

@ -160,7 +160,6 @@ interface smbXsrv
[ignore] gensec_security *gensec;
[ignore] user_struct *compat;
[ignore] smbXsrv_tcon_table *tcon_table;
[ignore] smbd_smb2_session *smb2sess;
} smbXsrv_session0;
typedef union {

View File

@ -88,19 +88,7 @@ bool conn_idle_all(struct smbd_server_connection *sconn, time_t t)
void conn_close_all(struct smbd_server_connection *sconn)
{
if (sconn->using_smb2) {
/* SMB2 */
struct smbd_smb2_session *sess;
for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
struct smbd_smb2_tcon *tcon, *tc_next;
file_close_user(sconn, sess->vuid);
for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
tc_next = tcon->next;
TALLOC_FREE(tcon);
}
}
smbXsrv_session_logoff_all(sconn->conn);
} else {
/* SMB1 */
connection_struct *conn, *next;
@ -131,21 +119,20 @@ void conn_force_tdis(struct smbd_server_connection *sconn, const char *sharename
}
if (sconn->using_smb2) {
/* SMB2 */
struct smbd_smb2_session *sess;
for (sess = sconn->smb2.sessions.list; sess; sess = sess->next) {
struct smbd_smb2_tcon *tcon, *tc_next;
for (conn=sconn->connections;conn;conn=next) {
struct smbXsrv_tcon *tcon;
for (tcon = sess->tcons.list; tcon; tcon = tc_next) {
tc_next = tcon->next;
if (tcon->compat_conn &&
strequal(lp_servicename(SNUM(tcon->compat_conn)),
sharename)) {
DEBUG(1,("Forcing close of share %s cnum=%d\n",
sharename, tcon->compat_conn->cnum));
TALLOC_FREE(tcon);
}
next = conn->next;
tcon = conn->tcon;
if (!strequal(lp_servicename(SNUM(conn)), sharename)) {
continue;
}
DEBUG(1,("Forcing close of share %s cnum=%d\n",
sharename, conn->cnum));
smbXsrv_tcon_disconnect(tcon, conn->vuid);
TALLOC_FREE(tcon);
}
} else {
/* SMB1 */

View File

@ -680,7 +680,7 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
return NULL;
}
if (smb2req->tcon->compat_conn != fsp->conn) {
if (smb2req->tcon->compat != fsp->conn) {
return NULL;
}
@ -688,7 +688,11 @@ struct files_struct *file_fsp_smb2(struct smbd_smb2_request *smb2req,
return NULL;
}
if (smb2req->session->vuid != fsp->vuid) {
if (smb2req->session->compat == NULL) {
return NULL;
}
if (smb2req->session->compat->vuid != fsp->vuid) {
return NULL;
}

View File

@ -115,8 +115,6 @@ extern bool exit_firsttime;
struct tstream_context;
struct smbd_smb2_request;
struct smbd_smb2_session;
struct smbd_smb2_tcon;
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn);
@ -411,11 +409,11 @@ struct smbd_smb2_request {
struct smbd_server_connection *sconn;
/* the session the request operates on, maybe NULL */
struct smbd_smb2_session *session;
struct smbXsrv_session *session;
uint64_t last_session_id;
/* the tcon the request operates on, maybe NULL */
struct smbd_smb2_tcon *tcon;
struct smbXsrv_tcon *tcon;
uint32_t last_tid;
int current_idx;
@ -487,37 +485,6 @@ struct smbd_smb2_request {
struct smbd_server_connection;
struct user_struct;
struct smbd_smb2_session {
struct smbd_smb2_session *prev, *next;
struct smbd_server_connection *sconn;
NTSTATUS status;
uint64_t vuid;
struct gensec_security *gensec_security;
struct auth_session_info *session_info;
struct smbXsrv_session *smbXsrv;
struct user_struct *compat_vuser;
struct {
/* an id tree used to allocate tids */
struct idr_context *idtree;
/* this is the limit of tid values for this connection */
uint32_t limit;
struct smbd_smb2_tcon *list;
} tcons;
};
struct smbd_smb2_tcon {
struct smbd_smb2_tcon *prev, *next;
struct smbd_smb2_session *session;
uint32_t tid;
int snum;
connection_struct *compat_conn;
};
struct pending_message_list;
struct pending_auth_data;
@ -673,9 +640,6 @@ struct smbd_server_connection {
struct tevent_queue *send_queue;
struct tstream_context *stream;
bool negprot_2ff;
struct {
struct smbd_smb2_session *list;
} sessions;
struct {
/* The event that makes us process our blocking lock queue */
struct timed_event *brl_timeout;

View File

@ -145,6 +145,7 @@ void invalidate_vuid(struct smbd_server_connection *sconn, uint64_t vuid)
void invalidate_all_vuids(struct smbd_server_connection *sconn)
{
if (sconn->using_smb2) {
smbXsrv_session_logoff_all(sconn->conn);
return;
}

View File

@ -988,9 +988,10 @@ bool set_current_service(connection_struct *conn, uint16 flags, bool do_chdir);
void load_registry_shares(void);
int add_home_service(const char *service, const char *username, const char *homedir);
int find_service(TALLOC_CTX *ctx, const char *service, char **p_service_out);
struct smbd_smb2_tcon;
struct smbXsrv_tcon0;
connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
struct smbd_smb2_tcon *tcon,
struct smbXsrv_tcon0 *tcon,
int snum,
struct user_struct *vuser,
const char *pdev,
NTSTATUS *pstatus);

View File

@ -941,7 +941,8 @@ static connection_struct *make_connection_smb1(struct smbd_server_connection *sc
****************************************************************************/
connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
struct smbd_smb2_tcon *tcon,
struct smbXsrv_tcon *tcon,
int snum,
struct user_struct *vuser,
const char *pdev,
NTSTATUS *pstatus)
@ -952,10 +953,13 @@ connection_struct *make_connection_smb2(struct smbd_server_connection *sconn,
*pstatus = NT_STATUS_INSUFFICIENT_RESOURCES;
return NULL;
}
conn->cnum = tcon->tid;
conn->cnum = tcon->global->tcon_wire_id;
conn->tcon = tcon;
*pstatus = make_connection_snum(sconn,
conn,
tcon->snum,
snum,
vuser,
pdev);
if (!NT_STATUS_IS_OK(*pstatus)) {

View File

@ -158,7 +158,7 @@ static NTSTATUS smbd_smb2_close(struct smbd_smb2_request *req,
{
NTSTATUS status;
struct smb_request *smbreq;
connection_struct *conn = req->tcon->compat_conn;
connection_struct *conn = req->tcon->compat;
struct smb_filename *smb_fname = NULL;
struct timespec mdate_ts, adate_ts, cdate_ts, create_date_ts;
uint64_t allocation_size = 0;

View File

@ -435,7 +435,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
ZERO_STRUCT(out_context_blobs);
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
requested_oplock_level = SMB2_OPLOCK_LEVEL_NONE;
} else {
requested_oplock_level = in_oplock_level;
@ -783,7 +783,7 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
smb2req->compat_chain_fsp = smb1req->chain_fsp;
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat_conn))) {
if(lp_fake_oplocks(SNUM(smb2req->tcon->compat))) {
state->out_oplock_level = in_oplock_level;
} else {
state->out_oplock_level = map_samba_oplock_levels_to_smb2(result->oplock_type);

View File

@ -211,7 +211,7 @@ static struct tevent_req *smbd_smb2_find_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
struct smbd_smb2_find_state *state;
struct smb_request *smbreq;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
NTSTATUS status;
NTSTATUS empty_status;
uint32_t info_level;

View File

@ -253,7 +253,7 @@ static struct tevent_req *smbd_smb2_getinfo_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
struct smbd_smb2_getinfo_state *state;
struct smb_request *smbreq;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
NTSTATUS status;
req = tevent_req_create(mem_ctx, &state,

View File

@ -37,9 +37,9 @@ struct smb_request *smbd_smb2_fake_smb_request(struct smbd_smb2_request *req)
}
smbreq->request_time = req->request_time;
smbreq->vuid = req->session->compat_vuser->vuid;
smbreq->tid = req->tcon->compat_conn->cnum;
smbreq->conn = req->tcon->compat_conn;
smbreq->vuid = req->session->compat->vuid;
smbreq->tid = req->tcon->compat->cnum;
smbreq->conn = req->tcon->compat;
smbreq->sconn = req->sconn;
smbreq->smbpid = (uint16_t)IVAL(inhdr, SMB2_HDR_PID);
smbreq->flags2 = FLAGS2_UNICODE_STRINGS |

View File

@ -195,7 +195,7 @@ static struct tevent_req *smbd_smb2_notify_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req;
struct smbd_smb2_notify_state *state;
struct smb_request *smbreq;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
bool recursive = (in_flags & SMB2_WATCH_TREE) ? true : false;
NTSTATUS status;

View File

@ -389,7 +389,7 @@ static struct tevent_req *smbd_smb2_read_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req = NULL;
struct smbd_smb2_read_state *state = NULL;
struct smb_request *smbreq = NULL;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
ssize_t nread = -1;
struct lock_struct lock;
int saved_errno;

View File

@ -108,7 +108,6 @@ static NTSTATUS smbd_initialize_smb2(struct smbd_server_connection *sconn)
return NT_STATUS_NO_MEMORY;
}
sconn->smb2.sessions.list = NULL;
sconn->smb2.seqnum_low = 0;
sconn->smb2.credits_granted = 0;
sconn->smb2.max_credits = lp_smb2_max_credits();
@ -811,7 +810,7 @@ static NTSTATUS smb2_send_async_interim_response(const struct smbd_smb2_request
/* Re-sign if needed. */
if (nreq->do_signing) {
NTSTATUS status;
struct smbXsrv_session *x = nreq->session->smbXsrv;
struct smbXsrv_session *x = nreq->session;
struct smbXsrv_connection *conn = x->connection;
DATA_BLOB signing_key = x->global->channels[0].signing_key;
@ -1100,7 +1099,7 @@ static void smbd_smb2_request_pending_timer(struct tevent_context *ev,
if (req->do_signing) {
NTSTATUS status;
struct smbXsrv_session *x = req->session->smbXsrv;
struct smbXsrv_session *x = req->session;
struct smbXsrv_connection *conn = x->connection;
DATA_BLOB signing_key = x->global->channels[0].signing_key;
@ -1203,8 +1202,9 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
int i = req->current_idx;
uint32_t in_flags;
uint32_t in_tid;
void *p;
struct smbd_smb2_tcon *tcon;
struct smbXsrv_tcon0 *tcon;
NTSTATUS status;
NTTIME now = timeval_to_nttime(&req->request_time);
req->tcon = NULL;
@ -1217,19 +1217,18 @@ static NTSTATUS smbd_smb2_request_check_tcon(struct smbd_smb2_request *req)
in_tid = req->last_tid;
}
/* lookup an existing session */
p = idr_find(req->session->tcons.idtree, in_tid);
if (p == NULL) {
return NT_STATUS_NETWORK_NAME_DELETED;
status = smb2srv_tcon_lookup(req->session,
in_tid, now, &tcon);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
tcon = talloc_get_type_abort(p, struct smbd_smb2_tcon);
if (!change_to_user(tcon->compat_conn,req->session->vuid)) {
if (!change_to_user(tcon->compat, req->session->compat->vuid)) {
return NT_STATUS_ACCESS_DENIED;
}
/* should we pass FLAG_CASELESS_PATHNAMES here? */
if (!set_current_service(tcon->compat_conn, 0, true)) {
if (!set_current_service(tcon->compat, 0, true)) {
return NT_STATUS_ACCESS_DENIED;
}
@ -1249,8 +1248,8 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
int i = req->current_idx;
uint32_t in_flags;
uint64_t in_session_id;
struct smbd_smb2_session *session;
struct smbXsrv_session *smbXsrv;
struct smbXsrv_session *session;
struct auth_session_info *session_info;
NTSTATUS status;
NTTIME now = timeval_to_nttime(&req->request_time);
@ -1269,18 +1268,19 @@ static NTSTATUS smbd_smb2_request_check_session(struct smbd_smb2_request *req)
/* lookup an existing session */
status = smb2srv_session_lookup(req->sconn->conn,
in_session_id, now,
&smbXsrv);
&session);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
session = smbXsrv->smb2sess;
if (!NT_STATUS_IS_OK(session->status)) {
return NT_STATUS_ACCESS_DENIED;
session_info = session->global->auth_session_info;
if (session_info == NULL) {
return NT_STATUS_INVALID_HANDLE;
}
set_current_user_info(session->session_info->unix_info->sanitized_username,
session->session_info->unix_info->unix_name,
session->session_info->info->domain_name);
set_current_user_info(session_info->unix_info->sanitized_username,
session_info->unix_info->unix_name,
session_info->info->domain_name);
req->session = session;
req->last_session_id = in_session_id;
@ -1445,9 +1445,7 @@ NTSTATUS smbd_smb2_request_dispatch(struct smbd_smb2_request *req)
* we defer the check of the session_status
*/
session_status = smbd_smb2_request_check_session(req);
if (req->session) {
x = req->session->smbXsrv;
}
x = req->session;
req->do_signing = false;
if (flags & SMB2_HDR_FLAG_SIGNED) {
@ -1949,7 +1947,7 @@ static NTSTATUS smbd_smb2_request_reply(struct smbd_smb2_request *req)
if (req->do_signing) {
NTSTATUS status;
struct smbXsrv_session *x = req->session->smbXsrv;
struct smbXsrv_session *x = req->session;
struct smbXsrv_connection *conn = x->connection;
DATA_BLOB signing_key = x->global->channels[0].signing_key;

View File

@ -174,33 +174,7 @@ static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
}
}
static int smbd_smb2_session_destructor(struct smbd_smb2_session *session)
{
if (session->sconn == NULL) {
return 0;
}
file_close_user(session->sconn, session->vuid);
/* first free all tcons */
while (session->tcons.list) {
talloc_free(session->tcons.list);
}
DLIST_REMOVE(session->sconn->smb2.sessions.list, session);
invalidate_vuid(session->sconn, session->vuid);
session->vuid = 0;
session->status = NT_STATUS_USER_SESSION_DELETED;
session->sconn = NULL;
session->smbXsrv->compat = NULL;
TALLOC_FREE(session->smbXsrv);
return 0;
}
static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
struct smbd_smb2_request *smb2req,
uint8_t in_security_mode,
uint64_t in_previous_session_id,
@ -211,16 +185,24 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
NTSTATUS status;
bool guest = false;
uint8_t session_key[16];
struct smbXsrv_session *x = session->smbXsrv;
struct auth_session_info *session_info = session->session_info;
struct smbXsrv_connection *conn = x->connection;
struct smbXsrv_session *x = session;
struct auth_session_info *session_info;
struct smbXsrv_connection *conn = session->connection;
if ((in_security_mode & SMB2_NEGOTIATE_SIGNING_REQUIRED) ||
lp_server_signing() == SMB_SIGNING_REQUIRED) {
x->global->signing_required = true;
}
if (security_session_user_level(session->session_info, NULL) < SECURITY_USER) {
status = gensec_session_info(session->gensec,
session->global,
&session_info);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
}
if (security_session_user_level(session_info, NULL) < SECURITY_USER) {
/* we map anonymous to guest internally */
*out_session_flags |= SMB2_SESSION_FLAG_IS_GUEST;
*out_session_flags |= SMB2_SESSION_FLAG_IS_NULL;
@ -230,8 +212,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
}
ZERO_STRUCT(session_key);
memcpy(session_key, session->session_info->session_key.data,
MIN(session->session_info->session_key.length, sizeof(session_key)));
memcpy(session_key, session_info->session_key.data,
MIN(session_info->session_key.length, sizeof(session_key)));
x->global->signing_key = data_blob_talloc(x->global,
session_key,
@ -286,55 +268,53 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
return NT_STATUS_NO_MEMORY;
}
session->compat_vuser = talloc_zero(session, struct user_struct);
if (session->compat_vuser == NULL) {
session->compat = talloc_zero(session, struct user_struct);
if (session->compat == NULL) {
TALLOC_FREE(session);
return NT_STATUS_NO_MEMORY;
}
session->compat_vuser->gensec_security = session->gensec_security;
session->compat_vuser->homes_snum = -1;
session->compat_vuser->session_info = session->session_info;
session->compat_vuser->session_keystr = NULL;
session->compat_vuser->vuid = session->vuid;
DLIST_ADD(session->sconn->users, session->compat_vuser);
session->sconn->num_users++;
session->compat->session = session;
session->compat->homes_snum = -1;
session->compat->session_info = session_info;
session->compat->session_keystr = NULL;
session->compat->vuid = session->global->session_wire_id;
DLIST_ADD(smb2req->sconn->users, session->compat);
smb2req->sconn->num_users++;
if (security_session_user_level(session->session_info, NULL) >= SECURITY_USER) {
session->compat_vuser->homes_snum =
register_homes_share(session->session_info->unix_info->unix_name);
if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
session->compat->homes_snum =
register_homes_share(session_info->unix_info->unix_name);
}
if (!session_claim(session->sconn, session->compat_vuser)) {
if (!session_claim(smb2req->sconn, session->compat)) {
DEBUG(1, ("smb2: Failed to claim session "
"for vuid=%llu\n",
(unsigned long long)session->compat_vuser->vuid));
(unsigned long long)session->compat->vuid));
TALLOC_FREE(session);
return NT_STATUS_LOGON_FAILURE;
}
set_current_user_info(session->session_info->unix_info->sanitized_username,
session->session_info->unix_info->unix_name,
session->session_info->info->domain_name);
set_current_user_info(session_info->unix_info->sanitized_username,
session_info->unix_info->unix_name,
session_info->info->domain_name);
reload_services(smb2req->sconn, conn_snum_used, true);
session->smbXsrv->status = NT_STATUS_OK;
session->smbXsrv->global->auth_session_info = session->session_info;
session->smbXsrv->global->auth_session_info_seqnum += 1;
session->smbXsrv->global->channels[0].auth_session_info_seqnum =
session->smbXsrv->global->auth_session_info_seqnum;
session->status = NT_STATUS_OK;
session->global->auth_session_info = session_info;
session->global->auth_session_info_seqnum += 1;
session->global->channels[0].auth_session_info_seqnum =
session->global->auth_session_info_seqnum;
status = smbXsrv_session_update(session->smbXsrv);
status = smbXsrv_session_update(session);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
(unsigned long long)session->compat_vuser->vuid,
(unsigned long long)session->compat->vuid,
nt_errstr(status)));
TALLOC_FREE(session);
return NT_STATUS_LOGON_FAILURE;
}
session->status = NT_STATUS_OK;
/*
* we attach the session to the request
* so that the response can be signed
@ -346,12 +326,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbd_smb2_session *session,
global_client_caps |= (CAP_LEVEL_II_OPLOCKS|CAP_STATUS32);
*out_session_id = session->vuid;
*out_session_id = session->global->session_wire_id;
return NT_STATUS_OK;
}
static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
static NTSTATUS smbd_smb2_auth_generic(struct smbXsrv_session *session,
struct smbd_smb2_request *smb2req,
uint8_t in_security_mode,
uint64_t in_previous_session_id,
@ -364,18 +344,20 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
*out_security_buffer = data_blob_null;
if (session->gensec_security == NULL) {
status = auth_generic_prepare(session, session->sconn->remote_address,
&session->gensec_security);
if (session->gensec == NULL) {
status = auth_generic_prepare(session,
session->connection->remote_address,
&session->gensec);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
}
gensec_want_feature(session->gensec_security, GENSEC_FEATURE_SESSION_KEY);
gensec_want_feature(session->gensec_security, GENSEC_FEATURE_UNIX_TOKEN);
gensec_want_feature(session->gensec, GENSEC_FEATURE_SESSION_KEY);
gensec_want_feature(session->gensec, GENSEC_FEATURE_UNIX_TOKEN);
status = gensec_start_mech_by_oid(session->gensec_security, GENSEC_OID_SPNEGO);
status = gensec_start_mech_by_oid(session->gensec,
GENSEC_OID_SPNEGO);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
@ -383,7 +365,7 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
}
become_root();
status = gensec_update(session->gensec_security,
status = gensec_update(session->gensec,
smb2req, NULL,
in_security_buffer,
out_security_buffer);
@ -395,20 +377,10 @@ static NTSTATUS smbd_smb2_auth_generic(struct smbd_smb2_session *session,
}
if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
*out_session_id = session->vuid;
*out_session_id = session->global->session_wire_id;
return status;
}
status = gensec_session_info(session->gensec_security,
session,
&session->session_info);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(session);
return status;
}
*out_session_id = session->vuid;
return smbd_smb2_auth_generic_return(session,
smb2req,
in_security_mode,
@ -428,7 +400,6 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
DATA_BLOB *out_security_buffer,
uint64_t *out_session_id)
{
struct smbd_smb2_session *smb2sess;
struct smbXsrv_session *session;
NTSTATUS status;
NTTIME now = timeval_to_nttime(&smb2req->request_time);
@ -438,33 +409,11 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
if (in_session_id == 0) {
/* create a new session */
smb2sess = talloc_zero(smb2req->sconn, struct smbd_smb2_session);
if (smb2sess == NULL) {
return NT_STATUS_NO_MEMORY;
}
status = smbXsrv_session_create(smb2req->sconn->conn,
now, &session);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
smb2sess->smbXsrv = session;
session->smb2sess = smb2sess;
talloc_set_destructor(smb2sess, smbd_smb2_session_destructor);
smb2sess->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
smb2sess->vuid = session->global->session_wire_id;
smb2sess->tcons.idtree = idr_init(smb2sess);
if (smb2sess->tcons.idtree == NULL) {
return NT_STATUS_NO_MEMORY;
}
smb2sess->tcons.limit = 0x0000FFFE;
smb2sess->tcons.list = NULL;
DLIST_ADD_END(smb2req->sconn->smb2.sessions.list, smb2sess,
struct smbd_smb2_session *);
smb2sess->sconn = smb2req->sconn;
} else {
status = smb2srv_session_lookup(smb2req->sconn->conn,
in_session_id, now,
@ -473,18 +422,11 @@ static NTSTATUS smbd_smb2_session_setup(struct smbd_smb2_request *smb2req,
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
return status;
}
smb2sess = session->smb2sess;
}
if (NT_STATUS_IS_OK(smb2sess->status)) {
return NT_STATUS_REQUEST_NOT_ACCEPTED;
}
return smbd_smb2_auth_generic(smb2sess,
return smbd_smb2_auth_generic(session,
smb2req,
in_security_mode,
in_previous_session_id,
@ -596,9 +538,19 @@ NTSTATUS smbd_smb2_request_process_logoff(struct smbd_smb2_request *req)
/*
* TODO: cancel all outstanding requests on the session
* and delete all tree connections.
*/
smbd_smb2_session_destructor(req->session);
status = smbXsrv_session_logoff(req->session);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("smbd_smb2_request_process_logoff: "
"smbXsrv_session_logoff() failed: %s\n",
nt_errstr(status)));
/*
* If we hit this case, there is something completely
* wrong, so we better disconnect the transport connection.
*/
return status;
}
/*
* we may need to sign the response, so we need to keep
* the session until the response is sent to the wire.

View File

@ -172,7 +172,7 @@ static struct tevent_req *smbd_smb2_setinfo_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req = NULL;
struct smbd_smb2_setinfo_state *state = NULL;
struct smb_request *smbreq = NULL;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
NTSTATUS status;
req = tevent_req_create(mem_ctx, &state,

View File

@ -169,27 +169,6 @@ static void smbd_smb2_request_tcon_done(struct tevent_req *subreq)
}
}
static int smbd_smb2_tcon_destructor(struct smbd_smb2_tcon *tcon)
{
if (tcon->session == NULL) {
return 0;
}
idr_remove(tcon->session->tcons.idtree, tcon->tid);
DLIST_REMOVE(tcon->session->tcons.list, tcon);
if (tcon->compat_conn) {
set_current_service(tcon->compat_conn, 0, true);
close_cnum(tcon->compat_conn, tcon->session->vuid);
}
tcon->compat_conn = NULL;
tcon->tid = 0;
tcon->session = NULL;
return 0;
}
static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
const char *in_path,
uint8_t *out_share_type,
@ -201,11 +180,12 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
const char *share = in_path;
char *service = NULL;
int snum = -1;
struct smbd_smb2_tcon *tcon;
struct smbXsrv_tcon *tcon;
NTTIME now = timeval_to_nttime(&req->request_time);
connection_struct *compat_conn = NULL;
struct user_struct *compat_vuser = req->session->compat_vuser;
int id;
struct user_struct *compat_vuser = req->session->compat;
NTSTATUS status;
const char *share_name = NULL;
if (strncmp(share, "\\\\", 2) == 0) {
const char *p = strchr(share+2, '\\');
@ -253,39 +233,42 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
}
/* create a new tcon as child of the session */
tcon = talloc_zero(req->session, struct smbd_smb2_tcon);
if (tcon == NULL) {
return NT_STATUS_NO_MEMORY;
status = smb2srv_tcon_create(req->session, now, &tcon);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
id = idr_get_new_random(req->session->tcons.idtree,
tcon,
req->session->tcons.limit);
if (id == -1) {
TALLOC_FREE(tcon);
return NT_STATUS_INSUFFICIENT_RESOURCES;
}
tcon->tid = id;
tcon->snum = snum;
DLIST_ADD_END(req->session->tcons.list, tcon,
struct smbd_smb2_tcon *);
tcon->session = req->session;
talloc_set_destructor(tcon, smbd_smb2_tcon_destructor);
compat_conn = make_connection_smb2(req->sconn,
tcon,
req->session->compat_vuser,
tcon, snum,
req->session->compat,
"???",
&status);
if (compat_conn == NULL) {
TALLOC_FREE(tcon);
return status;
}
tcon->compat_conn = talloc_move(tcon, &compat_conn);
if (IS_PRINT(tcon->compat_conn)) {
share_name = lp_servicename(SNUM(compat_conn));
tcon->global->share_name = talloc_strdup(tcon->global, share_name);
if (tcon->global->share_name == NULL) {
conn_free(compat_conn);
TALLOC_FREE(tcon);
return NT_STATUS_NO_MEMORY;
}
tcon->compat = talloc_move(tcon, &compat_conn);
tcon->status = NT_STATUS_OK;
status = smbXsrv_tcon_update(tcon);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(tcon);
return status;
}
if (IS_PRINT(tcon->compat)) {
*out_share_type = SMB2_SHARE_TYPE_PRINT;
} else if (IS_IPC(tcon->compat_conn)) {
} else if (IS_IPC(tcon->compat)) {
*out_share_type = SMB2_SHARE_TYPE_PIPE;
} else {
*out_share_type = SMB2_SHARE_TYPE_DISK;
@ -293,14 +276,14 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
*out_share_flags = 0;
if (lp_msdfs_root(SNUM(tcon->compat_conn)) && lp_host_msdfs()) {
if (lp_msdfs_root(SNUM(tcon->compat)) && lp_host_msdfs()) {
*out_share_flags |= (SMB2_SHAREFLAG_DFS|SMB2_SHAREFLAG_DFS_ROOT);
*out_capabilities = SMB2_SHARE_CAP_DFS;
} else {
*out_capabilities = 0;
}
switch(lp_csc_policy(SNUM(tcon->compat_conn))) {
switch(lp_csc_policy(SNUM(tcon->compat))) {
case CSC_POLICY_MANUAL:
break;
case CSC_POLICY_DOCUMENTS:
@ -316,14 +299,14 @@ static NTSTATUS smbd_smb2_tree_connect(struct smbd_smb2_request *req,
break;
}
if (lp_hideunreadable(SNUM(tcon->compat_conn)) ||
lp_hideunwriteable_files(SNUM(tcon->compat_conn))) {
if (lp_hideunreadable(SNUM(tcon->compat)) ||
lp_hideunwriteable_files(SNUM(tcon->compat))) {
*out_share_flags |= SMB2_SHAREFLAG_ACCESS_BASED_DIRECTORY_ENUM;
}
*out_maximal_access = tcon->compat_conn->share_access;
*out_maximal_access = tcon->compat->share_access;
*out_tree_id = tcon->tid;
*out_tree_id = tcon->global->tcon_wire_id;
return NT_STATUS_OK;
}
@ -406,8 +389,19 @@ NTSTATUS smbd_smb2_request_process_tdis(struct smbd_smb2_request *req)
/*
* TODO: cancel all outstanding requests on the tcon
* and delete all file handles.
*/
status = smbXsrv_tcon_disconnect(req->tcon, req->tcon->compat->vuid);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0, ("smbd_smb2_request_process_tdis: "
"smbXsrv_tcon_disconnect() failed: %s\n",
nt_errstr(status)));
/*
* If we hit this case, there is something completely
* wrong, so we better disconnect the transport connection.
*/
return status;
}
TALLOC_FREE(req->tcon);
outbody = data_blob_talloc(req->out.vector, NULL, 0x04);

View File

@ -246,7 +246,7 @@ static struct tevent_req *smbd_smb2_write_send(TALLOC_CTX *mem_ctx,
struct tevent_req *req = NULL;
struct smbd_smb2_write_state *state = NULL;
struct smb_request *smbreq = NULL;
connection_struct *conn = smb2req->tcon->compat_conn;
connection_struct *conn = smb2req->tcon->compat;
ssize_t nwritten;
struct lock_struct lock;