kinit: add KDB keytab support
authorSam Hartman <hartmans@mit.edu>
Wed, 15 Sep 2010 17:13:41 +0000 (17:13 +0000)
committerSam Hartman <hartmans@mit.edu>
Wed, 15 Sep 2010 17:13:41 +0000 (17:13 +0000)
This implements
http://k5wiki.kerberos.org/Projects/What_does_God_need_with_a_password.
If the KDB keytab is selected by command line options, then kinit will
register the KDB keytab and open the database.  This permits an
administrator to obtain tickets as a user without knowing that user's
password.

As a result kinit links against libkadm5srv and libkdb5. Discussion is
ongoing about whether this is desirable or about whether two versions
of kinit are required.

ticket: 6779

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24316 dc483132-0cff-0310-8789-dd5450dbe970

src/clients/kinit/Makefile.in
src/clients/kinit/extern.h [new file with mode: 0644]
src/clients/kinit/kinit.M
src/clients/kinit/kinit.c
src/clients/kinit/kinit_kdb.c [new file with mode: 0644]
src/tests/t_general.py

index 27879412074515ddf269239410251f43fe866b38..d60b1c7ae53002030cfc02bd1066fa378fc40030 100644 (file)
@@ -5,7 +5,7 @@ DEFS=
 PROG_LIBPATH=-L$(TOPLIBD)
 PROG_RPATH=$(KRB5_LIBDIR)
 
-SRCS=kinit.c
+SRCS=kinit.c kinit_kdb.c
 
 ##WIN32##LOCALINCLUDES=-I$(BUILDTOP)\util\windows
 ##WIN32##DEFINES=-DGETOPT_LONG
@@ -23,8 +23,8 @@ SRCS=kinit.c
 all-unix:: kinit
 ##WIN32##all-windows:: $(KINIT)
 
-kinit: kinit.o $(KRB5_BASE_DEPLIBS)
-       $(CC_LINK) -o $@ kinit.o $(KRB5_BASE_LIBS)
+kinit: kinit.o kinit_kdb.o $(KRB5_BASE_DEPLIBS) $(KADMSRV_DEPLIBS)
+       $(CC_LINK) -o $@ kinit.o kinit_kdb.o $(KADMSRV_LIBS) $(KRB5_BASE_LIBS)
 
 ##WIN32##$(KINIT): $(OUTPRE)kinit.obj $(BUILDTOP)\util\windows\$(OUTPRE)getopt.lib $(KLIB) $(CLIB) $(EXERES)
 ##WIN32##      link $(EXE_LINKOPTS) -out:$@ $** advapi32.lib
diff --git a/src/clients/kinit/extern.h b/src/clients/kinit/extern.h
new file mode 100644 (file)
index 0000000..bdb962c
--- /dev/null
@@ -0,0 +1,7 @@
+#ifndef _KINIT_EXTERN_H
+#define _KINIT_EXTERN_H
+krb5_error_code
+kinit_kdb_init (krb5_context *pcontext,
+               char *realm);
+
+#endif
index 1d434c0fbd47ee520185eb5d659dc68bd8411e43..80af95bbd1868dc4b9c0b95a05fa6829735df1fc 100644 (file)
@@ -131,13 +131,17 @@ ticket cannot be renewed, even if the ticket is still within its
 renewable life.
 .TP
 \fB\-k\fP [\fB\-t\fP \fIkeytab_file\fP]
-requests a host ticket, obtained from a key in the local host's
+requests a ticket, obtained from a key in the local host's
 .I keytab
 file.  The name and location of the keytab file may be specified with
 the
 .B \-t
 .I keytab_file
-option; otherwise the default name and location will be used.
+option; otherwise the default name and location will be used. By default a host ticket is requested but any principal may be specified. On a KDC, the special keytab location
+.B KDB:
+can be used to indicate that kinit should open the KDC database and
+look up the key directly. This permits an administrator to obtain
+tickets as any principal that supports password-based authentication.
 .TP
 \fB-n\fP
 Requests anonymous processing.  Two types of anonymous principals are
index 8eb059d3aa974785539bf01fb6ea5b5921aa0878..dca911aaa7f0301189c5d6aa159eb1b2ffcd146a 100644 (file)
@@ -31,6 +31,7 @@
 #include "autoconf.h"
 #include "k5-platform.h"        /* for asprintf */
 #include <krb5.h>
+#include "extern.h"
 #include <string.h>
 #include <stdio.h>
 #include <time.h>
@@ -447,7 +448,7 @@ k5_begin(opts, k5)
         com_err(progname, code, "while initializing Kerberos 5 library");
         return 0;
     }
-    errctx = k5->ctx;
+errctx = k5->ctx;
     if (opts->k5_cache_name)
     {
         code = krb5_cc_resolve(k5->ctx, opts->k5_cache_name, &k5->cc);
@@ -649,6 +650,16 @@ k5_kinit(opts, k5)
 
     if ((opts->action == INIT_KT) && opts->keytab_name)
     {
+        if (strncmp(opts->keytab_name, "KDB:", 3) == 0) {
+            code = kinit_kdb_init(&k5->ctx,
+                                  krb5_princ_realm(k5->ctx, k5->me)->data);
+            if (code != 0) {
+                com_err(progname, code, "while setting up KDB keytab for realm %s",
+                        krb5_princ_realm(k5->ctx, k5->me)->data);
+                goto cleanup;
+            }
+        }
+
         code = krb5_kt_resolve(k5->ctx, opts->keytab_name, &keytab);
         if (code != 0) {
             com_err(progname, code, "resolving keytab %s",
diff --git a/src/clients/kinit/kinit_kdb.c b/src/clients/kinit/kinit_kdb.c
new file mode 100644 (file)
index 0000000..972983a
--- /dev/null
@@ -0,0 +1,70 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * clients/kinit/kinit_kdb.c
+ *
+ * Copyright (C) 2010 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Export of this software from the United States of America may
+ *   require a specific license from the United States Government.
+ *   It is the responsibility of any person or organization contemplating
+ *   export to obtain such a license before exporting.
+ *
+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
+ * distribute this software and its documentation for any purpose and
+ * without fee is hereby granted, provided that the above copyright
+ * notice appear in all copies and that both that copyright notice and
+ * this permission notice appear in supporting documentation, and that
+ * the name of M.I.T. not be used in advertising or publicity pertaining
+ * to distribution of the software without specific, written prior
+ * permission.  Furthermore if you modify this software you must label
+ * your software as modified software and not distribute it in such a
+ * fashion that it might be confused with the original M.I.T. software.
+ * M.I.T. makes no representations about the suitability of
+ * this software for any purpose.  It is provided "as is" without express
+ * or implied warranty.
+ *
+ *
+  */
+/**
+ *    @file kinit_kdb.c
+ *    Operations to open the KDB and make the KDB key table available
+ *    for kinit.
+ */
+
+
+#include <k5-int.h>
+#include <kadm5/admin.h>
+#include <kdb_kt.h>
+#include "extern.h"
+
+/**Server handle*/
+static void * server_handle;
+
+/**
+ *@internal  Initialize KDB for given realm
+ * @param context pointer to context that will be re-initialized
+ * @@param realm name of realm to initialize
+ */
+krb5_error_code
+kinit_kdb_init (krb5_context *pcontext, char *realm)
+{
+  kadm5_config_params config;
+  krb5_error_code retval = 0;
+  if (*pcontext)
+    krb5_free_context(*pcontext);
+  memset(&config, 0, sizeof config);
+  retval = kadm5_init_krb5_context(pcontext);
+  if (retval)
+    return retval;
+  config.mask = KADM5_CONFIG_REALM;
+  config.realm = realm;
+  retval = kadm5_init(*pcontext, "kinit", NULL /*pass*/,
+                     "kinit", &config,
+                     KADM5_STRUCT_VERSION, KADM5_API_VERSION_3, NULL,
+                     &server_handle);
+  if (retval)
+      return retval;
+  retval = krb5_kt_register(*pcontext, &krb5_kt_kdb_ops);
+  return retval;
+}
index cb2fcbc746bf13f4eb9f210a145e63b8a8141be1..a2953fefde64a1677372c9befbd598ed12446895 100755 (executable)
@@ -28,6 +28,11 @@ for realm in multipass_realms(create_host=False):
     realm.kinit('user/fast', fastpw, flags=['-T', realm.ccache])
     realm.klist('user/fast@%s' % realm.realm)
 
+    # Test kinit against kdb keytab
+    realm.run_as_master([kinit, "-k", "-t",
+                         "KDB:", realm.user_princ])
+
+
     # Test kdestroy and klist of a non-existent ccache.
     realm.run_as_client([kdestroy])
     output = realm.run_as_client([klist], expected_code=1)