From: Greg Hudson Date: Fri, 17 May 2019 17:45:08 +0000 (-0400) Subject: Add KRB5RCACHENAME and default_rcache_name X-Git-Tag: krb5-1.18-beta1~114 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0e68760cb8dce4ea25fd73d6eab95bce103b6443;p=thirdparty%2Fkrb5.git Add KRB5RCACHENAME and default_rcache_name 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 --- diff --git a/doc/admin/conf_files/krb5_conf.rst b/doc/admin/conf_files/krb5_conf.rst index 89f02434b4..e4de1a0c1a 100644 --- a/doc/admin/conf_files/krb5_conf.rst +++ b/doc/admin/conf_files/krb5_conf.rst @@ -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 diff --git a/doc/basic/rcache_def.rst b/doc/basic/rcache_def.rst index 5e550fcc32..de3b2155cc 100644 --- a/doc/basic/rcache_def.rst +++ b/doc/basic/rcache_def.rst @@ -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:``. diff --git a/doc/user/user_config/kerberos.rst b/doc/user/user_config/kerberos.rst index 56412f0992..bcb79d9aad 100644 --- a/doc/user/user_config/kerberos.rst +++ b/doc/user/user_config/kerberos.rst @@ -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. diff --git a/src/include/k5-int.h b/src/include/k5-int.h index 30e45016ba..a2faa9d9ad 100644 --- a/src/include/k5-int.h +++ b/src/include/k5-int.h @@ -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" diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index 8bdca2f0cc..d65cf8f4e4 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -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 */ diff --git a/src/lib/krb5/krb/srv_rcache.c b/src/lib/krb5/krb/srv_rcache.c index 692c853a29..0929145a1d 100644 --- a/src/lib/krb5/krb/srv_rcache.c +++ b/src/lib/krb5/krb/srv_rcache.c @@ -28,60 +28,14 @@ #include #include -/* 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); } diff --git a/src/lib/krb5/rcache/rc_base.c b/src/lib/krb5/rcache/rc_base.c index c5f1d2342c..66937594d5 100644 --- a/src/lib/krb5/rcache/rc_base.c +++ b/src/lib/krb5/rcache/rc_base.c @@ -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; } diff --git a/src/man/kerberos.man b/src/man/kerberos.man index 026f4604ad..a109538fad 100644 --- a/src/man/kerberos.man +++ b/src/man/kerberos.man @@ -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. . diff --git a/src/man/krb5.conf.man b/src/man/krb5.conf.man index d6ff91c3be..e0bee9c431 100644 --- a/src/man/krb5.conf.man +++ b/src/man/krb5.conf.man @@ -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