From 3ab0a9a3fd0a07ea93ba937d8d4da236d32548ee Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Mon, 10 Jul 2023 00:01:10 +0100 Subject: [PATCH] mosquitto_ctrl dynsec init uses open( , O_EXCL | O_CREAT) This allows us to refuse to open an existing file, without a race condition. --- ChangeLog.txt | 2 ++ apps/mosquitto_ctrl/dynsec.c | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 93f8503c..df350ed2 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -48,6 +48,8 @@ Clients: Apps: - mosquitto_passwd uses mkstemp() for backup files. +- `mosquitto_ctrl dynsec init` will refuse to overwrite an existing file, + without a race-condition. 2.0.15 - 2022-08-16 diff --git a/apps/mosquitto_ctrl/dynsec.c b/apps/mosquitto_ctrl/dynsec.c index 8e5dd726..929217af 100644 --- a/apps/mosquitto_ctrl/dynsec.c +++ b/apps/mosquitto_ctrl/dynsec.c @@ -23,6 +23,8 @@ Contributors: #include #ifndef WIN32 +# include +# include # include #endif @@ -739,13 +741,6 @@ static int dynsec_init(int argc, char *argv[]) admin_password = password; } - fptr = mosquitto__fopen(filename, "rb", true); - if(fptr){ - fclose(fptr); - fprintf(stderr, "dynsec init: '%s' already exists. Remove the file or use a different location..\n", filename); - return -1; - } - tree = init_create(admin_user, admin_password, "admin"); if(tree == NULL){ fprintf(stderr, "dynsec init: Out of memory.\n"); @@ -754,7 +749,17 @@ static int dynsec_init(int argc, char *argv[]) json_str = cJSON_Print(tree); cJSON_Delete(tree); +#ifdef WIN32 fptr = mosquitto__fopen(filename, "wb", true); +#else + int fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, 0640); + if(fd < 0){ + free(json_str); + fprintf(stderr, "dynsec init: Unable to open '%s' for writing (%s).\n", filename, strerror(errno)); + return -1; + } + fptr = fdopen(fd, "wb"); +#endif if(fptr){ fprintf(fptr, "%s", json_str); free(json_str);