summaryrefslogtreecommitdiffstats
path: root/src/lib/krb5/krb/gic_keytab.c
diff options
context:
space:
mode:
authorTom Yu <tlyu@mit.edu>1997-12-06 08:00:17 +0000
committerTom Yu <tlyu@mit.edu>1997-12-06 08:00:17 +0000
commit32ab452e321b0d79d788c41c1b81bc039f9fe7fb (patch)
tree8dfbc45b401efd5e9e8ea5a498793fb7e95f2de4 /src/lib/krb5/krb/gic_keytab.c
parent555d66fca2b801e59618eda5433cf4389eba60f9 (diff)
downloadkrb5-32ab452e321b0d79d788c41c1b81bc039f9fe7fb.tar.gz
krb5-32ab452e321b0d79d788c41c1b81bc039f9fe7fb.tar.xz
krb5-32ab452e321b0d79d788c41c1b81bc039f9fe7fb.zip
* Makefile.in: Add files chpw.c, gic_*, preauth2.c, vfy_increds.c,
vic_opt.c. * chpw.c: New file; implement Cygnus chpw. * get_in_tkt.c: Implement support for Cygnus initial credentials API. * gic_keytab.c: New file; Cygnus initial creds. * gic_opt.c: New file; Cygnus initial creds. * gic_pwd.c: New file; Cygnus initial creds. * preauth.c: Add more SAM support (from Cygnus). * preauth2.c: New file; additional SAM support from Cygnus. * send_tgs.c: Account for additional parameter to sendto_kdc. * vfy_increds.c: New file; Cygnus initial creds. * vic_opt.c: New file; Cygnus initial creds. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@10321 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/lib/krb5/krb/gic_keytab.c')
-rw-r--r--src/lib/krb5/krb/gic_keytab.c126
1 files changed, 126 insertions, 0 deletions
diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
new file mode 100644
index 000000000..8b6f23199
--- /dev/null
+++ b/src/lib/krb5/krb/gic_keytab.c
@@ -0,0 +1,126 @@
+#include "k5-int.h"
+
+static krb5_error_code
+krb5_get_as_key_keytab(context, client, etype, prompter, prompter_data,
+ salt, as_key, gak_data)
+ krb5_context context;
+ krb5_principal client;
+ krb5_enctype etype;
+ krb5_prompter_fct prompter;
+ void *prompter_data;
+ krb5_data *salt;
+ krb5_keyblock *as_key;
+ void *gak_data;
+{
+ krb5_keytab keytab = (krb5_keytab) gak_data;
+ krb5_error_code ret;
+ krb5_keytab_entry kt_ent;
+ krb5_keyblock *kt_key;
+
+ /* if there's already a key of the correct etype, we're done.
+ if the etype is wrong, free the existing key, and make
+ a new one. */
+
+ if (as_key->length) {
+ if (as_key->enctype == etype)
+ return(0);
+
+ krb5_free_keyblock(context, as_key);
+ as_key->length = 0;
+ }
+
+ if (!valid_enctype(etype))
+ return(KRB5_PROG_ETYPE_NOSUPP);
+
+ if ((ret = krb5_kt_get_entry(context, keytab, client,
+ 0, /* don't have vno available */
+ etype, &kt_ent)))
+ return(ret);
+
+ ret = krb5_copy_keyblock(context, &kt_ent.key, &kt_key);
+
+ /* again, krb5's memory management is lame... */
+
+ *as_key = *kt_key;
+ krb5_xfree(kt_key);
+
+ (void) krb5_kt_free_entry(context, &kt_ent);
+
+ return(ret);
+}
+
+KRB5_DLLIMP krb5_error_code KRB5_CALLCONV
+krb5_get_init_creds_keytab(context, creds, client, arg_keytab,
+ start_time, in_tkt_service, options)
+ krb5_context context;
+ krb5_creds *creds;
+ krb5_principal client;
+ krb5_keytab arg_keytab;
+ krb5_deltat start_time;
+ char *in_tkt_service;
+ krb5_get_init_creds_opt *options;
+{
+ krb5_error_code ret, ret2;
+ int master;
+ krb5_keytab keytab;
+
+ if (arg_keytab == NULL) {
+ if (ret = krb5_kt_default(context, &keytab))
+ return ret;
+ } else {
+ keytab = arg_keytab;
+ }
+
+ master = 0;
+
+ /* first try: get the requested tkt from any kdc */
+
+ ret = krb5_get_init_creds(context, creds, client, NULL, NULL,
+ start_time, in_tkt_service, options,
+ krb5_get_as_key_keytab, (void *) keytab,
+ &master, NULL);
+
+ /* check for success */
+
+ if (ret == 0)
+ goto cleanup;
+
+ /* If all the kdc's are unavailable fail */
+
+ if (ret == KRB5_KDC_UNREACH)
+ goto cleanup;
+
+ /* if the reply did not come from the master kdc, try again with
+ the master kdc */
+
+ if (!master) {
+ master = 1;
+
+ ret2 = krb5_get_init_creds(context, creds, client, NULL, NULL,
+ start_time, in_tkt_service, options,
+ krb5_get_as_key_keytab, (void *) keytab,
+ &master, NULL);
+
+ if (ret2 == 0) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ /* if the master is unreachable, return the error from the
+ slave we were able to contact */
+
+ if (ret2 == KRB5_KDC_UNREACH)
+ goto cleanup;
+
+ ret = ret2;
+ }
+
+ /* at this point, we have a response from the master. Since we don't
+ do any prompting or changing for keytabs, that's it. */
+
+cleanup:
+ if (arg_keytab == NULL)
+ krb5_kt_close(context, keytab);
+
+ return(ret);
+}