From 6739152fda997efa85b5c6f38fc28d9f95349a08 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Fri, 27 Nov 2020 14:34:46 +0000 Subject: [PATCH] dynsec: Various minor fixes. --- plugins/dynamic-security/clients.c | 63 +++++++++++++++++------------ plugins/dynamic-security/rolelist.c | 28 +++++++------ 2 files changed, 54 insertions(+), 37 deletions(-) diff --git a/plugins/dynamic-security/clients.c b/plugins/dynamic-security/clients.c index 5ab3f38c..08dfe13b 100644 --- a/plugins/dynamic-security/clients.c +++ b/plugins/dynamic-security/clients.c @@ -57,20 +57,6 @@ static int client_cmp(void *a, void *b) return strcmp(client_a->username, client_b->username); } -static void client__free_item(struct dynsec__client *client) -{ - if(client == NULL) return; - - HASH_DEL(local_clients, client); - dynsec_rolelist__cleanup(&client->rolelist); - dynsec__remove_client_from_all_groups(client->username); - mosquitto_free(client->text_name); - mosquitto_free(client->text_description); - mosquitto_free(client->clientid); - mosquitto_free(client->username); - mosquitto_free(client); -} - struct dynsec__client *dynsec_clients__find(const char *username) { struct dynsec__client *client = NULL; @@ -82,6 +68,24 @@ struct dynsec__client *dynsec_clients__find(const char *username) } +static void client__free_item(struct dynsec__client *client) +{ + struct dynsec__client *client_found; + if(client == NULL) return; + + client_found = dynsec_clients__find(client->username); + if(client_found){ + HASH_DEL(local_clients, client_found); + } + dynsec_rolelist__cleanup(&client->rolelist); + dynsec__remove_client_from_all_groups(client->username); + mosquitto_free(client->text_name); + mosquitto_free(client->text_description); + mosquitto_free(client->clientid); + mosquitto_free(client->username); + mosquitto_free(client); +} + void dynsec_clients__cleanup(void) { struct dynsec__client *client, *client_tmp; @@ -428,6 +432,9 @@ int dynsec_clients__process_create(cJSON *j_responses, struct mosquitto *context return MOSQ_ERR_INVAL; } + /* Must add user before groups, otherwise adding groups will fail */ + HASH_ADD_KEYPTR_INORDER(hh, local_clients, client->username, strlen(client->username), client, client_cmp); + j_groups = cJSON_GetObjectItem(command, "groups"); if(j_groups && cJSON_IsArray(j_groups)){ cJSON_ArrayForEach(j_group, j_groups){ @@ -435,14 +442,21 @@ int dynsec_clients__process_create(cJSON *j_responses, struct mosquitto *context jtmp = cJSON_GetObjectItem(j_group, "groupname"); if(jtmp && cJSON_IsString(jtmp)){ json_get_int(j_group, "priority", &priority, true, -1); - dynsec_groups__add_client(username, jtmp->valuestring, priority, false); + rc = dynsec_groups__add_client(username, jtmp->valuestring, priority, false); + if(rc == ERR_GROUP_NOT_FOUND){ + dynsec__command_reply(j_responses, context, "createClient", "Group not found", correlation_data); + client__free_item(client); + return MOSQ_ERR_INVAL; + }else if(rc != MOSQ_ERR_SUCCESS){ + dynsec__command_reply(j_responses, context, "createClient", "Internal error", correlation_data); + client__free_item(client); + return MOSQ_ERR_INVAL; + } } } } } - HASH_ADD_KEYPTR_INORDER(hh, local_clients, client->username, strlen(client->username), client, client_cmp); - dynsec__config_save(); dynsec__command_reply(j_responses, context, "createClient", NULL, correlation_data); @@ -746,15 +760,14 @@ int dynsec_clients__process_modify(cJSON *j_responses, struct mosquitto *context client__remove_all_roles(client); client__add_new_roles(client, rolelist); dynsec_rolelist__cleanup(&rolelist); - }else if(rc == MOSQ_ERR_NOT_FOUND){ - dynsec__command_reply(j_responses, context, "modifyClient", "Role not found", correlation_data); - dynsec_rolelist__cleanup(&rolelist); - mosquitto_kick_client_by_username(username, false); - return MOSQ_ERR_INVAL; }else if(rc == ERR_LIST_NOT_FOUND){ /* There was no list in the JSON, so no modification */ }else{ - dynsec__command_reply(j_responses, context, "modifyClient", "Internal error", correlation_data); + if(rc == MOSQ_ERR_INVAL){ + dynsec__command_reply(j_responses, context, "modifyClient", "'roles' not an array", correlation_data); + }else{ + dynsec__command_reply(j_responses, context, "modifyClient", "Internal error", correlation_data); + } dynsec_rolelist__cleanup(&rolelist); mosquitto_kick_client_by_username(username, false); return MOSQ_ERR_INVAL; @@ -1015,7 +1028,7 @@ int dynsec_clients__process_remove_role(cJSON *j_responses, struct mosquitto *co } if(json_get_string(command, "rolename", &rolename, false) != MOSQ_ERR_SUCCESS){ - dynsec__command_reply(j_responses, context, "removeGroupRole", "Invalid/missing rolename", correlation_data); + dynsec__command_reply(j_responses, context, "removeClientRole", "Invalid/missing rolename", correlation_data); return MOSQ_ERR_INVAL; } if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){ @@ -1032,7 +1045,7 @@ int dynsec_clients__process_remove_role(cJSON *j_responses, struct mosquitto *co role = dynsec_roles__find(rolename); if(role == NULL){ - dynsec__command_reply(j_responses, context, "addClientRole", "Role not found", correlation_data); + dynsec__command_reply(j_responses, context, "removeClientRole", "Role not found", correlation_data); return MOSQ_ERR_SUCCESS; } diff --git a/plugins/dynamic-security/rolelist.c b/plugins/dynamic-security/rolelist.c index ddfe17a6..b9cfd7be 100644 --- a/plugins/dynamic-security/rolelist.c +++ b/plugins/dynamic-security/rolelist.c @@ -167,21 +167,25 @@ int dynsec_rolelist__load_from_json(cJSON *command, struct dynsec__rolelist **ro struct dynsec__role *role; j_roles = cJSON_GetObjectItem(command, "roles"); - if(j_roles && cJSON_IsArray(j_roles)){ - cJSON_ArrayForEach(j_role, j_roles){ - j_rolename = cJSON_GetObjectItem(j_role, "rolename"); - if(j_rolename && cJSON_IsString(j_rolename)){ - json_get_int(j_role, "priority", &priority, true, -1); - role = dynsec_roles__find(j_rolename->valuestring); - if(role){ - dynsec_rolelist__add(rolelist, role, priority); - }else{ - dynsec_rolelist__cleanup(rolelist); - return MOSQ_ERR_NOT_FOUND; + if(j_roles){ + if(cJSON_IsArray(j_roles)){ + cJSON_ArrayForEach(j_role, j_roles){ + j_rolename = cJSON_GetObjectItem(j_role, "rolename"); + if(j_rolename && cJSON_IsString(j_rolename)){ + json_get_int(j_role, "priority", &priority, true, -1); + role = dynsec_roles__find(j_rolename->valuestring); + if(role){ + dynsec_rolelist__add(rolelist, role, priority); + }else{ + dynsec_rolelist__cleanup(rolelist); + return MOSQ_ERR_NOT_FOUND; + } } } + return MOSQ_ERR_SUCCESS; + }else{ + return MOSQ_ERR_INVAL; } - return MOSQ_ERR_SUCCESS; }else{ return ERR_LIST_NOT_FOUND; }