2 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Rafal Krypa <r.krypa@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License
20 * @author Rafal Krypa <r.krypa@samsung.com>
21 * @brief Wrapper class for Cynara interface
24 #ifndef _SECURITY_MANAGER_CYNARA_
25 #define _SECURITY_MANAGER_CYNARA_
27 #include <cynara-client-async.h>
28 #include <cynara-admin.h>
29 #include <dpl/exception.h>
38 #include <sys/eventfd.h>
40 #include "security-manager.h"
42 namespace SecurityManager {
59 DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
60 DECLARE_EXCEPTION_TYPE(Base, MaxPendingRequests)
61 DECLARE_EXCEPTION_TYPE(Base, OutOfMemory)
62 DECLARE_EXCEPTION_TYPE(Base, InvalidParam)
63 DECLARE_EXCEPTION_TYPE(Base, ServiceNotAvailable)
64 DECLARE_EXCEPTION_TYPE(Base, MethodNotSupported)
65 DECLARE_EXCEPTION_TYPE(Base, OperationNotAllowed)
66 DECLARE_EXCEPTION_TYPE(Base, OperationFailed)
67 DECLARE_EXCEPTION_TYPE(Base, BucketNotFound)
68 DECLARE_EXCEPTION_TYPE(Base, UnknownError)
71 struct CynaraAdminPolicy : cynara_admin_policy
73 enum class Operation {
74 Deny = CYNARA_ADMIN_DENY,
75 Allow = CYNARA_ADMIN_ALLOW,
76 Delete = CYNARA_ADMIN_DELETE,
77 Bucket = CYNARA_ADMIN_BUCKET,
80 CynaraAdminPolicy(const std::string &client, const std::string &user,
81 const std::string &privilege, int operation,
82 const std::string &bucket = std::string(CYNARA_ADMIN_DEFAULT_BUCKET));
84 CynaraAdminPolicy(const std::string &client, const std::string &user,
85 const std::string &privilege, const std::string &goToBucket,
86 const std::string &bucket = std::string(CYNARA_ADMIN_DEFAULT_BUCKET));
88 /* Don't provide copy constructor, it would cause pointer trouble. */
89 CynaraAdminPolicy(const CynaraAdminPolicy &that) = delete;
91 /* Move constructor is the way to go. */
92 CynaraAdminPolicy(CynaraAdminPolicy &&that);
93 CynaraAdminPolicy& operator=(CynaraAdminPolicy &&that);
102 typedef std::map<Bucket, const std::string > BucketsMap;
103 static BucketsMap Buckets;
105 typedef std::map<int, std::string> TypeToDescriptionMap;
106 typedef std::map<std::string, int> DescriptionToTypeMap;
108 virtual ~CynaraAdmin();
110 static CynaraAdmin &getInstance();
113 * Update Cynara policies.
114 * Caller must have permission to access Cynara administrative socket.
116 * @param policies vector of CynaraAdminPolicy objects to send to Cynara
118 void SetPolicies(const std::vector<CynaraAdminPolicy> &policies);
121 * Update Cynara policies for the application and the user.
122 * Difference will be calculated, removing old unneeded privileges and
123 * adding new, previously not enabled privileges.
124 * Caller must have permission to access Cynara administrative socket.
126 * @param label application Smack label
127 * @param user user identifier
128 * @param privileges currently enabled privileges
131 void UpdateAppPolicy(const std::string &label, const std::string &user,
132 const std::vector<std::string> &privileges);
135 * Depending on user type, create link between MAIN bucket and appropriate
136 * USER_TYPE_* bucket for newly added user uid to apply permissions for that
138 * @throws CynaraException::InvalidParam.
140 * @param uid new user uid
141 * @param userType type as enumerated in security-manager.h
143 void UserInit(uid_t uid, security_manager_user_type userType);
146 * List all users registered in Cynara
148 * @param[out] listOfUsers list of users
150 void ListUsers(std::vector<uid_t> &listOfUsers);
153 * Removes all entries for a user from cynara database
155 * @param uid removed user uid
157 void UserRemove(uid_t uid);
160 * List Cynara policies that match selected criteria in given bucket.
162 * @param bucketName name of the bucket to search policies in
163 * @param appId string with id of app to match in search
164 * @param user user string to match in search
165 * @param privilege privilege string to match in search
166 * @param policies empty vector for results of policies filtering.
169 void ListPolicies(const std::string &bucketName,
170 const std::string &appId,
171 const std::string &user,
172 const std::string &privilege,
173 std::vector<CynaraAdminPolicy> &policies);
176 * Wrapper for Cynara API function cynara_admin_list_policies_descriptions.
177 * It collects all policies descriptions, extracts names
178 * of policies and returns as std strings. Caller is responsible for clearing
179 * vector passed as argument.
181 * @param policiesDescriptions empty vector for policies descriptions.
183 void ListPoliciesDescriptions(std::vector<std::string> &policiesDescriptions);
186 * Function translates internal Cynara policy type integer to string
187 * description. Descriptions are retrieved from Cynara using
188 * ListPoliciesDescriptions() function. Caller can force refetching of
189 * descriptions list from Cynara on each call.
191 * @throws std::out_of_range
193 * @param policyType Cynara policy result type.
194 * @param forceRefresh switch to force refetching of descriptions from Cynara.
196 std::string convertToPolicyDescription(const int policyType, bool forceRefresh = false);
199 * Function translates Cynara policy result string
200 * description to internal Cynara policy type integer.
201 * Descriptions are retrieved from Cynara using
202 * ListPoliciesDescriptions() function. Caller can force refetching of
203 * descriptions list from Cynara on each call.
205 * @throws std::out_of_range
207 * @param policy Cynara policy result string description.
208 * @param forceRefresh switch to force refetching of descriptions from Cynara.
210 int convertToPolicyType(const std::string &policy, bool forceRefresh = false);
213 * Ask Cynara for permission starting the search at specified bucket.
214 * Essentialy a wrapper on cynara_admin_check.
216 * @param label application Smack label
217 * @param privilege privilege string to match in search
218 * @param user user string to match in search
219 * @param bucket name of the bucket to search policies in
220 * @param result integer to return policy result
221 * @param resultExtra string to return additional information about policy
222 * result. If result is Bucket then resultExtra is the name of
224 * @param recursive flag to indicate if check should be done recursively in
225 * all buckets linked with bucket provided
227 void Check(const std::string &label,
228 const std::string &user,
229 const std::string &privilege,
230 const std::string &bucket,
232 std::string &resultExtra,
233 const bool recursive);
236 * Get current policy level for privilege-manager functionality
237 * Returns current policy value for given application, user and privilege
240 * @param label application Smack label
241 * @param user user identifier (uid)
242 * @param privilege privilege identifier
243 * @return current policy value
245 int GetPrivilegeManagerCurrLevel(const std::string &label, const std::string &user,
246 const std::string &privilege);
249 * Get maximum policy level for privilege-manager functionality
250 * Returns maximum possible policy value for given application, user and privilege
251 * identifiers. The maximum limit is imposed by other policy settings that are
252 * currently in place.
254 * @param label application Smack label
255 * @param user user identifier (uid)
256 * @param privilege privilege identifier
257 * @return maximum policy value for PRIVACY_MANAGER bucket
259 int GetPrivilegeManagerMaxLevel(const std::string &label, const std::string &user,
260 const std::string &privilege);
266 * Empty bucket using filter - matching rules will be removed
268 * @param bucketName name of the bucket to be emptied
269 * @param recursive flag to remove privileges recursively
270 * @param client client name
271 * @param user user name
272 * @param privilege privilege name
274 void EmptyBucket(const std::string &bucketName, bool recursive,
275 const std::string &client, const std::string &user, const std::string &privilege);
278 * Get Cynara policies result descriptions and cache them in std::map
280 * @param forceRefresh true if you want to reinitialize mappings
282 void FetchCynaraPolicyDescriptions(bool forceRefresh = false);
284 struct cynara_admin *m_CynaraAdmin;
286 static TypeToDescriptionMap TypeToDescription;
287 static DescriptionToTypeMap DescriptionToType;
288 bool m_policyDescriptionsInitialized;
296 static Cynara &getInstance();
299 * Ask Cynara for permission.
301 * @param label application Smack label
302 * @param privilege privilege identifier
303 * @param user user identifier (uid)
304 * @param session session identifier
305 * @return true if access is permitted, false if denied
307 bool check(const std::string &label, const std::string &privilege,
308 const std::string &user, const std::string &session);
313 static void statusCallback(int oldFd, int newFd,
314 cynara_async_status status, void *ptr);
316 static void responseCallback(cynara_check_id checkId,
317 cynara_async_call_cause cause, int response, void *ptr);
321 void threadNotifyPut();
322 void threadNotifyGet();
324 cynara_async *cynara;
325 struct pollfd pollFds[2];
328 std::atomic<bool> terminate{false};
331 } // namespace SecurityManager
333 #endif // _SECURITY_MANAGER_CYNARA_