s3-ntlmssp Split auth_ntlmssp_start into two functions
authorAndrew Bartlett <abartlet@samba.org>
Tue, 26 Jul 2011 00:19:54 +0000 (10:19 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Wed, 3 Aug 2011 08:48:04 +0000 (18:48 +1000)
This helps map on to the GENSEC semantics better, and ensures that the
full set of desired features are set before the mechanism starts.

Andrew Bartlett

Signed-off-by: Andrew Tridgell <tridge@samba.org>
source3/auth/auth_ntlmssp.c
source3/auth/proto.h
source3/rpc_server/dcesrv_ntlmssp.c
source3/smbd/seal.c
source3/smbd/sesssetup.c
source3/smbd/smb2_sesssetup.c

index c078416aad0fa456b2dedf203756dc47d2d8c368..f7d3619d3b3a5b88b2d3a2963f83569964747b7d 100644 (file)
@@ -188,8 +188,8 @@ static NTSTATUS auth_ntlmssp_check_password(struct ntlmssp_state *ntlmssp_state,
 
 static int auth_ntlmssp_state_destructor(void *ptr);
 
-NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
-                           struct auth_ntlmssp_state **auth_ntlmssp_state)
+NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
+                             struct auth_ntlmssp_state **auth_ntlmssp_state)
 {
        NTSTATUS nt_status;
        bool is_standalone;
@@ -212,20 +212,16 @@ NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
                return nt_status;
        }
 
+       ans->auth_context = talloc_steal(ans, auth_context);
+
        if (auth_context->prepare_gensec) {
                nt_status = auth_context->prepare_gensec(ans, &ans->gensec_security);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        TALLOC_FREE(ans);
                        return nt_status;
                } else {
-                       nt_status = auth_context->gensec_start_mech_by_oid(ans->gensec_security, GENSEC_OID_NTLMSSP);
-                       if (!NT_STATUS_IS_OK(nt_status)) {
-                               TALLOC_FREE(ans);
-                               return nt_status;
-                       } else {
-                               *auth_ntlmssp_state = ans;
-                               return NT_STATUS_OK;
-                       }
+                       *auth_ntlmssp_state = ans;
+                       return NT_STATUS_OK;
                }
        }
 
@@ -261,8 +257,6 @@ NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
                return nt_status;
        }
 
-       ans->auth_context = talloc_steal(ans, auth_context);
-
        ans->ntlmssp_state->callback_private = ans;
        ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
        ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
@@ -286,3 +280,12 @@ static int auth_ntlmssp_state_destructor(void *ptr)
        TALLOC_FREE(ans->ntlmssp_state);
        return 0;
 }
+
+NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state)
+{
+       if (auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid) {
+               return auth_ntlmssp_state->auth_context->gensec_start_mech_by_oid(auth_ntlmssp_state->gensec_security, GENSEC_OID_NTLMSSP);
+       }
+
+       return NT_STATUS_OK;
+}
index f2b7875997c2bd3ded757d6264715dcef0fe2c3a..bce27c86c3f84cfa190a302b4b35099252f28957 100644 (file)
@@ -72,8 +72,9 @@ NTSTATUS auth_netlogond_init(void);
 NTSTATUS auth_ntlmssp_steal_session_info(TALLOC_CTX *mem_ctx,
                                struct auth_ntlmssp_state *auth_ntlmssp_state,
                                struct auth_session_info **session_info);
-NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
+NTSTATUS auth_ntlmssp_prepare(const struct tsocket_address *remote_address,
                            struct auth_ntlmssp_state **auth_ntlmssp_state);
+NTSTATUS auth_ntlmssp_start(struct auth_ntlmssp_state *auth_ntlmssp_state);
 
 
 /* The following definitions come from auth/auth_sam.c  */
index fd5b820143538a4b4ca1f0aee06c71e599dbae0a..f9fbc060c524c420a60e00bcb0e28e64ac9c85ab 100644 (file)
@@ -36,9 +36,9 @@ NTSTATUS ntlmssp_server_auth_start(TALLOC_CTX *mem_ctx,
        struct auth_ntlmssp_state *a = NULL;
        NTSTATUS status;
 
-       status = auth_ntlmssp_start(remote_address, &a);
+       status = auth_ntlmssp_prepare(remote_address, &a);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
+               DEBUG(0, (__location__ ": auth_ntlmssp_prepare failed: %s\n",
                          nt_errstr(status)));
                return status;
        }
@@ -51,6 +51,13 @@ NTSTATUS ntlmssp_server_auth_start(TALLOC_CTX *mem_ctx,
                auth_ntlmssp_want_feature(a, NTLMSSP_FEATURE_SEAL);
        }
 
+       status = auth_ntlmssp_start(a);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, (__location__ ": auth_ntlmssp_start failed: %s\n",
+                         nt_errstr(status)));
+               return status;
+       }
+
        status = auth_ntlmssp_update(a, mem_ctx, *token_in, token_out);
        if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
                DEBUG(0, (__location__ ": auth_ntlmssp_update failed: %s\n",
index 12672681fe0514f8dd453f5e4099a9b9f7c02f06..979c97c38ac05f269e510e0ae527e66c3705e864 100644 (file)
@@ -86,7 +86,7 @@ bool is_encrypted_packet(const uint8_t *inbuf)
 static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
                                  struct smb_srv_trans_enc_ctx *ec)
 {
-       NTSTATUS status = auth_ntlmssp_start(remote_address,
+       NTSTATUS status = auth_ntlmssp_prepare(remote_address,
                                             &ec->auth_ntlmssp_state);
        if (!NT_STATUS_IS_OK(status)) {
                return nt_status_squash(status);
@@ -94,6 +94,12 @@ static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
 
        auth_ntlmssp_want_feature(ec->auth_ntlmssp_state, NTLMSSP_FEATURE_SEAL);
 
+       status = auth_ntlmssp_start(ec->auth_ntlmssp_state);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return nt_status_squash(status);
+       }
+
        /*
         * We must remember to update the pointer copy for the common
         * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
index 1eb4708994725c180e311d035c0dafffd0e6ca4d..20b31096b04aa253526bcf16dbf1b1bbbd046cdf 100644 (file)
@@ -624,8 +624,8 @@ static void reply_spnego_negotiate(struct smb_request *req,
                return;
        }
 
-       status = auth_ntlmssp_start(sconn->remote_address,
-                                   auth_ntlmssp_state);
+       status = auth_ntlmssp_prepare(sconn->remote_address,
+                                     auth_ntlmssp_state);
        if (!NT_STATUS_IS_OK(status)) {
                /* Kill the intermediate vuid */
                invalidate_vuid(sconn, vuid);
@@ -635,6 +635,14 @@ static void reply_spnego_negotiate(struct smb_request *req,
 
        auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
 
+       status = auth_ntlmssp_start(*auth_ntlmssp_state);
+       if (!NT_STATUS_IS_OK(status)) {
+               /* Kill the intermediate vuid */
+               invalidate_vuid(sconn, vuid);
+               reply_nterror(req, nt_status_squash(status));
+               return;
+       }
+
        status = auth_ntlmssp_update(*auth_ntlmssp_state, talloc_tos(),
                                        secblob, &chal);
 
@@ -728,8 +736,18 @@ static void reply_spnego_auth(struct smb_request *req,
        data_blob_free(&secblob);
 
        if (!*auth_ntlmssp_state) {
-               status = auth_ntlmssp_start(sconn->remote_address,
-                                           auth_ntlmssp_state);
+               status = auth_ntlmssp_prepare(sconn->remote_address,
+                                             auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       /* Kill the intermediate vuid */
+                       invalidate_vuid(sconn, vuid);
+                       reply_nterror(req, nt_status_squash(status));
+                       return;
+               }
+
+               auth_ntlmssp_want_feature(*auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+               status = auth_ntlmssp_start(*auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(status)) {
                        /* Kill the intermediate vuid */
                        invalidate_vuid(sconn, vuid);
@@ -1141,8 +1159,19 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
                DATA_BLOB chal;
 
                if (!vuser->auth_ntlmssp_state) {
-                       status = auth_ntlmssp_start(sconn->remote_address,
-                                                   &vuser->auth_ntlmssp_state);
+                       status = auth_ntlmssp_prepare(sconn->remote_address,
+                                                     &vuser->auth_ntlmssp_state);
+                       if (!NT_STATUS_IS_OK(status)) {
+                               /* Kill the intermediate vuid */
+                               invalidate_vuid(sconn, vuid);
+                               data_blob_free(&blob1);
+                               reply_nterror(req, nt_status_squash(status));
+                               return;
+                       }
+
+                       auth_ntlmssp_want_feature(vuser->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+                       status = auth_ntlmssp_start(vuser->auth_ntlmssp_state);
                        if (!NT_STATUS_IS_OK(status)) {
                                /* Kill the intermediate vuid */
                                invalidate_vuid(sconn, vuid);
index 40f98ce45fd7068037776a602ff6876d420c437b..7bc8692758d66c6d3a812035e5c1fbea800d915f 100644 (file)
@@ -386,7 +386,7 @@ static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session,
                status = NT_STATUS_MORE_PROCESSING_REQUIRED;
        } else {
                /* Fall back to NTLMSSP. */
-               status = auth_ntlmssp_start(session->sconn->remote_address,
+               status = auth_ntlmssp_prepare(session->sconn->remote_address,
                                            &session->auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(status)) {
                        goto out;
@@ -394,6 +394,11 @@ static NTSTATUS smbd_smb2_spnego_negotiate(struct smbd_smb2_session *session,
 
                auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
 
+               status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto out;
+               }
+
                status = auth_ntlmssp_update(session->auth_ntlmssp_state,
                                             talloc_tos(),
                                             secblob_in,
@@ -577,13 +582,22 @@ static NTSTATUS smbd_smb2_spnego_auth(struct smbd_smb2_session *session,
        }
 
        if (session->auth_ntlmssp_state == NULL) {
-               status = auth_ntlmssp_start(session->sconn->remote_address,
+               status = auth_ntlmssp_prepare(session->sconn->remote_address,
                                            &session->auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(status)) {
                        data_blob_free(&auth);
                        TALLOC_FREE(session);
                        return status;
                }
+
+               auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+               status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       data_blob_free(&auth);
+                       TALLOC_FREE(session);
+                       return status;
+               }
        }
 
        status = auth_ntlmssp_update(session->auth_ntlmssp_state,
@@ -642,12 +656,20 @@ static NTSTATUS smbd_smb2_raw_ntlmssp_auth(struct smbd_smb2_session *session,
        NTSTATUS status;
 
        if (session->auth_ntlmssp_state == NULL) {
-               status = auth_ntlmssp_start(session->sconn->remote_address,
+               status = auth_ntlmssp_prepare(session->sconn->remote_address,
                                            &session->auth_ntlmssp_state);
                if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(session);
                        return status;
                }
+
+               auth_ntlmssp_want_feature(session->auth_ntlmssp_state, NTLMSSP_FEATURE_SESSION_KEY);
+
+               status = auth_ntlmssp_start(session->auth_ntlmssp_state);
+               if (!NT_STATUS_IS_OK(status)) {
+                       TALLOC_FREE(session);
+                       return status;
+               }
        }
 
        /* RAW NTLMSSP */