From 11c5cf039f54c5de4263e311362e926bf6243b19 Mon Sep 17 00:00:00 2001 From: "Roger A. Light" Date: Thu, 27 Jan 2022 16:09:09 +0000 Subject: [PATCH] Simplify memory use for dynsec. --- plugins/dynamic-security/acl.c | 12 +++---- plugins/dynamic-security/clients.c | 21 +++++------- plugins/dynamic-security/config.c | 24 ++++++------- plugins/dynamic-security/default_acl.c | 18 +++++----- plugins/dynamic-security/dynamic_security.h | 11 ++++-- plugins/dynamic-security/groups.c | 38 +++++++++------------ plugins/dynamic-security/plugin.c | 3 ++ plugins/dynamic-security/roles.c | 31 ++++++----------- 8 files changed, 74 insertions(+), 84 deletions(-) diff --git a/plugins/dynamic-security/acl.c b/plugins/dynamic-security/acl.c index 70397154..592142b3 100644 --- a/plugins/dynamic-security/acl.c +++ b/plugins/dynamic-security/acl.c @@ -213,9 +213,9 @@ static int acl_check(struct mosquitto_evt_acl_check *ed, MOSQ_FUNC_acl_check che return rc; } } - }else if(dynsec_anonymous_group){ + }else if(g_dynsec_data.anonymous_group){ /* If we have a group for anonymous users, use that for checking. */ - rc = check(ed, dynsec_anonymous_group->rolelist); + rc = check(ed, g_dynsec_data.anonymous_group->rolelist); if(rc != MOSQ_ERR_NOT_FOUND){ return rc; } @@ -260,16 +260,16 @@ int dynsec__acl_check_callback(int event, void *event_data, void *userdata) switch(ed->access){ case MOSQ_ACL_SUBSCRIBE: - return acl_check(event_data, acl_check_subscribe, default_access.subscribe); + return acl_check(event_data, acl_check_subscribe, g_dynsec_data.default_access.subscribe); break; case MOSQ_ACL_UNSUBSCRIBE: - return acl_check(event_data, acl_check_unsubscribe, default_access.unsubscribe); + return acl_check(event_data, acl_check_unsubscribe, g_dynsec_data.default_access.unsubscribe); break; case MOSQ_ACL_WRITE: /* Client to broker */ - return acl_check(event_data, acl_check_publish_c_send, default_access.publish_c_send); + return acl_check(event_data, acl_check_publish_c_send, g_dynsec_data.default_access.publish_c_send); break; case MOSQ_ACL_READ: - return acl_check(event_data, acl_check_publish_c_recv, default_access.publish_c_recv); + return acl_check(event_data, acl_check_publish_c_recv, g_dynsec_data.default_access.publish_c_recv); break; default: return MOSQ_ERR_PLUGIN_DEFER; diff --git a/plugins/dynamic-security/clients.c b/plugins/dynamic-security/clients.c index ffd24549..9e47222b 100644 --- a/plugins/dynamic-security/clients.c +++ b/plugins/dynamic-security/clients.c @@ -43,9 +43,6 @@ static void client__remove_all_roles(struct dynsec__client *client); * # * ################################################################ */ -static struct dynsec__client *local_clients = NULL; - - /* ################################################################ * # * # Utility functions @@ -65,7 +62,7 @@ struct dynsec__client *dynsec_clients__find(const char *username) struct dynsec__client *client = NULL; if(username){ - HASH_FIND(hh, local_clients, username, strlen(username), client); + HASH_FIND(hh, g_dynsec_data.clients, username, strlen(username), client); } return client; } @@ -78,7 +75,7 @@ static void client__free_item(struct dynsec__client *client) client_found = dynsec_clients__find(client->username); if(client_found){ - HASH_DEL(local_clients, client_found); + HASH_DEL(g_dynsec_data.clients, client_found); } dynsec_rolelist__cleanup(&client->rolelist); dynsec__remove_client_from_all_groups(client->username); @@ -93,7 +90,7 @@ void dynsec_clients__cleanup(void) { struct dynsec__client *client, *client_tmp; - HASH_ITER(hh, local_clients, client, client_tmp){ + HASH_ITER(hh, g_dynsec_data.clients, client, client_tmp){ client__free_item(client); } } @@ -242,10 +239,10 @@ int dynsec_clients__config_load(cJSON *tree) } } - HASH_ADD_KEYPTR(hh, local_clients, client->username, strlen(client->username), client); + HASH_ADD_KEYPTR(hh, g_dynsec_data.clients, client->username, strlen(client->username), client); } } - HASH_SORT(local_clients, client_cmp); + HASH_SORT(g_dynsec_data.clients, client_cmp); return 0; } @@ -257,7 +254,7 @@ static int dynsec__config_add_clients(cJSON *j_clients) cJSON *j_client, *j_roles, *jtmp; char *buf; - HASH_ITER(hh, local_clients, client, client_tmp){ + HASH_ITER(hh, g_dynsec_data.clients, client, client_tmp){ j_client = cJSON_CreateObject(); if(j_client == NULL) return 1; cJSON_AddItemToArray(j_clients, j_client); @@ -433,7 +430,7 @@ int dynsec_clients__process_create(cJSON *j_responses, struct mosquitto *context } /* 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); + HASH_ADD_KEYPTR_INORDER(hh, g_dynsec_data.clients, client->username, strlen(client->username), client, client_cmp); j_groups = cJSON_GetObjectItem(command, "groups"); if(j_groups && cJSON_IsArray(j_groups)){ @@ -983,7 +980,7 @@ int dynsec_clients__process_list(cJSON *j_responses, struct mosquitto *context, if(cJSON_AddStringToObject(tree, "command", "listClients") == NULL || (j_data = cJSON_AddObjectToObject(tree, "data")) == NULL - || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, local_clients)) == NULL + || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, g_dynsec_data.clients)) == NULL || (j_clients = cJSON_AddArrayToObject(j_data, "clients")) == NULL || (correlation_data && cJSON_AddStringToObject(tree, "correlationData", correlation_data) == NULL) ){ @@ -994,7 +991,7 @@ int dynsec_clients__process_list(cJSON *j_responses, struct mosquitto *context, } i = 0; - HASH_ITER(hh, local_clients, client, client_tmp){ + HASH_ITER(hh, g_dynsec_data.clients, client, client_tmp){ if(i>=offset){ j_client = add_client_to_json(client, verbose); if(j_client == NULL){ diff --git a/plugins/dynamic-security/config.c b/plugins/dynamic-security/config.c index 639933cb..f2985a27 100644 --- a/plugins/dynamic-security/config.c +++ b/plugins/dynamic-security/config.c @@ -41,30 +41,30 @@ static int dynsec__general_config_load(cJSON *tree) if(j_default_access && cJSON_IsObject(j_default_access)){ jtmp = cJSON_GetObjectItem(j_default_access, ACL_TYPE_PUB_C_SEND); if(jtmp && cJSON_IsBool(jtmp)){ - default_access.publish_c_send = cJSON_IsTrue(jtmp); + g_dynsec_data.default_access.publish_c_send = cJSON_IsTrue(jtmp); }else{ - default_access.publish_c_send = false; + g_dynsec_data.default_access.publish_c_send = false; } jtmp = cJSON_GetObjectItem(j_default_access, ACL_TYPE_PUB_C_RECV); if(jtmp && cJSON_IsBool(jtmp)){ - default_access.publish_c_recv = cJSON_IsTrue(jtmp); + g_dynsec_data.default_access.publish_c_recv = cJSON_IsTrue(jtmp); }else{ - default_access.publish_c_recv = false; + g_dynsec_data.default_access.publish_c_recv = false; } jtmp = cJSON_GetObjectItem(j_default_access, ACL_TYPE_SUB_GENERIC); if(jtmp && cJSON_IsBool(jtmp)){ - default_access.subscribe = cJSON_IsTrue(jtmp); + g_dynsec_data.default_access.subscribe = cJSON_IsTrue(jtmp); }else{ - default_access.subscribe = false; + g_dynsec_data.default_access.subscribe = false; } jtmp = cJSON_GetObjectItem(j_default_access, ACL_TYPE_UNSUB_GENERIC); if(jtmp && cJSON_IsBool(jtmp)){ - default_access.unsubscribe = cJSON_IsTrue(jtmp); + g_dynsec_data.default_access.unsubscribe = cJSON_IsTrue(jtmp); }else{ - default_access.unsubscribe = false; + g_dynsec_data.default_access.unsubscribe = false; } } return MOSQ_ERR_SUCCESS; @@ -80,10 +80,10 @@ static int dynsec__general_config_save(cJSON *tree) } cJSON_AddItemToObject(tree, "defaultACLAccess", j_default_access); - if(cJSON_AddBoolToObject(j_default_access, ACL_TYPE_PUB_C_SEND, default_access.publish_c_send) == NULL - || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_PUB_C_RECV, default_access.publish_c_recv) == NULL - || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_SUB_GENERIC, default_access.subscribe) == NULL - || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_UNSUB_GENERIC, default_access.unsubscribe) == NULL + if(cJSON_AddBoolToObject(j_default_access, ACL_TYPE_PUB_C_SEND, g_dynsec_data.default_access.publish_c_send) == NULL + || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_PUB_C_RECV, g_dynsec_data.default_access.publish_c_recv) == NULL + || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_SUB_GENERIC, g_dynsec_data.default_access.subscribe) == NULL + || cJSON_AddBoolToObject(j_default_access, ACL_TYPE_UNSUB_GENERIC, g_dynsec_data.default_access.unsubscribe) == NULL ){ return 1; diff --git a/plugins/dynamic-security/default_acl.c b/plugins/dynamic-security/default_acl.c index befc490a..8dbc4264 100644 --- a/plugins/dynamic-security/default_acl.c +++ b/plugins/dynamic-security/default_acl.c @@ -33,8 +33,6 @@ Contributors: #include "dynamic_security.h" -struct dynsec__acl_default_access default_access = {false, false, false, false}; - int dynsec__process_set_default_acl_access(cJSON *j_responses, struct mosquitto *context, cJSON *command, char *correlation_data) { cJSON *j_actions, *j_action, *j_acltype, *j_allow; @@ -59,13 +57,13 @@ int dynsec__process_set_default_acl_access(cJSON *j_responses, struct mosquitto allow = cJSON_IsTrue(j_allow); if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_PUB_C_SEND)){ - default_access.publish_c_send = allow; + g_dynsec_data.default_access.publish_c_send = allow; }else if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_PUB_C_RECV)){ - default_access.publish_c_recv = allow; + g_dynsec_data.default_access.publish_c_recv = allow; }else if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_SUB_GENERIC)){ - default_access.subscribe = allow; + g_dynsec_data.default_access.subscribe = allow; }else if(!strcasecmp(j_acltype->valuestring, ACL_TYPE_UNSUB_GENERIC)){ - default_access.unsubscribe = allow; + g_dynsec_data.default_access.unsubscribe = allow; } mosquitto_log_printf(MOSQ_LOG_INFO, "dynsec: %s/%s | setDefaultACLAccess | acltype=%s | allow=%s", admin_clientid, admin_username, j_acltype->valuestring, allow?"true":"false"); @@ -115,7 +113,7 @@ int dynsec__process_get_default_acl_access(cJSON *j_responses, struct mosquitto } cJSON_AddItemToArray(j_acls, j_acl); if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_SEND) == NULL - || cJSON_AddBoolToObject(j_acl, "allow", default_access.publish_c_send) == NULL + || cJSON_AddBoolToObject(j_acl, "allow", g_dynsec_data.default_access.publish_c_send) == NULL ){ goto internal_error; @@ -128,7 +126,7 @@ int dynsec__process_get_default_acl_access(cJSON *j_responses, struct mosquitto } cJSON_AddItemToArray(j_acls, j_acl); if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_PUB_C_RECV) == NULL - || cJSON_AddBoolToObject(j_acl, "allow", default_access.publish_c_recv) == NULL + || cJSON_AddBoolToObject(j_acl, "allow", g_dynsec_data.default_access.publish_c_recv) == NULL ){ goto internal_error; @@ -141,7 +139,7 @@ int dynsec__process_get_default_acl_access(cJSON *j_responses, struct mosquitto } cJSON_AddItemToArray(j_acls, j_acl); if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_SUB_GENERIC) == NULL - || cJSON_AddBoolToObject(j_acl, "allow", default_access.subscribe) == NULL + || cJSON_AddBoolToObject(j_acl, "allow", g_dynsec_data.default_access.subscribe) == NULL ){ goto internal_error; @@ -154,7 +152,7 @@ int dynsec__process_get_default_acl_access(cJSON *j_responses, struct mosquitto } cJSON_AddItemToArray(j_acls, j_acl); if(cJSON_AddStringToObject(j_acl, "acltype", ACL_TYPE_UNSUB_GENERIC) == NULL - || cJSON_AddBoolToObject(j_acl, "allow", default_access.unsubscribe) == NULL + || cJSON_AddBoolToObject(j_acl, "allow", g_dynsec_data.default_access.unsubscribe) == NULL ){ goto internal_error; diff --git a/plugins/dynamic-security/dynamic_security.h b/plugins/dynamic-security/dynamic_security.h index adef7a35..95435b80 100644 --- a/plugins/dynamic-security/dynamic_security.h +++ b/plugins/dynamic-security/dynamic_security.h @@ -130,8 +130,15 @@ struct dynsec__acl_default_access{ bool unsubscribe; }; -extern struct dynsec__group *dynsec_anonymous_group; -extern struct dynsec__acl_default_access default_access; +struct dynsec__data{ + struct dynsec__client *clients; + struct dynsec__group *groups; + struct dynsec__role *roles; + struct dynsec__group *anonymous_group; + struct dynsec__acl_default_access default_access; +}; + +extern struct dynsec__data g_dynsec_data; extern char *g_config_file; /* ################################################################ diff --git a/plugins/dynamic-security/groups.c b/plugins/dynamic-security/groups.c index ca33a067..dd45615d 100644 --- a/plugins/dynamic-security/groups.c +++ b/plugins/dynamic-security/groups.c @@ -34,9 +34,6 @@ Contributors: * # * ################################################################ */ -struct dynsec__group *dynsec_anonymous_group = NULL; - - /* ################################################################ * # * # Function declarations @@ -54,9 +51,6 @@ static cJSON *add_group_to_json(struct dynsec__group *group); * # * ################################################################ */ -static struct dynsec__group *local_groups = NULL; - - /* ################################################################ * # * # Utility functions @@ -65,7 +59,7 @@ static struct dynsec__group *local_groups = NULL; static void group__kick_all(struct dynsec__group *group) { - if(group == dynsec_anonymous_group){ + if(group == g_dynsec_data.anonymous_group){ mosquitto_kick_client_by_username(NULL, false); } dynsec_clientlist__kick_all(group->clientlist); @@ -86,7 +80,7 @@ struct dynsec__group *dynsec_groups__find(const char *groupname) struct dynsec__group *group = NULL; if(groupname){ - HASH_FIND(hh, local_groups, groupname, strlen(groupname), group); + HASH_FIND(hh, g_dynsec_data.groups, groupname, strlen(groupname), group); } return group; } @@ -99,7 +93,7 @@ static void group__free_item(struct dynsec__group *group) found_group = dynsec_groups__find(group->groupname); if(found_group){ - HASH_DEL(local_groups, found_group); + HASH_DEL(g_dynsec_data.groups, found_group); } dynsec__remove_all_clients_from_group(group); mosquitto_free(group->text_name); @@ -180,7 +174,7 @@ void dynsec_groups__cleanup(void) { struct dynsec__group *group, *group_tmp = NULL; - HASH_ITER(hh, local_groups, group, group_tmp){ + HASH_ITER(hh, g_dynsec_data.groups, group, group_tmp){ group__free_item(group); } } @@ -271,7 +265,7 @@ int dynsec_groups__config_load(cJSON *tree) } /* This must go before clients are loaded, otherwise the group won't be found */ - HASH_ADD_KEYPTR(hh, local_groups, group->groupname, strlen(group->groupname), group); + HASH_ADD_KEYPTR(hh, g_dynsec_data.groups, group->groupname, strlen(group->groupname), group); /* Clients */ j_clientlist = cJSON_GetObjectItem(j_group, "clients"); @@ -288,11 +282,11 @@ int dynsec_groups__config_load(cJSON *tree) } } } - HASH_SORT(local_groups, group_cmp); + HASH_SORT(g_dynsec_data.groups, group_cmp); j_group = cJSON_GetObjectItem(tree, "anonymousGroup"); if(j_group && cJSON_IsString(j_group)){ - dynsec_anonymous_group = dynsec_groups__find(j_group->valuestring); + g_dynsec_data.anonymous_group = dynsec_groups__find(j_group->valuestring); } return 0; @@ -311,7 +305,7 @@ static int dynsec__config_add_groups(cJSON *j_groups) struct dynsec__group *group, *group_tmp = NULL; cJSON *j_group, *j_clients, *j_roles; - HASH_ITER(hh, local_groups, group, group_tmp){ + HASH_ITER(hh, g_dynsec_data.groups, group, group_tmp){ j_group = cJSON_CreateObject(); if(j_group == NULL) return 1; cJSON_AddItemToArray(j_groups, j_group); @@ -354,8 +348,8 @@ int dynsec_groups__config_save(cJSON *tree) return 1; } - if(dynsec_anonymous_group - && cJSON_AddStringToObject(tree, "anonymousGroup", dynsec_anonymous_group->groupname) == NULL){ + if(g_dynsec_data.anonymous_group + && cJSON_AddStringToObject(tree, "anonymousGroup", g_dynsec_data.anonymous_group->groupname) == NULL){ return 1; } @@ -436,7 +430,7 @@ int dynsec_groups__process_create(cJSON *j_responses, struct mosquitto *context, return MOSQ_ERR_INVAL; } - HASH_ADD_KEYPTR_INORDER(hh, local_groups, group->groupname, strlen(group->groupname), group, group_cmp); + HASH_ADD_KEYPTR_INORDER(hh, g_dynsec_data.groups, group->groupname, strlen(group->groupname), group, group_cmp); admin_clientid = mosquitto_client_id(context); admin_username = mosquitto_client_username(context); @@ -744,7 +738,7 @@ int dynsec_groups__process_list(cJSON *j_responses, struct mosquitto *context, c if(cJSON_AddStringToObject(tree, "command", "listGroups") == NULL || (j_data = cJSON_AddObjectToObject(tree, "data")) == NULL - || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, local_groups)) == NULL + || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, g_dynsec_data.groups)) == NULL || (j_groups = cJSON_AddArrayToObject(j_data, "groups")) == NULL || (correlation_data && cJSON_AddStringToObject(tree, "correlationData", correlation_data) == NULL) ){ @@ -755,7 +749,7 @@ int dynsec_groups__process_list(cJSON *j_responses, struct mosquitto *context, c } i = 0; - HASH_ITER(hh, local_groups, group, group_tmp){ + HASH_ITER(hh, g_dynsec_data.groups, group, group_tmp){ if(i>=offset){ if(verbose){ j_group = add_group_to_json(group); @@ -1030,7 +1024,7 @@ int dynsec_groups__process_set_anonymous_group(cJSON *j_responses, struct mosqui return MOSQ_ERR_SUCCESS; } - dynsec_anonymous_group = group; + g_dynsec_data.anonymous_group = group; dynsec__config_save(); dynsec__command_reply(j_responses, context, "setAnonymousGroup", NULL, correlation_data); @@ -1060,8 +1054,8 @@ int dynsec_groups__process_get_anonymous_group(cJSON *j_responses, struct mosqui return MOSQ_ERR_NOMEM; } - if(dynsec_anonymous_group){ - groupname = dynsec_anonymous_group->groupname; + if(g_dynsec_data.anonymous_group){ + groupname = g_dynsec_data.anonymous_group->groupname; }else{ groupname = ""; } diff --git a/plugins/dynamic-security/plugin.c b/plugins/dynamic-security/plugin.c index 419f051b..db85a884 100644 --- a/plugins/dynamic-security/plugin.c +++ b/plugins/dynamic-security/plugin.c @@ -33,6 +33,7 @@ Contributors: MOSQUITTO_PLUGIN_DECLARE_VERSION(5); +struct dynsec__data g_dynsec_data; static mosquitto_plugin_id_t *plg_id = NULL; char *g_config_file = NULL; @@ -42,6 +43,8 @@ int mosquitto_plugin_init(mosquitto_plugin_id_t *identifier, void **user_data, s UNUSED(user_data); + memset(&g_dynsec_data, 0, sizeof(struct dynsec__data)); + for(i=0; iclientlist); dynsec_grouplist__cleanup(&role->grouplist); @@ -97,7 +88,7 @@ struct dynsec__role *dynsec_roles__find(const char *rolename) struct dynsec__role *role = NULL; if(rolename){ - HASH_FIND(hh, local_roles, rolename, strlen(rolename), role); + HASH_FIND(hh, g_dynsec_data.roles, rolename, strlen(rolename), role); } return role; } @@ -107,7 +98,7 @@ void dynsec_roles__cleanup(void) { struct dynsec__role *role, *role_tmp = NULL; - HASH_ITER(hh, local_roles, role, role_tmp){ + HASH_ITER(hh, g_dynsec_data.roles, role, role_tmp){ role__free_item(role, true); } } @@ -120,7 +111,7 @@ static void role__kick_all(struct dynsec__role *role) dynsec_clientlist__kick_all(role->clientlist); HASH_ITER(hh, role->grouplist, grouplist, grouplist_tmp){ - if(grouplist->group == dynsec_anonymous_group){ + if(grouplist->group == g_dynsec_data.anonymous_group){ mosquitto_kick_client_by_username(NULL, false); } dynsec_clientlist__kick_all(grouplist->group->clientlist); @@ -191,7 +182,7 @@ int dynsec_roles__config_save(cJSON *tree) return 1; } - HASH_ITER(hh, local_roles, role, role_tmp){ + HASH_ITER(hh, g_dynsec_data.roles, role, role_tmp){ j_role = add_role_to_json(role, true); if(j_role == NULL){ return 1; @@ -330,10 +321,10 @@ int dynsec_roles__config_load(cJSON *tree) } } - HASH_ADD_KEYPTR(hh, local_roles, role->rolename, strlen(role->rolename), role); + HASH_ADD_KEYPTR(hh, g_dynsec_data.roles, role->rolename, strlen(role->rolename), role); } } - HASH_SORT(local_roles, role_cmp); + HASH_SORT(g_dynsec_data.roles, role_cmp); return 0; } @@ -426,7 +417,7 @@ int dynsec_roles__process_create(cJSON *j_responses, struct mosquitto *context, } - HASH_ADD_KEYPTR_INORDER(hh, local_roles, role->rolename, strlen(role->rolename), role, role_cmp); + HASH_ADD_KEYPTR_INORDER(hh, g_dynsec_data.roles, role->rolename, strlen(role->rolename), role, role_cmp); dynsec__config_save(); @@ -462,7 +453,7 @@ static void role__remove_all_groups(struct dynsec__role *role) struct dynsec__grouplist *grouplist, *grouplist_tmp = NULL; HASH_ITER(hh, role->grouplist, grouplist, grouplist_tmp){ - if(grouplist->group == dynsec_anonymous_group){ + if(grouplist->group == g_dynsec_data.anonymous_group){ mosquitto_kick_client_by_username(NULL, false); } dynsec_clientlist__kick_all(grouplist->group->clientlist); @@ -559,7 +550,7 @@ int dynsec_roles__process_list(cJSON *j_responses, struct mosquitto *context, cJ if(cJSON_AddStringToObject(tree, "command", "listRoles") == NULL || (j_data = cJSON_AddObjectToObject(tree, "data")) == NULL - || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, local_roles)) == NULL + || cJSON_AddIntToObject(j_data, "totalCount", (int)HASH_CNT(hh, g_dynsec_data.roles)) == NULL || (j_roles = cJSON_AddArrayToObject(j_data, "roles")) == NULL || (correlation_data && cJSON_AddStringToObject(tree, "correlationData", correlation_data) == NULL) ){ @@ -570,7 +561,7 @@ int dynsec_roles__process_list(cJSON *j_responses, struct mosquitto *context, cJ } i = 0; - HASH_ITER(hh, local_roles, role, role_tmp){ + HASH_ITER(hh, g_dynsec_data.roles, role, role_tmp){ if(i>=offset){ j_role = add_role_to_json(role, verbose); if(j_role == NULL){