From 611c43e537de16193c8a74348f2e616ef3f3444f Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Tue, 27 Dec 2022 08:15:38 +0000 Subject: [PATCH] Dynsec: Save file at end of command batch, not after each command --- plugins/dynamic-security/clients.c | 20 ++++++++++---------- plugins/dynamic-security/config.c | 6 ++++++ plugins/dynamic-security/control.c | 9 ++++++++- plugins/dynamic-security/default_acl.c | 2 +- plugins/dynamic-security/dynamic_security.h | 2 ++ plugins/dynamic-security/groups.c | 16 ++++++++-------- plugins/dynamic-security/roles.c | 10 +++++----- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/plugins/dynamic-security/clients.c b/plugins/dynamic-security/clients.c index 257adee4..83fc9f96 100644 --- a/plugins/dynamic-security/clients.c +++ b/plugins/dynamic-security/clients.c @@ -454,7 +454,7 @@ int dynsec_clients__process_create(struct dynsec__data *data, struct plugin_cmd } } - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); @@ -483,7 +483,7 @@ int dynsec_clients__process_delete(struct dynsec__data *data, struct plugin_cmd dynsec__remove_client_from_all_groups(data, username); client__remove_all_roles(client); client__free_item(data, client); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -526,7 +526,7 @@ int dynsec_clients__process_disable(struct dynsec__data *data, struct plugin_cmd dynsec_kicklist__add(data, username); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); admin_clientid = mosquitto_client_id(context); @@ -561,7 +561,7 @@ int dynsec_clients__process_enable(struct dynsec__data *data, struct plugin_cmd client->disabled = false; - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); admin_clientid = mosquitto_client_id(context); @@ -620,7 +620,7 @@ int dynsec_clients__process_set_id(struct dynsec__data *data, struct plugin_cmd mosquitto_free(client->clientid); client->clientid = clientid_heap; - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -680,7 +680,7 @@ int dynsec_clients__process_set_password(struct dynsec__data *data, struct plugi } rc = client__set_password(client, password); if(rc == MOSQ_ERR_SUCCESS){ - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -849,7 +849,7 @@ int dynsec_clients__process_modify(struct dynsec__data *data, struct plugin_cmd * *now* will mean the client can log in again. This might be * "good", but is inconsistent, so save the config to be * consistent. */ - dynsec__config_save(data); + dynsec__config_batch_save(data); rc = MOSQ_ERR_NOMEM; goto error; } @@ -876,7 +876,7 @@ int dynsec_clients__process_modify(struct dynsec__data *data, struct plugin_cmd dynsec_rolelist__cleanup(&rolelist); } - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -1172,7 +1172,7 @@ int dynsec_clients__process_add_role(struct dynsec__data *data, struct plugin_cm plugin__command_reply(cmd, "Internal error"); return MOSQ_ERR_UNKNOWN; } - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -1226,7 +1226,7 @@ int dynsec_clients__process_remove_role(struct dynsec__data *data, struct plugin } dynsec_rolelist__client_remove(client, role); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ diff --git a/plugins/dynamic-security/config.c b/plugins/dynamic-security/config.c index b89caf27..0192b9b6 100644 --- a/plugins/dynamic-security/config.c +++ b/plugins/dynamic-security/config.c @@ -200,7 +200,13 @@ int dynsec__write_json_config(FILE* fptr, void* user_data) return rc; } +void dynsec__config_batch_save(struct dynsec__data *data) +{ + data->need_save = true; +} + void dynsec__config_save(struct dynsec__data *data) { + data->need_save = false; mosquitto_write_file(data->config_file, true, &dynsec__write_json_config, data, &dynsec__log_write_error); } diff --git a/plugins/dynamic-security/control.c b/plugins/dynamic-security/control.c index e0c68d3c..49aa6360 100644 --- a/plugins/dynamic-security/control.c +++ b/plugins/dynamic-security/control.c @@ -123,8 +123,15 @@ static int dynsec__handle_command(struct plugin_cmd *cmd, struct mosquitto *cont int dynsec_control_callback(int event, void *event_data, void *userdata) { struct mosquitto_evt_control *ed = event_data; + struct dynsec__data *data = userdata; + int rc; UNUSED(event); - return plugin__generic_control_callback(ed, RESPONSE_TOPIC, userdata, dynsec__handle_command); + data->need_save = false; + rc = plugin__generic_control_callback(ed, RESPONSE_TOPIC, userdata, dynsec__handle_command); + if(rc == MOSQ_ERR_SUCCESS && data->need_save){ + dynsec__config_save(data); + } + return rc; } diff --git a/plugins/dynamic-security/default_acl.c b/plugins/dynamic-security/default_acl.c index 042e36f1..c4ba67b0 100644 --- a/plugins/dynamic-security/default_acl.c +++ b/plugins/dynamic-security/default_acl.c @@ -71,7 +71,7 @@ int dynsec__process_set_default_acl_access(struct dynsec__data *data, struct plu } } - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); return MOSQ_ERR_SUCCESS; } diff --git a/plugins/dynamic-security/dynamic_security.h b/plugins/dynamic-security/dynamic_security.h index 36483bc1..fd1396d5 100644 --- a/plugins/dynamic-security/dynamic_security.h +++ b/plugins/dynamic-security/dynamic_security.h @@ -152,6 +152,7 @@ struct dynsec__data{ struct dynsec__kicklist *kicklist; struct dynsec__acl_default_access default_access; int init_mode; + bool need_save; }; /* ################################################################ @@ -162,6 +163,7 @@ struct dynsec__data{ int dynsec__config_init(struct dynsec__data *data); void dynsec__config_save(struct dynsec__data *data); +void dynsec__config_batch_save(struct dynsec__data *data); int dynsec__config_load(struct dynsec__data *data); char *dynsec__config_to_json(struct dynsec__data *data); int dynsec__config_from_json(struct dynsec__data *data, const char *json_str); diff --git a/plugins/dynamic-security/groups.c b/plugins/dynamic-security/groups.c index 7b81495c..37471285 100644 --- a/plugins/dynamic-security/groups.c +++ b/plugins/dynamic-security/groups.c @@ -159,7 +159,7 @@ int dynsec_groups__process_add_role(struct dynsec__data *data, struct plugin_cmd mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | addGroupRole | groupname=%s | rolename=%s | priority=%d", admin_clientid, admin_username, groupname, rolename, priority); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -436,7 +436,7 @@ int dynsec_groups__process_create(struct dynsec__data *data, struct plugin_cmd * mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | createGroup | groupname=%s", admin_clientid, admin_username, groupname); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); return MOSQ_ERR_SUCCESS; } @@ -469,7 +469,7 @@ int dynsec_groups__process_delete(struct dynsec__data *data, struct plugin_cmd * dynsec__remove_all_roles_from_group(group); group__free_item(data, group); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); admin_clientid = mosquitto_client_id(context); @@ -519,7 +519,7 @@ int dynsec_groups__add_client(struct dynsec__data *data, const char *username, c } if(update_config){ - dynsec__config_save(data); + dynsec__config_batch_save(data); } return MOSQ_ERR_SUCCESS; @@ -623,7 +623,7 @@ int dynsec_groups__remove_client(struct dynsec__data *data, const char *username dynsec_grouplist__remove(&client->grouplist, group); if(update_config){ - dynsec__config_save(data); + dynsec__config_batch_save(data); } return MOSQ_ERR_SUCCESS; } @@ -892,7 +892,7 @@ int dynsec_groups__process_remove_role(struct dynsec__data *data, struct plugin_ } dynsec_rolelist__group_remove(group, role); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ @@ -1031,7 +1031,7 @@ int dynsec_groups__process_modify(struct dynsec__data *data, struct plugin_cmd * } /* And save */ - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); @@ -1081,7 +1081,7 @@ int dynsec_groups__process_set_anonymous_group(struct dynsec__data *data, struct data->anonymous_group = group; - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); /* Enforce any changes */ diff --git a/plugins/dynamic-security/roles.c b/plugins/dynamic-security/roles.c index d69be20d..f3414570 100644 --- a/plugins/dynamic-security/roles.c +++ b/plugins/dynamic-security/roles.c @@ -421,7 +421,7 @@ int dynsec_roles__process_create(struct dynsec__data *data, struct plugin_cmd *c HASH_ADD_INORDER(hh, data->roles, rolename, rolename_len, role, role_cmp); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); @@ -484,7 +484,7 @@ int dynsec_roles__process_delete(struct dynsec__data *data, struct plugin_cmd *c role__remove_all_clients(data, role); role__remove_all_groups(data, role); role__free_item(data, role, true); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); admin_clientid = mosquitto_client_id(context); @@ -675,7 +675,7 @@ int dynsec_roles__process_add_acl(struct dynsec__data *data, struct plugin_cmd * json_get_bool(cmd->j_command, "allow", &acl->allow, true, false); HASH_ADD_INORDER(hh, *acllist, topic, topic_len, acl, insert_acl_cmp); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); role__kick_all(data, role); @@ -753,7 +753,7 @@ int dynsec_roles__process_remove_acl(struct dynsec__data *data, struct plugin_cm HASH_FIND(hh, *acllist, topic, strlen(topic), acl); if(acl){ role__free_acl(acllist, acl); - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL); role__kick_all(data, role); @@ -924,7 +924,7 @@ int dynsec_roles__process_modify(struct dynsec__data *data, struct plugin_cmd *c if(do_kick){ role__kick_all(data, role); } - dynsec__config_save(data); + dynsec__config_batch_save(data); plugin__command_reply(cmd, NULL);