s3:loadparm: prevent infinite include nesting.
authorMichael Adam <obnox@samba.org>
Mon, 27 Apr 2009 16:10:14 +0000 (18:10 +0200)
committerMichael Adam <obnox@samba.org>
Tue, 28 Apr 2009 10:20:38 +0000 (12:20 +0200)
This introduces a hard coded MAX_INCLUDE_DEPTH of 100.
When this is exceeded, handle_include (and hence lp_load) fails.

One could of course implement a more intelligent loop detection
in the include-tree, but this would require some restructuring
of the internal loadparm housekeeping. Maybe as a second improvement
step.

Michael

source3/param/loadparm.c

index b7c34d0028407cf11d632105e25789e94f90b54a..7e2affed082a3a4d70124d1bffc840646d3b41e6 100644 (file)
@@ -6908,6 +6908,10 @@ done:
        return ret;
 }
 
+#define MAX_INCLUDE_DEPTH 100
+
+static uint8_t include_depth;
+
 static struct file_lists {
        struct file_lists *next;
        char *name;
@@ -7095,12 +7099,22 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
 {
        char *fname;
 
+       if (include_depth >= MAX_INCLUDE_DEPTH) {
+               DEBUG(0, ("Error: Maximum include depth (%u) exceeded!\n",
+                         include_depth));
+               return false;
+       }
+
        if (strequal(pszParmValue, INCLUDE_REGISTRY_NAME)) {
                if (!bAllowIncludeRegistry) {
                        return true;
                }
                if (bInGlobalSection) {
-                       return process_registry_globals();
+                       bool ret;
+                       include_depth++;
+                       ret = process_registry_globals();
+                       include_depth--;
+                       return ret;
                } else {
                        DEBUG(1, ("\"include = registry\" only effective "
                                  "in %s section\n", GLOBAL_NAME));
@@ -7117,7 +7131,10 @@ static bool handle_include(int snum, const char *pszParmValue, char **ptr)
        string_set(ptr, fname);
 
        if (file_exist(fname)) {
-               bool ret = pm_process(fname, do_section, do_parameter, NULL);
+               bool ret;
+               include_depth++;
+               ret = pm_process(fname, do_section, do_parameter, NULL);
+               include_depth--;
                SAFE_FREE(fname);
                return ret;
        }