1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-13 13:18:06 +03:00

r21997: Implement the server side of gss seal negotiate.

Jeremy.
(This used to be commit 6b923acfee)
This commit is contained in:
Jeremy Allison 2007-03-28 01:11:27 +00:00 committed by Gerald (Jerry) Carter
parent 3215c09a81
commit e9157961d6
2 changed files with 92 additions and 17 deletions

View File

@ -332,8 +332,12 @@ static void common_free_gss_state(struct smb_tran_enc_state_gss **pp_gss_state)
OM_uint32 minor = 0;
struct smb_tran_enc_state_gss *gss_state = *pp_gss_state;
gss_release_cred(&minor, &gss_state->creds);
gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL);
if (gss_state->creds != GSS_C_NO_CREDENTIAL) {
gss_release_cred(&minor, &gss_state->creds);
}
if (gss_state->gss_ctx != GSS_C_NO_CONTEXT) {
gss_delete_sec_context(&minor, &gss_state->gss_ctx, NULL);
}
SAFE_FREE(*pp_gss_state);
}
#endif

View File

@ -97,7 +97,7 @@ static NTSTATUS get_gss_creds(const char *service,
gss_cred_id_t *p_srv_cred)
{
OM_uint32 ret;
OM_uint32 min;
OM_uint32 min;
gss_name_t srv_name;
gss_buffer_desc input_name;
char *host_princ_s = NULL;
@ -141,6 +141,8 @@ static NTSTATUS get_gss_creds(const char *service,
/******************************************************************************
Create a gss state.
Try and get the cifs/server@realm principal first, then fall back to
host/server@realm.
******************************************************************************/
static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
@ -160,6 +162,18 @@ static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
}
}
ec->es->s.gss_state = SMB_MALLOC_P(struct smb_tran_enc_state_gss);
if (!ec->es->s.gss_state) {
OM_uint32 min;
gss_release_cred(&min, &srv_cred);
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(ec->es->s.gss_state);
ec->es->s.gss_state->creds = srv_cred;
/* No context yet. */
ec->es->s.gss_state->gss_ctx = GSS_C_NO_CONTEXT;
return NT_STATUS_OK;
}
#endif
@ -197,19 +211,21 @@ static void srv_free_encryption_context(struct smb_srv_trans_enc_ctx **pp_ec)
Create a server encryption context.
******************************************************************************/
static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type)
static NTSTATUS make_srv_encryption_context(enum smb_trans_enc_type smb_enc_type, struct smb_srv_trans_enc_ctx **pp_ec)
{
struct smb_srv_trans_enc_ctx *ec;
*pp_ec = NULL;
ec = SMB_MALLOC_P(struct smb_srv_trans_enc_ctx);
if (!ec) {
return NULL;
return NT_STATUS_NO_MEMORY;
}
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;
return NT_STATUS_NO_MEMORY;
}
ZERO_STRUCTP(ec->es);
ec->es->smb_enc_type = smb_enc_type;
@ -219,7 +235,7 @@ static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_
NTSTATUS status = make_auth_ntlmssp(ec);
if (!NT_STATUS_IS_OK(status)) {
srv_free_encryption_context(&ec);
return NULL;
return status;
}
}
break;
@ -231,16 +247,17 @@ static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_
NTSTATUS status = make_auth_gss(ec);
if (!NT_STATUS_IS_OK(status)) {
srv_free_encryption_context(&ec);
return NULL;
return status;
}
}
break;
#endif
default:
srv_free_encryption_context(&ec);
return NULL;
return NT_STATUS_INVALID_PARAMETER;
}
return ec;
*pp_ec = ec;
return NT_STATUS_OK;
}
/******************************************************************************
@ -308,14 +325,68 @@ NTSTATUS srv_encrypt_buffer(char *buf, char **buf_out)
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
static NTSTATUS srv_enc_spnego_gss_negotiate(unsigned char **ppdata, size_t *p_data_size, DATA_BLOB secblob)
{
OM_uint32 ret;
OM_uint32 min;
OM_uint32 flags = 0;
gss_buffer_desc in_buf, out_buf;
struct smb_tran_enc_state_gss *gss_state;
if (!partial_srv_trans_enc_ctx) {
partial_srv_trans_enc_ctx = make_srv_encryption_context(SMB_TRANS_ENC_GSS);
if (!partial_srv_trans_enc_ctx) {
return NT_STATUS_NO_MEMORY;
NTSTATUS status = make_srv_encryption_context(SMB_TRANS_ENC_GSS, &partial_srv_trans_enc_ctx);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
}
return NT_STATUS_NOT_SUPPORTED;
gss_state = partial_srv_trans_enc_ctx->es->s.gss_state;
in_buf.value = secblob.data;
in_buf.length = secblob.length;
out_buf.value = NULL;
out_buf.length = 0;
ret = gss_accept_sec_context(&min,
&gss_state->gss_ctx,
gss_state->creds,
&in_buf,
GSS_C_NO_CHANNEL_BINDINGS,
NULL,
NULL, /* Ignore oids. */
&out_buf, /* To return. */
&flags,
NULL, /* Ingore time. */
NULL); /* Ignore delegated creds. */
if (ret != GSS_S_COMPLETE && ret != GSS_S_CONTINUE_NEEDED) {
return gss_err_to_ntstatus(ret, min);
}
/* Ensure we've got sign+seal available. */
if (ret == GSS_S_COMPLETE) {
if ((flags & (GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) !=
(GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG)) {
DEBUG(0,("srv_enc_spnego_gss_negotiate: quality of service not good enough "
"for SMB sealing.\n"));
gss_release_buffer(&min, &out_buf);
return NT_STATUS_ACCESS_DENIED;
}
}
SAFE_FREE(*ppdata);
*ppdata = memdup(out_buf.value, out_buf.length);
if (!*ppdata) {
gss_release_buffer(&min, &out_buf);
return NT_STATUS_NO_MEMORY;
}
*p_data_size = out_buf.length;
gss_release_buffer(&min, &out_buf);
if (ret != GSS_S_CONTINUE_NEEDED) {
return NT_STATUS_MORE_PROCESSING_REQUIRED;
} else {
return NT_STATUS_OK;
}
}
#endif
@ -330,9 +401,9 @@ static NTSTATUS srv_enc_ntlm_negotiate(unsigned char **ppdata, size_t *p_data_si
DATA_BLOB chal = data_blob(NULL, 0);
DATA_BLOB response = data_blob(NULL, 0);
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 = make_srv_encryption_context(SMB_TRANS_ENC_NTLM, &partial_srv_trans_enc_ctx);
if (!NT_STATUS_IS_OK(status)) {
return status;
}
status = auth_ntlmssp_update(partial_srv_trans_enc_ctx->auth_ntlmssp_state, secblob, &chal);