{\r
khm_handle identity = NULL;\r
krb5_error_code code = 0;\r
- krb5_context ctx = 0;\r
- krb5_ccache cc = 0;\r
+ krb5_context ctx = NULL;\r
+ krb5_ccache cc = NULL;\r
+ krb5_principal me = NULL, server = NULL;\r
+ krb5_creds in_creds, cc_creds;\r
+ krb5_creds * out_creds = NULL;\r
+\r
+ wchar_t wname[512];\r
+ khm_size cbname;\r
+ char name[512];\r
+ khm_boolean brenewIdentity = FALSE;\r
+ khm_boolean istgt = FALSE;\r
+\r
+ memset(&in_creds, 0, sizeof(in_creds));\r
+ memset(&cc_creds, 0, sizeof(cc_creds));\r
\r
if (cred == NULL) {\r
#ifdef DEBUG\r
assert(FALSE);\r
#endif\r
- goto _cleanup;\r
+ goto cleanup;\r
}\r
\r
if (KHM_FAILED(kcdb_cred_get_identity(cred, &identity))) {\r
#ifdef DEBUG\r
assert(FALSE);\r
#endif\r
- goto _cleanup;\r
+ goto cleanup;\r
}\r
\r
code = khm_krb5_initialize(identity, &ctx, &cc);\r
if (code)\r
- goto _cleanup;\r
+ goto cleanup;\r
\r
- /* TODO: going here */\r
+ code = pkrb5_cc_get_principal(ctx, cc, &me);\r
+ if (code) \r
+ goto cleanup;\r
\r
- _cleanup:\r
+ cbname = sizeof(wname);\r
+ if (KHM_FAILED(kcdb_cred_get_name(cred, wname, &cbname)))\r
+ goto cleanup;\r
\r
- if (identity)\r
- kcdb_identity_release(identity);\r
+ UnicodeStrToAnsi(name, sizeof(name), wname);\r
+\r
+ code = pkrb5_parse_name(ctx, name, &server);\r
+ if (code)\r
+ goto cleanup;\r
+\r
+ in_creds.client = me;\r
+ in_creds.server = server;\r
+\r
+#ifdef KRB5_TC_NOTICKET\r
+ pkrb5_cc_set_flags(ctx, cc, 0);\r
+#endif\r
+\r
+ if (strlen("krbtgt") != krb5_princ_name(ctx, server)->length ||\r
+ strncmp("krbtgt", krb5_princ_name(ctx, server)->data, krb5_princ_name(ctx, server)->length)) \r
+ {\r
+ code = pkrb5_get_renewed_creds(ctx, &cc_creds, me, cc, name);\r
+ if (code) {\r
+ code = pkrb5_cc_retrieve_cred(ctx, cc, 0, &in_creds, &cc_creds);\r
+ if (code == 0) {\r
+ code = pkrb5_cc_remove_cred(ctx, cc, 0, &cc_creds);\r
+ if (code) {\r
+ brenewIdentity = TRUE;\r
+ goto cleanup;\r
+ }\r
+ }\r
+ }\r
+\r
+ code = pkrb5_get_credentials(ctx, 0, cc, &in_creds, &out_creds);\r
+ } else {\r
+ istgt = TRUE;\r
+ code = pkrb5_get_renewed_creds(ctx, &cc_creds, me, cc, NULL);\r
+ }\r
+\r
+#ifdef KRB5_TC_NOTICKET\r
+ pkrb5_cc_set_flags(ctx, cc, KRB5_TC_NOTICKET);\r
+#endif\r
+ if (code) {\r
+ if ( code != KRB5KDC_ERR_ETYPE_NOSUPP ||\r
+ code != KRB5_KDC_UNREACH)\r
+ khm_krb5_error(code, "krb5_get_renewed_creds()", 0, &ctx, &cc);\r
+ goto cleanup;\r
+ }\r
+\r
+ if (istgt) {\r
+ code = pkrb5_cc_initialize(ctx, cc, me);\r
+ if (code) goto cleanup;\r
+\r
+ }\r
+\r
+ code = pkrb5_cc_store_cred(ctx, cc, istgt ? &cc_creds : out_creds);\r
+ if (code) goto cleanup;\r
+\r
+\r
+ cleanup:\r
+\r
+ if (in_creds.client == me)\r
+ in_creds.client = NULL;\r
+ if (in_creds.server == server)\r
+ in_creds.server = NULL;\r
+\r
+ if (me)\r
+ pkrb5_free_principal(ctx, me);\r
+\r
+ if (server)\r
+ pkrb5_free_principal(ctx, server);\r
+\r
+ pkrb5_free_cred_contents(ctx, &in_creds);\r
+ pkrb5_free_cred_contents(ctx, &cc_creds); \r
+\r
+ if (out_creds)\r
+ pkrb5_free_creds(ctx, out_creds);\r
\r
if (cc && ctx)\r
pkrb5_cc_close(ctx, cc);\r
if (ctx)\r
pkrb5_free_context(ctx);\r
\r
+ if (identity) {\r
+ if (brenewIdentity)\r
+ code = khm_krb5_renew_ident(identity);\r
+ kcdb_identity_release(identity);\r
+ }\r
+\r
return code;\r
}\r
\r
khm_krb5_renew_ident(khm_handle identity)\r
{\r
krb5_error_code code = 0;\r
- krb5_context ctx = 0;\r
- krb5_ccache cc = 0;\r
- krb5_principal me = 0;\r
- krb5_principal server = 0;\r
+ krb5_context ctx = NULL;\r
+ krb5_ccache cc = NULL;\r
+ krb5_principal me = NULL;\r
+ krb5_principal server = NULL;\r
krb5_creds my_creds;\r
- krb5_data *realm = 0;\r
+ krb5_data *realm = NULL;\r
\r
memset(&my_creds, 0, sizeof(krb5_creds));\r
\r
\r
cleanup:\r
if (my_creds.client == me)\r
- my_creds.client = 0;\r
+ my_creds.client = NULL;\r
if (my_creds.server == server)\r
- my_creds.server = 0;\r
+ my_creds.server = NULL;\r
\r
pkrb5_free_cred_contents(ctx, &my_creds);\r
\r