Add new option to asterisk.conf (lockconfdir) to protect conf dir during reloads
authorJeff Peeler <jpeeler@digium.com>
Wed, 27 Jan 2010 18:29:49 +0000 (18:29 +0000)
committerJeff Peeler <jpeeler@digium.com>
Wed, 27 Jan 2010 18:29:49 +0000 (18:29 +0000)
(closes issue #16358)
Reported by: raarts
Patches:
      lockconfdir.diff uploaded by raarts (license 937)
      modified by me

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@243551 65c4cc65-6c06-0410-ace0-fbb531ad65f3

CHANGES
Makefile
include/asterisk/options.h
main/asterisk.c
main/loader.c

diff --git a/CHANGES b/CHANGES
index 60504e7..ca811ca 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -389,6 +389,8 @@ Miscellaneous
  * An 'X' option has been added to the asterisk application which enables #exec support.
    This allows #exec to be used in asterisk.conf.
  * jabber.conf supports a new option auth_policy that toggles auto user registration.
+ * A new lockconfdir option has been added to asterisk.conf to protect the
+   AST_CONFIG_DIR during reloads.
 
 ------------------------------------------------------------------------------
 --- Functionality changes from Asterisk 1.6.1 to Asterisk 1.6.2  -------------
index a198d7a..a252101 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -743,6 +743,7 @@ samples: adsi
                echo ";lightbackground = yes ; If your terminal is set for a light-colored background" ; \
                echo "documentation_language = en_US ; Set the Language you want Documentation displayed in. Value is in the same format as locale names" ; \
                echo ";hideconnect = yes ; Hide messages displayed when a remote console connects and disconnects" ; \
+               echo ";lockconfdir = no ; Protect the directory containing the configuration files (/etc/asterisk) with a lock" ; \
                echo "" ; \
                echo "; Changing the following lines may compromise your security." ; \
                echo ";[files]" ; \
index 065d0c9..d3305be 100644 (file)
@@ -90,6 +90,8 @@ enum ast_option_flags {
        AST_OPT_FLAG_FORCE_BLACK_BACKGROUND = (1 << 27),
        /*! Hide remote console connect messages on console */
        AST_OPT_FLAG_HIDE_CONSOLE_CONNECT = (1 << 28),
+       /*! Protect the configuration file path with a lock */
+       AST_OPT_FLAG_LOCK_CONFIG_DIR = (1 << 29),
 };
 
 /*! These are the options that set by default when Asterisk starts */
@@ -122,6 +124,7 @@ enum ast_option_flags {
 #define ast_opt_light_background               ast_test_flag(&ast_options, AST_OPT_FLAG_LIGHT_BACKGROUND)
 #define ast_opt_force_black_background         ast_test_flag(&ast_options, AST_OPT_FLAG_FORCE_BLACK_BACKGROUND)
 #define ast_opt_hide_connect           ast_test_flag(&ast_options, AST_OPT_FLAG_HIDE_CONSOLE_CONNECT)
+#define ast_opt_lock_confdir           ast_test_flag(&ast_options, AST_OPT_FLAG_LOCK_CONFIG_DIR)
 
 extern struct ast_flags ast_options;
 
index 5ccfd20..4b691d8 100644 (file)
@@ -2997,6 +2997,8 @@ static void ast_readconfig(void)
                        ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_FORCE_BLACK_BACKGROUND);
                } else if (!strcasecmp(v->name, "hideconnect")) {
                        ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_HIDE_CONSOLE_CONNECT);
+               } else if (!strcasecmp(v->name, "lockconfdir")) {
+                       ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_LOCK_CONFIG_DIR);
                }
        }
        for (v = ast_variable_browse(cfg, "compat"); v; v = v->next) {
index 8c0067d..99c9f12 100644 (file)
@@ -49,6 +49,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/dsp.h"
 #include "asterisk/udptl.h"
 #include "asterisk/heap.h"
+#include "asterisk/app.h"
 
 #include <dlfcn.h>
 
@@ -652,6 +653,22 @@ int ast_module_reload(const char *name)
        }
        ast_lastreloadtime = ast_tvnow();
 
+       if (ast_opt_lock_confdir) {
+               int try;
+               int res;
+               for (try = 1, res = AST_LOCK_TIMEOUT; try < 6 && (res == AST_LOCK_TIMEOUT); try++) {
+                       res = ast_lock_path(ast_config_AST_CONFIG_DIR);
+                       if (res == AST_LOCK_TIMEOUT) {
+                               ast_log(LOG_WARNING, "Failed to grab lock on %s, try %d\n", ast_config_AST_CONFIG_DIR, try);
+                       }
+               }
+               if (res != AST_LOCK_SUCCESS) {
+                       ast_verbose("Cannot grab lock on %s\n", ast_config_AST_CONFIG_DIR);
+                       ast_mutex_unlock(&reloadlock);
+                       return -1;
+               }
+       }
+
        /* Call "predefined" reload here first */
        for (i = 0; reload_classes[i].name; i++) {
                if (!name || !strcasecmp(name, reload_classes[i].name)) {
@@ -661,6 +678,9 @@ int ast_module_reload(const char *name)
        }
 
        if (name && res) {
+               if (ast_opt_lock_confdir) {
+                       ast_unlock_path(ast_config_AST_CONFIG_DIR);
+               }
                ast_mutex_unlock(&reloadlock);
                return res;
        }
@@ -695,6 +715,9 @@ int ast_module_reload(const char *name)
        }
        AST_LIST_UNLOCK(&module_list);
 
+       if (ast_opt_lock_confdir) {
+               ast_unlock_path(ast_config_AST_CONFIG_DIR);
+       }
        ast_mutex_unlock(&reloadlock);
 
        return res;