STEP07c? TODO s3:smb2_sesssetup: smbXsrv_session_auth0 .... before preauth???
authorStefan Metzmacher <metze@samba.org>
Fri, 19 Sep 2014 01:26:00 +0000 (03:26 +0200)
committerMichael Adam <obnox@samba.org>
Fri, 15 May 2015 09:46:54 +0000 (11:46 +0200)
source3/librpc/idl/smbXsrv.idl
source3/smbd/globals.h
source3/smbd/smb2_sesssetup.c
source3/smbd/smbXsrv_session.c

index 7dee54b42ee1b25d895a4e4fd5997ac89ff8dcbd..75a5eba720241ff1eb0c0369d8ff7039158dcadd 100644 (file)
@@ -256,6 +256,8 @@ interface smbXsrv
                [ignore] smbXsrv_connection             *connection;
                [ignore] gensec_security                *gensec;
                [ignore] smbXsrv_preauth                *preauth;
+               uint8                                   in_flags;
+               uint8                                   in_security_mode;
                NTTIME                                  creation_time;
                NTTIME                                  idle_time;
        } smbXsrv_session_auth0;
@@ -273,7 +275,6 @@ interface smbXsrv
                [ignore] gensec_security                *gensec;
                [ignore] user_struct                    *compat;
                [ignore] smbXsrv_tcon_table             *tcon_table;
-               [ignore] smbXsrv_preauth                *preauth;
                smbXsrv_session_auth0                   *pending_auth;
        } smbXsrv_session;
 
index a2ba5a72809e0937d245b9fe8b76e795dad5f23b..9eb6744482bf682e285d5a47184dfdc9ccf5f4e0 100644 (file)
@@ -570,6 +570,8 @@ NTSTATUS smbXsrv_session_find_auth(const struct smbXsrv_session *session,
 NTSTATUS smbXsrv_session_create_auth(struct smbXsrv_session *session,
                                     struct smbXsrv_connection *conn,
                                     NTTIME now,
+                                    uint8_t in_flags,
+                                    uint8_t in_security_mode,
                                     struct smbXsrv_session_auth0 **_a);
 struct tevent_req *smb2srv_session_shutdown_send(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *ev,
index bb3cc8880413f679dfd21f6920282d19af1218b6..f00e028a526f01cd8a88043830bf434ca6caad40 100644 (file)
@@ -174,6 +174,7 @@ static void smbd_smb2_request_sesssetup_done(struct tevent_req *subreq)
 }
 
 static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
+                                       struct smbXsrv_session_auth0 **_auth,
                                        struct smbd_smb2_request *smb2req,
                                        uint8_t in_security_mode,
                                        struct auth_session_info *session_info,
@@ -184,6 +185,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
        bool guest = false;
        uint8_t session_key[16];
        struct smbXsrv_session *x = session;
+       struct smbXsrv_session_auth0 *auth = *_auth;
        struct smbXsrv_connection *xconn = smb2req->xconn;
        size_t i;
        struct _derivation {
@@ -197,13 +199,15 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
                struct _derivation application;
        } derivation = { };
 
+       *_auth = NULL;
+
        if (xconn->protocol >= PROTOCOL_SMB3_10) {
                struct smbXsrv_preauth *preauth;
                struct _derivation *d;
                DATA_BLOB p;
                struct hc_sha512state sctx;
 
-               preauth = talloc_move(smb2req, &session->preauth);
+               preauth = talloc_move(smb2req, &auth->preauth);
 
                samba_SHA512_Init(&sctx);
                samba_SHA512_Update(&sctx, preauth->sha512_value,
@@ -418,7 +422,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
                        session->global->auth_session_info_seqnum;
        }
        session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
-       session->global->expiration_time = gensec_expire_time(session->gensec);
+       session->global->expiration_time = gensec_expire_time(auth->gensec);
 
        if (!session_claim(session)) {
                DEBUG(1, ("smb2: Failed to claim session "
@@ -427,6 +431,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
                return NT_STATUS_LOGON_FAILURE;
        }
 
+       TALLOC_FREE(auth);
        status = smbXsrv_session_update(session);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
@@ -451,6 +456,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session,
 }
 
 static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
+                                       struct smbXsrv_session_auth0 **_auth,
                                        struct smbd_smb2_request *smb2req,
                                        struct auth_session_info *session_info,
                                        uint16_t *out_session_flags,
@@ -458,9 +464,12 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
 {
        NTSTATUS status;
        struct smbXsrv_session *x = session;
+       struct smbXsrv_session_auth0 *auth = *_auth;
        struct smbXsrv_connection *xconn = smb2req->xconn;
        size_t i;
 
+       *_auth = NULL;
+
        data_blob_clear_free(&session_info->session_key);
        session_info->session_key = data_blob_dup_talloc(session_info,
                                                x->global->application_key);
@@ -493,8 +502,9 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
                        session->global->auth_session_info_seqnum;
        }
        session->global->auth_time = timeval_to_nttime(&smb2req->request_time);
-       session->global->expiration_time = gensec_expire_time(session->gensec);
+       session->global->expiration_time = gensec_expire_time(auth->gensec);
 
+       TALLOC_FREE(auth);
        status = smbXsrv_session_update(session);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
@@ -515,6 +525,7 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session,
 }
 
 static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
+                                          struct smbXsrv_session_auth0 **_auth,
                                           struct smbd_smb2_request *smb2req,
                                           struct auth_session_info *session_info,
                                           uint16_t *out_session_flags,
@@ -522,6 +533,7 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
 {
        NTSTATUS status;
        struct smbXsrv_session *x = session;
+       struct smbXsrv_session_auth0 *auth = *_auth;
        struct smbXsrv_connection *xconn = smb2req->xconn;
        struct smbXsrv_channel_global0 *c = NULL;
        uint8_t session_key[16];
@@ -535,13 +547,15 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
        } derivation = { };
        bool ok;
 
+       *_auth = NULL;
+
        if (xconn->protocol >= PROTOCOL_SMB3_10) {
                struct smbXsrv_preauth *preauth;
                struct _derivation *d;
                DATA_BLOB p;
                struct hc_sha512state sctx;
 
-               preauth = talloc_move(smb2req, &session->preauth);
+               preauth = talloc_move(smb2req, &auth->preauth);
 
                samba_SHA512_Init(&sctx);
                samba_SHA512_Update(&sctx, preauth->sha512_value,
@@ -606,6 +620,7 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session,
        }
        ZERO_STRUCT(session_key);
 
+       TALLOC_FREE(auth);
        status = smbXsrv_session_update(session);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(0, ("smb2: Failed to update session for vuid=%llu - %s\n",
@@ -628,6 +643,7 @@ struct smbd_smb2_session_setup_state {
        uint64_t in_previous_session_id;
        DATA_BLOB in_security_buffer;
        struct smbXsrv_session *session;
+       struct smbXsrv_session_auth0 *auth;
        struct auth_session_info *session_info;
        uint16_t out_session_flags;
        DATA_BLOB out_security_buffer;
@@ -772,44 +788,60 @@ auth:
                        return tevent_req_post(req, ev);
                }
 
-               //TODO use smbXsrv_session_auth ....
                state->session = smb2req->session;
                status = state->session->status;
                if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_SESSION_EXPIRED)) {
                        status = NT_STATUS_OK;
                }
-               if (NT_STATUS_IS_OK(status)) {
+               if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
+                       status = NT_STATUS_OK;
+               }
+               if (tevent_req_nterror(req, status)) {
+                       return tevent_req_post(req, ev);
+               }
+               if (!(in_flags & SMB2_SESSION_FLAG_BINDING)) {
                        state->session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
-                       status = NT_STATUS_MORE_PROCESSING_REQUIRED;
-                       TALLOC_FREE(state->session->gensec);
                }
-               if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
-                       tevent_req_nterror(req, status);
+       }
+
+       status = smbXsrv_session_find_auth(state->session, smb2req->xconn,
+                                          now, &state->auth);
+       if (!NT_STATUS_IS_OK(status)) {
+               status = smbXsrv_session_create_auth(state->session,
+                                                    smb2req->xconn, now,
+                                                    in_flags, in_security_mode,
+                                                    &state->auth);
+               if (tevent_req_nterror(req, status)) {
                        return tevent_req_post(req, ev);
                }
        }
 
-       if (state->session->gensec == NULL) {
-               status = auth_generic_prepare(state->session,
+       if (state->auth->gensec == NULL) {
+               status = auth_generic_prepare(state->auth,
                                              state->smb2req->xconn->remote_address,
-                                             &state->session->gensec);
+                                             &state->auth->gensec);
                if (tevent_req_nterror(req, status)) {
                        return tevent_req_post(req, ev);
                }
 
-               gensec_want_feature(state->session->gensec, GENSEC_FEATURE_SESSION_KEY);
-               gensec_want_feature(state->session->gensec, GENSEC_FEATURE_UNIX_TOKEN);
+               gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_SESSION_KEY);
+               gensec_want_feature(state->auth->gensec, GENSEC_FEATURE_UNIX_TOKEN);
 
-               status = gensec_start_mech_by_oid(state->session->gensec,
+               status = gensec_start_mech_by_oid(state->auth->gensec,
                                                  GENSEC_OID_SPNEGO);
                if (tevent_req_nterror(req, status)) {
                        return tevent_req_post(req, ev);
                }
        }
 
+       status = smbXsrv_session_update(state->session);
+       if (tevent_req_nterror(req, status)) {
+               return tevent_req_post(req, ev);
+       }
+
        become_root();
        subreq = gensec_update_send(state, state->ev,
-                                   state->session->gensec,
+                                   state->auth->gensec,
                                    state->in_security_buffer);
        unbecome_root();
        if (tevent_req_nomem(subreq, req)) {
@@ -843,12 +875,12 @@ static void smbd_smb2_session_setup_gensec_done(struct tevent_req *subreq)
 
        if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                state->out_session_id = state->session->global->session_wire_id;
-               state->smb2req->preauth = state->session->preauth;
+               state->smb2req->preauth = state->auth->preauth;
                tevent_req_nterror(req, status);
                return;
        }
 
-       status = gensec_session_info(state->session->gensec,
+       status = gensec_session_info(state->auth->gensec,
                                     state,
                                     &state->session_info);
        if (tevent_req_nterror(req, status)) {
@@ -901,6 +933,7 @@ static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
 
        if (state->in_flags & SMB2_SESSION_FLAG_BINDING) {
                status = smbd_smb2_bind_auth_return(state->session,
+                                                   &state->auth,
                                                    state->smb2req,
                                                    state->session_info,
                                                    &state->out_session_flags,
@@ -914,6 +947,7 @@ static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
 
        if (state->session->global->auth_session_info != NULL) {
                status = smbd_smb2_reauth_generic_return(state->session,
+                                                        &state->auth,
                                                         state->smb2req,
                                                         state->session_info,
                                                         &state->out_session_flags,
@@ -926,6 +960,7 @@ static void smbd_smb2_session_setup_auth_return(struct tevent_req *req)
        }
 
        status = smbd_smb2_auth_generic_return(state->session,
+                                              &state->auth,
                                               state->smb2req,
                                               state->in_security_mode,
                                               state->session_info,
index 17323dd6c337abac5fae21f8abf2fbe07661cb2a..9fb09bd58b88c85b3897285efc4e660350ba3eeb 100644 (file)
@@ -1179,15 +1179,6 @@ NTSTATUS smbXsrv_session_create(struct smbXsrv_connection *conn,
        session->status = NT_STATUS_MORE_PROCESSING_REQUIRED;
        session->client = conn->client;
 
-       if (conn->protocol >= PROTOCOL_SMB3_10) {
-               session->preauth = talloc(session, struct smbXsrv_preauth);
-               if (session->preauth == NULL) {
-                       TALLOC_FREE(session);
-                       return NT_STATUS_NO_MEMORY;
-               }
-               *session->preauth = conn->smb2.preauth;
-       }
-
        status = smbXsrv_session_global_allocate(table->global.db_ctx,
                                                 session,
                                                 &global);
@@ -1446,6 +1437,8 @@ static int smbXsrv_session_auth0_destructor(struct smbXsrv_session_auth0 *a)
 NTSTATUS smbXsrv_session_create_auth(struct smbXsrv_session *session,
                                     struct smbXsrv_connection *conn,
                                     NTTIME now,
+                                    uint8_t in_flags,
+                                    uint8_t in_security_mode,
                                     struct smbXsrv_session_auth0 **_a)
 {
        struct smbXsrv_session_auth0 *a;
@@ -1462,12 +1455,24 @@ NTSTATUS smbXsrv_session_create_auth(struct smbXsrv_session *session,
        }
        a->session = session;
        a->connection = conn;
+       a->in_flags = in_flags;
+       a->in_security_mode = in_security_mode;
        a->creation_time = now;
        a->idle_time = now;
 
+       if (conn->protocol >= PROTOCOL_SMB3_10) {
+               a->preauth = talloc(a, struct smbXsrv_preauth);
+               if (a->preauth == NULL) {
+                       TALLOC_FREE(session);
+                       return NT_STATUS_NO_MEMORY;
+               }
+               *a->preauth = conn->smb2.preauth;
+       }
+
        talloc_set_destructor(a, smbXsrv_session_auth0_destructor);
        DLIST_ADD_END(session->pending_auth, a, NULL);
 
+       *_a = a;
        return NT_STATUS_OK;
 }