summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2012-06-15 11:14:39 -0400
committerGreg Hudson <ghudson@mit.edu>2012-07-02 00:59:45 -0400
commitd1fe0728c830fe52bdcb5d53c517a9462391069d (patch)
tree9030eff3f99c4fb2f240380999b09be246b8fb41
parent49ba7c90fce86581ff6faaa9ee48c80b0be9491e (diff)
downloadkrb5-d1fe0728c830fe52bdcb5d53c517a9462391069d.tar.gz
krb5-d1fe0728c830fe52bdcb5d53c517a9462391069d.tar.xz
krb5-d1fe0728c830fe52bdcb5d53c517a9462391069d.zip
Add krb5_kt_client_default API
The default client keytab is intended to be used to automatically acquire initial credentials for client applications. The current hardcoded default is a placeholder, and will likely change before 1.11. Add test framework settings to ensure that a system default client keytab doesn't interfere with tests, and to allow tests to be written to deliberately use the default client keytab. Add documentation about keytabs to the concepts section of the RST docs, and describe the default client keytab there. ticket: 7188 (new)
-rw-r--r--doc/rst_source/conf.py1
-rw-r--r--doc/rst_source/krb_admins/conf_files/krb5_conf.rst4
-rw-r--r--doc/rst_source/krb_admins/env_variables.rst4
-rw-r--r--doc/rst_source/krb_appldev/refs/api/index.rst1
-rw-r--r--doc/rst_source/krb_basic/index.rst1
-rw-r--r--doc/rst_source/krb_basic/keytab_def.rst61
-rw-r--r--doc/rst_source/mitK5defaults.rst1
-rw-r--r--src/include/k5-int.h4
-rw-r--r--src/include/krb5/krb5.hin16
-rw-r--r--src/include/osconf.hin2
-rwxr-xr-xsrc/kadmin/testing/scripts/env-setup.shin1
-rwxr-xr-xsrc/kadmin/testing/scripts/init_db1
-rw-r--r--src/lib/krb5/keytab/ktdefault.c14
-rw-r--r--src/lib/krb5/libkrb5.exports1
-rw-r--r--src/lib/krb5/os/ktdefname.c33
-rw-r--r--src/tests/dejagnu/config/default.exp16
-rw-r--r--src/util/k5test.py5
17 files changed, 164 insertions, 2 deletions
diff --git a/doc/rst_source/conf.py b/doc/rst_source/conf.py
index 31b4892e4b..655d3a9cb6 100644
--- a/doc/rst_source/conf.py
+++ b/doc/rst_source/conf.py
@@ -233,6 +233,7 @@ rst_epilog += '.. |libdir| replace:: %s\n' % libdir
rst_epilog += '.. |kdcdir| replace:: %s\\ ``/krb5kdc``\n' % localstatedir
rst_epilog += '.. |sysconfdir| replace:: %s\n' % sysconfdir
rst_epilog += '''
+.. |clkeytab| replace:: ``/etc/krb5.client-keytab``
.. |keytab| replace:: ``/etc/krb5.keytab``
.. |krb5conf| replace:: ``/etc/krb5.conf``
.. |defkeysalts| replace:: ``aes256-cts-hmac-sha1-96:normal aes128-cts-hmac-sha1-96:normal des3-cbc-sha1:normal arcfour-hmac-md5:normal``
diff --git a/doc/rst_source/krb_admins/conf_files/krb5_conf.rst b/doc/rst_source/krb_admins/conf_files/krb5_conf.rst
index 51ec79fc18..04d4d4d304 100644
--- a/doc/rst_source/krb_admins/conf_files/krb5_conf.rst
+++ b/doc/rst_source/krb_admins/conf_files/krb5_conf.rst
@@ -132,6 +132,10 @@ The libdefaults section may contain any of the following relations:
library will tolerate before assuming that a Kerberos message is
invalid. The default value is 300 seconds, or five minutes.
+**default_client_keytab_name**
+ This relation specifies the name of the default keytab for
+ obtaining client credentials. The default is |clkeytab|.
+
**default_keytab_name**
This relation specifies the default keytab name to be used by
application servers such as telnetd and rlogind. The default is
diff --git a/doc/rst_source/krb_admins/env_variables.rst b/doc/rst_source/krb_admins/env_variables.rst
index 8963158acc..e85d54da0f 100644
--- a/doc/rst_source/krb_admins/env_variables.rst
+++ b/doc/rst_source/krb_admins/env_variables.rst
@@ -15,6 +15,10 @@ The following environment variables can be used during runtime:
Default keytab file name. (See :ref:`mitK5defaults` for the
default name.)
+**KRB5_CLIENT_KTNAME**
+ Default client keytab file name. (See :ref:`mitK5defaults` for
+ the default name.)
+
**KRB5CCNAME**
Default name for the credentials cache file, in the form *type*\:\
*residual*. The type of the default cache may determine the
diff --git a/doc/rst_source/krb_appldev/refs/api/index.rst b/doc/rst_source/krb_appldev/refs/api/index.rst
index c61f2a00b1..9f9f399011 100644
--- a/doc/rst_source/krb_appldev/refs/api/index.rst
+++ b/doc/rst_source/krb_appldev/refs/api/index.rst
@@ -64,6 +64,7 @@ Frequently used public interfaces
krb5_is_config_principal.rst
krb5_is_thread_safe.rst
krb5_kt_close.rst
+ krb5_kt_client_default.rst
krb5_kt_default.rst
krb5_kt_default_name.rst
krb5_kt_get_name.rst
diff --git a/doc/rst_source/krb_basic/index.rst b/doc/rst_source/krb_basic/index.rst
index d402f21848..59e2783ea1 100644
--- a/doc/rst_source/krb_basic/index.rst
+++ b/doc/rst_source/krb_basic/index.rst
@@ -7,4 +7,5 @@ Basic Kerberos V5 concepts
.. toctree::
:maxdepth: 1
+ keytab_def.rst
stash_file_def.rst
diff --git a/doc/rst_source/krb_basic/keytab_def.rst b/doc/rst_source/krb_basic/keytab_def.rst
new file mode 100644
index 0000000000..3f1f0de10b
--- /dev/null
+++ b/doc/rst_source/krb_basic/keytab_def.rst
@@ -0,0 +1,61 @@
+.. _keytab_definition:
+
+keytab
+======
+
+A keytab (short for "key table") stores long-term keys for one or more
+principals. Keytabs are normally represented by files in a standard
+format, although in rare cases they can be represented in other ways.
+Keytabs are used most often to allow server applications to accept
+authentications from clients, but can also be used to obtain initial
+credentials for client applications.
+
+Keytabs are named using the format *type*\ ``:``\ *value*. Usually
+*type* is ``FILE`` and *value* is the absolute pathname of the file.
+Other possible values for *type* are ``SRVTAB``, which indicates a
+file in the deprecated Kerberos 4 srvtab format, and ``MEMORY``, which
+indicates a temporary keytab stored in the memory of the current
+process.
+
+A keytab contains one or more entries, where each entry consists of a
+timestamp (indicating when the entry was written to the keytab), a
+principal name, a key version number, an encryption type, and the
+encryption key itself.
+
+A keytab can be displayed using the :ref:`klist(1)` command with the
+``-k`` option. Keytabs can be created or appended to by extracting
+keys from the KDC database using the :ref:`kadmin(1)` :ref:`ktadd`
+command. Keytabs can be manipulated using the :ref:`ktutil(1)` and
+:ref:`k5srvutil(1)` commands.
+
+
+Default keytab
+--------------
+
+The default keytab is used by server applications if the application
+does not request a specific keytab. The name of the default keytab is
+determined by the following, in decreasing order of preference:
+
+#. The **KRB5_KTNAME** environment variable.
+
+#. The **default_keytab_name** profile variable in :ref:`libdefaults`.
+
+#. The hardcoded default, ``FILE:``\ |keytab|.
+
+
+Default client keytab
+---------------------
+
+The default client keytab is used, if it is present and readable, to
+automatically obtain initial credentials for GSSAPI client
+applications. The principal name of the first entry in the client
+keytab is used by default when obtaining initial credentials. The
+name of the default client keytab is determined by the following, in
+decreasing order of preference:
+
+#. The **KRB5_CLIENT_KTNAME** environment variable.
+
+#. The **default_client_keytab_name** profile variable in
+ :ref:`libdefaults`.
+
+#. The hardcoded default, ``FILE:``\ |clkeytab|.
diff --git a/doc/rst_source/mitK5defaults.rst b/doc/rst_source/mitK5defaults.rst
index 1d27bfcc02..eca502fb4d 100644
--- a/doc/rst_source/mitK5defaults.rst
+++ b/doc/rst_source/mitK5defaults.rst
@@ -10,6 +10,7 @@ General defaults
Description Default Environment
========================== ============================= ====================
Keytab file ``FILE:``\ |keytab| **KRB5_KTNAME**
+Client keytab file ``FILE:``\ |clkeytab| **KRB5_CLIENT_KTNAME**
Kerberos config file |krb5conf|\ ``:``\ **KRB5_CONFIG**
|sysconfdir|\ ``/krb5.conf``
KDC config file |kdcdir|\ ``/kdc.conf`` **KRB5_KDC_PROFILE**
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index b1e535e598..69d30b3b57 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -199,6 +199,7 @@ typedef INT64_TYPE krb5_int64;
#define KRB5_CONF_DB_MODULE_DIR "db_module_dir"
#define KRB5_CONF_DEFAULT "default"
#define KRB5_CONF_DEFAULT_REALM "default_realm"
+#define KRB5_CONF_DEFAULT_CLIENT_KEYTAB_NAME "default_client_keytab_name"
#define KRB5_CONF_DEFAULT_DOMAIN "default_domain"
#define KRB5_CONF_DEFAULT_TKT_ENCTYPES "default_tkt_enctypes"
#define KRB5_CONF_DEFAULT_TGS_ENCTYPES "default_tgs_enctypes"
@@ -2353,6 +2354,9 @@ krb5_error_code KRB5_CALLCONV krb5_kt_register(krb5_context,
krb5_error_code k5_kt_get_principal(krb5_context context, krb5_keytab keytab,
krb5_principal *princ_out);
+krb5_error_code k5_kt_client_default_name(krb5_context context,
+ char **name_out);
+
krb5_error_code krb5_principal2salt_norealm(krb5_context, krb5_const_principal,
krb5_data *);
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index 470835a2d3..51ebbb2e60 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -4209,6 +4209,22 @@ krb5_error_code KRB5_CALLCONV
krb5_kt_default(krb5_context context, krb5_keytab *id);
/**
+ * Resolve the default client key table.
+ *
+ * @param [in] context Library context
+ * @param [out] keytab_out Key table handle
+ *
+ * Fill @a keytab_out with a handle to the default client key table.
+ *
+ * @retval
+ * 0 Success
+ * @return
+ * Kerberos error codes
+ */
+krb5_error_code KRB5_CALLCONV
+krb5_kt_client_default(krb5_context context, krb5_keytab *keytab_out);
+
+/**
* Free the contents of a key table entry.
*
* @param [in] context Library context
diff --git a/src/include/osconf.hin b/src/include/osconf.hin
index f53ef1b5cc..97aae48f0d 100644
--- a/src/include/osconf.hin
+++ b/src/include/osconf.hin
@@ -43,6 +43,7 @@
#if defined(_WIN32)
#define DEFAULT_PROFILE_FILENAME "krb5.ini"
#define DEFAULT_KEYTAB_NAME "FILE:%s\\krb5kt"
+#define DEFAULT_CLIENT_KEYTAB_NAME "FILE:%s\\krb5clientkt"
#else /* !_WINDOWS */
#if TARGET_OS_MAC
#define DEFAULT_SECURE_PROFILE_PATH "/Library/Preferences/edu.mit.Kerberos:/etc/krb5.conf:@SYSCONFDIR/krb5.conf"
@@ -55,6 +56,7 @@
#define DEFAULT_PROFILE_PATH DEFAULT_SECURE_PROFILE_PATH
#endif
#define DEFAULT_KEYTAB_NAME "FILE:/etc/krb5.keytab"
+#define DEFAULT_CLIENT_KEYTAB_NAME "FILE:/etc/krb5.client-keytab"
#endif /* _WINDOWS */
#define DEFAULT_PLUGIN_BASE_DIR "@LIBDIR/krb5/plugins"
diff --git a/src/kadmin/testing/scripts/env-setup.shin b/src/kadmin/testing/scripts/env-setup.shin
index bee5b5482c..de1578b569 100755
--- a/src/kadmin/testing/scripts/env-setup.shin
+++ b/src/kadmin/testing/scripts/env-setup.shin
@@ -78,6 +78,7 @@ SRVTCL=$TESTDIR/util/kadm5_srv_tcl; export SRVTCL
KRB5_CONFIG=$K5ROOT/krb5.conf; export KRB5_CONFIG
KRB5_KDC_PROFILE=$K5ROOT/kdc.conf; export KRB5_KDC_PROFILE
KRB5_KTNAME=$K5ROOT/ovsec_adm.srvtab; export KRB5_KTNAME
+KRB5_CLIENT_KTNAME=$K5ROOT/client_keytab; export KRB5_CLIENT_KTNAME
KRB5CCNAME=$K5ROOT/krb5cc_unit-test; export KRB5CCNAME
# Make sure we don't get confused by translated messages.
diff --git a/src/kadmin/testing/scripts/init_db b/src/kadmin/testing/scripts/init_db
index 5cf7491099..12a118d765 100755
--- a/src/kadmin/testing/scripts/init_db
+++ b/src/kadmin/testing/scripts/init_db
@@ -223,6 +223,7 @@ cat > $K5ROOT/setup.csh <<EOF
setenv KRB5_CONFIG $KRB5_CONFIG
setenv KRB5_KDC_PROFILE $KRB5_KDC_PROFILE
setenv KRB5_KTNAME $KRB5_KTNAME
+setenv KRB5_CLIENT_KTNAME $KRB5_CLIENT_KTNAME
$KRB5_RUN_ENV_CSH
EOF
diff --git a/src/lib/krb5/keytab/ktdefault.c b/src/lib/krb5/keytab/ktdefault.c
index 7ee94edae0..2b1c298ce2 100644
--- a/src/lib/krb5/keytab/ktdefault.c
+++ b/src/lib/krb5/keytab/ktdefault.c
@@ -44,4 +44,18 @@ krb5_kt_default(krb5_context context, krb5_keytab *id)
return krb5_kt_resolve(context, defname, id);
}
+krb5_error_code KRB5_CALLCONV
+krb5_kt_client_default(krb5_context context, krb5_keytab *keytab_out)
+{
+ krb5_error_code ret;
+ char *name;
+
+ ret = k5_kt_client_default_name(context, &name);
+ if (ret)
+ return ret;
+ ret = krb5_kt_resolve(context, name, keytab_out);
+ free(name);
+ return ret;
+}
+
#endif /* LEAN_CLIENT */
diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports
index 0af5150ccb..e5acff2d8a 100644
--- a/src/lib/krb5/libkrb5.exports
+++ b/src/lib/krb5/libkrb5.exports
@@ -395,6 +395,7 @@ krb5_is_referral_realm
krb5_is_thread_safe
krb5_kdc_rep_decrypt_proc
krb5_kt_add_entry
+krb5_kt_client_default
krb5_kt_close
krb5_kt_default
krb5_kt_default_name
diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c
index afc344e4d9..a213750dba 100644
--- a/src/lib/krb5/os/ktdefname.c
+++ b/src/lib/krb5/os/ktdefname.c
@@ -74,3 +74,36 @@ krb5_kt_default_name(krb5_context context, char *name, int name_size)
}
return 0;
}
+
+krb5_error_code
+k5_kt_client_default_name(krb5_context context, char **name_out)
+{
+ char *str, *name;
+
+ *name_out = NULL;
+ if (!context->profile_secure &&
+ (str = getenv("KRB5_CLIENT_KTNAME")) != NULL) {
+ name = strdup(str);
+ } else if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+ KRB5_CONF_DEFAULT_CLIENT_KEYTAB_NAME, NULL,
+ NULL, &str) == 0 && str != NULL) {
+ name = strdup(str);
+ profile_release_string(str);
+ } else {
+#ifdef _WIN32
+ char windir[160];
+ unsigned int len;
+
+ len = GetWindowsDirectory(windir, sizeof(windir) - 2);
+ windir[len] = '\0';
+ if (asprintf(&name, DEFAULT_CLIENT_KEYTAB_NAME, windir) < 0)
+ return ENOMEM;
+#else
+ name = strdup(DEFAULT_CLIENT_KEYTAB_NAME);
+#endif
+ }
+ if (name == NULL)
+ return ENOMEM;
+ *name_out = name;
+ return 0;
+}
diff --git a/src/tests/dejagnu/config/default.exp b/src/tests/dejagnu/config/default.exp
index 8ab4b7902d..192ac6da9f 100644
--- a/src/tests/dejagnu/config/default.exp
+++ b/src/tests/dejagnu/config/default.exp
@@ -631,7 +631,7 @@ proc envstack_pop { } {
# Initialize the envstack
#
set envvars_tosave {
- KRB5_CONFIG KRB5CCNAME KRBTKFILE KRB5RCACHEDIR KRB5_KDC_PROFILE
+ KRB5_CONFIG KRB5CCNAME KRB5_CLIENT_KTNAME KRB5RCACHEDIR KRB5_KDC_PROFILE
}
set krb5_init_vars [list ]
# XXX -- fix me later!
@@ -997,6 +997,12 @@ if [info exists env(KRB5CCNAME)] {
catch "unset orig_krb5ccname"
}
+if [info exists env(KRB5_CLIENT_KTNAME)] {
+ set orig_krb5clientktname $env(KRB5_CLIENT_KTNAME)
+} else {
+ catch "unset orig_krb5clientktname"
+}
+
if [ info exists env(KRB5RCACHEDIR)] {
set orig_krb5rcachedir $env(KRB5RCACHEDIR)
} else {
@@ -1024,6 +1030,10 @@ proc setup_kerberos_env { {type client} } {
set env(KRB5CCNAME) $tmppwd/tkt
verbose "KRB5CCNAME=$env(KRB5CCNAME)"
+ # Direct the Kerberos programs at a local client keytab.
+ set env(KRB5_CLIENT_KTNAME) $tmppwd/client_keytab
+ verbose "KRB5_CLIENT_KTNAME=$env(KRB5_CLIENT_KTNAME)"
+
# Direct the Kerberos server at a cache file stored in the
# temporary directory.
set env(KRB5RCACHEDIR) $tmppwd
@@ -1049,6 +1059,7 @@ proc setup_kerberos_env { {type client} } {
set envfile [open $tmppwd/$type-env.sh w]
puts $envfile "KRB5_CONFIG=$env(KRB5_CONFIG)"
puts $envfile "KRB5CCNAME=$env(KRB5CCNAME)"
+ puts $envfile "KRB5_CLIENT_KTNAME=$env(KRB5_CLIENT_KTNAME)"
puts $envfile "KRB5RCACHEDIR=$env(KRB5RCACHEDIR)"
if [info exists env(KRB5_KDC_PROFILE)] {
puts $envfile "KRB5_KDC_PROFILE=$env(KRB5_KDC_PROFILE)"
@@ -1056,7 +1067,7 @@ proc setup_kerberos_env { {type client} } {
puts $envfile "unset KRB5_KDC_PROFILE"
}
puts $envfile "export KRB5_CONFIG KRB5CCNAME KRB5RCACHEDIR"
- puts $envfile "export KRB5_KDC_PROFILE"
+ puts $envfile "export KRB5_KDC_PROFILE KRB5_CLIENT_KTNAME"
foreach i $krb5_init_vars {
regexp "^(\[^=\]*)=(.*)" $i foo evar evalue
puts $envfile "$evar=$env($evar)"
@@ -1068,6 +1079,7 @@ proc setup_kerberos_env { {type client} } {
set envfile [open $tmppwd/$type-env.csh w]
puts $envfile "setenv KRB5_CONFIG $env(KRB5_CONFIG)"
puts $envfile "setenv KRB5CCNAME $env(KRB5CCNAME)"
+ puts $envfile "setenv KRB5_CLIENT_KTNAME $env(KRB5_CLIENT_KTNAME)"
puts $envfile "setenv KRB5RCACHEDIR $env(KRB5RCACHEDIR)"
if [info exists env(KRB5_KDC_PROFILE)] {
puts $envfile "setenv KRB5_KDC_PROFILE $env(KRB5_KDC_PROFILE)"
diff --git a/src/util/k5test.py b/src/util/k5test.py
index f60cb5d0b5..c5669bef29 100644
--- a/src/util/k5test.py
+++ b/src/util/k5test.py
@@ -309,6 +309,9 @@ Scripts may use the following realm methods and attributes:
* realm.keytab: A keytab file in realm.testdir. Initially contains a
host keytab unless disabled by the realm construction options.
+* realm.client_keytab: A keytab file in realm.testdir. Initially
+ nonexistent.
+
* realm.ccache: A ccache file in realm.testdir. Initially contains
credentials for user unless disabled by the realm construction
options.
@@ -705,6 +708,7 @@ class K5Realm(object):
self.nfs_princ = 'nfs/%s@%s' % (hostname, self.realm)
self.krbtgt_princ = 'krbtgt/%s@%s' % (self.realm, self.realm)
self.keytab = os.path.join(self.testdir, 'keytab')
+ self.client_keytab = os.path.join(self.testdir, 'client_keytab')
self.ccache = os.path.join(self.testdir, 'ccache')
self.kadmin_ccache = os.path.join(self.testdir, 'kadmin_ccache')
self._krb5_conf = _cfg_merge(_default_krb5_conf, krb5_conf)
@@ -835,6 +839,7 @@ class K5Realm(object):
env['KRB5_KDC_PROFILE'] = filename
env['KRB5CCNAME'] = self.ccache
env['KRB5_KTNAME'] = self.keytab
+ env['KRB5_CLIENT_KTNAME'] = self.client_keytab
env['KRB5RCACHEDIR'] = self.testdir
return env