]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Add KRB5RCACHENAME and default_rcache_name 899/head
authorGreg Hudson <ghudson@mit.edu>
Fri, 17 May 2019 17:45:08 +0000 (13:45 -0400)
committerGreg Hudson <ghudson@mit.edu>
Fri, 31 May 2019 17:43:29 +0000 (13:43 -0400)
In krb5_get_server_rcache(), stop constructing a residual value based
on piece and the euid, and instead resolve default replay cache
(previously an unused operation, as krb5_rc_default() was not part of
the API and was never used).

To determine the default replay cache name, try the KRB5RCACHENAME
environment variable first, and then try KRB5RCACHETYPE for
compatibility.  If neither of those environment variables are set, try
the default_rcache_name profile relation in [libdefaults] before
falling back to "dfl:".

ticket: 8786

doc/admin/conf_files/krb5_conf.rst
doc/basic/rcache_def.rst
doc/user/user_config/kerberos.rst
src/include/k5-int.h
src/include/krb5/krb5.hin
src/lib/krb5/krb/srv_rcache.c
src/lib/krb5/rcache/rc_base.c
src/man/kerberos.man
src/man/krb5.conf.man

index 89f02434b415f0d5e09ae6e2b8c8d60f0992ced9..e4de1a0c1a4b2ffbd11ce1abf79d4a372930cf58 100644 (file)
@@ -148,6 +148,11 @@ The libdefaults section may contain any of the following relations:
     application servers such as sshd.  The default is |keytab|.  This
     relation is subject to parameter expansion (see below).
 
+**default_rcache_name**
+    This relation specifies the name of the default replay cache.
+    The default is ``dfl:``.  This relation is subject to parameter
+    expansion (see below).  New in release 1.18.
+
 **default_realm**
     Identifies the default Kerberos realm for the client.  Set its
     value to your Kerberos realm.  If this value is not set, then a
index 5e550fcc32b2298d03b1b67157bfbc59d5c54ce4..de3b2155cc2f505bc4a2c4f2f20142aebe108303 100644 (file)
@@ -74,9 +74,6 @@ are in lowercase.  The following types are defined:
    a file2 replay cache with a filename based on the effective uid.
    The residual value is ignored.
 
-The default type can be overridden by the **KRB5RCACHETYPE**
-environment variable.
-
 For the dfl type, the location of the replay cache file is determined
 as follows:
 
@@ -96,21 +93,19 @@ directory, unless overridden by the **KRB5RCACHEDIR** environment
 variable.  The filename on Windows is ``krb5.rcache2``, and the file
 is opened normally.
 
-Performance issues
-------------------
+Default replay cache name
+-------------------------
+
+The default replay cache name is determined by the following, in
+descending order of priority:
 
-Several known minor performance issues that may occur when replay
-cache is enabled on the Kerberos system include: delays due to writing
-the authenticator data to disk slowing down response time for very
-heavily loaded servers, and delays during the rewrite that may be
-unacceptable to high-performance services.
+#. The **KRB5RCACHENAME** environment variable (new in release 1.18).
 
-For use cases where replays are adequately defended against for all
-protocols using a given service principal name, or where performance
-or other considerations outweigh the risk of replays, the special
-replay cache type "none" can be specified::
+#. The **KRB5RCACHETYPE** environment variable.  If this variable is
+   set, the residual value is empty.
 
-    KRB5RCACHETYPE=none
+#. The **default_rcache_name** profile variable in :ref:`libdefaults`
+   (new in release 1.18).
 
-It doesn't record any information about authenticators, and reports
-that any authenticator seen is not a replay.
+#. If none of the above are set, the default replay cache name is
+   ``dfl:``.
index 56412f099242ddae2d8f6134e80eda186e2d1a28..bcb79d9aad996170e629ccdf993d66b799d56e12 100644 (file)
@@ -108,13 +108,22 @@ programs.  These include:
     Distribution Center daemon and associated programs.  The default
     is |kdcdir|\ ``/kdc.conf``.
 
+**KRB5RCACHENAME**
+    (New in release 1.18) Specifies the location of the default replay
+    cache, in the form *type*:*residual*.  The ``file2`` type with a
+    pathname residual specifies a replay cache file in the version-2
+    format in the specified location.  The ``none`` type (residual is
+    ignored) disables the replay cache.  The ``dfl`` type (residual is
+    ignored) indicates the default, which uses a file2 replay cache in
+    a temporary directory.  The default is ``dfl:``.
+
 **KRB5RCACHETYPE**
-    Specifies the default type of replay cache to use for servers.
-    Valid types include ``dfl`` for the normal file type and ``none``
-    for no replay cache.  The default is ``dfl``.
+    Specifies the type of the default replay cache, if
+    **KRB5RCACHENAME** is unspecified.  No residual can be specified,
+    so ``none`` and ``dfl`` are the only useful types.
 
 **KRB5RCACHEDIR**
-    Specifies the default directory for replay caches used by servers.
+    Specifies the directory used by the ``dfl`` replay cache type.
     The default is the value of the **TMPDIR** environment variable,
     or ``/var/tmp`` if **TMPDIR** is not set.
 
index 30e45016baad6c3336278e11f426629db68fccec..a2faa9d9adfbbd89166414841045ac39b2157e47 100644 (file)
@@ -196,6 +196,7 @@ typedef unsigned char   u_char;
 #define KRB5_CONF_DEFAULT_KEYTAB_NAME          "default_keytab_name"
 #define KRB5_CONF_DEFAULT_PRINCIPAL_EXPIRATION "default_principal_expiration"
 #define KRB5_CONF_DEFAULT_PRINCIPAL_FLAGS      "default_principal_flags"
+#define KRB5_CONF_DEFAULT_RCACHE_NAME          "default_rcache_name"
 #define KRB5_CONF_DEFAULT_REALM                "default_realm"
 #define KRB5_CONF_DEFAULT_TGS_ENCTYPES         "default_tgs_enctypes"
 #define KRB5_CONF_DEFAULT_TKT_ENCTYPES         "default_tkt_enctypes"
index 8bdca2f0cc68b33a1957bd2f43fb47b0257dffaa..d65cf8f4e4bb7eda7b4104787f37c4c0d3746453 100644 (file)
@@ -3944,13 +3944,14 @@ krb5_copy_checksum(krb5_context context, const krb5_checksum *ckfrom,
  * Generate a replay cache object for server use and open it.
  *
  * @param [in]  context         Library context
- * @param [in]  piece           Unique identifier for replay cache
+ * @param [in]  piece           Unused (replay cache identifier)
  * @param [out] rcptr           Handle to an open rcache
  *
- * This function generates a replay cache name based on @a piece and opens a
- * handle to it.  Typically @a piece is the first component of the service
- * principal name.  Use krb5_rc_close() to close @a rcptr when it is no longer
- * needed.
+ * This function creates a handle to the default replay cache.  Use
+ * krb5_rc_close() to close @a rcptr when it is no longer needed.
+ *
+ * @version Prior to release 1.18, this function creates a handle to a
+ * different replay cache for each unique value of @a piece.
  *
  * @retval 0 Success; otherwise - Kerberos error codes
  */
index 692c853a29357b92fe08c0a6241facc5e04b3342..0929145a1d6cdefbafa3ed3af25c7fd6194cc94a 100644 (file)
 #include <ctype.h>
 #include <stdio.h>
 
-/* Macro for valid RC name characters*/
-#define isvalidrcname(x) ((!ispunct(x))&&isgraph(x))
 krb5_error_code KRB5_CALLCONV
 krb5_get_server_rcache(krb5_context context, const krb5_data *piece,
                        krb5_rcache *rcptr)
 {
-    krb5_rcache rcache = 0;
-    char *cachetype;
-    krb5_error_code retval;
-    unsigned int i;
-    struct k5buf buf = EMPTY_K5BUF;
-#ifdef HAVE_GETEUID
-    unsigned long uid = geteuid();
-#endif
-
-    if (piece == NULL)
-        return ENOMEM;
-
-    cachetype = krb5_rc_default_type(context);
-
-    k5_buf_init_dynamic(&buf);
-    k5_buf_add(&buf, cachetype);
-    k5_buf_add(&buf, ":");
-    for (i = 0; i < piece->length; i++) {
-        if (piece->data[i] == '-')
-            k5_buf_add(&buf, "--");
-        else if (!isvalidrcname((int) piece->data[i]))
-            k5_buf_add_fmt(&buf, "-%03o", piece->data[i]);
-        else
-            k5_buf_add_len(&buf, &piece->data[i], 1);
-    }
-#ifdef HAVE_GETEUID
-    k5_buf_add_fmt(&buf, "_%lu", uid);
-#endif
-
-    if (k5_buf_status(&buf) != 0)
-        return ENOMEM;
-
-    retval = krb5_rc_resolve_full(context, &rcache, buf.data);
-    if (retval)
-        goto cleanup;
-
-    retval = krb5_rc_recover_or_initialize(context, rcache,
-                                           context->clockskew);
-    if (retval)
-        goto cleanup;
-
-    *rcptr = rcache;
-    rcache = 0;
-    retval = 0;
-
-cleanup:
-    if (rcache)
-        krb5_rc_close(context, rcache);
-    k5_buf_free(&buf);
-    return retval;
+    /*
+     * This function used to compose a name based on the first component of the
+     * server principal, but now ignores the piece argument and resolves the
+     * default replay cache.
+     */
+    return krb5_rc_default(context, rcptr);
 }
index c5f1d2342cbaf89fb650f66e987536b9c224094e..66937594d5cfaca892a7a6e67561d9c26abe32f5 100644 (file)
@@ -13,6 +13,7 @@
 #include "rc_base.h"
 #include "rc-int.h"
 #include "k5-thread.h"
+#include "../os/os-proto.h"
 
 struct krb5_rc_typelist {
     const krb5_rc_ops *ops;
@@ -124,25 +125,65 @@ krb5_rc_default_name(krb5_context context)
         return (char *) 0;
 }
 
+static krb5_error_code
+resolve_type_and_residual(krb5_context context, const char *type,
+                          char *residual, krb5_rcache *rc_out)
+{
+    krb5_error_code ret;
+    krb5_rcache rc;
+
+    *rc_out = NULL;
+
+    ret = krb5_rc_resolve_type(context, &rc, type);
+    if (ret)
+        return ret;
+
+    ret = krb5_rc_resolve(context, rc, residual);
+    if (ret) {
+        k5_mutex_destroy(&rc->lock);
+        free(rc);
+        return ret;
+    }
+
+    rc->magic = KV5M_RCACHE;
+    *rc_out = rc;
+    return 0;
+}
+
 krb5_error_code
 krb5_rc_default(krb5_context context, krb5_rcache *idptr)
 {
-    krb5_error_code retval;
-    krb5_rcache id;
+    krb5_error_code ret;
+    const char *val;
+    char *profstr, *rcname;
 
     *idptr = NULL;
-    retval = krb5_rc_resolve_type(context, &id, krb5_rc_default_type(context));
-    if (retval)
-        return retval;
-    retval = krb5_rc_resolve(context, id, krb5_rc_default_name(context));
-    if (retval) {
-        k5_mutex_destroy(&id->lock);
-        free(id);
-        return retval;
+
+    /* If KRB5RCACHENAME is set in the environment, resolve it. */
+    val = secure_getenv("KRB5RCACHENAME");
+    if (val != NULL)
+        return krb5_rc_resolve_full(context, idptr, val);
+
+    /* If KRB5RCACHETYPE is set in the environment, resolve it with an empty
+     * residual (primarily to support KRB5RCACHETYPE=none). */
+    val = secure_getenv("KRB5RCACHETYPE");
+    if (val != NULL)
+        return resolve_type_and_residual(context, val, "", idptr);
+
+    /* If [libdefaults] default_rcache_name is set, expand path tokens in the
+     * value and resolve it. */
+    if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS,
+                           KRB5_CONF_DEFAULT_RCACHE_NAME, NULL, NULL,
+                           &profstr) == 0 && profstr != NULL) {
+        ret = k5_expand_path_tokens(context, profstr, &rcname);
+        profile_release_string(profstr);
+        ret = krb5_rc_resolve_full(context, idptr, rcname);
+        free(rcname);
+        return ret;
     }
-    id->magic = KV5M_RCACHE;
-    *idptr = id;
-    return retval;
+
+    /* Resolve the default type with no residual. */
+    return resolve_type_and_residual(context, "dfl", "", idptr);
 }
 
 
@@ -150,33 +191,20 @@ krb5_error_code
 krb5_rc_resolve_full(krb5_context context, krb5_rcache *idptr,
                      const char *string_name)
 {
-    char *type;
-    char *residual;
-    krb5_error_code retval;
-    unsigned int diff;
-    krb5_rcache id;
+    krb5_error_code ret;
+    char *type, *sep;
 
     *idptr = NULL;
 
-    if (!(residual = strchr(string_name,':')))
+    sep = strchr(string_name, ':');
+    if (sep == NULL)
         return KRB5_RC_PARSE;
 
-    diff = residual - string_name;
-    if (!(type = malloc(diff + 1)))
-        return KRB5_RC_MALLOC;
-    (void) strncpy(type, string_name, diff);
-    type[residual - string_name] = '\0';
+    type = k5memdup0(string_name, sep - string_name, &ret);
+    if (type == NULL)
+        return ret;
 
-    retval = krb5_rc_resolve_type(context, &id,type);
+    ret = resolve_type_and_residual(context, type, sep + 1, idptr);
     free(type);
-    if (retval)
-        return retval;
-    if ((retval = krb5_rc_resolve(context, id,residual + 1))) {
-        k5_mutex_destroy(&id->lock);
-        free(id);
-        return retval;
-    }
-    id->magic = KV5M_RCACHE;
-    *idptr = id;
-    return retval;
+    return ret;
 }
index 026f4604ad81ccc1e5341afc38837661ccacbe68..a109538fade4963a60eaa7c2e99f9bb2c0fcef0f 100644 (file)
@@ -1,6 +1,6 @@
 .\" Man page generated from reStructuredText.
 .
-.TH "KERBEROS" "7" " " "1.17" "MIT Kerberos"
+.TH "KERBEROS" "7" " " "1.18" "MIT Kerberos"
 .SH NAME
 kerberos \- Overview of using Kerberos
 .
@@ -141,13 +141,22 @@ contains additional configuration directives for the Key
 Distribution Center daemon and associated programs.  The default
 is \fB@LOCALSTATEDIR@\fP\fB/krb5kdc\fP\fB/kdc.conf\fP\&.
 .TP
+\fBKRB5RCACHENAME\fP
+(New in release 1.18) Specifies the location of the default replay
+cache, in the form \fItype\fP:\fIresidual\fP\&.  The \fBfile2\fP type with a
+pathname residual specifies a replay cache file in the version\-2
+format in the specified location.  The \fBnone\fP type (residual is
+ignored) disables the replay cache.  The \fBdfl\fP type (residual is
+ignored) indicates the default, which uses a file2 replay cache in
+a temporary directory.  The default is \fBdfl:\fP\&.
+.TP
 \fBKRB5RCACHETYPE\fP
-Specifies the default type of replay cache to use for servers.
-Valid types include \fBdfl\fP for the normal file type and \fBnone\fP
-for no replay cache.  The default is \fBdfl\fP\&.
+Specifies the type of the default replay cache, if
+\fBKRB5RCACHENAME\fP is unspecified.  No residual can be specified,
+so \fBnone\fP and \fBdfl\fP are the only useful types.
 .TP
 \fBKRB5RCACHEDIR\fP
-Specifies the default directory for replay caches used by servers.
+Specifies the directory used by the \fBdfl\fP replay cache type.
 The default is the value of the \fBTMPDIR\fP environment variable,
 or \fB/var/tmp\fP if \fBTMPDIR\fP is not set.
 .TP
@@ -197,6 +206,6 @@ Institute of Technology
 .SH AUTHOR
 MIT
 .SH COPYRIGHT
-1985-2018, MIT
+1985-2019, MIT
 .\" Generated by docutils manpage writer.
 .
index d6ff91c3be03bf33819636eb59d1e0c158045fac..e0bee9c431afbf6b6950697a8735be4bafa97eb1 100644 (file)
@@ -242,6 +242,11 @@ This relation specifies the default keytab name to be used by
 application servers such as sshd.  The default is \fB@KTNAME@\fP\&.  This
 relation is subject to parameter expansion (see below).
 .TP
+\fBdefault_rcache_name\fP
+This relation specifies the name of the default replay cache.
+The default is \fBdfl:\fP\&.  This relation is subject to parameter
+expansion (see below).  New in release 1.18.
+.TP
 \fBdefault_realm\fP
 Identifies the default Kerberos realm for the client.  Set its
 value to your Kerberos realm.  If this value is not set, then a