summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/include/vfs.h1
-rw-r--r--source3/librpc/idl/smbXsrv.idl1
-rw-r--r--source3/smbd/conn_idle.c41
-rw-r--r--source3/smbd/files.c8
-rw-r--r--source3/smbd/globals.h40
-rw-r--r--source3/smbd/password.c1
-rw-r--r--source3/smbd/proto.h5
-rw-r--r--source3/smbd/service.c10
-rw-r--r--source3/smbd/smb2_close.c2
-rw-r--r--source3/smbd/smb2_create.c4
-rw-r--r--source3/smbd/smb2_find.c2
-rw-r--r--source3/smbd/smb2_getinfo.c2
-rw-r--r--source3/smbd/smb2_glue.c6
-rw-r--r--source3/smbd/smb2_notify.c2
-rw-r--r--source3/smbd/smb2_read.c2
-rw-r--r--source3/smbd/smb2_server.c48
-rw-r--r--source3/smbd/smb2_sesssetup.c176
-rw-r--r--source3/smbd/smb2_setinfo.c2
-rw-r--r--source3/smbd/smb2_tcon.c100
-rw-r--r--source3/smbd/smb2_write.c2
20 files changed, 180 insertions, 275 deletions
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index e6a9ef4541..1496164faf 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -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;
diff --git a/source3/librpc/idl/smbXsrv.idl b/source3/librpc/idl/smbXsrv.idl
index 44af7c83af..215b72ebfb 100644
--- a/source3/librpc/idl/smbXsrv.idl
+++ b/source3/librpc/idl/smbXsrv.idl
@@ -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 {
diff --git a/source3/smbd/conn_idle.c b/source3/smbd/conn_idle.c
index 4dfa4097c3..22bc20ef1f 100644
--- a/source3/smbd/conn_idle.c
+++ b/source3/smbd/conn_idle.c
@@ -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 (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);
- }
+ for (conn=sconn->connections;conn;conn=next) {
+ struct smbXsrv_tcon *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 */
diff --git a/source3/smbd/files.c b/source3/smbd/files.c
index bec157b3da..d11d6d764b 100644
--- a/source3/smbd/files.c
+++ b/source3/smbd/files.c
@@ -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;
}
diff --git a/source3/smbd/globals.h b/source3/smbd/globals.h
index 9eadc99c0e..a68c2034c8 100644
--- a/source3/smbd/globals.h
+++ b/source3/smbd/globals.h
@@ -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;
@@ -674,9 +641,6 @@ struct smbd_server_connection {
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;
bool blocking_lock_unlock_state;
diff --git a/source3/smbd/password.c b/source3/smbd/password.c
index e8b48c464d..b1ba66ac3f 100644
--- a/source3/smbd/password.c
+++ b/source3/smbd/password.c
@@ -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;
}
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 8196e69634..f774a3bf8c 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -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);
diff --git a/source3/smbd/service.c b/source3/smbd/service.c
index 1bcbbcda6a..fe5838225d 100644
--- a/source3/smbd/service.c
+++ b/source3/smbd/service.c
@@ -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)) {
diff --git a/source3/smbd/smb2_close.c b/source3/smbd/smb2_close.c
index a7f5df5ebb..566ac93ea2 100644
--- a/source3/smbd/smb2_close.c
+++ b/source3/smbd/smb2_close.c
@@ -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;
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 7dd7c5ca60..f540377dcc 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -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);
diff --git a/source3/smbd/smb2_find.c b/source3/smbd/smb2_find.c
index 0464ad2c39..ef6887d3b7 100644
--- a/source3/smbd/smb2_find.c
+++ b/source3/smbd/smb2_find.c
@@ -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;
diff --git a/source3/smbd/smb2_getinfo.c b/source3/smbd/smb2_getinfo.c
index 10b093737f..efd65a9daa 100644
--- a/source3/smbd/smb2_getinfo.c
+++ b/source3/smbd/smb2_getinfo.c
@@ -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,
diff --git a/source3/smbd/smb2_glue.c b/source3/smbd/smb2_glue.c
index a71679fdf2..d9d8f9a01c 100644
--- a/source3/smbd/smb2_glue.c
+++ b/source3/smbd/smb2_glue.c
@@ -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 |
diff --git a/source3/smbd/smb2_notify.c b/source3/smbd/smb2_notify.c
index 20496c1c2c..aa6d1906df 100644
--- a/source3/smbd/smb2_notify.c
+++ b/source3/smbd/smb2_notify.c
@@ -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;
diff --git a/source3/smbd/smb2_read.c b/source3/smbd/smb2_read.c
index 54bd3cdf7c..0e08ff4a52 100644
--- a/source3/smbd/smb2_read.c
+++ b/source3/smbd/smb2_read.c
@@ -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;
diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c
index f49c05cd56..a3d7c2c506 100644
--- a/source3/smbd/smb2_server.c
+++ b/source3/smbd/smb2_server.c
@@ -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;
diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c
index 9aa73d39ca..dc01fc38bd 100644
--- a/source3/smbd/smb2_sesssetup.c
+++ b/source3/smbd/smb2_sesssetup.c
@@ -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,19 +377,9 @@ 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;
- return status;
- }
-
- status = gensec_session_info(session->gensec_security,
- session,
- &session->session_info);
-
- if (!NT_STATUS_IS_OK(status)) {
- TALLOC_FREE(session);
+ *out_session_id = session->global->session_wire_id;
return status;
}
- *out_session_id = session->vuid;
return smbd_smb2_auth_generic_return(session,
smb2req,
@@ -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.
diff --git a/source3/smbd/smb2_setinfo.c b/source3/smbd/smb2_setinfo.c
index c7652f6644..32fbcca43c 100644
--- a/source3/smbd/smb2_setinfo.c
+++ b/source3/smbd/smb2_setinfo.c
@@ -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,
diff --git a/source3/smbd/smb2_tcon.c b/source3/smbd/smb2_tcon.c
index 14294aefaf..ceb145ff63 100644
--- a/source3/smbd/smb2_tcon.c
+++ b/source3/smbd/smb2_tcon.c
@@ -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;
- }
- 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;
+ status = smb2srv_tcon_create(req->session, now, &tcon);
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
}
- 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);
diff --git a/source3/smbd/smb2_write.c b/source3/smbd/smb2_write.c
index 778f15a567..0150b0cd25 100644
--- a/source3/smbd/smb2_write.c
+++ b/source3/smbd/smb2_write.c
@@ -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;