[RFC ] include with wildcard filenames

Bill Shirley bill at c3po.polymerindustries.biz
Wed Feb 28 08:52:29 UTC 2018


This sounds like the wrong approach to addressing your problem because
for dhcpd to honor the new configuration, it would need to be restarted every
time a file is added/deleted/changed in the wildcard directory.

This sounds more like a task for iptables and ipsets.

Are all four of these private networks on the same NIC?  Are these subnets
VLANs?

As far as I know, there is no mechanism to consult an source external to the
dhcpd program for information.

Bill

On 2/27/2018 5:33 PM, Ulf Samuelsson wrote:
> I was trying out a dhcpd configuration, and found to my dismay
> that the DHCP server did not support wildcards for include statements.
> include "/etc/dhcp/pools/*.conf";
> did not work.
>
> BACKGROUND:
>
> I have an application, where I want to use the DHCP server
> as part of the authentication process for connected machines.
>
> I want to use three ranges.
> pool 0 => 169.254.128.x            trusted units
> pool 1 => 169.254.254.x            units demanding to be trusted
> pool 2 => 169.254.1.x              normal units
> pool 3 => 169.254.253.x            untrusted units/intruders
>
> The DHCP CPU Ethernet Controller communicates through a five port switch.
> port 0: trusted units    pool 0
> port 2: internet port
> port 3: service port
> port 4: CPU port    169.254.1.1
>
> Units connected on port 0, provides a dhcp-client-identifier indicating that they want an address in pool 0, but initially 
> they will get a short term lease in pool 1, until it is verified that they are on port 0.
>
> Units without this dhcp-client-identifier, should get an address in pool 2.
>
> An intruder, trying to get a pool 0 address, will supply the same dhcp-client-identifier as port 0 units. They will also 
> initially get a short term pool 1 address, but when the intrusion attempt is detected, they should be declared "untrusted". 
> Future leases should be in pool 3.
>
> =====
> When a pool 1 address is allocated, the commit event is used to run a script which will read out information from the switch 
> and determine if the request comes from port 0.
>
> Request comes from (port == 0) => the mac address should be "trusted"
> Request comes from (port != 0) => the mac address should be "untrusted".
>
> I define:
> class "trusted" {
>     match hardware;
> }
>
> class "untrusted" {
>     match hardware;
> }
>
> An incoming request from "00:11:22:33:44:55" adds a file:
> /etc/dhcp/trusted/00:11:22:33:44:55:
>       sub-class "trusted" 1:00:11:22:33:44:55;
> or
> /etc/dhcp/untrusted/00:11:22:33:44:55:
>       sub-class "trusted" 1:00:11:22:33:44:55;
>
>
> When the short term pool 1 lease expires (after 1-2 minutes)
> the new lease will be classified either as "trusted" (getting a pool 0 lease) or "untrusted" (getting a pool 3 lease).
>
> It would be practical to have the dhcpd.conf file contain:
>
> include "/etc/dhcp/trusted/*";
> include "/etc/dhcp/untrusted/*";
>
> but unfortunately wildcards in include statements are not supported.
>
> ====================================
>
> I did a patch for dhcp-4.3.6 which is slightly limited.
> It supports only wildcards on files within a single directory.
> I.E: include "/etc/dhcp/pools/*.conf"; is supported
> I.E: include "/etc/dhcp/*/dhcp.conf"; is not supported
> The wildcard may not be in a directory.
>
> Did a small test program which tested the functionality of wildcards,
> and then patched the dhcp server, but it has not been tested yet, as part of dhcp
> Still would like to have peoples opinion, whether this type of functionality is desirable.
> It is certainly possible to do this without wildcards,
> but wildcards seems a much cleaner solution.
> ====================================
>
> From dcc981f1371f390befffc950b9dc3a8107059643 Mon Sep 17 00:00:00 2001
> From: Ulf Samuelsson <ulf at emagii.com>
> Date: Tue, 27 Feb 2018 21:03:52 +0100
> Subject: [PATCH 14/14] Support wildcard in include files
>
> Signed-off-by: Ulf Samuelsson <ulf at emagii.com>
> ---
>  includes/dhcpd.h  |  3 +++
>  server/confpars.c | 71 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
>  2 files changed, 72 insertions(+), 2 deletions(-)
>
> diff --git a/includes/dhcpd.h b/includes/dhcpd.h
> index eab09a6..8208fbe 100644
> --- a/includes/dhcpd.h
> +++ b/includes/dhcpd.h
> @@ -53,6 +53,9 @@
>  #include <sys/mman.h>
>  #include <ctype.h>
>  #include <time.h>
> +#include <dirent.h>
> +#include <libgen.h>
> +#include <fnmatch.h>
>
>  #include <net/if.h>
>  #undef FDDI
> diff --git a/server/confpars.c b/server/confpars.c
> index c0735fe..c12f5c7 100644
> --- a/server/confpars.c
> +++ b/server/confpars.c
> @@ -327,7 +327,7 @@ isc_result_t lease_file_subparse (struct parse *cfile)
>     parameter :== DEFAULT_LEASE_TIME lease_time
>             | MAX_LEASE_TIME lease_time
>             | DYNAMIC_BOOTP_LEASE_CUTOFF date
> -           | DYNAMIC_BOOTP_LEASE_LENGTH lease_time
> +           | DYNAMIC_BOOTP_LEASE_LENGTH l#include <string.h>ease_time
>             | BOOT_UNKNOWN_CLIENTS boolean
>             | ONE_LEASE_PER_CLIENT boolean
>             | GET_LEASE_HOSTNAMES boolean
> @@ -352,6 +352,73 @@ isc_result_t lease_file_subparse (struct parse *cfile)
>           | VENDOR_CLASS class-declaration
>           | USER_CLASS class-declaration
>           | RANGE address-range-declaration */
> +#include <string.h>
> +isc_result_t read_multiple_conf_files(path, group, type)
> +    const char *path;
> +    struct group *group;
> +    int type;
> +{
> +    char    *buf_dir;
> +    char    *dir;
> +    char    *buf_base;
> +    char    *base;
> +    DIR    *d;
> +    struct    dirent *entry;
> +    int reti;
> +    isc_result_t status;
> +
> +    dir    = dirname (buf_dir    = strdup(path));
> +    base    = basename(buf_base    = strdup(path));
> +
> +    if (!(d = opendir(dir))) {
> +        status = DHCP_R_INVALIDARG;
> +        goto    exit;
> +    }
> +
> +    while ((entry = readdir(d)) != NULL) {
> +        if (entry->d_type == DT_DIR) {
> +            continue;
> +        } else {
> +            reti = fnmatch(base, entry->d_name, 0);
> +            if (reti == 0) {
> +                status = read_conf_file (path, group, type, 0);
> +                if (status != ISC_R_SUCCESS) {
> +                    goto exit;
> +                }
> +            } else {
> +                continue;
> +            }
> +        }
> +    }
> +    closedir(d);
> +exit:
> +    free(buf_dir);
> +    free(buf_base);
> +    return status;
> +}
> +
> +isc_result_t include_files(path, group, type)
> +    const char *path;
> +    struct group *group;
> +    int type;
> +{
> +    const char    *eos;
> +    const char    *wildcard = strchr(path, '*');
> +    char    *p;
> +
> +    if (wildcard == NULL) {
> +        return read_conf_file (path, group, type, 0);
> +    }
> +
> +    eos = &path[strlen(path)];
> +    for (wildcard++; wildcard < eos; wildcard++) {
> +        if (*wildcard == '/') {
> +            /* wildcard in directory, not allowed */
> +            return DHCP_R_INVALIDARG;
> +        }
> +    }
> +    return read_multiple_conf_files(path, group, type);
> +}
>
>  int parse_statement (cfile, group, type, host_decl, declaration)
>      struct parse *cfile;
> @@ -383,7 +450,7 @@ int parse_statement (cfile, group, type, host_decl, declaration)
>              parse_warn (cfile, "filename string expected.");
>              skip_to_semi (cfile);
>          } else {
> -            status = read_conf_file (val, group, type, 0);
> +            status = include_files(val, group, type);
>              if (status != ISC_R_SUCCESS)
>                  parse_warn (cfile, "%s: bad parse.", val);
>              parse_semi (cfile);



More information about the dhcp-users mailing list