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:
parent
9d34ee1c8b
commit
8b63654c2e
@ -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;
|
||||
};
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user