diff options
author | George Joseph <george.joseph@fairview5.com> | 2014-09-10 16:04:23 +0000 |
---|---|---|
committer | George Joseph <george.joseph@fairview5.com> | 2014-09-10 16:04:23 +0000 |
commit | 43c4529f15c9d09865a9a9d05c99f7f7a2f14a10 (patch) | |
tree | a5ad3e144e6cc006139ba83d9ee0688145921d56 /main/config.c | |
parent | 8f15395e096170fa6c63b91b221cf953c00a7b04 (diff) |
config: bug: fix truncation of included config files on permissions error
ast_config_text_file_save() currently truncates include files as they
are processed. If a subsequent include file or the main config file has
a permissions error that prevents writing, earlier include files are left
truncated resulting in a frantic search for backups.
This patch causes ast_config_text_file_save to check for write access
on all files before it truncates any of them.
Will be applied 1.8 > trunk.
Tested by: George Joseph
Review: https://reviewboard.asterisk.org/r/3986/
........
Merged revisions 422900 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 422903 from http://svn.asterisk.org/svn/asterisk/branches/11
........
Merged revisions 422904 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@422905 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/config.c')
-rw-r--r-- | main/config.c | 50 |
1 files changed, 36 insertions, 14 deletions
diff --git a/main/config.c b/main/config.c index cd2e8b8eb..ab9e9c245 100644 --- a/main/config.c +++ b/main/config.c @@ -2067,21 +2067,27 @@ static void inclfile_destroy(void *obj) ast_free(o->fname); } - -static struct inclfile *set_fn(char *fn, int fn_size, const char *file, const char *configfile, struct ao2_container *fileset) +static void make_fn(char *fn, size_t fn_size, const char *file, const char *configfile) { - struct inclfile lookup; - struct inclfile *fi; - if (ast_strlen_zero(file)) { - if (configfile[0] == '/') + if (configfile[0] == '/') { ast_copy_string(fn, configfile, fn_size); - else + } else { snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, configfile); - } else if (file[0] == '/') + } + } else if (file[0] == '/') { ast_copy_string(fn, file, fn_size); - else + } else { snprintf(fn, fn_size, "%s/%s", ast_config_AST_CONFIG_DIR, file); + } +} + +static struct inclfile *set_fn(char *fn, size_t fn_size, const char *file, const char *configfile, struct ao2_container *fileset) +{ + struct inclfile lookup; + struct inclfile *fi; + + make_fn(fn, fn_size, file, configfile); lookup.fname = fn; fi = ao2_find(fileset, &lookup, OBJ_POINTER); if (fi) { @@ -2190,11 +2196,29 @@ int ast_config_text_file_save(const char *configfile, const struct ast_config *c return -1; } - /* reset all the output flags, in case this isn't our first time saving this data */ + /* Check all the files for write access before attempting to modify any of them */ for (incl = cfg->includes; incl; incl = incl->next) { + /* reset all the output flags in case this isn't our first time saving this data */ incl->output = 0; + /* now make sure we have write access */ + if (!incl->exec) { + make_fn(fn, sizeof(fn), incl->included_file, configfile); + if (access(fn, R_OK | W_OK)) { + ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno)); + return -1; + } + } } + /* now make sure we have write access to the main config file */ + make_fn(fn, sizeof(fn), 0, configfile); + if (access(fn, R_OK | W_OK)) { + ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno)); + return -1; + } + + /* Now that we know we have write access to all files, it's safe to start truncating them */ + /* go thru all the inclusions and make sure all the files involved (configfile plus all its inclusions) are all truncated to zero bytes and have that nice header*/ for (incl = cfg->includes; incl; incl = incl->next) { @@ -2206,8 +2230,7 @@ int ast_config_text_file_save(const char *configfile, const struct ast_config *c gen_header(f, configfile, fn, generator); fclose(f); /* this should zero out the file */ } else { - ast_debug(1, "Unable to open for writing: %s\n", fn); - ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno)); + ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno)); } if (fi) { ao2_ref(fi, -1); @@ -2240,8 +2263,7 @@ int ast_config_text_file_save(const char *configfile, const struct ast_config *c fi = set_fn(fn, sizeof(fn), cat->file, configfile, fileset); f = fopen(fn, "a"); if (!f) { - ast_debug(1, "Unable to open for writing: %s\n", fn); - ast_verb(2, "Unable to write %s (%s)\n", fn, strerror(errno)); + ast_log(LOG_ERROR, "Unable to write %s (%s)\n", fn, strerror(errno)); if (fi) { ao2_ref(fi, -1); } |