1
0
mirror of https://github.com/samba-team/samba.git synced 2025-02-03 13:47:25 +03:00

r21969: Start working on the gss-side of the server negotiation.

Jeremy.
(This used to be commit fbc569b530104679e47fe743963eb0c4384de6ae)
This commit is contained in:
Jeremy Allison 2007-03-27 00:50:53 +00:00 committed by Gerald (Jerry) Carter
parent 9d34ee1c8b
commit 8b63654c2e
6 changed files with 128 additions and 9 deletions

View File

@ -81,13 +81,20 @@ struct rpc_pipe_client {
/* Transport encryption state. */
enum smb_trans_enc_type { SMB_TRANS_ENC_NTLM, SMB_TRANS_ENC_GSS };
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
struct smb_tran_enc_state_gss {
gss_ctx_id_t gss_ctx;
gss_cred_id_t creds;
};
#endif
struct smb_trans_enc_state {
enum smb_trans_enc_type smb_enc_type;
BOOL enc_on;
union {
NTLMSSP_STATE *ntlmssp_state;
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
gss_ctx_id_t context_handle;
struct smb_tran_enc_state_gss *gss_state;
#endif
} s;
};

View File

@ -1188,10 +1188,10 @@ krb5_error_code smb_krb5_mk_error(krb5_context context,
/* Call for SMB transport encryption. */
#if defined(HAVE_GSSAPI)
NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf);
NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf);
#endif
#if defined(HAVE_GSSAPI)
NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **buf_out);
NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf, char **buf_out);
#endif
#endif /* HAVE_KRB5 */

View File

@ -530,6 +530,7 @@ findfirst/findnext is SMB_FIND_FILE_UNIX_INFO2.
#define CIFS_UNIX_POSIX_PATHNAMES_CAP 0x10 /* Use POSIX pathnames on the wire. */
#define CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP 0x20 /* We can cope with POSIX open/mkdir/unlink etc. */
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP 0x40 /* We can do SPNEGO negotiations for encryption. */
#define CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP 0x80 /* We *must* SPNEGO negotiations for encryption. */
#define SMB_QUERY_POSIX_FS_INFO 0x201

View File

@ -126,8 +126,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
******************************************************************************/
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
NTSTATUS common_gss_decrypt_buffer(gss_ctx_id_t context_handle, char *buf)
NTSTATUS common_gss_decrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf)
{
gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
OM_uint32 ret = 0;
OM_uint32 minor = 0;
int flags_got = 0;
@ -142,7 +143,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
in_buf.length = buf_len - 8;
ret = gss_unwrap(&minor,
context_handle,
gss_ctx,
&in_buf,
&out_buf,
&flags_got, /* did we get sign+seal ? */
@ -178,8 +179,9 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
******************************************************************************/
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
NTSTATUS common_gss_encrypt_buffer(gss_ctx_id_t context_handle, char *buf, char **ppbuf_out)
NTSTATUS common_gss_encrypt_buffer(struct smb_tran_enc_state_gss *gss_state, char *buf, char **ppbuf_out)
{
gss_ctx_id_t gss_ctx = gss_state->gss_ctx;
OM_uint32 ret = 0;
OM_uint32 minor = 0;
int flags_got = 0;
@ -196,7 +198,7 @@ NTSTATUS common_ntlm_encrypt_buffer(NTLMSSP_STATE *ntlmssp_state, char *buf, cha
in_buf.length = buf_len - 8;
ret = gss_wrap(&minor,
context_handle,
gss_ctx,
True, /* we want sign+seal. */
GSS_C_QOP_DEFAULT,
&in_buf,
@ -267,7 +269,7 @@ NTSTATUS common_encrypt_buffer(struct smb_trans_enc_state *es, char *buffer, cha
return common_ntlm_encrypt_buffer(es->s.ntlmssp_state, buffer, buf_out);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_encrypt_buffer(es->s.context_handle, buffer, buf_out);
return common_gss_encrypt_buffer(es->s.gss_state, buffer, buf_out);
#endif
default:
return NT_STATUS_NOT_SUPPORTED;
@ -297,13 +299,29 @@ NTSTATUS common_decrypt_buffer(struct smb_trans_enc_state *es, char *buf)
return common_ntlm_decrypt_buffer(es->s.ntlmssp_state, buf);
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
return common_gss_decrypt_buffer(es->s.context_handle, buf);
return common_gss_decrypt_buffer(es->s.gss_state, buf);
#endif
default:
return NT_STATUS_NOT_SUPPORTED;
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
/******************************************************************************
Shutdown a gss encryption state.
******************************************************************************/
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);
SAFE_FREE(*pp_gss_state);
}
#endif
/******************************************************************************
Shutdown an encryption state.
******************************************************************************/
@ -324,6 +342,9 @@ void common_free_encryption_state(struct smb_trans_enc_state **pp_es)
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
if (es->smb_enc_type == SMB_TRANS_ENC_GSS) {
/* Free the gss context handle. */
if (es->s.gss_state) {
common_free_gss_state(&es->s.gss_state);
}
}
#endif
SAFE_FREE(es);

View File

@ -228,6 +228,10 @@ static DATA_BLOB negprot_spnego(void)
name_to_fqdn(myname, global_myname());
strlower_m(myname);
asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm());
if (host_princ_s == NULL) {
blob = data_blob(NULL, 0);
return blob;
}
blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s);
SAFE_FREE(host_princ_s);
}

View File

@ -85,6 +85,85 @@ static void destroy_auth_ntlmssp(struct smb_srv_trans_enc_ctx *ec)
}
}
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
/******************************************************************************
Import a name.
******************************************************************************/
static NTSTATUS get_gss_creds(const char *service,
const char *name,
gss_cred_usage_t cred_type,
gss_cred_id_t *p_srv_cred)
{
OM_uint32 ret;
OM_uint32 min;
gss_name_t srv_name;
gss_buffer_desc input_name;
char *host_princ_s = NULL;
NTSTATUS status = NT_STATUS_OK;
asprintf(&host_princ_s, "%s@%s", service, name);
if (host_princ_s == NULL) {
return NT_STATUS_NO_MEMORY;
}
input_name.value = host_princ_s;
input_name.length = strlen(host_princ_s) + 1;
ret = gss_import_name(&min,
&input_name,
GSS_C_NT_HOSTBASED_SERVICE,
&srv_name);
if (ret != GSS_S_COMPLETE) {
SAFE_FREE(host_princ_s);
return map_nt_error_from_gss(ret, min);
}
ret = gss_acquire_cred(&min,
&srv_name,
GSS_C_INDEFINITE,
GSS_C_NULL_OID_SET,
cred_type,
p_srv_cred,
NULL,
NULL);
if (ret != GSS_S_COMPLETE) {
status = map_nt_error_from_gss(ret, min);
}
SAFE_FREE(host_princ_s);
gss_release_name(&min, &srv_name);
return status;
}
/******************************************************************************
Create a gss state.
******************************************************************************/
static NTSTATUS make_auth_gss(struct smb_srv_trans_enc_ctx *ec)
{
NTSTATUS status;
gss_cred_id_t srv_cred;
fstring fqdn;
name_to_fqdn(fqdn, global_myname());
strlower_m(fqdn);
status = get_gss_creds("cifs", fqdn, GSS_C_ACCEPT, &srv_cred);
if (!NT_STATUS_IS_OK(status)) {
status = get_gss_creds("host", fqdn, GSS_C_ACCEPT, &srv_cred);
if (!NT_STATUS_IS_OK(status)) {
return nt_status_squash(status);
}
}
return NT_STATUS_OK;
}
#endif
/******************************************************************************
Shutdown a server encryption context.
******************************************************************************/
@ -148,6 +227,13 @@ static struct smb_srv_trans_enc_ctx *make_srv_encryption_context(enum smb_trans_
#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5)
case SMB_TRANS_ENC_GSS:
/* Acquire our credentials by calling gss_acquire_cred here. */
{
NTSTATUS status = make_auth_gss(ec);
if (!NT_STATUS_IS_OK(status)) {
srv_free_encryption_context(&ec);
return NULL;
}
}
break;
#endif
default: