summaryrefslogtreecommitdiff
path: root/source4/libcli/auth/gensec_krb5.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/libcli/auth/gensec_krb5.c')
-rw-r--r--source4/libcli/auth/gensec_krb5.c164
1 files changed, 85 insertions, 79 deletions
diff --git a/source4/libcli/auth/gensec_krb5.c b/source4/libcli/auth/gensec_krb5.c
index 569fd81206..4a97d51c40 100644
--- a/source4/libcli/auth/gensec_krb5.c
+++ b/source4/libcli/auth/gensec_krb5.c
@@ -38,13 +38,14 @@ enum GENSEC_KRB5_STATE {
struct gensec_krb5_state {
TALLOC_CTX *mem_ctx;
DATA_BLOB session_key;
- struct PAC_LOGON_INFO logon_info;
+ struct PAC_LOGON_INFO *logon_info;
enum GENSEC_KRB5_STATE state_position;
krb5_context krb5_context;
krb5_auth_context krb5_auth_context;
krb5_ccache krb5_ccache;
krb5_data ticket;
krb5_keyblock krb5_keyblock;
+ char *peer_principal;
};
#ifdef KRB5_DO_VERIFY_PAC
@@ -56,6 +57,7 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data,
krb5_error_code ret;
krb5_crypto crypto;
Checksum cksum;
+ int i;
cksum.cksumtype = (CKSUMTYPE)sig->type;
cksum.checksum.length = sizeof(sig->signature);
@@ -70,21 +72,19 @@ static NTSTATUS gensec_krb5_pac_checksum(DATA_BLOB pac_data,
DEBUG(0,("krb5_crypto_init() failed\n"));
return NT_STATUS_FOOBAR;
}
-{
-int i;
-for (i=0; i < 40; i++) {
- keyusage = i;
- ret = krb5_verify_checksum(gensec_krb5_state->krb5_context,
- crypto,
- keyusage,
- pac_data.data,
- pac_data.length,
- &cksum);
- if (!ret) {
- DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage));
- break;
+ for (i=0; i < 40; i++) {
+ keyusage = i;
+ ret = krb5_verify_checksum(gensec_krb5_state->krb5_context,
+ crypto,
+ keyusage,
+ pac_data.data,
+ pac_data.length,
+ &cksum);
+ if (!ret) {
+ DEBUG(0,("PAC Verified: keyusage: %d\n", keyusage));
+ break;
+ }
}
-}}
krb5_crypto_destroy(gensec_krb5_state->krb5_context, crypto);
if (ret) {
@@ -99,7 +99,7 @@ for (i=0; i < 40; i++) {
#endif
static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx,
- struct PAC_LOGON_INFO *logon_info_out,
+ struct PAC_LOGON_INFO **logon_info_out,
DATA_BLOB blob,
struct gensec_krb5_state *gensec_krb5_state)
{
@@ -220,7 +220,7 @@ static NTSTATUS gensec_krb5_decode_pac(TALLOC_CTX *mem_ctx,
}
#endif
DEBUG(0,("account_name: %s [%s]\n",logon_info->account_name.string, logon_info->full_name.string));
- *logon_info_out = *logon_info;
+ *logon_info_out = logon_info;
return status;
}
@@ -542,16 +542,22 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL
return nt_status;
}
- /* decode and verify the pac */
- nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac,
- gensec_krb5_state);
+ if (pac.data) {
+ /* decode and verify the pac */
+ nt_status = gensec_krb5_decode_pac(gensec_krb5_state->mem_ctx, &gensec_krb5_state->logon_info, pac,
+ gensec_krb5_state);
+ } else {
+ /* NULL PAC, we might need to figure this information out the hard way */
+ gensec_krb5_state->logon_info = NULL;
+ }
if (NT_STATUS_IS_OK(nt_status)) {
gensec_krb5_state->state_position = GENSEC_KRB5_DONE;
/* wrap that up in a nice GSS-API wrapping */
*out = gensec_gssapi_gen_krb5_wrap(out_mem_ctx, &unwrapped_out, TOK_ID_KRB_AP_REP);
+
+ gensec_krb5_state->peer_principal = talloc_steal(gensec_krb5_state->mem_ctx, principal);
}
- SAFE_FREE(principal);
return nt_status;
}
case GENSEC_KRB5_DONE:
@@ -597,88 +603,88 @@ static NTSTATUS gensec_krb5_session_key(struct gensec_security *gensec_security,
return NT_STATUS_NO_USER_SESSION_KEY;
}
}
-/*
-struct gensec_krb5_state {
- TALLOC_CTX *mem_ctx;
- DATA_BLOB session_key;
- struct PAC_LOGON_INFO logon_info;
- enum GENSEC_KRB5_STATE state_position;
- krb5_context krb5_context;
- krb5_auth_context krb5_auth_context;
- krb5_ccache krb5_ccache;
- krb5_data ticket;
- krb5_keyblock krb5_keyblock;
-};
-struct auth_session_info
-{
- TALLOC_CTX *mem_ctx;
- int refcount;
-
- NT_USER_TOKEN *nt_user_token;
-
- struct auth_serversupplied_info *server_info;
-
- DATA_BLOB session_key;
-
- const char *workstation;
-};
-*/
static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security,
struct auth_session_info **session_info_out)
{
+ NTSTATUS nt_status;
struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data;
TALLOC_CTX *mem_ctx;
+ struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info = NULL;
- struct PAC_LOGON_INFO *logon_info = &gensec_krb5_state->logon_info;
+ struct PAC_LOGON_INFO *logon_info = gensec_krb5_state->logon_info;
struct nt_user_token *ptoken;
struct dom_sid *sid;
+ char *p;
+ char *principal;
*session_info_out = NULL;
- mem_ctx = talloc_init("krb5: session_info");
-
- session_info = talloc_p(mem_ctx, struct auth_session_info);
- if (!session_info) {
- return NT_STATUS_NO_MEMORY;
- }
-
- session_info->mem_ctx = mem_ctx;
- session_info->refcount = 1;
- session_info->server_info = NULL;
-
- ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token);
- if (!ptoken) {
- return NT_STATUS_NO_MEMORY;
+ nt_status = make_server_info(&server_info, gensec_krb5_state->peer_principal);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
}
- ptoken->num_sids = 0;
+ server_info->guest = False;
- ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2);
- if (!ptoken->user_sids) {
+ principal = talloc_strdup(server_info->mem_ctx, gensec_krb5_state->peer_principal);
+ p = strchr(principal, '@');
+ if (p) {
+ *p = '\0';
+ }
+ server_info->account_name = principal;
+ server_info->domain = talloc_strdup(server_info->mem_ctx, p++);
+ if (!server_info->domain) {
+ free_server_info(&server_info);
return NT_STATUS_NO_MEMORY;
}
+ nt_status = make_session_info(server_info, &session_info);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ free_server_info(&server_info);
+ return nt_status;
+ }
- sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid);
- ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid);
- ptoken->num_sids++;
- sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid);
- ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid);
- ptoken->num_sids++;
+ /* IF we have the PAC - otherwise (TODO) we need to get this
+ * data from elsewere - local ldb, or lookup of some
+ * kind... */
- for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) {
+ if (logon_info) {
+ ptoken = talloc_p(session_info->mem_ctx, struct nt_user_token);
+ if (!ptoken) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ ptoken->num_sids = 0;
+
+ ptoken->user_sids = talloc_array_p(mem_ctx, struct dom_sid*, logon_info->groups_count + 2);
+ if (!ptoken->user_sids) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+
+ sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid);
+ ptoken->user_sids[0] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->user_rid);
+ ptoken->num_sids++;
sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid);
- ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid);
+ ptoken->user_sids[1] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->group_rid);
+ ptoken->num_sids++;
+
+ for (;ptoken->num_sids < logon_info->groups_count; ptoken->num_sids++) {
+ sid = dom_sid_dup(session_info->mem_ctx, logon_info->dom_sid);
+ ptoken->user_sids[ptoken->num_sids] = dom_sid_add_rid(session_info->mem_ctx, sid, logon_info->groups[ptoken->num_sids - 2].rid);
+ }
+
+ debug_nt_user_token(DBGC_AUTH, 0, ptoken);
+
+ session_info->nt_user_token = ptoken;
+ } else {
+ session_info->nt_user_token = NULL;
}
-
- debug_nt_user_token(DBGC_AUTH, 0, ptoken);
-
- session_info->nt_user_token = ptoken;
session_info->session_key = data_blob_talloc(session_info->mem_ctx,
- gensec_krb5_state->session_key.data,
- gensec_krb5_state->session_key.length);
+ gensec_krb5_state->session_key.data,
+ gensec_krb5_state->session_key.length);
session_info->workstation = NULL;