]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
r21894: Some refactoring of server side encryption context. Support
authorJeremy Allison <jra@samba.org>
Tue, 20 Mar 2007 22:01:02 +0000 (22:01 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:18:46 +0000 (12:18 -0500)
"raw" NTLM auth (no spnego).
Jeremy.

source/libsmb/cliconnect.c
source/libsmb/smb_seal.c
source/smbd/seal.c

index 0f09747dbf1115d1a2ba82e94132a20f32b8b037..3970731b45fba45eff90e3533a23e1e6c4c6c640 100644 (file)
@@ -763,7 +763,7 @@ static NTSTATUS cli_session_setup_ntlmssp(struct cli_state *cli, const char *use
                }
        }
 
-       /* we have a reference conter on ntlmssp_state, if we are signing
+       /* we have a reference counter on ntlmssp_state, if we are signing
           then the state will be kept by the signing engine */
 
        ntlmssp_end(&ntlmssp_state);
@@ -973,7 +973,6 @@ NTSTATUS cli_session_setup(struct cli_state *cli,
        }
 
        return NT_STATUS_OK;
-
 }
 
 /****************************************************************************
index e7b3e8f024c847d6449f9cd57a2e7d4f19a36bcd..06662e53fbf5110f07cbb09ffbf1efe2c55e4b1b 100644 (file)
@@ -282,3 +282,15 @@ NTSTATUS cli_encrypt_message(struct cli_state *cli, char **buf_out)
 {
        return common_encrypt_buffer(cli->trans_enc_state, cli->outbuf, buf_out);
 }
+
+/******************************************************************************
+ Start a raw ntlmssp encryption.
+******************************************************************************/
+
+NTSTATUS cli_ntlm_smb_encryption_on(struct cli_state *cli, 
+                               const char *user,
+                               const char *pass,
+                               const char *workgroup)
+{
+
+}
index 0a530526a2a273c670a76912050ead48f028f7ec..9910a84f4c4e9237dddf38bac94e4eeb5a48b523 100644 (file)
@@ -49,7 +49,44 @@ BOOL srv_encryption_on(void)
 }
 
 /******************************************************************************
- Shutdown a server encryption state.
+ Create an auth_ntlmssp_state and ensure pointer copy is correct.
+******************************************************************************/
+
+static NTSTATUS make_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
+{
+       NTSTATUS 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.
+        */
+       ec->es->ntlmssp_state = ec->auth_ntlmssp_state->ntlmssp_state;
+       return status;
+}
+
+/******************************************************************************
+ Destroy an auth_ntlmssp_state and ensure pointer copy is correct.
+******************************************************************************/
+
+static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
+{
+       /*
+        * We must remember to update the pointer copy for the common
+        * functions after any auth_ntlmssp_start/auth_ntlmssp_end.
+        */
+
+       if (ec->auth_ntlmssp_state) {
+               auth_ntlmssp_end(&ec->auth_ntlmssp_state);
+               /* The auth_ntlmssp_end killed this already. */
+               ec->es->ntlmssp_state = NULL;
+       }
+}
+
+/******************************************************************************
+ Shutdown a server encryption context.
 ******************************************************************************/
 
 static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
@@ -61,12 +98,8 @@ static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
        }
 
        if (ec->es) {
-               struct smb_trans_enc_state *es = ec->es;
-               if (es->smb_enc_type == SMB_TRANS_ENC_NTLM &&
-                               ec->auth_ntlmssp_state) {
-                       auth_ntlmssp_end(&ec->auth_ntlmssp_state);
-                       /* The auth_ntlmssp_end killed this already. */
-                       es->ntlmssp_state = NULL;
+               if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
+                       destroy_auth_ntlmssp(ec);
                }
                common_free_encryption_state(&ec->es);
        }
@@ -75,6 +108,36 @@ static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
        *pp_ec = NULL;
 }
 
+/******************************************************************************
+ Create a server encryption context.
+******************************************************************************/
+
+static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type)
+{
+       struct smb_srv_trans_enc_ctx *ec;
+
+       ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
+       if (!ec) {
+               return NULL;
+       }
+       ZERO_STRUCTP(partial_srv_trans_enc_ctx);
+       ec->es = SMB_MALLOC_P(struct smb_trans_enc_state);
+       if (!ec->es) {
+               SAFE_FREE(ec);
+               return NULL;
+       }
+       ZERO_STRUCTP(ec->es);
+       ec->es->smb_enc_type = smb_enc_type;
+       if (smb_enc_type == SMB_TRANS_ENC_NTLM) {
+               NTSTATUS status = make_auth_ntlmssp(ec);
+               if (!NT_STATUS_IS_OK(status)) {
+                       srv_free_encryption_context(&ec);
+                       return NULL;
+               }
+       }
+       return ec;
+}
+
 /******************************************************************************
  Free an encryption-allocated buffer.
 ******************************************************************************/
@@ -125,29 +188,33 @@ static NTSTATUS srv_enc_spnego_gss_negotiate(char **ppdata, size_t *p_data_size,
 #endif
 
 /******************************************************************************
- Do the NTLM SPNEGO encryption negotiation. Parameters are in/out.
+ Do the NTLM SPNEGO (or raw) encryption negotiation. Parameters are in/out.
  Until success we do everything on the partial enc ctx.
 ******************************************************************************/
 
-static NTSTATUS srv_enc_spnego_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
+static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob, BOOL spnego_wrap)
 {
        NTSTATUS status;
        DATA_BLOB chal = data_blob(NULL, 0);
        DATA_BLOB response = data_blob(NULL, 0);
-       struct smb_srv_trans_enc_ctx *ec = partial_srv_trans_enc_ctx;
 
-       status = auth_ntlmssp_start(&ec->auth_ntlmssp_state);
-       if (!NT_STATUS_IS_OK(status)) {
-               return nt_status_squash(status);
+       partial_srv_trans_enc_ctx = make_srv_encryption_context(SMB_TRANS_ENC_NTLM);
+       if (!partial_srv_trans_enc_ctx) {
+               return NT_STATUS_NO_MEMORY;
        }
 
-       status = auth_ntlmssp_update(ec->auth_ntlmssp_state, secblob, &chal);
+       status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);
 
        /* status here should be NT_STATUS_MORE_PROCESSING_REQUIRED
         * for success ... */
 
-       response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
-       data_blob_free(&chal);
+       if (spnego_wrap) {
+               response = spnego_gen_auth_response(&chal, status, OID_NTLMSSP);
+               data_blob_free(&chal);
+       } else {
+               /* Return the raw blob. */
+               response = chal;
+       }
 
        SAFE_FREE(*ppdata);
        *ppdata = response.data;
@@ -179,20 +246,13 @@ static NTSTATUS srv_enc_spnego_negotiate(unsigned char **ppdata, size_t *p_data_
 
        srv_free_encryption_context(&partial_srv_trans_enc_ctx);
 
-       partial_srv_trans_enc_ctx = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
-       if (!partial_srv_trans_enc_ctx) {
-               data_blob_free(&secblob);
-               return NT_STATUS_NO_MEMORY;
-       }
-       ZERO_STRUCTP(partial_srv_trans_enc_ctx);
-
 #if defined(HAVE_GSSAPI_SUPPORT) && defined(HAVE_KRB5)
        if (got_kerberos_mechanism && lp_use_kerberos_keytab()) ) {
                status = srv_enc_spnego_gss_negotiate(ppdata, p_data_size, secblob);
        } else 
 #endif
        {
-               status = srv_enc_spnego_ntlm_negotiate(ppdata, p_data_size, secblob);
+               status = srv_enc_ntlm_negotiate(ppdata, p_data_size, secblob, True);
        }
 
        data_blob_free(&secblob);
@@ -220,7 +280,7 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_
 
        /* We must have a partial context here. */
 
-       if (!ec || ec->auth_ntlmssp_state == NULL) {
+       if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
                srv_free_encryption_context(&partial_srv_trans_enc_ctx);
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -243,6 +303,44 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(unsigned char **ppdata, size_t *p_data_
        return status;
 }
 
+/******************************************************************************
+ Raw NTLM encryption negotiation. Parameters are in/out.
+ This function does both steps.
+******************************************************************************/
+
+static NTSTATUS srv_enc_raw_ntlm_auth(unsigned char **ppdata, size_t *p_data_size)
+{
+       NTSTATUS status;
+       DATA_BLOB blob = data_blob_const(*ppdata, *p_data_size);
+       DATA_BLOB response = data_blob(NULL,0);
+       struct smb_srv_trans_enc_ctx *ec;
+
+       if (!partial_srv_trans_enc_ctx) {
+               /* This is the initial step. */
+               status = srv_enc_ntlm_negotiate(ppdata, p_data_size, blob, False);
+               if (!NT_STATUS_IS_OK(status)) {
+                       srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+                       return nt_status_squash(status);
+               }
+               return status;
+       }
+
+       ec = partial_srv_trans_enc_ctx;
+       if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
+               srv_free_encryption_context(&partial_srv_trans_enc_ctx);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       /* Second step. */
+       status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, blob, &response);
+
+       /* Return the raw blob. */
+       SAFE_FREE(*ppdata);
+       *ppdata = response.data;
+       *p_data_size = response.length;
+       return status;
+}
+
 /******************************************************************************
  Do the SPNEGO encryption negotiation. Parameters are in/out.
 ******************************************************************************/
@@ -265,11 +363,22 @@ NTSTATUS srv_request_encryption_setup(unsigned char **ppdata, size_t *p_data_siz
        }
 
        if (pdata[0] == ASN1_CONTEXT(1)) {
-               /* Its a auth packet */
+               /* It's an auth packet */
                return srv_enc_spnego_ntlm_auth(ppdata, p_data_size);
        }
 
-       return NT_STATUS_INVALID_PARAMETER;
+       /* Maybe it's a raw unwrapped auth ? */
+       if (*p_data_size < 7) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       if (strncmp((char *)pdata, "NTLMSSP", 7) == 0) {
+               return srv_enc_raw_ntlm_auth(ppdata, p_data_size);
+       }
+
+       DEBUG(1,("srv_request_encryption_setup: Unknown packet\n"));
+
+       return NT_STATUS_LOGON_FAILURE;
 }
 
 /******************************************************************************