summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 31b4892e4..655d3a9cb 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 51ec79fc1..04d4d4d30 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 8963158ac..e85d54da0 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 c61f2a00b..9f9f39901 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 d402f2184..59e2783ea 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 000000000..3f1f0de10
--- /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 1d27bfcc0..eca502fb4 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 b1e535e59..69d30b3b5 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 470835a2d..51ebbb2e6 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 f53ef1b5c..97aae48f0 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 bee5b5482..de1578b56 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 5cf749109..12a118d76 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 7ee94edae..2b1c298ce 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 0af5150cc..e5acff2d8 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 afc344e4d..a213750db 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 8ab4b7902..192ac6da9 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 f60cb5d0b..c5669bef2 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