Add include/includedir directives for krb5.conf

This commit is contained in:
Nicolas Williams
2017-02-16 11:49:05 -06:00
parent 3a0d9f07a8
commit fe43be8558
6 changed files with 136 additions and 19 deletions

View File

@@ -52,7 +52,14 @@ separated from the equal sign with some whitespace). Subsections have a
other bindings are treated as variable assignments. The value of a
variable extends to the end of the line.
Configuration files can also include other files, or all files in a
directory. Use absolute paths in include directives. When including a
directoty, only files whose names consist of alphanumeric, hyphen, or
underscore characters are allowed, though they may end in '.conf'.
@example
include /some/config/file
includedir /some/config/directory
[section1]
a-subsection = @{
var = value1

View File

@@ -41,6 +41,7 @@
/* Gaah! I want a portable funopen */
struct fileptr {
krb5_context context;
const char *s;
FILE *f;
};
@@ -363,7 +364,7 @@ krb5_config_parse_debug (struct fileptr *f,
++p;
if (*p == '#' || *p == ';')
continue;
if (*p == '[') {
if (*p == '[') {
ret = parse_section(p, &s, res, err_message);
if (ret)
return ret;
@@ -371,6 +372,22 @@ krb5_config_parse_debug (struct fileptr *f,
} else if (*p == '}') {
*err_message = "unmatched }";
return KRB5_CONFIG_BADFORMAT;
} else if (strncmp(p, "include", sizeof("include") - 1) == 0 &&
isspace(p[sizeof("include") - 1])) {
p += sizeof("include");
while (isspace(*p))
p++;
ret = krb5_config_parse_file_multi(f->context, p, res);
if (ret)
return ret;
} else if (strncmp(p, "includedir", sizeof("includedir") - 1) == 0 &&
isspace(p[sizeof("includedir") - 1])) {
p += sizeof("includedir");
while (isspace(*p))
p++;
ret = krb5_config_parse_dir_multi(f->context, p, res);
if (ret)
return ret;
} else if(*p != '\0') {
if (s == NULL) {
*err_message = "binding before section";
@@ -396,6 +413,64 @@ is_plist_file(const char *fname)
return 1;
}
/**
* Parse configuration files in the given directory and add the result
* into res. Only files whose names consist only of alphanumeric
* characters, hyphen, and underscore, will be parsed, though files
* ending in ".conf" will also be parsed.
*
* This interface can be used to parse several configuration directories
* into one resulting krb5_config_section by calling it repeatably.
*
* @param context a Kerberos 5 context.
* @param dname a directory 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_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_config_parse_dir_multi(krb5_context context,
const char *dname,
krb5_config_section **res)
{
struct dirent *entry;
krb5_error_code ret;
DIR *d;
if ((d = opendir(dname)) == NULL)
return errno;
while ((entry = readdir(d)) != NULL) {
char *p = entry->d_name;
char *path;
int is_valid = 1;
while (*p) {
if (!isalpha(*p) && *p != '_' && *p != '-' &&
strcmp(p, ".conf") != 0) {
is_valid = 0;
break;
}
p++;
}
if (!is_valid)
continue;
if (asprintf(&path, "%s/%s", dname, entry->d_name) == -1 ||
path == NULL)
return krb5_enomem(context);
ret = krb5_config_parse_file_multi(context, path, res);
free(path);
if (ret == ENOMEM)
return krb5_enomem(context);;
/* Ignore malformed config files */
}
(void) closedir(d);
return 0;
}
/**
* Parse a configuration file and add the result into res. This
* interface can be used to parse several configuration files into one
@@ -420,6 +495,13 @@ krb5_config_parse_file_multi (krb5_context context,
krb5_error_code ret;
struct fileptr f;
if (context->config_include_depth > 5) {
krb5_warnx(context, "Maximum config file include depth reached; "
"not including %s", fname);
return 0;
}
context->config_include_depth++;
/**
* If the fname starts with "~/" parse configuration file in the
* current users home directory. The behavior can be disabled and
@@ -430,6 +512,7 @@ krb5_config_parse_file_multi (krb5_context context,
const char *home = NULL;
if (!_krb5_homedir_access(context)) {
context->config_include_depth--;
krb5_set_error_message(context, EPERM,
"Access to home directory not allowed");
return EPERM;
@@ -447,14 +530,18 @@ krb5_config_parse_file_multi (krb5_context context,
int aret;
aret = asprintf(&newfname, "%s%s", home, &fname[1]);
if (aret == -1 || newfname == NULL)
if (aret == -1 || newfname == NULL) {
context->config_include_depth--;
return krb5_enomem(context);
}
fname = newfname;
}
#else /* KRB5_USE_PATH_TOKENS */
if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 ||
newfname == NULL)
newfname == NULL) {
context->config_include_depth--;
return krb5_enomem(context);
}
fname = newfname;
#endif
}
@@ -462,6 +549,7 @@ krb5_config_parse_file_multi (krb5_context context,
if (is_plist_file(fname)) {
#ifdef __APPLE__
ret = parse_plist_config(context, fname, res);
context->config_include_depth--;
if (ret) {
krb5_set_error_message(context, ret,
"Failed to parse plist %s", fname);
@@ -480,6 +568,7 @@ krb5_config_parse_file_multi (krb5_context context,
ret = _krb5_expand_path_tokens(context, fname, 1, &exp_fname);
if (ret) {
context->config_include_depth--;
if (newfname)
free(newfname);
return ret;
@@ -490,9 +579,11 @@ krb5_config_parse_file_multi (krb5_context context,
fname = newfname = exp_fname;
#endif
f.context = context;
f.f = fopen(fname, "r");
f.s = NULL;
if(f.f == NULL) {
context->config_include_depth--;
ret = errno;
krb5_set_error_message (context, ret, "open %s: %s",
fname, strerror(ret));
@@ -502,6 +593,7 @@ krb5_config_parse_file_multi (krb5_context context,
}
ret = krb5_config_parse_debug (&f, res, &lineno, &str);
context->config_include_depth--;
fclose(f.f);
if (ret) {
krb5_set_error_message (context, ret, "%s:%u: %s",
@@ -1309,6 +1401,8 @@ krb5_config_parse_string_multi(krb5_context context,
unsigned lineno = 0;
krb5_error_code ret;
struct fileptr f;
f.context = context;
f.f = NULL;
f.s = string;

View File

@@ -54,6 +54,7 @@ The grammar looks like:
file:
/* empty */
sections
includes
sections:
section sections
@@ -76,10 +77,22 @@ binding:
name:
STRING
includes:
'include' path
'includedir' path
path: STRING
.Ed
.Li STRINGs
consists of one or more non-whitespace characters.
.Pp
Files and directories may be included by absolute path. Including a
directory causes all files in the directory to be included as if each
file had been included separately, but only files whose names consist of
alphanumeric, hyphen, and underscore are included, though they may also
end in '.conf'.
.Pp
STRINGs that are specified later in this man-page uses the following
notation.
.Bl -tag -width "xxx" -offset indent

View File

@@ -231,6 +231,7 @@ typedef struct krb5_context_data {
int32_t kdc_sec_offset;
int32_t kdc_usec_offset;
krb5_config_section *cf;
size_t config_include_depth;
struct et_list *et_list;
struct krb5_log_facility *warn_dest;
struct krb5_log_facility *debug_dest;

View File

@@ -0,0 +1,17 @@
[libdefaults]
default_realm = TEST.H5L.SE
no-addresses = TRUE
dns_canonicalize_hostname = false
dns_lookup_realm = false
name_canon_rules = as-is:realm=TEST.H5L.SE
name_canon_rules = qualify:domain=test.h5l.se
[domain_realms]
.test.h5l.se = TEST.H5L.SE
[kdc]
enable-digest = true
digests_allowed = ntlm-v2,ntlm-v1-session,ntlm-v1
[kadmin]
save-password = true

View File

@@ -1,26 +1,14 @@
# $Id$
include @srcdir@/include-krb5.conf
[libdefaults]
default_realm = TEST.H5L.SE
no-addresses = TRUE
default_keytab_name = @objdir@/server.keytab
dns_canonicalize_hostname = false
dns_lookup_realm = false
name_canon_rules = as-is:realm=TEST.H5L.SE
name_canon_rules = qualify:domain=test.h5l.se
[realms]
TEST.H5L.SE = {
kdc = localhost:@port@
}
[domain_realms]
.test.h5l.se = TEST.H5L.SE
[kdc]
enable-digest = true
digests_allowed = ntlm-v2,ntlm-v1-session,ntlm-v1
database = {
dbname = @objdir@/current-db
realm = TEST.H5L.SE
@@ -34,6 +22,3 @@
[logging]
kdc = 0-/FILE:@objdir@/messages.log
default = 0-/FILE:@objdir@/messages.log
[kadmin]
save-password = true