From: Greg Hudson Date: Tue, 24 Jul 2012 20:26:27 +0000 (-0400) Subject: Add token expansion for keytab names X-Git-Tag: krb5-1.11-alpha1~385 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=fc3e8c660d98b134767c574d899528dfd29d7a16;p=thirdparty%2Fkrb5.git Add token expansion for keytab names Make the default_keytab_name and default_client_keytab_name variables subject to parameter expansion. ticket: 7219 (new) --- 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 b595a6dce8..d9c3ffbd75 100644 --- a/doc/rst_source/krb_admins/conf_files/krb5_conf.rst +++ b/doc/rst_source/krb_admins/conf_files/krb5_conf.rst @@ -136,12 +136,13 @@ The libdefaults section may contain any of the following relations: **default_client_keytab_name** This relation specifies the name of the default keytab for - obtaining client credentials. The default is |clkeytab|. + obtaining client credentials. The default is |clkeytab|. This + relation is subject to parameter expansion (see below). **default_keytab_name** This relation specifies the default keytab name to be used by - application servers such as telnetd and rlogind. The default is - |keytab|. + application servers such as sshd. The default is |keytab|. This + relation is subject to parameter expansion (see below). **default_realm** Identifies the default Kerberos realm for the client. Set its @@ -968,6 +969,33 @@ PKINIT krb5.conf options The default is false. +.. _parameter_expansion: + +Parameter expansion +------------------- + +Several variables, such as **default_keytab_name**, allow parameters +to be expanded. Valid parameters are: + + ================= =================================================== + %{TEMP} Temporary directory + %{uid} Unix real UID or Windows SID + %{euid} Unix effective user ID or Windows SID + %{USERID} Same as %{uid} + %{null} Empty string + %{LIBDIR} Installation library directory + %{BINDIR} Installation binary directory + %{SBINDIR} Installation admin binary directory + %{APPDATA} (Windows) Roaming application data for current user + %{COMMON_APPDATA} (Windows) Application data for all users + %{LOCAL_APPDATA} (Windows) Local application data for current user + %{SYSTEM} (Windows) Windows system folder + %{WINDOWS} (Windows) Windows folder + %{USERCONFIG} (Windows) Per-user MIT krb5 config file directory + %{COMMONCONFIG} (Windows) Common MIT krb5 config file directory + ================ =================================================== + + Sample krb5.conf file --------------------- diff --git a/src/include/osconf.hin b/src/include/osconf.hin index 3f33cc3bc3..803d73bd55 100644 --- a/src/include/osconf.hin +++ b/src/include/osconf.hin @@ -42,8 +42,8 @@ #if defined(_WIN32) #define DEFAULT_PROFILE_FILENAME "krb5.ini" -#define DEFAULT_KEYTAB_NAME "FILE:%s\\krb5kt" -#define DEFAULT_CLIENT_KEYTAB_NAME "FILE:%s\\krb5clientkt" +#define DEFAULT_KEYTAB_NAME "FILE:%{WINDOWS}\\krb5kt" +#define DEFAULT_CLIENT_KEYTAB_NAME "FILE:%{WINDOWS}\\krb5clientkt" #else /* !_WINDOWS */ #if TARGET_OS_MAC #define DEFAULT_SECURE_PROFILE_PATH "/Library/Preferences/edu.mit.Kerberos:/etc/krb5.conf:@SYSCONFDIR/krb5.conf" diff --git a/src/lib/krb5/os/ktdefname.c b/src/lib/krb5/os/ktdefname.c index a213750dba..93b28dd38c 100644 --- a/src/lib/krb5/os/ktdefname.c +++ b/src/lib/krb5/os/ktdefname.c @@ -27,83 +27,71 @@ #define NEED_WINDOWS #include "k5-int.h" +#include "os-proto.h" extern char *krb5_defkeyname; /* this is a an exceedinly gross thing. */ char *krb5_overridekeyname = NULL; -krb5_error_code KRB5_CALLCONV -krb5_kt_default_name(krb5_context context, char *name, int name_size) +static krb5_error_code +kt_default_name(krb5_context context, char **name_out) { - char *cp = 0; - char *retval; - unsigned int namesize = (name_size < 0 ? 0 : name_size); + krb5_error_code ret; + char *str; - if (krb5_overridekeyname) { - if (strlcpy(name, krb5_overridekeyname, namesize) >= namesize) - return KRB5_CONFIG_NOTENUFSPACE; - } else if ((context->profile_secure == FALSE) && - (cp = getenv("KRB5_KTNAME"))) { - if (strlcpy(name, cp, namesize) >= namesize) - return KRB5_CONFIG_NOTENUFSPACE; - } else if ((profile_get_string(context->profile, - KRB5_CONF_LIBDEFAULTS, - KRB5_CONF_DEFAULT_KEYTAB_NAME, NULL, - NULL, &retval) == 0) && - retval) { - if (strlcpy(name, retval, namesize) >= namesize) - return KRB5_CONFIG_NOTENUFSPACE; - profile_release_string(retval); + if (krb5_overridekeyname != NULL) { + *name_out = strdup(krb5_overridekeyname); + return (*name_out == NULL) ? ENOMEM : 0; + } else if (context->profile_secure == FALSE && + (str = getenv("KRB5_KTNAME")) != NULL) { + *name_out = strdup(str); + return (*name_out == NULL) ? ENOMEM : 0; + } else if (profile_get_string(context->profile, KRB5_CONF_LIBDEFAULTS, + KRB5_CONF_DEFAULT_KEYTAB_NAME, NULL, NULL, + &str) == 0 && str != NULL) { + ret = k5_expand_path_tokens(context, str, name_out); + profile_release_string(str); + return ret; } else { -#if defined(_WIN32) - { - char defname[160]; - int len; - - len= GetWindowsDirectory( defname, sizeof(defname)-2 ); - defname[len]= '\0'; - if ( (len + strlen(krb5_defkeyname) + 1) > namesize ) - return KRB5_CONFIG_NOTENUFSPACE; - snprintf(name, namesize, krb5_defkeyname, defname); - } -#else - if (strlcpy(name, krb5_defkeyname, namesize) >= namesize) - return KRB5_CONFIG_NOTENUFSPACE; -#endif + return k5_expand_path_tokens(context, krb5_defkeyname, name_out); } - return 0; } krb5_error_code k5_kt_client_default_name(krb5_context context, char **name_out) { - char *str, *name; + krb5_error_code ret; + char *str; - *name_out = NULL; - if (!context->profile_secure && + if (context->profile_secure == FALSE && (str = getenv("KRB5_CLIENT_KTNAME")) != NULL) { - name = strdup(str); + *name_out = strdup(str); + return (*name_out == NULL) ? ENOMEM : 0; } 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); + ret = k5_expand_path_tokens(context, str, name_out); profile_release_string(str); + return ret; } 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 + return k5_expand_path_tokens(context, DEFAULT_CLIENT_KEYTAB_NAME, + name_out); } - if (name == NULL) - return ENOMEM; - *name_out = name; - return 0; +} + +krb5_error_code KRB5_CALLCONV +krb5_kt_default_name(krb5_context context, char *name, int name_size) +{ + krb5_error_code ret; + unsigned int namesize = (name_size < 0 ? 0 : name_size); + char *ktname; + + ret = kt_default_name(context, &ktname); + if (ret) + return ret; + if (strlcpy(name, ktname, namesize) >= namesize) + ret = KRB5_CONFIG_NOTENUFSPACE; + free(ktname); + return ret; } diff --git a/src/tests/t_keytab.py b/src/tests/t_keytab.py index 8d73636c8d..f8cea68d40 100644 --- a/src/tests/t_keytab.py +++ b/src/tests/t_keytab.py @@ -40,4 +40,20 @@ output = realm.run_kadminl('getprinc %s' % princ) if 'Key: vno 258,' not in output: fail('Expected vno not seen in kadmin.local output') +# Test parameter expansion in profile variables +realm.stop() +conf = {'client': {'libdefaults': { + 'default_keytab_name': 'testdir/%{null}abc%{uid}', + 'default_client_keytab_name': 'testdir/%{null}xyz%{uid}'}}} +realm = K5Realm(krb5_conf=conf, create_kdb=False) +del realm.env_client['KRB5_KTNAME'] +del realm.env_client['KRB5_CLIENT_KTNAME'] +uidstr = str(os.getuid()) +out = realm.run_as_client([klist, '-k'], expected_code=1) +if 'FILE:testdir/abc%s' % uidstr not in out: + fail('Wrong keytab in klist -k output') +out = realm.run_as_client([klist, '-ki'], expected_code=1) +if 'FILE:testdir/xyz%s' % uidstr not in out: + fail('Wrong keytab in klist -ki output') + success('Keytab-related tests')