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``
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
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
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
.. toctree::
:maxdepth: 1
+ keytab_def.rst
stash_file_def.rst
--- /dev/null
+.. _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|.
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**
#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"
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 *);
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.
*
#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"
#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"
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.
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
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 */
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
}
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;
+}
# 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!
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 {
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
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)"
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)"
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)"
* 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.
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)
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