s3:smbd: make use of smbXsrv_tcon and smbXsrv_session for smb2
authorStefan Metzmacher <metze@samba.org>
Tue, 27 Mar 2012 09:09:05 +0000 (11:09 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 25 Jun 2012 18:55:06 +0000 (20:55 +0200)
The removes the protocol specific smbd_smb2_session and
smbd_smb2_tcon.

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

metze

20 files changed:
source3/include/vfs.h
source3/librpc/idl/smbXsrv.idl
source3/smbd/conn_idle.c
source3/smbd/files.c
source3/smbd/globals.h
source3/smbd/password.c
source3/smbd/proto.h
source3/smbd/service.c
source3/smbd/smb2_close.c
source3/smbd/smb2_create.c
source3/smbd/smb2_find.c
source3/smbd/smb2_getinfo.c
source3/smbd/smb2_glue.c
source3/smbd/smb2_notify.c
source3/smbd/smb2_read.c
source3/smbd/smb2_server.c
source3/smbd/smb2_sesssetup.c
source3/smbd/smb2_setinfo.c
source3/smbd/smb2_tcon.c
source3/smbd/smb2_write.c

index e6a9ef4541d482561a4d581bcfdfb3df89bef6f5..1496164fafe1b06a9c2d160d9729d3cfba27cccb 100644 (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;
index 44af7c83afa5d841ce6fb7312710d8d83d84e545..215b72ebfbfcd529ffec64e7695fcb0af6f02fc2 100644 (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 {
index 4dfa4097c31ff3dbc4261db1c91fd82a3b728d61..22bc20ef1f597ff5c781f2a1ee24b6f11d807ee1 100644 (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 (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 */
index bec157b3da733c5de76c809dded91d1d0fae18c5..d11d6d764bd2237c1bc1f24a5169a43075be7610 100644 (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;
        }
 
index 9eadc99c0e24897ef6315deed46a490f65224c6b..a68c2034c8a25b46cdb1ba0f209a01f59c118c18 100644 (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;
index e8b48c464d85e8f42b332ca9cf3a1fd99096e597..b1ba66ac3fc6abf3e2f3ef62cbef3cc6a1ee0273 100644 (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;
        }
 
index 8196e6963433c64a287338a90ef9c67518f50dca..f774a3bf8ccf715c086e2650b44b71fc4d383d3d 100644 (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);
index 1bcbbcda6a38c549f0da4ff6f868f36cb5eb87dc..fe5838225d9f690529ac6b61a6ad3c09df39c096 100644 (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)) {
index a7f5df5ebbaed794323b7857606c149bfb866c05..566ac93ea2563394187caf092bef8eaf3f72a389 100644 (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;
index 7dd7c5ca60e498f3fd9dc64a23297a718b097753..f540377dcce7c1db77b43007109621dc82d876c8 100644 (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);
index 0464ad2c397a6eadb6a61b81f0f6a81c95ed43cb..ef6887d3b7b0dc959d8fb529cdd87ef0928f49cd 100644 (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;
index 10b093737fa89c1cee62f598404b28e955f6f6eb..efd65a9daa9a2a233343bf3147bc488c3f1756ba 100644 (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,
index a71679fdf2f1b515c9b24a2398889be2ec813099..d9d8f9a01c11eb39077a633ae1421105341ac7e8 100644 (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 |
index 20496c1c2c12961e975810b18ac46f4bed6374f1..aa6d1906df60134d35b0e7bb9badd29d90c096af 100644 (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;
 
index 54bd3cdf7c06b60cc85e06ef257412906354057a..0e08ff4a52f181c9f6dabcaa9fd619817b387354 100644 (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;
index f49c05cd56836b83e724ed07d490c84e954a570d..a3d7c2c506967d155ef54ea0a0b9b3d096a555e3 100644 (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;
 
index 9aa73d39cacac2815c4df0a238a7c6150d82d281..dc01fc38bd87b3472db9ac5eadd16347be2cd42d 100644 (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,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.
index c7652f6644bba4ddd12de0dadd54252a500c5a8e..32fbcca43c9628794eb398d87192e4674d9b1d10 100644 (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,
index 14294aefaf44a8e8c8a9a0bbc7424ef89832ea65..ceb145ff63a5a15c6fdb5f3e7bc898e2e158b5c4 100644 (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;
-       }
-       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);
index 778f15a567b4b87898dc0b346fabb451551cdf58..0150b0cd25d62e6a5ef6dcc60ef770d3c60036d9 100644 (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;