From c58b6587a522499aac183ea5116d3ce69462b0f7 Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Fri, 19 Dec 2014 10:52:22 +0100 Subject: [PATCH] Add api side implementation of plugin descriptions listing Add: * description of api function cynara_admin_list_policies_descriptions * implementation in admin-api * utilities for creating null terminated array Change-Id: I4b7d56757e22fab4cce81665f16ceef61f3a0e2c --- src/admin/api/ApiInterface.h | 2 + src/admin/api/admin-api.cpp | 116 +++++++++++++++++++++++---------------- src/admin/logic/Logic.cpp | 5 ++ src/admin/logic/Logic.h | 1 + src/admin/logic/OfflineLogic.cpp | 5 ++ src/admin/logic/OfflineLogic.h | 1 + src/admin/logic/OnlineLogic.cpp | 5 ++ src/admin/logic/OnlineLogic.h | 2 +- src/admin/logic/Utility.h | 69 +++++++++++++++++++++++ src/include/cynara-admin-types.h | 13 +++++ src/include/cynara-admin.h | 49 +++++++++++++++++ 11 files changed, 219 insertions(+), 49 deletions(-) create mode 100644 src/admin/logic/Utility.h diff --git a/src/admin/api/ApiInterface.h b/src/admin/api/ApiInterface.h index 89ac978..9484b7f 100644 --- a/src/admin/api/ApiInterface.h +++ b/src/admin/api/ApiInterface.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -56,6 +57,7 @@ public: std::vector &policies) = 0; virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter) = 0; + virtual int listDescriptions(std::vector &descriptions) = 0; }; diff --git a/src/admin/api/admin-api.cpp b/src/admin/api/admin-api.cpp index d3b6a36..10077df 100644 --- a/src/admin/api/admin-api.cpp +++ b/src/admin/api/admin-api.cpp @@ -22,11 +22,9 @@ #include #include -#include -#include #include #include -#include +#include #include #include @@ -36,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +44,8 @@ #include #include +#include +#include struct cynara_admin { Cynara::ApiInterface *impl; @@ -228,59 +229,40 @@ int cynara_admin_check(struct cynara_admin *p_cynara_admin, }); } -static int createPoliciesArray(const char *bucket, - const std::vector &policiesVector, - struct cynara_admin_policy ***policies) { - typedef struct cynara_admin_policy Elem; - size_t elems = policiesVector.size(); - - Elem **tab = reinterpret_cast(calloc(elems + 1U, sizeof(Elem*))); - if (!tab) +static int copyPolicy(const char *bucket, const Cynara::Policy &from, cynara_admin_policy *&to) { + to = reinterpret_cast(calloc(1, sizeof(cynara_admin_policy))); + if (!to) return CYNARA_API_OUT_OF_MEMORY; - std::unique_ptr> plumber(tab, - [](Elem **tab) { - for (int i = 0; tab[i] != nullptr; i++) { - free(tab[i]->bucket); - free(tab[i]->client); - free(tab[i]->user); - free(tab[i]->privilege); - free(tab[i]->result_extra); - free(tab[i]); - } - free(tab); - }); - - for (size_t i = 0U; i < elems; ++i) { - tab[i] = reinterpret_cast(calloc(1U, sizeof(Elem))); - if (!tab[i]) - return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->bucket = strdup(bucket); - if (!tab[i]->bucket) + to->bucket = strdup(bucket); + if (!to->bucket) + return CYNARA_API_OUT_OF_MEMORY; + to->client = strdup(from.key().client().value().c_str()); + if (!to->client) return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->client = strdup(policiesVector[i].key().client().value().c_str()); - if (!tab[i]->client) + to->user = strdup(from.key().user().value().c_str()); + if (!to->user) return CYNARA_API_OUT_OF_MEMORY; - tab[i]->user = strdup(policiesVector[i].key().user().value().c_str()); - if (!tab[i]->user) + to->privilege = strdup(from.key().privilege().value().c_str()); + if (!to->privilege) return CYNARA_API_OUT_OF_MEMORY; - tab[i]->privilege = strdup(policiesVector[i].key().privilege().value().c_str()); - if (!tab[i]->privilege) + to->result = static_cast(from.result().policyType()); + if (!from.result().metadata().empty()) { + to->result_extra = strdup(from.result().metadata().c_str()); + if (!to->result_extra) return CYNARA_API_OUT_OF_MEMORY; - - tab[i]->result = static_cast(policiesVector[i].result().policyType()); - if (!policiesVector[i].result().metadata().empty()) { - tab[i]->result_extra = strdup(policiesVector[i].result().metadata().c_str()); - if (!tab[i]->result_extra) - return CYNARA_API_OUT_OF_MEMORY; - } } - *policies = tab; - plumber.release(); return CYNARA_API_SUCCESS; } +static void freeElem(struct cynara_admin_policy *policyPtr) { + free(policyPtr->bucket); + free(policyPtr->client); + free(policyPtr->user); + free(policyPtr->privilege); + free(policyPtr->result_extra); + free(policyPtr); +} + CYNARA_API int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char *bucket, const char *client, const char *user, const char *privilege, @@ -313,7 +295,45 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char * if (ret != CYNARA_API_SUCCESS) return ret; - return createPoliciesArray(bucket, policiesVector, policies); + auto copyFun = std::bind(copyPolicy, bucket, std::placeholders::_1, std::placeholders::_2); + return Cynara::createNullTerminatedArray + (policiesVector, policies, copyFun); + }); +} + +static int copyDescr(const Cynara::PolicyDescription &from, cynara_admin_policy_descr *&to) { + to = reinterpret_cast(calloc(1, sizeof(cynara_admin_policy_descr))); + if (!to) + return CYNARA_API_OUT_OF_MEMORY; + to->result = static_cast(from.type); + to->name = strdup(from.name.c_str()); + if (!to->name) + return CYNARA_API_OUT_OF_MEMORY; + return CYNARA_API_SUCCESS; +} + +static void freeElem(struct cynara_admin_policy_descr *descrPtr) { + free(descrPtr->name); + free(descrPtr); +} + +CYNARA_API +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions) { + if (!p_cynara_admin || !p_cynara_admin->impl) + return CYNARA_API_INVALID_PARAM; + if (!descriptions) + return CYNARA_API_INVALID_PARAM; + + return Cynara::tryCatch([&p_cynara_admin, &descriptions] () { + std::vector descriptionsVector; + int ret = p_cynara_admin->impl->listDescriptions(descriptionsVector); + + if (ret != CYNARA_API_SUCCESS) + return ret; + return Cynara::createNullTerminatedArray + (descriptionsVector, descriptions, copyDescr); }); } diff --git a/src/admin/logic/Logic.cpp b/src/admin/logic/Logic.cpp index 57fc0b5..3f23370 100644 --- a/src/admin/logic/Logic.cpp +++ b/src/admin/logic/Logic.cpp @@ -66,6 +66,11 @@ int Logic::adminCheck(const PolicyBucketId &startBucket, bool recursive, const P recursive, std::cref(key), std::ref(result))); } +int Logic::listDescriptions(std::vector &descriptions) { + using std::placeholders::_1; + return callApiFunction(std::bind(&ApiInterface::listDescriptions, _1, std::ref(descriptions))); +} + int Logic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { using std::placeholders::_1; diff --git a/src/admin/logic/Logic.h b/src/admin/logic/Logic.h index 9a24de7..e9c7774 100644 --- a/src/admin/logic/Logic.h +++ b/src/admin/logic/Logic.h @@ -48,6 +48,7 @@ public: virtual int removeBucket(const PolicyBucketId &bucket); virtual int adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, PolicyResult &result); + virtual int listDescriptions(std::vector &descriptions); virtual int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies); virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, diff --git a/src/admin/logic/OfflineLogic.cpp b/src/admin/logic/OfflineLogic.cpp index a52a0fe..c860ad8 100644 --- a/src/admin/logic/OfflineLogic.cpp +++ b/src/admin/logic/OfflineLogic.cpp @@ -103,6 +103,11 @@ int OfflineLogic::adminCheck(const PolicyBucketId &startBucket, bool recursive, return CYNARA_API_SUCCESS; } +int OfflineLogic::listDescriptions(std::vector &descriptions) { + (void) descriptions; + return CYNARA_API_SUCCESS; +} + int OfflineLogic::listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies) { try { diff --git a/src/admin/logic/OfflineLogic.h b/src/admin/logic/OfflineLogic.h index ec180f2..fc04d5e 100644 --- a/src/admin/logic/OfflineLogic.h +++ b/src/admin/logic/OfflineLogic.h @@ -47,6 +47,7 @@ public: int removeBucket(const PolicyBucketId &bucket); int adminCheck(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &key, PolicyResult &result); + int listDescriptions(std::vector &descriptions); int listPolicies(const PolicyBucketId &bucket, const PolicyKey &filter, std::vector &policies); int erasePolicies(const PolicyBucketId &startBucket, bool recursive, diff --git a/src/admin/logic/OnlineLogic.cpp b/src/admin/logic/OnlineLogic.cpp index 9aa1831..6626a77 100644 --- a/src/admin/logic/OnlineLogic.cpp +++ b/src/admin/logic/OnlineLogic.cpp @@ -205,4 +205,9 @@ int OnlineLogic::erasePolicies(const PolicyBucketId &startBucket, bool recursive return askCynaraAndInterpreteCodeResponse(startBucket, recursive, filter); } +int OnlineLogic::listDescriptions(std::vector &descriptions) { + (void) descriptions; + return CYNARA_API_SUCCESS; +} + } // namespace Cynara diff --git a/src/admin/logic/OnlineLogic.h b/src/admin/logic/OnlineLogic.h index 19e3304..84becd7 100644 --- a/src/admin/logic/OnlineLogic.h +++ b/src/admin/logic/OnlineLogic.h @@ -52,7 +52,7 @@ public: std::vector &policies); virtual int erasePolicies(const PolicyBucketId &startBucket, bool recursive, const PolicyKey &filter); - + virtual int listDescriptions(std::vector &descriptions); }; } // namespace Cynara diff --git a/src/admin/logic/Utility.h b/src/admin/logic/Utility.h new file mode 100644 index 0000000..10e62da --- /dev/null +++ b/src/admin/logic/Utility.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License + */ +/** + * @file src/admin/logic/Utility.h + * @author Zofia Abramowska + * @version 1.0 + * @brief This file contains implementation of utility function for managing null pointer + * terminated lists. + */ + +#ifndef SRC_ADMIN_LOGIC_UTILITY_H_ +#define SRC_ADMIN_LOGIC_UTILITY_H_ + +#include +#include +#include +#include + +#include + +namespace Cynara { + +//This function requires proper freeElem function for given type T. +template +static void freeNullTerminatedList(T **list) { + for (int i = 0; list[i]; i++) { + freeElem(list[i]); + } + free(list); +} + +template +static int createNullTerminatedArray(const std::vector &vectorized, T ***array, + std::function copyFun) { + size_t elems = vectorized.size(); + + T **tab = reinterpret_cast(calloc(elems + 1U, sizeof(T*))); + if (!tab) + return CYNARA_API_OUT_OF_MEMORY; + + std::unique_ptr> plumber(tab, freeNullTerminatedList); + + for (size_t i = 0; i < elems; i++) { + int ret = copyFun(vectorized[i], tab[i]); + if (ret != CYNARA_API_SUCCESS) + return ret; + } + + *array = tab; + plumber.release(); + return CYNARA_API_SUCCESS; +} + +} // namespace Cynara + +#endif /* SRC_ADMIN_LOGIC_UTILITY_H_ */ diff --git a/src/include/cynara-admin-types.h b/src/include/cynara-admin-types.h index b83c81d..bb4c1bf 100644 --- a/src/include/cynara-admin-types.h +++ b/src/include/cynara-admin-types.h @@ -17,6 +17,7 @@ * \file src/include/cynara-admin-types.h * \author Lukasz Wojciechowski * \author Aleksander Zdyb + * \author Zofia Abramowska * \version 1.0 * \brief This file contains structs and consts for cynara admin. */ @@ -49,6 +50,18 @@ struct cynara_admin_policy { }; /** + * \name cynara_admin_policy_descr + * describes policy of type given with result + * result - result of policy to describe + * name - name of given policy result + */ + +struct cynara_admin_policy_descr { + int result; + char *name; +}; + +/** * \name Wildcard * definition of WILDCARD, that can replace client, user or privilege name. * WILDCARD matches any string during check procedure from libcynara-client. diff --git a/src/include/cynara-admin.h b/src/include/cynara-admin.h index bb1b8d1..0d958f8 100644 --- a/src/include/cynara-admin.h +++ b/src/include/cynara-admin.h @@ -16,6 +16,7 @@ /** * @file src/include/cynara-admin.h * \author Lukasz Wojciechowski + * \author Zofia Abramowska * \version 1.0 * \brief This file contains administration APIs of cynara available with libcynara-admin. */ @@ -358,6 +359,54 @@ int cynara_admin_list_policies(struct cynara_admin *p_cynara_admin, const char * int cynara_admin_erase(struct cynara_admin *p_cynara_admin, const char *start_bucket, int recursive, const char *client, const char *user, const char *privilege); + +/** + * \par Description: + * + * Lists available cynara policy results with name description. + * + * \par Purpose: + * This API should be used to list all available policy results + * (also from cynara extension plugins). + * + * \par Typical use case: + * Gathering information about possible policy results and presenting them to user (using name + * attribute of description). Result can be passed to cynara_admin_set_policies(). + * + * \par Method of function operation: + * Policies are based on policy result number. Policies can be built in (like primitives: ALLOW, + * DENY...) or can be loaded from cynara plugin extensions. This API gives possibility of checking, + * which of these result exist in current cynara server and can be presented to user in a readable + * way (of course additional translation may be needed). + * + * Descriptions of existing policy results are returned as NULL terminated array of pointers of + * cynara_admin_policy_descr structures. + * + * Example output could be {{0, "Deny"}, {11, "AskUser"}, {65535, "Allow"}, NULL} + * + * In case of successful call CYNARA_API_SUCCESS is returned and *descriptions points + * to newly created array of pointers to struct cynara_admin_policy_descr. It is responsibility + * of caller to release: + * * all non-NULL char* pointers in all cynara_admin_policy_descr structures; + * * all pointers to cynara_admin_policy_descr structures kept in *descriptions array; + * * *descriptions array itself. + * All allocation made by cynara admin library are done with malloc(3) function and must be released + * with free(3) function. + * + * \par Sync (or) Async: + * This is a synchronous API. + * + * \param[in] p_cynara_admin cynara admin structure. + * \param[out] descriptions placeholder for NULL terminated array of pointers of + * description structures. + * + * \return CYNARA_API_SUCCESS on success, or error code otherwise. + * + * \brief Lists available policies with their name description. + */ +int cynara_admin_list_policies_descriptions(struct cynara_admin *p_cynara_admin, + struct cynara_admin_policy_descr ***descriptions); + #ifdef __cplusplus } #endif -- 2.7.4