1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-12 20:58:37 +03:00

s3-ntlmssp Remove references to auth_ntlmssp_context from the smb sealing code

Andrew Bartlett

Signed-off-by: Stefan Metzmacher <metze@samba.org>
This commit is contained in:
Andrew Bartlett 2011-10-19 15:57:18 +11:00 committed by Stefan Metzmacher
parent 0a0839821a
commit 0fe4192054
4 changed files with 54 additions and 46 deletions

View File

@ -52,7 +52,7 @@ struct smb_trans_enc_state {
uint16_t enc_ctx_num;
bool enc_on;
union {
struct auth_ntlmssp_state *auth_ntlmssp_state;
struct gensec_security *gensec_security;
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
struct smb_tran_enc_state_gss *gss_state;
#endif

View File

@ -609,36 +609,37 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli,
DATA_BLOB blob_out = data_blob_null;
DATA_BLOB param_out = data_blob_null;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
struct auth_ntlmssp_state *auth_ntlmssp_state;
struct smb_trans_enc_state *es = make_cli_enc_state(SMB_TRANS_ENC_NTLM);
if (!es) {
return NT_STATUS_NO_MEMORY;
}
status = auth_ntlmssp_client_prepare(NULL,
&es->s.auth_ntlmssp_state);
&auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
goto fail;
}
gensec_want_feature(es->s.auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
gensec_want_feature(es->s.auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SEAL);
gensec_want_feature(auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SESSION_KEY);
gensec_want_feature(auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SEAL);
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_username(es->s.auth_ntlmssp_state, user))) {
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_username(auth_ntlmssp_state, user))) {
goto fail;
}
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_domain(es->s.auth_ntlmssp_state, domain))) {
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_domain(auth_ntlmssp_state, domain))) {
goto fail;
}
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_password(es->s.auth_ntlmssp_state, pass))) {
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_set_password(auth_ntlmssp_state, pass))) {
goto fail;
}
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_client_start(es->s.auth_ntlmssp_state))) {
if (!NT_STATUS_IS_OK(status = auth_ntlmssp_client_start(auth_ntlmssp_state))) {
goto fail;
}
do {
status = gensec_update(es->s.auth_ntlmssp_state->gensec_security, es->s.auth_ntlmssp_state,
status = gensec_update(auth_ntlmssp_state->gensec_security, auth_ntlmssp_state,
NULL, blob_in, &blob_out);
data_blob_free(&blob_in);
data_blob_free(&param_out);
@ -667,13 +668,18 @@ NTSTATUS cli_raw_ntlm_smb_encryption_start(struct cli_state *cli,
if (cli->trans_enc_state) {
common_free_encryption_state(&cli->trans_enc_state);
}
/* We only need the gensec_security part from here.
* es is a malloc()ed pointer, so we cannot make
* gensec_security a talloc child */
es->s.gensec_security = talloc_move(NULL,
&auth_ntlmssp_state->gensec_security);
cli->trans_enc_state = es;
cli->trans_enc_state->enc_on = True;
es = NULL;
}
fail:
TALLOC_FREE(auth_ntlmssp_state);
common_free_encryption_state(&es);
return status;
}

View File

@ -18,10 +18,8 @@
*/
#include "includes.h"
#include "../auth/ntlmssp/ntlmssp.h"
#include "smb_crypt.h"
#include "libsmb/libsmb.h"
#include "ntlmssp_wrap.h"
#include "libcli/auth/krb5_wrap.h"
#include "auth/gensec/gensec.h"
@ -75,14 +73,12 @@ bool common_encryption_on(struct smb_trans_enc_state *es)
/******************************************************************************
Generic code for client and server.
NTLM decrypt an incoming buffer.
Abartlett tells me that SSPI puts the signature first before the encrypted
output, so cope with the same for compatibility.
GENSEC decrypt an incoming buffer.
******************************************************************************/
static NTSTATUS common_ntlm_decrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state, char *buf)
static NTSTATUS common_gensec_decrypt_buffer(struct gensec_security *gensec,
char *buf)
{
struct gensec_security *gensec = auth_ntlmssp_state->gensec_security;
NTSTATUS status;
size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
DATA_BLOB in_buf, out_buf;
@ -99,14 +95,14 @@ static NTSTATUS common_ntlm_decrypt_buffer(struct auth_ntlmssp_state *auth_ntlms
status = gensec_unwrap(gensec, frame, &in_buf, &out_buf);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("common_ntlm_decrypt_buffer: gensec_unwrap failed. Error %s\n",
DEBUG(0,("common_gensec_decrypt_buffer: gensec_unwrap failed. Error %s\n",
nt_errstr(status)));
TALLOC_FREE(frame);
return status;
}
if (out_buf.length > in_buf.length) {
DEBUG(0,("common_ntlm_decrypt_buffer: gensec_unwrap size (%u) too large (%u) !\n",
DEBUG(0,("common_gensec_decrypt_buffer: gensec_unwrap size (%u) too large (%u) !\n",
(unsigned int)out_buf.length,
(unsigned int)in_buf.length ));
TALLOC_FREE(frame);
@ -126,16 +122,13 @@ static NTSTATUS common_ntlm_decrypt_buffer(struct auth_ntlmssp_state *auth_ntlms
/******************************************************************************
Generic code for client and server.
NTLM encrypt an outgoing buffer. Return the encrypted pointer in ppbuf_out.
Abartlett tells me that SSPI puts the signature first before the encrypted
output, so do the same for compatibility.
******************************************************************************/
static NTSTATUS common_ntlm_encrypt_buffer(struct auth_ntlmssp_state *auth_ntlmssp_state,
uint16_t enc_ctx_num,
char *buf,
char **ppbuf_out)
static NTSTATUS common_gensec_encrypt_buffer(struct gensec_security *gensec,
uint16_t enc_ctx_num,
char *buf,
char **ppbuf_out)
{
struct gensec_security *gensec = auth_ntlmssp_state->gensec_security;
NTSTATUS status;
DATA_BLOB in_buf, out_buf;
size_t buf_len = smb_len_nbt(buf) + 4; /* Don't forget the 4 length bytes. */
@ -152,7 +145,7 @@ static NTSTATUS common_ntlm_encrypt_buffer(struct auth_ntlmssp_state *auth_ntlms
status = gensec_wrap(gensec, frame, &in_buf, &out_buf);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("common_ntlm_encrypt_buffer: gensec_wrap failed. Error %s\n",
DEBUG(0,("common_gensec_encrypt_buffer: gensec_wrap failed. Error %s\n",
nt_errstr(status)));
TALLOC_FREE(frame);
return status;
@ -331,7 +324,7 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha
switch (es->smb_enc_type) {
case SMB_TRANS_ENC_NTLM:
return common_ntlm_encrypt_buffer(es->s.auth_ntlmssp_state, es->enc_ctx_num, buffer, buf_out);
return common_gensec_encrypt_buffer(es->s.gensec_security, es->enc_ctx_num, buffer, buf_out);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_encrypt_buffer(es->s.gss_state, es->enc_ctx_num, buffer, buf_out);
@ -356,7 +349,7 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
switch (es->smb_enc_type) {
case SMB_TRANS_ENC_NTLM:
return common_ntlm_decrypt_buffer(es->s.auth_ntlmssp_state, buf);
return common_gensec_decrypt_buffer(es->s.gensec_security, buf);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_decrypt_buffer(es->s.gss_state, buf);
@ -399,8 +392,8 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
}
if (es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
if (es->s.auth_ntlmssp_state) {
TALLOC_FREE(es->s.auth_ntlmssp_state);
if (es->s.gensec_security) {
TALLOC_FREE(es->s.gensec_security);
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)

View File

@ -40,7 +40,7 @@
struct smb_srv_trans_enc_ctx {
struct smb_trans_enc_state *es;
struct auth_ntlmssp_state *auth_ntlmssp_state; /* Must be kept in sync with pointer in ec->ntlmssp_state. */
struct gensec_security *gensec_security; /* Must be kept in sync with pointer in ec->ntlmssp_state. */
};
/******************************************************************************
@ -88,17 +88,19 @@ bool is_encrypted_packet(struct smbd_server_connection *sconn,
static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
struct smb_srv_trans_enc_ctx *ec)
{
struct auth_ntlmssp_state *auth_ntlmssp_state;
NTSTATUS status = auth_ntlmssp_prepare(remote_address,
&ec->auth_ntlmssp_state);
&auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
return nt_status_squash(status);
}
gensec_want_feature(ec->auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SEAL);
gensec_want_feature(auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SEAL);
status = auth_ntlmssp_start(ec->auth_ntlmssp_state);
status = auth_ntlmssp_start(auth_ntlmssp_state);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(auth_ntlmssp_state);
return nt_status_squash(status);
}
@ -106,7 +108,14 @@ static NTSTATUS make_auth_ntlmssp(const struct tsocket_address *remote_address,
* We must remember to update the pointer copy for the common
* functions after any auth_ntlmssp_start/auth_ntlmssp_end.
*/
ec->es->s.auth_ntlmssp_state = ec->auth_ntlmssp_state;
ec->es->s.gensec_security = ec->gensec_security;
/* We do not need the auth_ntlmssp layer any more, which was
* allocated on NULL, so promote gensec_security to the NULL
* context */
ec->gensec_security = talloc_move(NULL, &auth_ntlmssp_state->gensec_security);
TALLOC_FREE(auth_ntlmssp_state);
return status;
}
@ -121,10 +130,10 @@ static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
* functions after any auth_ntlmssp_start/auth_ntlmssp_end.
*/
if (ec->auth_ntlmssp_state) {
TALLOC_FREE(ec->auth_ntlmssp_state);
if (ec->gensec_security) {
TALLOC_FREE(ec->gensec_security);
/* The auth_ntlmssp_end killed this already. */
ec->es->s.auth_ntlmssp_state = NULL;
ec->es->s.gensec_security = NULL;
}
}
@ -489,7 +498,7 @@ static NTSTATUS srv_enc_ntlm_negotiate(const struct tsocket_address *remote_addr
return status;
}
status = gensec_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state->gensec_security,
status = gensec_update(partial_srv_trans_enc_ctx->gensec_security,
talloc_tos(), NULL,
secblob, &chal);
@ -603,7 +612,7 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
/* We must have a partial context here. */
if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
if (!ec || !ec->es || ec->gensec_security == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
srv_free_encryption_context(&partial_srv_trans_enc_ctx);
return NT_STATUS_INVALID_PARAMETER;
}
@ -614,7 +623,7 @@ static NTSTATUS srv_enc_spnego_ntlm_auth(connection_struct *conn,
return NT_STATUS_INVALID_PARAMETER;
}
status = gensec_update(ec->auth_ntlmssp_state->gensec_security, talloc_tos(), NULL, auth, &auth_reply);
status = gensec_update(ec->gensec_security, talloc_tos(), NULL, auth, &auth_reply);
data_blob_free(&auth);
/* From RFC4178.
@ -678,13 +687,13 @@ static NTSTATUS srv_enc_raw_ntlm_auth(connection_struct *conn,
}
ec = partial_srv_trans_enc_ctx;
if (!ec || !ec->es || ec->auth_ntlmssp_state == NULL || ec->es->smb_enc_type != SMB_TRANS_ENC_NTLM) {
if (!ec || !ec->es || ec->gensec_security == 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 = gensec_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state->gensec_security,
status = gensec_update(partial_srv_trans_enc_ctx->gensec_security,
talloc_tos(), NULL,
blob, &response);
@ -761,11 +770,11 @@ static NTSTATUS check_enc_good(struct smb_srv_trans_enc_ctx *ec)
}
if (ec->es->smb_enc_type == SMB_TRANS_ENC_NTLM) {
if (!gensec_have_feature(ec->auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SIGN)) {
if (!gensec_have_feature(ec->gensec_security, GENSEC_FEATURE_SIGN)) {
return NT_STATUS_INVALID_PARAMETER;
}
if (!gensec_have_feature(ec->auth_ntlmssp_state->gensec_security, GENSEC_FEATURE_SEAL)) {
if (!gensec_have_feature(ec->gensec_security, GENSEC_FEATURE_SEAL)) {
return NT_STATUS_INVALID_PARAMETER;
}
}