]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
fix issues and allow for loading of dynamic home servers at boot
authorAlan T. DeKok <aland@freeradius.org>
Sun, 19 Apr 2020 15:38:28 +0000 (11:38 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Sun, 19 Apr 2020 15:38:28 +0000 (11:38 -0400)
src/include/realms.h
src/main/realms.c

index cbbb9da4a92e930b05b490605b9b62ba29ddd33b..dcb420371e5f1927792a2ea1108097bbc109a1eb 100644 (file)
@@ -59,6 +59,7 @@ typedef struct home_server {
                                                        //!< stats or when specifying home servers for a pool.
 
        bool                    dual;                   //!< One of a pair of homeservers on consecutive ports.
+       bool                    dynamic;                //!< is this a dynamically added home server?
        char const              *server;                //!< For internal proxying
        char const              *parent_server;
 
index 1bd916c05bc23463726f67fd21f5a4241dc7e7dd..d48d1e2e65d5a60b4fd3bfb6c237e8580a582d9c 100644 (file)
@@ -37,6 +37,10 @@ static rbtree_t *realms_byname = NULL;
 bool home_servers_udp = false;
 #endif
 
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+
 #ifdef HAVE_REGEX
 typedef struct realm_regex realm_regex_t;
 
@@ -53,6 +57,9 @@ static realm_regex_t *realms_regex = NULL;
 
 struct realm_config {
        CONF_SECTION            *cs;
+#ifdef HAVE_DIRENT_H
+       char const              *directory;
+#endif
        uint32_t                dead_time;
        uint32_t                retry_count;
        uint32_t                retry_delay;
@@ -107,6 +114,10 @@ static const CONF_PARSER proxy_config[] = {
 
        { "dynamic", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, realm_config_t, dynamic), NULL },
 
+#ifdef HAVE_DIRENT_H
+       { "directory", FR_CONF_OFFSET(PW_TYPE_STRING, realm_config_t, directory), NULL },
+#endif
+
        { "dead_time", FR_CONF_OFFSET(PW_TYPE_INTEGER, realm_config_t, dead_time), STRINGIFY(DEAD_TIME)  },
 
        { "wake_all_if_all_dead", FR_CONF_OFFSET(PW_TYPE_BOOLEAN, realm_config_t, wake_all_if_all_dead), "no" },
@@ -2258,6 +2269,56 @@ int realms_init(CONF_SECTION *config)
 #endif
 
        realm_config = rc;
+
+#ifdef HAVE_DIRENT_H
+       if (!rc->dynamic) {
+               if (rc->directory) {
+                       WARN("Ignoring 'directory' as dynamic home servers were not configured.");
+               }
+       } else {
+               DIR             *dir;
+               struct dirent   *dp;
+
+               DEBUG2("including files in directory %s", rc->directory);
+
+               dir = opendir(rc->directory);
+               if (!dir) {
+                       cf_log_err_cs(config, "Error reading directory %s: %s",
+                                     rc->directory, fr_syserror(errno));                                     
+                       goto error;
+               }
+
+               /*
+                *      Read the directory, ignoring "." files.
+                */
+               while ((dp = readdir(dir)) != NULL) {
+                       char const *p;
+                       
+                       if (dp->d_name[0] == '.') continue;
+
+                       /*
+                        *      Check for valid characters
+                        */
+                       for (p = dp->d_name; *p != '\0'; p++) {
+                               if (isalpha((int)*p) ||
+                                   isdigit((int)*p) ||
+                                   (*p == '-') ||
+                                   (*p == '_') ||
+                                   (*p == '.')) continue;
+                               break;
+                       }
+                       if (*p != '\0') continue;
+               
+                       if (home_server_afrom_file(dp->d_name) < 0) {
+                               ERROR("Failed reading home_server from %s - %s",
+                                     dp->d_name, fr_strerror());
+                               goto error;
+                       }
+               }
+               closedir(dir);
+       }
+#endif
+
        return 1;
 }
 
@@ -2810,6 +2871,7 @@ int home_server_afrom_file(char const *filename)
 {
        CONF_SECTION *cs, *subcs;
        char const *p;
+       home_server_t *home;
 
        if (!realm_config->dynamic) {
                fr_strerror_printf("Must set 'dynamic' in proxy.conf for dynamic home servers to work");
@@ -2837,7 +2899,7 @@ int home_server_afrom_file(char const *filename)
 
        subcs = cf_section_sub_find_name2(cs, "home", p);
        if (!subcs) {
-               fr_strerror_printf("No 'home_server %p' definition in the file.");
+               fr_strerror_printf("No 'home_server %s' definition in the file.", p);
                talloc_free(cs);
                return -1;
        }
@@ -2878,7 +2940,7 @@ int home_server_delete(char const *name, char const *type_name)
                return -1;
        }
 
-       type = fr_str2int(home_server_types, home->type_str, HOME_TYPE_INVALID);
+       type = fr_str2int(home_server_types, type_name, HOME_TYPE_INVALID);
        if (type == HOME_TYPE_INVALID) {
                fr_strerror_printf("Unknown home_server type '%s'", type_name);
                return -1;