mirror of
https://github.com/eclipse-mosquitto/mosquitto.git
synced 2026-09-23 08:33:48 +08:00
dynsec: Rolelist as own file for consistency.
This commit is contained in:
@@ -25,6 +25,7 @@ add_library(mosquitto_dynamic_security SHARED
|
||||
json_help.h
|
||||
plugin.c
|
||||
roles.c
|
||||
rolelist.c
|
||||
sub_matches_sub.c)
|
||||
|
||||
set_target_properties(mosquitto_dynamic_security PROPERTIES
|
||||
|
||||
@@ -15,6 +15,7 @@ OBJS= \
|
||||
json_help.o \
|
||||
plugin.o \
|
||||
roles.o \
|
||||
rolelist.o \
|
||||
sub_matches_sub.o
|
||||
|
||||
all : binary
|
||||
@@ -50,6 +51,9 @@ plugin.o : plugin.c dynamic_security.h
|
||||
roles.o : roles.c dynamic_security.h
|
||||
${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) -c $< -o $@
|
||||
|
||||
rolelist.o : rolelist.c dynamic_security.h
|
||||
${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) -c $< -o $@
|
||||
|
||||
sub_matches_sub.o : sub_matches_sub.c dynamic_security.h
|
||||
${CROSS_COMPILE}${CC} $(LOCAL_CPPFLAGS) $(PLUGIN_CPPFLAGS) $(PLUGIN_CFLAGS) -c $< -o $@
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ static void client__free_item(struct dynsec__client *client)
|
||||
if(client == NULL) return;
|
||||
|
||||
HASH_DEL(local_clients, client);
|
||||
dynsec_rolelists__free_all(&client->rolelist);
|
||||
dynsec_rolelist__cleanup(&client->rolelist);
|
||||
dynsec__remove_client_from_all_groups(client->username);
|
||||
mosquitto_free(client->text_name);
|
||||
mosquitto_free(client->text_description);
|
||||
@@ -237,7 +237,7 @@ int dynsec_clients__config_load(cJSON *tree)
|
||||
if(jtmp && cJSON_IsString(jtmp)){
|
||||
json_get_int(j_role, "priority", &priority, true, -1);
|
||||
role = dynsec_roles__find(jtmp->valuestring);
|
||||
dynsec_rolelists__client_add_role(client, role, priority);
|
||||
dynsec_rolelist__client_add(client, role, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -273,7 +273,7 @@ static int dynsec__config_add_clients(cJSON *j_clients)
|
||||
return 1;
|
||||
}
|
||||
|
||||
j_roles = dynsec_rolelists__all_to_json(client->rolelist);
|
||||
j_roles = dynsec_rolelist__all_to_json(client->rolelist);
|
||||
if(j_roles == NULL){
|
||||
return 1;
|
||||
}
|
||||
@@ -419,7 +419,7 @@ int dynsec_clients__process_create(cJSON *j_responses, struct mosquitto *context
|
||||
}
|
||||
}
|
||||
|
||||
rc = dynsec_rolelists__load_from_json(command, &client->rolelist);
|
||||
rc = dynsec_rolelist__load_from_json(command, &client->rolelist);
|
||||
if(rc == MOSQ_ERR_SUCCESS || rc == ERR_LIST_NOT_FOUND){
|
||||
}else if(rc == MOSQ_ERR_NOT_FOUND){
|
||||
dynsec__command_reply(j_responses, context, "createClient", "Role not found", correlation_data);
|
||||
@@ -644,7 +644,7 @@ static void client__add_new_roles(struct dynsec__client *client, struct dynsec__
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
|
||||
HASH_ITER(hh, base_rolelist, rolelist, rolelist_tmp){
|
||||
dynsec_rolelists__client_add_role(client, rolelist->role, rolelist->priority);
|
||||
dynsec_rolelist__client_add(client, rolelist->role, rolelist->priority);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -653,7 +653,7 @@ static void client__remove_all_roles(struct dynsec__client *client)
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
|
||||
HASH_ITER(hh, client->rolelist, rolelist, rolelist_tmp){
|
||||
dynsec_rolelists__client_remove_role(client, rolelist->role);
|
||||
dynsec_rolelist__client_remove(client, rolelist->role);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -726,21 +726,21 @@ int dynsec_clients__process_modify(cJSON *j_responses, struct mosquitto *context
|
||||
client->text_description = str;
|
||||
}
|
||||
|
||||
rc = dynsec_rolelists__load_from_json(command, &rolelist);
|
||||
rc = dynsec_rolelist__load_from_json(command, &rolelist);
|
||||
if(rc == MOSQ_ERR_SUCCESS){
|
||||
client__remove_all_roles(client);
|
||||
client__add_new_roles(client, rolelist);
|
||||
dynsec_rolelists__free_all(&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_rolelists__free_all(&rolelist);
|
||||
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);
|
||||
dynsec_rolelists__free_all(&rolelist);
|
||||
dynsec_rolelist__cleanup(&rolelist);
|
||||
mosquitto_kick_client_by_username(username, false);
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
@@ -807,7 +807,7 @@ static cJSON *add_client_to_json(struct dynsec__client *client, bool verbose)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
j_roles = dynsec_rolelists__all_to_json(client->rolelist);
|
||||
j_roles = dynsec_rolelist__all_to_json(client->rolelist);
|
||||
if(j_roles == NULL){
|
||||
cJSON_Delete(j_client);
|
||||
return NULL;
|
||||
@@ -1014,7 +1014,7 @@ int dynsec_clients__process_add_role(cJSON *j_responses, struct mosquitto *conte
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
dynsec_rolelists__client_add_role(client, role, priority);
|
||||
dynsec_rolelist__client_add(client, role, priority);
|
||||
dynsec__config_save();
|
||||
dynsec__command_reply(j_responses, context, "addClientRole", NULL, correlation_data);
|
||||
|
||||
@@ -1062,7 +1062,7 @@ int dynsec_clients__process_remove_role(cJSON *j_responses, struct mosquitto *co
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
dynsec_rolelists__client_remove_role(client, role);
|
||||
dynsec_rolelist__client_remove(client, role);
|
||||
dynsec__config_save();
|
||||
dynsec__command_reply(j_responses, context, "removeClientRole", NULL, correlation_data);
|
||||
|
||||
|
||||
@@ -253,12 +253,19 @@ int dynsec_roles__process_modify(cJSON *j_responses, struct mosquitto *context,
|
||||
int dynsec_roles__process_remove_acl(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data);
|
||||
struct dynsec__role *dynsec_roles__find(const char *rolename);
|
||||
|
||||
int dynsec_rolelists__client_add_role(struct dynsec__client *client, struct dynsec__role *role, int priority);
|
||||
int dynsec_rolelists__client_remove_role(struct dynsec__client *client, struct dynsec__role *role);
|
||||
int dynsec_rolelists__group_add_role(struct dynsec__group *group, struct dynsec__role *role, int priority);
|
||||
void dynsec_rolelists__group_remove_role(struct dynsec__group *group, struct dynsec__role *role);
|
||||
int dynsec_rolelists__load_from_json(cJSON *command, struct dynsec__rolelist **rolelist);
|
||||
void dynsec_rolelists__free_all(struct dynsec__rolelist **base_rolelist);
|
||||
cJSON *dynsec_rolelists__all_to_json(struct dynsec__rolelist *base_rolelist);
|
||||
|
||||
/* ################################################################
|
||||
* #
|
||||
* # Role List Functions
|
||||
* #
|
||||
* ################################################################ */
|
||||
|
||||
int dynsec_rolelist__client_add(struct dynsec__client *client, struct dynsec__role *role, int priority);
|
||||
int dynsec_rolelist__client_remove(struct dynsec__client *client, struct dynsec__role *role);
|
||||
int dynsec_rolelist__group_add(struct dynsec__group *group, struct dynsec__role *role, int priority);
|
||||
void dynsec_rolelist__group_remove(struct dynsec__group *group, struct dynsec__role *role);
|
||||
int dynsec_rolelist__load_from_json(cJSON *command, struct dynsec__rolelist **rolelist);
|
||||
void dynsec_rolelist__cleanup(struct dynsec__rolelist **base_rolelist);
|
||||
cJSON *dynsec_rolelist__all_to_json(struct dynsec__rolelist *base_rolelist);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -78,7 +78,7 @@ static void group__free_item(struct dynsec__group *group)
|
||||
mosquitto_free(group->text_name);
|
||||
mosquitto_free(group->text_description);
|
||||
mosquitto_free(group->groupname);
|
||||
dynsec_rolelists__free_all(&group->rolelist);
|
||||
dynsec_rolelist__cleanup(&group->rolelist);
|
||||
mosquitto_free(group);
|
||||
}
|
||||
|
||||
@@ -130,7 +130,7 @@ int dynsec_groups__process_add_role(cJSON *j_responses, struct mosquitto *contex
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
dynsec_rolelists__group_add_role(group, role, priority);
|
||||
dynsec_rolelist__group_add(group, role, priority);
|
||||
dynsec__config_save();
|
||||
dynsec__command_reply(j_responses, context, "addGroupRole", NULL, correlation_data);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
@@ -230,7 +230,7 @@ int dynsec_groups__config_load(cJSON *tree)
|
||||
if(j_rolename && cJSON_IsString(j_rolename)){
|
||||
json_get_int(j_role, "priority", &priority, true, -1);
|
||||
role = dynsec_roles__find(j_rolename->valuestring);
|
||||
dynsec_rolelists__group_add_role(group, role, priority);
|
||||
dynsec_rolelist__group_add(group, role, priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -290,7 +290,7 @@ static int dynsec__config_add_groups(cJSON *j_groups)
|
||||
return 1;
|
||||
}
|
||||
|
||||
j_roles = dynsec_rolelists__all_to_json(group->rolelist);
|
||||
j_roles = dynsec_rolelist__all_to_json(group->rolelist);
|
||||
if(j_roles == NULL){
|
||||
return 1;
|
||||
}
|
||||
@@ -389,7 +389,7 @@ int dynsec_groups__process_create(cJSON *j_responses, struct mosquitto *context,
|
||||
}
|
||||
}
|
||||
|
||||
rc = dynsec_rolelists__load_from_json(command, &group->rolelist);
|
||||
rc = dynsec_rolelist__load_from_json(command, &group->rolelist);
|
||||
if(rc == MOSQ_ERR_SUCCESS || rc == ERR_LIST_NOT_FOUND){
|
||||
}else if(rc == MOSQ_ERR_NOT_FOUND){
|
||||
dynsec__command_reply(j_responses, context, "createGroup", "Role not found", correlation_data);
|
||||
@@ -644,7 +644,7 @@ static cJSON *add_group_to_json(struct dynsec__group *group)
|
||||
cJSON_AddItemToObject(j_client, "username", jtmp);
|
||||
}
|
||||
|
||||
j_rolelist = dynsec_rolelists__all_to_json(group->rolelist);
|
||||
j_rolelist = dynsec_rolelist__all_to_json(group->rolelist);
|
||||
if(j_rolelist == NULL){
|
||||
cJSON_Delete(j_group);
|
||||
return NULL;
|
||||
@@ -845,7 +845,7 @@ int dynsec_groups__process_remove_role(cJSON *j_responses, struct mosquitto *con
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
dynsec_rolelists__group_remove_role(group, role);
|
||||
dynsec_rolelist__group_remove(group, role);
|
||||
dynsec__config_save();
|
||||
dynsec__command_reply(j_responses, context, "removeGroupRole", NULL, correlation_data);
|
||||
|
||||
@@ -904,19 +904,19 @@ int dynsec_groups__process_modify(cJSON *j_responses, struct mosquitto *context,
|
||||
group->text_description = str;
|
||||
}
|
||||
|
||||
rc = dynsec_rolelists__load_from_json(command, &rolelist);
|
||||
rc = dynsec_rolelist__load_from_json(command, &rolelist);
|
||||
if(rc == MOSQ_ERR_SUCCESS){
|
||||
dynsec_rolelists__free_all(&group->rolelist);
|
||||
dynsec_rolelist__cleanup(&group->rolelist);
|
||||
group->rolelist = rolelist;
|
||||
}else if(rc == MOSQ_ERR_NOT_FOUND){
|
||||
dynsec__command_reply(j_responses, context, "modifyGroup", "Role not found", correlation_data);
|
||||
dynsec_rolelists__free_all(&rolelist);
|
||||
dynsec_rolelist__cleanup(&rolelist);
|
||||
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, "modifyGroup", "Internal error", correlation_data);
|
||||
dynsec_rolelists__free_all(&rolelist);
|
||||
dynsec_rolelist__cleanup(&rolelist);
|
||||
return MOSQ_ERR_INVAL;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
Copyright (c) 2020 Roger Light <roger@atchoo.org>
|
||||
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are made available under the terms of the Eclipse Public License v1.0
|
||||
and Eclipse Distribution License v1.0 which accompany this distribution.
|
||||
|
||||
The Eclipse Public License is available at
|
||||
http://www.eclipse.org/legal/epl-v10.html
|
||||
and the Eclipse Distribution License is available at
|
||||
http://www.eclipse.org/org/documents/edl-v10.php.
|
||||
|
||||
Contributors:
|
||||
Roger Light - initial implementation and documentation.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <cJSON.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <uthash.h>
|
||||
#include <utlist.h>
|
||||
|
||||
#include "dynamic_security.h"
|
||||
#include "json_help.h"
|
||||
#include "mosquitto.h"
|
||||
#include "mosquitto_broker.h"
|
||||
|
||||
|
||||
/* ################################################################
|
||||
* #
|
||||
* # Utility functions
|
||||
* #
|
||||
* ################################################################ */
|
||||
|
||||
static int rolelist_cmp(void *a, void *b)
|
||||
{
|
||||
int prio;
|
||||
struct dynsec__rolelist *rolelist_a = a;
|
||||
struct dynsec__rolelist *rolelist_b = b;
|
||||
|
||||
prio = rolelist_b->priority - rolelist_a->priority;
|
||||
if(prio == 0){
|
||||
return strcmp(rolelist_a->rolename, rolelist_b->rolename);
|
||||
}else{
|
||||
return prio;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dynsec_rolelist__free_item(struct dynsec__rolelist **base_rolelist, struct dynsec__rolelist *rolelist)
|
||||
{
|
||||
HASH_DELETE(hh, *base_rolelist, rolelist);
|
||||
mosquitto_free(rolelist->rolename);
|
||||
mosquitto_free(rolelist);
|
||||
}
|
||||
|
||||
void dynsec_rolelist__cleanup(struct dynsec__rolelist **base_rolelist)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
|
||||
HASH_ITER(hh, *base_rolelist, rolelist, rolelist_tmp){
|
||||
dynsec_rolelist__free_item(base_rolelist, rolelist);
|
||||
}
|
||||
}
|
||||
|
||||
int dynsec_rolelist__remove_role(struct dynsec__rolelist **base_rolelist, const struct dynsec__role *role)
|
||||
{
|
||||
struct dynsec__rolelist *found_rolelist;
|
||||
|
||||
HASH_FIND(hh, *base_rolelist, role->rolename, strlen(role->rolename), found_rolelist);
|
||||
if(found_rolelist){
|
||||
dynsec_rolelist__free_item(base_rolelist, found_rolelist);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelist__client_remove(struct dynsec__client *client, struct dynsec__role *role)
|
||||
{
|
||||
int rc;
|
||||
struct dynsec__clientlist *found_clientlist;
|
||||
|
||||
rc = dynsec_rolelist__remove_role(&client->rolelist, role);
|
||||
if(rc) return rc;
|
||||
|
||||
HASH_FIND(hh, role->clientlist, client->username, strlen(client->username), found_clientlist);
|
||||
if(found_clientlist){
|
||||
HASH_DELETE(hh, role->clientlist, found_clientlist);
|
||||
mosquitto_free(found_clientlist);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dynsec_rolelist__group_remove(struct dynsec__group *group, struct dynsec__role *role)
|
||||
{
|
||||
dynsec_rolelist__remove_role(&group->rolelist, role);
|
||||
dynsec_grouplist__remove(&role->grouplist, group);
|
||||
}
|
||||
|
||||
|
||||
static int dynsec_rolelist__add(struct dynsec__rolelist **base_rolelist, struct dynsec__role *role, int priority)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist;
|
||||
|
||||
if(role == NULL) return MOSQ_ERR_INVAL;
|
||||
|
||||
HASH_FIND(hh, *base_rolelist, role->rolename, strlen(role->rolename), rolelist);
|
||||
if(rolelist){
|
||||
return MOSQ_ERR_ALREADY_EXISTS;
|
||||
}else{
|
||||
rolelist = mosquitto_calloc(1, sizeof(struct dynsec__rolelist));
|
||||
if(rolelist == NULL) return MOSQ_ERR_NOMEM;
|
||||
|
||||
rolelist->role = role;
|
||||
rolelist->priority = priority;
|
||||
rolelist->rolename = mosquitto_strdup(role->rolename);
|
||||
if(rolelist->rolename == NULL){
|
||||
mosquitto_free(rolelist);
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
HASH_ADD_KEYPTR_INORDER(hh, *base_rolelist, role->rolename, strlen(role->rolename), rolelist, rolelist_cmp);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelist__client_add(struct dynsec__client *client, struct dynsec__role *role, int priority)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist;
|
||||
int rc;
|
||||
|
||||
rc = dynsec_rolelist__add(&client->rolelist, role, priority);
|
||||
if(rc) return rc;
|
||||
|
||||
HASH_FIND(hh, client->rolelist, role->rolename, strlen(role->rolename), rolelist);
|
||||
if(rolelist == NULL){
|
||||
/* This should never happen because the above add_role succeeded. */
|
||||
return MOSQ_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return dynsec_clientlist__add(&role->clientlist, client, priority);
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelist__group_add(struct dynsec__group *group, struct dynsec__role *role, int priority)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = dynsec_rolelist__add(&group->rolelist, role, priority);
|
||||
if(rc) return rc;
|
||||
|
||||
return dynsec_grouplist__add(&role->grouplist, group, priority);
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelist__load_from_json(cJSON *command, struct dynsec__rolelist **rolelist)
|
||||
{
|
||||
cJSON *j_roles, *j_role, *j_rolename;
|
||||
int priority;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return ERR_LIST_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cJSON *dynsec_rolelist__all_to_json(struct dynsec__rolelist *base_rolelist)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
cJSON *j_roles, *j_role;
|
||||
|
||||
j_roles = cJSON_CreateArray();
|
||||
if(j_roles == NULL) return NULL;
|
||||
|
||||
HASH_ITER(hh, base_rolelist, rolelist, rolelist_tmp){
|
||||
j_role = cJSON_CreateObject();
|
||||
if(j_role == NULL){
|
||||
cJSON_Delete(j_roles);
|
||||
return NULL;
|
||||
}
|
||||
cJSON_AddItemToArray(j_roles, j_role);
|
||||
|
||||
if(cJSON_AddStringToObject(j_role, "rolename", rolelist->role->rolename) == NULL
|
||||
|| (rolelist->priority != -1 && cJSON_AddIntToObject(j_role, "priority", rolelist->priority) == NULL)
|
||||
){
|
||||
|
||||
cJSON_Delete(j_roles);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return j_roles;
|
||||
}
|
||||
@@ -54,187 +54,6 @@ static int role_cmp(void *a, void *b)
|
||||
return strcmp(role_a->rolename, role_b->rolename);
|
||||
}
|
||||
|
||||
static int rolelist_cmp(void *a, void *b)
|
||||
{
|
||||
int prio;
|
||||
struct dynsec__rolelist *rolelist_a = a;
|
||||
struct dynsec__rolelist *rolelist_b = b;
|
||||
|
||||
prio = rolelist_b->priority - rolelist_a->priority;
|
||||
if(prio == 0){
|
||||
return strcmp(rolelist_a->rolename, rolelist_b->rolename);
|
||||
}else{
|
||||
return prio;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dynsec_rolelists__free_item(struct dynsec__rolelist **base_rolelist, struct dynsec__rolelist *rolelist)
|
||||
{
|
||||
HASH_DELETE(hh, *base_rolelist, rolelist);
|
||||
mosquitto_free(rolelist->rolename);
|
||||
mosquitto_free(rolelist);
|
||||
}
|
||||
|
||||
void dynsec_rolelists__free_all(struct dynsec__rolelist **base_rolelist)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
|
||||
HASH_ITER(hh, *base_rolelist, rolelist, rolelist_tmp){
|
||||
dynsec_rolelists__free_item(base_rolelist, rolelist);
|
||||
}
|
||||
}
|
||||
|
||||
int dynsec_rolelists__remove_role(struct dynsec__rolelist **base_rolelist, const struct dynsec__role *role)
|
||||
{
|
||||
struct dynsec__rolelist *found_rolelist;
|
||||
|
||||
HASH_FIND(hh, *base_rolelist, role->rolename, strlen(role->rolename), found_rolelist);
|
||||
if(found_rolelist){
|
||||
dynsec_rolelists__free_item(base_rolelist, found_rolelist);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelists__client_remove_role(struct dynsec__client *client, struct dynsec__role *role)
|
||||
{
|
||||
int rc;
|
||||
struct dynsec__clientlist *found_clientlist;
|
||||
|
||||
rc = dynsec_rolelists__remove_role(&client->rolelist, role);
|
||||
if(rc) return rc;
|
||||
|
||||
HASH_FIND(hh, role->clientlist, client->username, strlen(client->username), found_clientlist);
|
||||
if(found_clientlist){
|
||||
HASH_DELETE(hh, role->clientlist, found_clientlist);
|
||||
mosquitto_free(found_clientlist);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void dynsec_rolelists__group_remove_role(struct dynsec__group *group, struct dynsec__role *role)
|
||||
{
|
||||
dynsec_rolelists__remove_role(&group->rolelist, role);
|
||||
dynsec_grouplist__remove(&role->grouplist, group);
|
||||
}
|
||||
|
||||
|
||||
static int dynsec_rolelists__add_role(struct dynsec__rolelist **base_rolelist, struct dynsec__role *role, int priority)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist;
|
||||
|
||||
if(role == NULL) return MOSQ_ERR_INVAL;
|
||||
|
||||
HASH_FIND(hh, *base_rolelist, role->rolename, strlen(role->rolename), rolelist);
|
||||
if(rolelist){
|
||||
return MOSQ_ERR_ALREADY_EXISTS;
|
||||
}else{
|
||||
rolelist = mosquitto_calloc(1, sizeof(struct dynsec__rolelist));
|
||||
if(rolelist == NULL) return MOSQ_ERR_NOMEM;
|
||||
|
||||
rolelist->role = role;
|
||||
rolelist->priority = priority;
|
||||
rolelist->rolename = mosquitto_strdup(role->rolename);
|
||||
if(rolelist->rolename == NULL){
|
||||
mosquitto_free(rolelist);
|
||||
return MOSQ_ERR_NOMEM;
|
||||
}
|
||||
HASH_ADD_KEYPTR_INORDER(hh, *base_rolelist, role->rolename, strlen(role->rolename), rolelist, rolelist_cmp);
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelists__client_add_role(struct dynsec__client *client, struct dynsec__role *role, int priority)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist;
|
||||
int rc;
|
||||
|
||||
rc = dynsec_rolelists__add_role(&client->rolelist, role, priority);
|
||||
if(rc) return rc;
|
||||
|
||||
HASH_FIND(hh, client->rolelist, role->rolename, strlen(role->rolename), rolelist);
|
||||
if(rolelist == NULL){
|
||||
/* This should never happen because the above add_role succeeded. */
|
||||
return MOSQ_ERR_UNKNOWN;
|
||||
}
|
||||
|
||||
return dynsec_clientlist__add(&role->clientlist, client, priority);
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelists__group_add_role(struct dynsec__group *group, struct dynsec__role *role, int priority)
|
||||
{
|
||||
int rc;
|
||||
|
||||
rc = dynsec_rolelists__add_role(&group->rolelist, role, priority);
|
||||
if(rc) return rc;
|
||||
|
||||
return dynsec_grouplist__add(&role->grouplist, group, priority);
|
||||
}
|
||||
|
||||
|
||||
int dynsec_rolelists__load_from_json(cJSON *command, struct dynsec__rolelist **rolelist)
|
||||
{
|
||||
cJSON *j_roles, *j_role, *j_rolename;
|
||||
int priority;
|
||||
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_rolelists__add_role(rolelist, role, priority);
|
||||
}else{
|
||||
dynsec_rolelists__free_all(rolelist);
|
||||
return MOSQ_ERR_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
}
|
||||
return MOSQ_ERR_SUCCESS;
|
||||
}else{
|
||||
return ERR_LIST_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
cJSON *dynsec_rolelists__all_to_json(struct dynsec__rolelist *base_rolelist)
|
||||
{
|
||||
struct dynsec__rolelist *rolelist, *rolelist_tmp;
|
||||
cJSON *j_roles, *j_role;
|
||||
|
||||
j_roles = cJSON_CreateArray();
|
||||
if(j_roles == NULL) return NULL;
|
||||
|
||||
HASH_ITER(hh, base_rolelist, rolelist, rolelist_tmp){
|
||||
j_role = cJSON_CreateObject();
|
||||
if(j_role == NULL){
|
||||
cJSON_Delete(j_roles);
|
||||
return NULL;
|
||||
}
|
||||
cJSON_AddItemToArray(j_roles, j_role);
|
||||
|
||||
if(cJSON_AddStringToObject(j_role, "rolename", rolelist->role->rolename) == NULL
|
||||
|| (rolelist->priority != -1 && cJSON_AddIntToObject(j_role, "priority", rolelist->priority) == NULL)
|
||||
){
|
||||
|
||||
cJSON_Delete(j_roles);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return j_roles;
|
||||
}
|
||||
|
||||
|
||||
static void role__free_acl(struct dynsec__acl **acl, struct dynsec__acl *item)
|
||||
{
|
||||
@@ -618,7 +437,7 @@ static void role__remove_all_clients(struct dynsec__role *role)
|
||||
HASH_ITER(hh, role->clientlist, clientlist, clientlist_tmp){
|
||||
mosquitto_kick_client_by_username(clientlist->client->username, false);
|
||||
|
||||
dynsec_rolelists__client_remove_role(clientlist->client, role);
|
||||
dynsec_rolelist__client_remove(clientlist->client, role);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -632,7 +451,7 @@ static void role__remove_all_groups(struct dynsec__role *role)
|
||||
}
|
||||
dynsec_clientlist__kick_all(grouplist->group->clientlist);
|
||||
|
||||
dynsec_rolelists__group_remove_role(grouplist->group, role);
|
||||
dynsec_rolelist__group_remove(grouplist->group, role);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user