r22191: Add a samba4kinit binary to the build, so I can test using an existing
authorAndrew Bartlett <abartlet@samba.org>
Thu, 12 Apr 2007 11:23:58 +0000 (11:23 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 19:50:02 +0000 (14:50 -0500)
ccache, as well as PKINIT.

Andrew Bartlett
(This used to be commit 440b8d9e4b09d5e8c943504ade85c17f752fe705)

source4/heimdal/kuser/kinit.c [new file with mode: 0644]
source4/heimdal/kuser/kuser_locl.h [new file with mode: 0644]
source4/heimdal/lib/krb5/convert_creds.c [new file with mode: 0644]
source4/heimdal/lib/krb5/prompter_posix.c [new file with mode: 0644]
source4/heimdal_build/config.mk
source4/heimdal_build/kafs.h [new file with mode: 0644]

diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c
new file mode 100644 (file)
index 0000000..667e096
--- /dev/null
@@ -0,0 +1,930 @@
+/*
+ * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "kuser_locl.h"
+RCSID("$Id: kinit.c,v 1.141 2006/12/12 16:35:41 lha Exp $");
+
+#ifndef KRB4
+#include "krb5-v4compat.h"
+#endif
+
+struct krb5_pk_identity;
+struct krb5_pk_cert;
+struct ContentInfo;
+struct _krb5_krb_auth_data;
+struct krb5_dh_moduli;
+struct krb5_plugin;
+enum plugin_type;
+#include "krb5-private.h"
+
+int forwardable_flag   = -1;
+int proxiable_flag     = -1;
+int renewable_flag     = -1;
+int renew_flag         = 0;
+int pac_flag           = -1;
+int validate_flag      = 0;
+int version_flag       = 0;
+int help_flag          = 0;
+int addrs_flag         = -1;
+struct getarg_strings extra_addresses;
+int anonymous_flag     = 0;
+char *lifetime                 = NULL;
+char *renew_life       = NULL;
+char *server_str       = NULL;
+char *cred_cache       = NULL;
+char *start_str                = NULL;
+struct getarg_strings etype_str;
+int use_keytab         = 0;
+char *keytab_str       = NULL;
+int do_afslog          = -1;
+int get_v4_tgt         = -1;
+int convert_524                = 0;
+int fcache_version;
+char *password_file    = NULL;
+char *pk_user_id       = NULL;
+char *pk_x509_anchors  = NULL;
+int pk_use_enckey      = 0;
+
+static char *krb4_cc_name;
+
+static struct getargs args[] = {
+    /* 
+     * used by MIT
+     * a: ~A
+     * V: verbose
+     * F: ~f
+     * P: ~p
+     * C: v4 cache name?
+     * 5: 
+     */
+    { "524init",       '4', arg_flag, &get_v4_tgt,
+      "obtain version 4 TGT" },
+
+    { "524convert",    '9', arg_flag, &convert_524,
+      "only convert ticket to version 4" },
+
+    { "afslog",        0  , arg_flag, &do_afslog,
+      "obtain afs tokens"  },
+
+    { "cache",                 'c', arg_string, &cred_cache,
+      "credentials cache", "cachename" },
+
+    { "forwardable",   'f', arg_flag, &forwardable_flag,
+      "get forwardable tickets"},
+
+    { "keytab",         't', arg_string, &keytab_str,
+      "keytab to use", "keytabname" },
+
+    { "lifetime",      'l', arg_string, &lifetime,
+      "lifetime of tickets", "time"},
+
+    { "proxiable",     'p', arg_flag, &proxiable_flag,
+      "get proxiable tickets" },
+
+    { "renew",          'R', arg_flag, &renew_flag,
+      "renew TGT" },
+
+    { "renewable",     0,   arg_flag, &renewable_flag,
+      "get renewable tickets" },
+
+    { "renewable-life",        'r', arg_string, &renew_life,
+      "renewable lifetime of tickets", "time" },
+
+    { "server",        'S', arg_string, &server_str,
+      "server to get ticket for", "principal" },
+
+    { "start-time",    's', arg_string, &start_str,
+      "when ticket gets valid", "time" },
+
+    { "use-keytab",     'k', arg_flag, &use_keytab,
+      "get key from keytab" },
+
+    { "validate",      'v', arg_flag, &validate_flag,
+      "validate TGT" },
+
+    { "enctypes",      'e', arg_strings, &etype_str,
+      "encryption types to use", "enctypes" },
+
+    { "fcache-version", 0,   arg_integer, &fcache_version,
+      "file cache version to create" },
+
+    { "addresses",     'A',   arg_negative_flag,       &addrs_flag,
+      "request a ticket with no addresses" },
+
+    { "extra-addresses",'a', arg_strings,      &extra_addresses,
+      "include these extra addresses", "addresses" },
+
+    { "anonymous",     0,   arg_flag,  &anonymous_flag,
+      "request an anonymous ticket" },
+
+    { "request-pac",   0,   arg_flag,  &pac_flag,
+      "request a Windows PAC" },
+
+    { "password-file", 0,   arg_string, &password_file,
+      "read the password from a file" },
+
+#ifdef PKINIT
+    {  "pk-user",      'C',    arg_string,     &pk_user_id,
+       "principal's public/private/certificate identifier",
+       "id" },
+
+    {  "x509-anchors", 'D',  arg_string, &pk_x509_anchors,
+       "directory with CA certificates", "directory" },
+
+    {  "pk-use-enckey",        0,  arg_flag, &pk_use_enckey,
+       "Use RSA encrypted reply (instead of DH)" },
+
+#endif
+    { "version",       0,   arg_flag, &version_flag },
+    { "help",          0,   arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+    arg_printusage (args,
+                   sizeof(args)/sizeof(*args),
+                   NULL,
+                   "[principal [command]]");
+    exit (ret);
+}
+
+#ifdef KRB4
+/* for when the KDC tells us it's a v4 one, we try to talk that */
+
+static int
+key_to_key(const char *user,
+          char *instance,
+          const char *realm,
+          const void *arg,
+          des_cblock *key)
+{
+    memcpy(key, arg, sizeof(des_cblock));
+    return 0;
+}
+
+static int
+do_v4_fallback (krb5_context context,
+               const krb5_principal principal,
+               int lifetime,
+               int use_srvtab, const char *srvtab_str,
+               const char *passwd)
+{
+    int ret;
+    krb_principal princ;
+    des_cblock key;
+    krb5_error_code kret;
+
+    if (lifetime == 0)
+       lifetime = DEFAULT_TKT_LIFE;
+    else
+       lifetime = krb_time_to_life (0, lifetime);
+
+    kret = krb5_524_conv_principal (context, principal,
+                                   princ.name,
+                                   princ.instance,
+                                   princ.realm);
+    if (kret) {
+       krb5_warn (context, kret, "krb5_524_conv_principal");
+       return 1;
+    }
+
+    if (use_srvtab || srvtab_str) {
+       if (srvtab_str == NULL)
+           srvtab_str = KEYFILE;
+
+       ret = read_service_key (princ.name, princ.instance, princ.realm,
+                               0, srvtab_str, (char *)&key);
+       if (ret) {
+           warnx ("read_service_key %s: %s", srvtab_str,
+                  krb_get_err_text (ret));
+           return 1;
+       }
+       ret = krb_get_in_tkt (princ.name, princ.instance, princ.realm,
+                             KRB_TICKET_GRANTING_TICKET, princ.realm,
+                             lifetime, key_to_key, NULL, key);
+    } else {
+       ret = krb_get_pw_in_tkt(princ.name, princ.instance, princ.realm, 
+                               KRB_TICKET_GRANTING_TICKET, princ.realm, 
+                               lifetime, passwd);
+    }
+    memset (key, 0, sizeof(key));
+    if (ret) {
+       warnx ("%s", krb_get_err_text(ret));
+       return 1;
+    }
+    if (do_afslog && k_hasafs()) {
+       if ((ret = krb_afslog(NULL, NULL)) != 0 && ret != KDC_PR_UNKNOWN) {
+           if(ret > 0)
+               warnx ("%s", krb_get_err_text(ret));
+           else
+               warnx ("failed to store AFS token");
+       }
+    }
+    return 0;
+}
+
+
+/*
+ * the special version of get_default_principal that takes v4 into account
+ */
+
+static krb5_error_code
+kinit_get_default_principal (krb5_context context,
+                            krb5_principal *princ)
+{
+    krb5_error_code ret;
+    krb5_ccache id;
+    krb_principal v4_princ;
+    int kret;
+
+    ret = krb5_cc_default (context, &id);
+    if (ret == 0) {
+       ret = krb5_cc_get_principal (context, id, princ);
+       krb5_cc_close (context, id);
+       if (ret == 0)
+           return 0;
+    }
+
+    kret = krb_get_tf_fullname (tkt_string(),
+                               v4_princ.name,
+                               v4_princ.instance,
+                               v4_princ.realm);
+    if (kret == KSUCCESS) {
+       ret = krb5_425_conv_principal (context,
+                                      v4_princ.name,
+                                      v4_princ.instance,
+                                      v4_princ.realm,
+                                      princ);
+       if (ret == 0)
+           return 0;
+    }
+    return krb5_get_default_principal (context, princ);
+}
+
+#else /* !KRB4 */
+
+static krb5_error_code
+kinit_get_default_principal (krb5_context context,
+                            krb5_principal *princ)
+{
+    return krb5_get_default_principal (context, princ);
+}
+
+#endif /* !KRB4 */
+
+static krb5_error_code
+get_server(krb5_context context,
+          krb5_principal client,
+          const char *server,
+          krb5_principal *princ)
+{
+    krb5_realm *client_realm;
+    if(server)
+       return krb5_parse_name(context, server, princ);
+
+    client_realm = krb5_princ_realm (context, client);
+    return krb5_make_principal(context, princ, *client_realm,
+                              KRB5_TGS_NAME, *client_realm, NULL);
+}
+
+static krb5_error_code
+do_524init(krb5_context context, krb5_ccache ccache, 
+          krb5_creds *creds, const char *server)
+{
+    krb5_error_code ret;
+
+    struct credentials c;
+    krb5_creds in_creds, *real_creds;
+
+    if(creds != NULL)
+       real_creds = creds;
+    else {
+       krb5_principal client;
+       krb5_cc_get_principal(context, ccache, &client);
+       memset(&in_creds, 0, sizeof(in_creds));
+       ret = get_server(context, client, server, &in_creds.server);
+       if(ret) {
+           krb5_free_principal(context, client);
+           return ret;
+       }
+       in_creds.client = client;
+       ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds);
+       krb5_free_principal(context, client);
+       krb5_free_principal(context, in_creds.server);
+       if(ret)
+           return ret;
+    }
+    ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c);
+    if(ret)
+       krb5_warn(context, ret, "converting creds");
+    else {
+       krb5_error_code tret = _krb5_krb_tf_setup(context, &c, NULL, 0);
+       if(tret)
+           krb5_warn(context, tret, "saving v4 creds");
+    }
+
+    if(creds == NULL)
+       krb5_free_creds(context, real_creds);
+    memset(&c, 0, sizeof(c));
+
+    return ret;
+}
+
+static int
+renew_validate(krb5_context context, 
+              int renew,
+              int validate,
+              krb5_ccache cache, 
+              const char *server,
+              krb5_deltat life)
+{
+    krb5_error_code ret;
+    krb5_creds in, *out = NULL;
+    krb5_kdc_flags flags;
+
+    memset(&in, 0, sizeof(in));
+
+    ret = krb5_cc_get_principal(context, cache, &in.client);
+    if(ret) {
+       krb5_warn(context, ret, "krb5_cc_get_principal");
+       return ret;
+    }
+    ret = get_server(context, in.client, server, &in.server);
+    if(ret) {
+       krb5_warn(context, ret, "get_server");
+       goto out;
+    }
+
+    if (renew) {
+       /* 
+        * no need to check the error here, its only to be 
+        * friendly to the user
+        */
+       krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out);
+    }
+
+    flags.i = 0;
+    flags.b.renewable         = flags.b.renew = renew;
+    flags.b.validate          = validate;
+
+    if (forwardable_flag != -1)
+       flags.b.forwardable       = forwardable_flag;
+    else if (out)
+       flags.b.forwardable       = out->flags.b.forwardable;
+
+    if (proxiable_flag != -1)
+       flags.b.proxiable         = proxiable_flag;
+    else if (out)
+       flags.b.proxiable         = out->flags.b.proxiable;
+
+    if (anonymous_flag != -1)
+       flags.b.request_anonymous = anonymous_flag;
+    if(life)
+       in.times.endtime = time(NULL) + life;
+
+    if (out) {
+       krb5_free_creds (context, out);
+       out = NULL;
+    }
+
+
+    ret = krb5_get_kdc_cred(context,
+                           cache,
+                           flags,
+                           NULL,
+                           NULL,
+                           &in,
+                           &out);
+    if(ret) {
+       krb5_warn(context, ret, "krb5_get_kdc_cred");
+       goto out;
+    }
+    ret = krb5_cc_initialize(context, cache, in.client);
+    if(ret) {
+       krb5_free_creds (context, out);
+       krb5_warn(context, ret, "krb5_cc_initialize");
+       goto out;
+    }
+    ret = krb5_cc_store_cred(context, cache, out);
+
+    if(ret == 0 && server == NULL) {
+       /* only do this if it's a general renew-my-tgt request */
+       if(get_v4_tgt)
+           do_524init(context, cache, out, NULL);
+       if(do_afslog && k_hasafs())
+           krb5_afslog(context, cache, NULL, NULL);
+    }
+
+    krb5_free_creds (context, out);
+    if(ret) {
+       krb5_warn(context, ret, "krb5_cc_store_cred");
+       goto out;
+    }
+out:
+    krb5_free_cred_contents(context, &in);
+    return ret;
+}
+
+static krb5_error_code
+get_new_tickets(krb5_context context, 
+               krb5_principal principal,
+               krb5_ccache ccache,
+               krb5_deltat ticket_life,
+               int interactive)
+{
+    krb5_error_code ret;
+    krb5_get_init_creds_opt *opt;
+    krb5_creds cred;
+    char passwd[256];
+    krb5_deltat start_time = 0;
+    krb5_deltat renew = 0;
+    char *renewstr = NULL;
+    krb5_enctype *enctype = NULL;
+
+    passwd[0] = '\0';
+
+    if (password_file) {
+       FILE *f;
+
+       if (strcasecmp("STDIN", password_file) == 0)
+           f = stdin;
+       else
+           f = fopen(password_file, "r");
+       if (f == NULL)
+           krb5_errx(context, 1, "Failed to open the password file %s",
+                     password_file);
+
+       if (fgets(passwd, sizeof(passwd), f) == NULL)
+           krb5_errx(context, 1, 
+                     "Failed to read password from file %s", password_file);
+       if (f != stdin)
+           fclose(f);
+       passwd[strcspn(passwd, "\n")] = '\0';
+    }
+
+
+    memset(&cred, 0, sizeof(cred));
+
+    ret = krb5_get_init_creds_opt_alloc (context, &opt);
+    if (ret)
+       krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
+    
+    krb5_get_init_creds_opt_set_default_flags(context, "kinit", 
+                                             /* XXX */principal->realm, opt);
+
+    if(forwardable_flag != -1)
+       krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);
+    if(proxiable_flag != -1)
+       krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
+    if(anonymous_flag != -1)
+       krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
+    if (pac_flag != -1)
+       krb5_get_init_creds_opt_set_pac_request(context, opt, 
+                                               pac_flag ? TRUE : FALSE);
+    if (pk_user_id) {
+       ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
+                                                principal,
+                                                pk_user_id,
+                                                pk_x509_anchors,
+                                                NULL,
+                                                NULL,
+                                                pk_use_enckey ? 2 : 0,
+                                                krb5_prompter_posix,
+                                                NULL,
+                                                passwd);
+       if (ret)
+           krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
+    }
+
+    if (addrs_flag != -1)
+       krb5_get_init_creds_opt_set_addressless(context, opt, 
+                                               addrs_flag ? FALSE : TRUE);
+
+    if (renew_life == NULL && renewable_flag)
+       renewstr = "1 month";
+    if (renew_life)
+       renewstr = renew_life;
+    if (renewstr) {
+       renew = parse_time (renewstr, "s");
+       if (renew < 0)
+           errx (1, "unparsable time: %s", renewstr);
+       
+       krb5_get_init_creds_opt_set_renew_life (opt, renew);
+    }
+
+    if(ticket_life != 0)
+       krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life);
+
+    if(start_str) {
+       int tmp = parse_time (start_str, "s");
+       if (tmp < 0)
+           errx (1, "unparsable time: %s", start_str);
+
+       start_time = tmp;
+    }
+
+    if(etype_str.num_strings) {
+       int i;
+
+       enctype = malloc(etype_str.num_strings * sizeof(*enctype));
+       if(enctype == NULL)
+           errx(1, "out of memory");
+       for(i = 0; i < etype_str.num_strings; i++) {
+           ret = krb5_string_to_enctype(context, 
+                                        etype_str.strings[i], 
+                                        &enctype[i]);
+           if(ret)
+               errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
+       }
+       krb5_get_init_creds_opt_set_etype_list(opt, enctype, 
+                                              etype_str.num_strings);
+    }
+
+    if(use_keytab || keytab_str) {
+       krb5_keytab kt;
+       if(keytab_str)
+           ret = krb5_kt_resolve(context, keytab_str, &kt);
+       else
+           ret = krb5_kt_default(context, &kt);
+       if (ret)
+           krb5_err (context, 1, ret, "resolving keytab");
+       ret = krb5_get_init_creds_keytab (context,
+                                         &cred,
+                                         principal,
+                                         kt,
+                                         start_time,
+                                         server_str,
+                                         opt);
+       krb5_kt_close(context, kt);
+    } else if (pk_user_id) {
+       ret = krb5_get_init_creds_password (context,
+                                           &cred,
+                                           principal,
+                                           passwd,
+                                           krb5_prompter_posix,
+                                           NULL,
+                                           start_time,
+                                           server_str,
+                                           opt);
+    } else if (!interactive) {
+       krb5_warnx(context, "Not interactive, failed to get initial ticket");
+       krb5_get_init_creds_opt_free(context, opt);
+       return 0;
+    } else {
+
+       if (passwd[0] == '\0') {
+           char *p, *prompt;
+           
+           krb5_unparse_name (context, principal, &p);
+           asprintf (&prompt, "%s's Password: ", p);
+           free (p);
+           
+           if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
+               memset(passwd, 0, sizeof(passwd));
+               exit(1);
+           }
+           free (prompt);
+       }
+
+       
+       ret = krb5_get_init_creds_password (context,
+                                           &cred,
+                                           principal,
+                                           passwd,
+                                           krb5_prompter_posix,
+                                           NULL,
+                                           start_time,
+                                           server_str,
+                                           opt);
+    }
+    krb5_get_init_creds_opt_free(context, opt);
+#ifdef KRB4
+    if (ret == KRB5KRB_AP_ERR_V4_REPLY || ret == KRB5_KDC_UNREACH) {
+       int exit_val;
+
+       exit_val = do_v4_fallback (context, principal, ticket_life,
+                                  use_keytab, keytab_str, passwd);
+       get_v4_tgt = 0;
+       do_afslog  = 0;
+       memset(passwd, 0, sizeof(passwd));
+       if (exit_val == 0 || ret == KRB5KRB_AP_ERR_V4_REPLY)
+           return exit_val;
+    }
+#endif
+    memset(passwd, 0, sizeof(passwd));
+
+    switch(ret){
+    case 0:
+       break;
+    case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
+       exit(1);
+    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+    case KRB5KRB_AP_ERR_MODIFIED:
+       krb5_errx(context, 1, "Password incorrect");
+       break;
+    default:
+       krb5_err(context, 1, ret, "krb5_get_init_creds");
+    }
+
+    if(ticket_life != 0) {
+       if(abs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
+           char life[64];
+           unparse_time_approx(cred.times.endtime - cred.times.starttime, 
+                               life, sizeof(life));
+           krb5_warnx(context, "NOTICE: ticket lifetime is %s", life);
+       }
+    }
+    if(renew_life) {
+       if(abs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
+           char life[64];
+           unparse_time_approx(cred.times.renew_till - cred.times.starttime, 
+                               life, sizeof(life));
+           krb5_warnx(context, "NOTICE: ticket renewable lifetime is %s", 
+                      life);
+       }
+    }
+
+    ret = krb5_cc_initialize (context, ccache, cred.client);
+    if (ret)
+       krb5_err (context, 1, ret, "krb5_cc_initialize");
+    
+    ret = krb5_cc_store_cred (context, ccache, &cred);
+    if (ret)
+       krb5_err (context, 1, ret, "krb5_cc_store_cred");
+
+    krb5_free_cred_contents (context, &cred);
+
+    if (enctype)
+       free(enctype);
+
+    return 0;
+}
+
+static time_t
+ticket_lifetime(krb5_context context, krb5_ccache cache, 
+               krb5_principal client, const char *server)
+{
+    krb5_creds in_cred, *cred;
+    krb5_error_code ret;
+    time_t timeout;
+
+    memset(&in_cred, 0, sizeof(in_cred));
+
+    ret = krb5_cc_get_principal(context, cache, &in_cred.client);
+    if(ret) {
+       krb5_warn(context, ret, "krb5_cc_get_principal");
+       return 0;
+    }
+    ret = get_server(context, in_cred.client, server, &in_cred.server);
+    if(ret) {
+       krb5_free_principal(context, in_cred.client);
+       krb5_warn(context, ret, "get_server");
+       return 0;
+    }
+
+    ret = krb5_get_credentials(context, KRB5_GC_CACHED,
+                              cache, &in_cred, &cred);
+    krb5_free_principal(context, in_cred.client);
+    krb5_free_principal(context, in_cred.server);
+    if(ret) {
+       krb5_warn(context, ret, "krb5_get_credentials");
+       return 0;
+    }
+    timeout = cred->times.endtime - cred->times.starttime;
+    if (timeout < 0)
+       timeout = 0;
+    krb5_free_creds(context, cred);
+    return timeout;
+}
+
+struct renew_ctx {
+    krb5_context context;
+    krb5_ccache  ccache;
+    krb5_principal principal;
+    krb5_deltat ticket_life;
+};
+
+static time_t
+renew_func(void *ptr)
+{
+    struct renew_ctx *ctx = ptr;
+    krb5_error_code ret;
+    time_t expire;
+    int new_tickets = 0;
+
+    if (renewable_flag) {
+       ret = renew_validate(ctx->context, renewable_flag, validate_flag,
+                            ctx->ccache, server_str, ctx->ticket_life);
+       if (ret)
+           new_tickets = 1;
+    } else
+       new_tickets = 1;
+
+    if (new_tickets)
+       get_new_tickets(ctx->context, ctx->principal, 
+                       ctx->ccache, ctx->ticket_life, 0);
+
+    if(get_v4_tgt || convert_524)
+       do_524init(ctx->context, ctx->ccache, NULL, server_str);
+    if(do_afslog && k_hasafs())
+       krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
+
+    expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
+                            server_str) / 2;
+    return expire + 1;
+}
+
+int
+main (int argc, char **argv)
+{
+    krb5_error_code ret;
+    krb5_context context;
+    krb5_ccache  ccache;
+    krb5_principal principal;
+    int optidx = 0;
+    krb5_deltat ticket_life = 0;
+
+    setprogname (argv[0]);
+    
+    ret = krb5_init_context (&context);
+    if (ret == KRB5_CONFIG_BADFORMAT)
+       errx (1, "krb5_init_context failed to parse configuration file");
+    else if (ret)
+       errx(1, "krb5_init_context failed: %d", ret);
+  
+    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+       usage(1);
+    
+    if (help_flag)
+       usage (0);
+
+    if(version_flag) {
+       print_version(NULL);
+       exit(0);
+    }
+
+    argc -= optidx;
+    argv += optidx;
+
+    if (argv[0]) {
+       ret = krb5_parse_name (context, argv[0], &principal);
+       if (ret)
+           krb5_err (context, 1, ret, "krb5_parse_name");
+    } else {
+       ret = kinit_get_default_principal (context, &principal);
+       if (ret)
+           krb5_err (context, 1, ret, "krb5_get_default_principal");
+    }
+
+    if(fcache_version)
+       krb5_set_fcache_version(context, fcache_version);
+
+    if(renewable_flag == -1)
+       /* this seems somewhat pointless, but whatever */
+       krb5_appdefault_boolean(context, "kinit",
+                               krb5_principal_get_realm(context, principal),
+                               "renewable", FALSE, &renewable_flag);
+    if(get_v4_tgt == -1)
+       krb5_appdefault_boolean(context, "kinit", 
+                               krb5_principal_get_realm(context, principal), 
+                               "krb4_get_tickets", FALSE, &get_v4_tgt);
+    if(do_afslog == -1)
+       krb5_appdefault_boolean(context, "kinit", 
+                               krb5_principal_get_realm(context, principal), 
+                               "afslog", TRUE, &do_afslog);
+
+    if(cred_cache) 
+       ret = krb5_cc_resolve(context, cred_cache, &ccache);
+    else {
+       if(argc > 1) {
+           char s[1024];
+           ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &ccache);
+           if(ret)
+               krb5_err(context, 1, ret, "creating cred cache");
+           snprintf(s, sizeof(s), "%s:%s",
+                    krb5_cc_get_type(context, ccache),
+                    krb5_cc_get_name(context, ccache));
+           setenv("KRB5CCNAME", s, 1);
+           if (get_v4_tgt) {
+               int fd;
+               if (asprintf(&krb4_cc_name, "%s_XXXXXX", TKT_ROOT) < 0)
+                   krb5_errx(context, 1, "out of memory");
+               if((fd = mkstemp(krb4_cc_name)) >= 0) {
+                   close(fd);
+                   setenv("KRBTKFILE", krb4_cc_name, 1);
+               } else {
+                   free(krb4_cc_name);
+                   krb4_cc_name = NULL;
+               }
+           }
+       } else
+           ret = krb5_cc_default (context, &ccache);
+    }
+    if (ret)
+       krb5_err (context, 1, ret, "resolving credentials cache");
+
+    if(argc > 1 && k_hasafs ())
+       k_setpag();
+
+    if (lifetime) {
+       int tmp = parse_time (lifetime, "s");
+       if (tmp < 0)
+           errx (1, "unparsable time: %s", lifetime);
+
+       ticket_life = tmp;
+    }
+
+    if(addrs_flag == 0 && extra_addresses.num_strings > 0)
+       krb5_errx(context, 1, "specifying both extra addresses and "
+                 "no addresses makes no sense");
+    {
+       int i;
+       krb5_addresses addresses;
+       memset(&addresses, 0, sizeof(addresses));
+       for(i = 0; i < extra_addresses.num_strings; i++) {
+           ret = krb5_parse_address(context, extra_addresses.strings[i], 
+                                    &addresses);
+           if (ret == 0) {
+               krb5_add_extra_addresses(context, &addresses);
+               krb5_free_addresses(context, &addresses);
+           }
+       }
+       free_getarg_strings(&extra_addresses);
+    }
+
+    if(renew_flag || validate_flag) {
+       ret = renew_validate(context, renew_flag, validate_flag, 
+                            ccache, server_str, ticket_life);
+       exit(ret != 0);
+    }
+
+    if(!convert_524)
+       get_new_tickets(context, principal, ccache, ticket_life, 1);
+
+    if(get_v4_tgt || convert_524)
+       do_524init(context, ccache, NULL, server_str);
+    if(do_afslog && k_hasafs())
+       krb5_afslog(context, ccache, NULL, NULL);
+    if(argc > 1) {
+       struct renew_ctx ctx;
+       time_t timeout;
+
+       timeout = ticket_lifetime(context, ccache, principal, server_str) / 2;
+
+       ctx.context = context;
+       ctx.ccache = ccache;
+       ctx.principal = principal;
+       ctx.ticket_life = ticket_life;
+
+       ret = simple_execvp_timed(argv[1], argv+1, 
+                                 renew_func, &ctx, timeout);
+#define EX_NOEXEC      126
+#define EX_NOTFOUND    127
+       if(ret == EX_NOEXEC)
+           krb5_warnx(context, "permission denied: %s", argv[1]);
+       else if(ret == EX_NOTFOUND)
+           krb5_warnx(context, "command not found: %s", argv[1]);
+       
+       krb5_cc_destroy(context, ccache);
+       _krb5_krb_dest_tkt(context, krb4_cc_name);
+       if(k_hasafs())
+           k_unlog();
+    } else {
+       krb5_cc_close (context, ccache);
+       ret = 0;
+    }
+    krb5_free_principal(context, principal);
+    krb5_free_context (context);
+    return ret;
+}
diff --git a/source4/heimdal/kuser/kuser_locl.h b/source4/heimdal/kuser/kuser_locl.h
new file mode 100644 (file)
index 0000000..06403cb
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1997 - 1999 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+/* $Id: kuser_locl.h,v 1.13 2003/01/21 14:13:51 nectar Exp $ */
+
+#ifndef __KUSER_LOCL_H__
+#define __KUSER_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <roken.h>
+#include <getarg.h>
+#include <parse_time.h>
+#include <err.h>
+#include <krb5.h>
+
+#ifdef KRB4
+#include <krb.h>
+#endif
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <kafs.h>
+#include "crypto-headers.h" /* for des_read_pw_string */
+
+#endif /* __KUSER_LOCL_H__ */
diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c
new file mode 100644 (file)
index 0000000..bff56a2
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "krb5_locl.h"
+RCSID("$Id: convert_creds.c,v 1.32 2005/04/23 19:40:57 lha Exp $");
+
+#include "krb5-v4compat.h"
+
+static krb5_error_code
+check_ticket_flags(TicketFlags f)
+{
+    return 0; /* maybe add some more tests here? */
+}
+
+/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'.
+ * This is done by sending them to the 524 function in the KDC.  If
+ * `in_cred' doesn't contain a DES session key, then a new one is
+ * gotten from the KDC and stored in the cred cache `ccache'.
+ */
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb524_convert_creds_kdc(krb5_context context, 
+                        krb5_creds *in_cred,
+                        struct credentials *v4creds)
+{
+    krb5_error_code ret;
+    krb5_data reply;
+    krb5_storage *sp;
+    int32_t tmp;
+    krb5_data ticket;
+    char realm[REALM_SZ];
+    krb5_creds *v5_creds = in_cred;
+
+    ret = check_ticket_flags(v5_creds->flags.b);
+    if(ret)
+       goto out2;
+
+    {
+       krb5_krbhst_handle handle;
+
+       ret = krb5_krbhst_init(context,
+                              krb5_principal_get_realm(context, 
+                                                       v5_creds->server),
+                              KRB5_KRBHST_KRB524,
+                              &handle);
+       if (ret)
+           goto out2;
+
+       ret = krb5_sendto (context,
+                          &v5_creds->ticket,
+                          handle,
+                          &reply);
+       krb5_krbhst_free(context, handle);
+       if (ret)
+           goto out2;
+    }
+    sp = krb5_storage_from_mem(reply.data, reply.length);
+    if(sp == NULL) {
+       ret = ENOMEM;
+       krb5_set_error_string (context, "malloc: out of memory");
+       goto out2;
+    }
+    krb5_ret_int32(sp, &tmp);
+    ret = tmp;
+    if(ret == 0) {
+       memset(v4creds, 0, sizeof(*v4creds));
+       ret = krb5_ret_int32(sp, &tmp);
+       if(ret)
+           goto out;
+       v4creds->kvno = tmp;
+       ret = krb5_ret_data(sp, &ticket);
+       if(ret)
+           goto out;
+       v4creds->ticket_st.length = ticket.length;
+       memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length);
+       krb5_data_free(&ticket);
+       ret = krb5_524_conv_principal(context, 
+                                     v5_creds->server, 
+                                     v4creds->service, 
+                                     v4creds->instance, 
+                                     v4creds->realm);
+       if(ret)
+           goto out;
+       v4creds->issue_date = v5_creds->times.starttime;
+       v4creds->lifetime = _krb5_krb_time_to_life(v4creds->issue_date,
+                                                  v5_creds->times.endtime);
+       ret = krb5_524_conv_principal(context, v5_creds->client, 
+                                     v4creds->pname, 
+                                     v4creds->pinst, 
+                                     realm);
+       if(ret)
+           goto out;
+       memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8);
+    } else {
+       krb5_set_error_string(context, "converting credentials: %s", 
+                             krb5_get_err_text(context, ret));
+    }
+out:
+    krb5_storage_free(sp);
+    krb5_data_free(&reply);
+out2:
+    if (v5_creds != in_cred)
+       krb5_free_creds (context, v5_creds);
+    return ret;
+}
+
+krb5_error_code KRB5_LIB_FUNCTION
+krb524_convert_creds_kdc_ccache(krb5_context context, 
+                               krb5_ccache ccache,
+                               krb5_creds *in_cred,
+                               struct credentials *v4creds)
+{
+    krb5_error_code ret;
+    krb5_creds *v5_creds = in_cred;
+    krb5_keytype keytype;
+
+    keytype = v5_creds->session.keytype;
+
+    if (keytype != ENCTYPE_DES_CBC_CRC) {
+       /* MIT krb524d doesn't like nothing but des-cbc-crc tickets,
+           so go get one */
+       krb5_creds template;
+
+       memset (&template, 0, sizeof(template));
+       template.session.keytype = ENCTYPE_DES_CBC_CRC;
+       ret = krb5_copy_principal (context, in_cred->client, &template.client);
+       if (ret) {
+           krb5_free_cred_contents (context, &template);
+           return ret;
+       }
+       ret = krb5_copy_principal (context, in_cred->server, &template.server);
+       if (ret) {
+           krb5_free_cred_contents (context, &template);
+           return ret;
+       }
+
+       ret = krb5_get_credentials (context, 0, ccache,
+                                   &template, &v5_creds);
+       krb5_free_cred_contents (context, &template);
+       if (ret)
+           return ret;
+    }
+
+    ret = krb524_convert_creds_kdc(context, v5_creds, v4creds);
+
+    if (v5_creds != in_cred)
+       krb5_free_creds (context, v5_creds);
+    return ret;
+}
diff --git a/source4/heimdal/lib/krb5/prompter_posix.c b/source4/heimdal/lib/krb5/prompter_posix.c
new file mode 100644 (file)
index 0000000..3ea512c
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden). 
+ * All rights reserved. 
+ *
+ * Redistribution and use in source and binary forms, with or without 
+ * modification, are permitted provided that the following conditions 
+ * are met: 
+ *
+ * 1. Redistributions of source code must retain the above copyright 
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright 
+ *    notice, this list of conditions and the following disclaimer in the 
+ *    documentation and/or other materials provided with the distribution. 
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors 
+ *    may be used to endorse or promote products derived from this software 
+ *    without specific prior written permission. 
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 
+ * SUCH DAMAGE. 
+ */
+
+#include "krb5_locl.h"
+
+RCSID("$Id: prompter_posix.c,v 1.10 2004/05/25 21:38:14 lha Exp $");
+
+int KRB5_LIB_FUNCTION
+krb5_prompter_posix (krb5_context context,
+                    void *data,
+                    const char *name,
+                    const char *banner,
+                    int num_prompts,
+                    krb5_prompt prompts[])
+{
+    int i;
+
+    if (name)
+       fprintf (stderr, "%s\n", name);
+    if (banner)
+       fprintf (stderr, "%s\n", banner);
+    if (name || banner)
+       fflush(stderr);
+    for (i = 0; i < num_prompts; ++i) {
+       if (prompts[i].hidden) {
+           if(UI_UTIL_read_pw_string(prompts[i].reply->data,
+                                 prompts[i].reply->length,
+                                 prompts[i].prompt,
+                                 0))
+              return 1;
+       } else {
+           char *s = prompts[i].reply->data;
+
+           fputs (prompts[i].prompt, stdout);
+           fflush (stdout);
+           if(fgets(prompts[i].reply->data,
+                    prompts[i].reply->length,
+                    stdin) == NULL)
+               return 1;
+           s[strcspn(s, "\n")] = '\0';
+       }
+    }
+    return 0;
+}
index 9764da6bd66ec0524d0d77124799bd6d7d8dee0d..8e59009d7054ba4a915a7a2bf38855356aac2788 100644 (file)
@@ -163,7 +163,7 @@ OBJ_FILES = \
        ../heimdal/lib/gssapi/krb5/accept_sec_context.o \
        ../heimdal/lib/gssapi/krb5/set_sec_context_option.o \
        ../heimdal/lib/gssapi/krb5/process_context_token.o
-PRIVATE_DEPENDENCIES = HEIMDAL_KRB5 HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_ASN1 HEIMDAL_GLUE HEIMDAL_SPNEGO_ASN1
+PRIVATE_DEPENDENCIES = HEIMDAL_KRB5 HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_ASN1 HEIMDAL_SPNEGO_ASN1
 # End SUBSYSTEM HEIMDAL_GSSAPI
 #######################
 
@@ -171,7 +171,7 @@ PRIVATE_DEPENDENCIES = HEIMDAL_KRB5 HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_ASN1 HEIMD
 # Start SUBSYSTEM HEIMDAL_KRB5
 [SUBSYSTEM::HEIMDAL_KRB5]
 CFLAGS = -Iheimdal_build -Iheimdal/lib/krb5 
-PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_HX509 HEIMDAL_PKINIT_ASN1
+PRIVATE_DEPENDENCIES = HEIMDAL_ROKEN HEIMDAL_DES HEIMDAL_HX509 HEIMDAL_PKINIT_ASN1 HEIMDAL_GLUE
 PUBLIC_DEPENDENCIES = HEIMDAL_KRB5_ASN1
 OBJ_FILES = \
        ../heimdal/lib/krb5/acache.o \
@@ -189,6 +189,7 @@ OBJ_FILES = \
        ../heimdal/lib/krb5/config_file_netinfo.o \
        ../heimdal/lib/krb5/constants.o \
        ../heimdal/lib/krb5/context.o \
+       ../heimdal/lib/krb5/convert_creds.o \
        ../heimdal/lib/krb5/copy_host_realm.o \
        ../heimdal/lib/krb5/crc.o \
        ../heimdal/lib/krb5/creds.o \
@@ -236,6 +237,7 @@ OBJ_FILES = \
        ../heimdal/lib/krb5/plugin.o \
        ../heimdal/lib/krb5/principal.o \
        ../heimdal/lib/krb5/pac.o \
+       ../heimdal/lib/krb5/prompter_posix.o \
        ../heimdal/lib/krb5/rd_cred.o \
        ../heimdal/lib/krb5/rd_error.o \
        ../heimdal/lib/krb5/rd_priv.o \
@@ -579,5 +581,17 @@ PUBLIC_DEPENDENCIES = HEIMDAL
 # End SUBSYSTEM KERBEROS_LIB
 #######################
 
+#######################
+# Start BINARY compile_et
+[BINARY::samba4kinit]
+CFLAGS = -Iheimdal_build -Iheimdal/lib/roken
+OBJ_FILES = ../heimdal/kuser/kinit.o \
+       ../heimdal/lib/vers/print_version.o \
+       ../heimdal/lib/roken/setprogname.o \
+       ../heimdal/lib/roken/getarg.o 
+PRIVATE_DEPENDENCIES = HEIMDAL_KRB5
+# End BINARY compile_et
+#######################
+
 dist:: heimdal/lib/asn1/lex.c heimdal/lib/com_err/lex.c \
        heimdal/lib/asn1/parse.c heimdal/lib/com_err/parse.c
diff --git a/source4/heimdal_build/kafs.h b/source4/heimdal_build/kafs.h
new file mode 100644 (file)
index 0000000..878dd08
--- /dev/null
@@ -0,0 +1,19 @@
+int k_hasafs (void) {
+       return 0;
+};
+
+int krb_afslog (const char *cell, const char *realm) {
+       return 0;
+};
+int k_unlog (void) {
+       return 0;
+};
+int k_setpag (void) {
+       return 0;
+};
+krb5_error_code krb5_afslog (krb5_context context,
+                                krb5_ccache id, 
+                                const char *cell,
+                            krb5_const_realm realm) {
+       return 0;
+};