diff options
Diffstat (limited to 'source4/heimdal/lib/krb5/config_file.c')
-rw-r--r-- | source4/heimdal/lib/krb5/config_file.c | 53 |
1 files changed, 48 insertions, 5 deletions
diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index 75c48a001b..ee226c78a2 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -32,9 +32,6 @@ */ #include "krb5_locl.h" -RCSID("$Id$"); - -#ifndef HAVE_NETINFO /* Gaah! I want a portable funopen */ struct fileptr { @@ -302,21 +299,65 @@ krb5_config_parse_string_multi(krb5_context context, return 0; } +/** + * Parse a configuration file and add the result into res. This + * interface can be used to parse several configuration files into one + * resulting krb5_config_section by calling it repeatably. + * + * @param context a Kerberos 5 context. + * @param fname a file name to a Kerberos configuration file + * @param res the returned result, must be free with krb5_free_config_files(). + * @return Return an error code or 0, see krb5_get_error_message(). + * + * @ingroup krb5_support + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_config_parse_file_multi (krb5_context context, const char *fname, krb5_config_section **res) { const char *str; + char *newfname = NULL; unsigned lineno = 0; krb5_error_code ret; struct fileptr f; + + /** + * If the fname starts with "~/" parse configuration file in the + * current users home directory. The behavior can be disabled and + * enabled by calling krb5_set_home_dir_access(). + */ + if (_krb5_homedir_access(context) && fname[0] == '~' && fname[1] == '/') { + const char *home = NULL; + + if(!issuid()) + home = getenv("HOME"); + + if (home == NULL) { + struct passwd *pw = getpwuid(getuid()); + if(pw != NULL) + home = pw->pw_dir; + } + if (home) { + asprintf(&newfname, "%s%s", home, &fname[1]); + if (newfname == NULL) { + krb5_set_error_message(context, ENOMEM, + N_("malloc: out of memory", "")); + return ENOMEM; + } + fname = newfname; + } + } + f.f = fopen(fname, "r"); f.s = NULL; if(f.f == NULL) { ret = errno; krb5_set_error_message (context, ret, "open %s: %s", fname, strerror(ret)); + if (newfname) + free(newfname); return ret; } @@ -324,8 +365,12 @@ krb5_config_parse_file_multi (krb5_context context, fclose(f.f); if (ret) { krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str); + if (newfname) + free(newfname); return ret; } + if (newfname) + free(newfname); return 0; } @@ -338,8 +383,6 @@ krb5_config_parse_file (krb5_context context, return krb5_config_parse_file_multi(context, fname, res); } -#endif /* !HAVE_NETINFO */ - static void free_binding (krb5_context context, krb5_config_binding *b) { |