summaryrefslogtreecommitdiff
path: root/source4/auth/gensec/gensec_gssapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/auth/gensec/gensec_gssapi.c')
-rw-r--r--source4/auth/gensec/gensec_gssapi.c80
1 files changed, 61 insertions, 19 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 533448e06f..a95805f9fa 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -3,8 +3,8 @@
Kerberos backend for GENSEC
- Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004
- Copyright (C) Stefan Metzmacher <metze@samba.org> 2005
+ Copyright (C) Andrew Bartlett <abartlet@samba.org> 2004-2005
+ Copyright (C) Stefan Metzmacher <metze@samba.org> 2004-2005
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -224,6 +224,7 @@ static NTSTATUS gensec_gssapi_server_start(struct gensec_security *gensec_securi
static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security)
{
struct gensec_gssapi_state *gensec_gssapi_state;
+ struct cli_credentials *creds = gensec_get_credentials(gensec_security);
NTSTATUS nt_status;
gss_buffer_desc name_token;
OM_uint32 maj_stat, min_stat;
@@ -251,8 +252,8 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
return NT_STATUS_UNSUCCESSFUL;
}
- name_token.value = cli_credentials_get_principal(gensec_get_credentials(gensec_security),
- gensec_gssapi_state),
+ name_token.value = cli_credentials_get_principal(creds,
+ gensec_gssapi_state);
name_token.length = strlen(name_token.value);
maj_stat = gss_import_name (&min_stat,
@@ -267,7 +268,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
}
nt_status = kinit_to_ccache(gensec_gssapi_state,
- gensec_get_credentials(gensec_security),
+ creds,
gensec_gssapi_state->smb_krb5_context,
&gensec_gssapi_state->ccache, &gensec_gssapi_state->ccache_name);
if (!NT_STATUS_IS_OK(nt_status)) {
@@ -724,16 +725,22 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
struct auth_session_info **_session_info)
{
NTSTATUS nt_status;
+ TALLOC_CTX *mem_ctx;
struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info = NULL;
+ struct PAC_LOGON_INFO *logon_info;
char *p;
char *principal;
const char *account_name;
const char *realm;
OM_uint32 maj_stat, min_stat;
gss_buffer_desc name_token;
+ gss_buffer_desc pac;
+ mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context");
+ NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
+
maj_stat = gss_display_name (&min_stat,
gensec_gssapi_state->client_name,
&name_token,
@@ -742,11 +749,14 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
return NT_STATUS_FOOBAR;
}
- principal = talloc_strndup(gensec_gssapi_state, name_token.value, name_token.length);
+ principal = talloc_strndup(mem_ctx, name_token.value, name_token.length);
gss_release_buffer(&min_stat, &name_token);
- NT_STATUS_HAVE_NO_MEMORY(principal);
+ if (!principal) {
+ talloc_free(mem_ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
p = strchr(principal, '@');
if (p) {
@@ -757,24 +767,56 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
realm = lp_realm();
}
account_name = principal;
+
+ maj_stat = gsskrb5_extract_authz_data_from_sec_context(&min_stat,
+ gensec_gssapi_state->gssapi_context,
+ 1,
+ &pac);
+
+ if (maj_stat == 0) {
+ DATA_BLOB pac_blob = data_blob_talloc(mem_ctx, pac.value, pac.length);
+ pac_blob = unwrap_pac(mem_ctx, &pac_blob);
+ gss_release_buffer(&min_stat, &pac);
+
+ /* decode and verify the pac */
+ nt_status = kerberos_decode_pac(mem_ctx, &logon_info, pac_blob,
+ gensec_gssapi_state->smb_krb5_context);
+
+ if (NT_STATUS_IS_OK(nt_status)) {
+ union netr_Validation validation;
+ validation.sam3 = &logon_info->info3;
+ nt_status = make_server_info_netlogon_validation(gensec_gssapi_state,
+ account_name,
+ 3, &validation,
+ &server_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(mem_ctx);
+ return nt_status;
+ }
+ } else {
+ maj_stat = 1;
+ }
+ }
+
+ if (maj_stat) {
+ /* IF we have the PAC - otherwise we need to get this
+ * data from elsewere - local ldb, or (TODO) lookup of some
+ * kind...
+ *
+ * when heimdal can generate the PAC, we should fail if there's
+ * no PAC present
+ */
- /* IF we have the PAC - otherwise we need to get this
- * data from elsewere - local ldb, or (TODO) lookup of some
- * kind...
- *
- * when heimdal can generate the PAC, we should fail if there's
- * no PAC present
- */
-
- {
DATA_BLOB user_sess_key = data_blob(NULL, 0);
DATA_BLOB lm_sess_key = data_blob(NULL, 0);
/* TODO: should we pass the krb5 session key in here? */
- nt_status = sam_get_server_info(gensec_gssapi_state, account_name, realm,
+ nt_status = sam_get_server_info(mem_ctx, account_name, realm,
user_sess_key, lm_sess_key,
&server_info);
- talloc_free(principal);
- NT_STATUS_NOT_OK_RETURN(nt_status);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ talloc_free(mem_ctx);
+ return nt_status;
+ }
}
/* references the server_info into the session_info */