dynsec: Various minor fixes.

This commit is contained in:
Roger A. Light 2020-11-27 14:34:46 +00:00
parent f6e17b81b9
commit 6739152fda
2 changed files with 54 additions and 37 deletions

View File

@ -57,20 +57,6 @@ static int client_cmp(void *a, void *b)
return strcmp(client_a->username, client_b->username); 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 *dynsec_clients__find(const char *username)
{ {
struct dynsec__client *client = NULL; 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) void dynsec_clients__cleanup(void)
{ {
struct dynsec__client *client, *client_tmp; 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; 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"); j_groups = cJSON_GetObjectItem(command, "groups");
if(j_groups && cJSON_IsArray(j_groups)){ if(j_groups && cJSON_IsArray(j_groups)){
cJSON_ArrayForEach(j_group, 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"); jtmp = cJSON_GetObjectItem(j_group, "groupname");
if(jtmp && cJSON_IsString(jtmp)){ if(jtmp && cJSON_IsString(jtmp)){
json_get_int(j_group, "priority", &priority, true, -1); 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__config_save();
dynsec__command_reply(j_responses, context, "createClient", NULL, correlation_data); 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__remove_all_roles(client);
client__add_new_roles(client, rolelist); client__add_new_roles(client, rolelist);
dynsec_rolelist__cleanup(&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){ }else if(rc == ERR_LIST_NOT_FOUND){
/* There was no list in the JSON, so no modification */ /* There was no list in the JSON, so no modification */
}else{ }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); dynsec_rolelist__cleanup(&rolelist);
mosquitto_kick_client_by_username(username, false); mosquitto_kick_client_by_username(username, false);
return MOSQ_ERR_INVAL; 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){ 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; return MOSQ_ERR_INVAL;
} }
if(mosquitto_validate_utf8(rolename, (int)strlen(rolename)) != MOSQ_ERR_SUCCESS){ 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); role = dynsec_roles__find(rolename);
if(role == NULL){ 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; return MOSQ_ERR_SUCCESS;
} }

View File

@ -167,21 +167,25 @@ int dynsec_rolelist__load_from_json(cJSON *command, struct dynsec__rolelist **ro
struct dynsec__role *role; struct dynsec__role *role;
j_roles = cJSON_GetObjectItem(command, "roles"); j_roles = cJSON_GetObjectItem(command, "roles");
if(j_roles && cJSON_IsArray(j_roles)){ if(j_roles){
cJSON_ArrayForEach(j_role, j_roles){ if(cJSON_IsArray(j_roles)){
j_rolename = cJSON_GetObjectItem(j_role, "rolename"); cJSON_ArrayForEach(j_role, j_roles){
if(j_rolename && cJSON_IsString(j_rolename)){ j_rolename = cJSON_GetObjectItem(j_role, "rolename");
json_get_int(j_role, "priority", &priority, true, -1); if(j_rolename && cJSON_IsString(j_rolename)){
role = dynsec_roles__find(j_rolename->valuestring); json_get_int(j_role, "priority", &priority, true, -1);
if(role){ role = dynsec_roles__find(j_rolename->valuestring);
dynsec_rolelist__add(rolelist, role, priority); if(role){
}else{ dynsec_rolelist__add(rolelist, role, priority);
dynsec_rolelist__cleanup(rolelist); }else{
return MOSQ_ERR_NOT_FOUND; dynsec_rolelist__cleanup(rolelist);
return MOSQ_ERR_NOT_FOUND;
}
} }
} }
return MOSQ_ERR_SUCCESS;
}else{
return MOSQ_ERR_INVAL;
} }
return MOSQ_ERR_SUCCESS;
}else{ }else{
return ERR_LIST_NOT_FOUND; return ERR_LIST_NOT_FOUND;
} }