Merge lp:~ansharyan015/drizzle/regex_policy_dynamic_fix into lp:drizzle
- regex_policy_dynamic_fix
- Merge into 7.2
Proposed by
Daniel Nichter
Status: | Merged |
---|---|
Approved by: | Brian Aker |
Approved revision: | 2566 |
Merged at revision: | 2566 |
Proposed branch: | lp:~ansharyan015/drizzle/regex_policy_dynamic_fix |
Merge into: | lp:drizzle |
Diff against target: |
424 lines (+206/-61) 9 files modified
plugin/regex_policy/docs/index.rst (+17/-1) plugin/regex_policy/module.cc (+136/-56) plugin/regex_policy/policy.h (+11/-4) plugin/regex_policy/tests/r/dynamic_plugin.result (+13/-0) plugin/regex_policy/tests/t/dynamic.policy1 (+3/-0) plugin/regex_policy/tests/t/dynamic.policy2 (+3/-0) plugin/regex_policy/tests/t/dynamic.policy3 (+3/-0) plugin/regex_policy/tests/t/dynamic_plugin-master.opt (+1/-0) plugin/regex_policy/tests/t/dynamic_plugin.test (+19/-0) |
To merge this branch: | bzr merge lp:~ansharyan015/drizzle/regex_policy_dynamic_fix |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Daniel Nichter (community) | code review | Approve | |
Drizzle Merge Team | Pending | ||
Review via email: mp+108953@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Daniel Nichter (daniel-nichter) : | # |
review:
Approve
(code review)
Revision history for this message
Olaf van der Spek (olafvdspek) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'plugin/regex_policy/docs/index.rst' |
2 | --- plugin/regex_policy/docs/index.rst 2012-03-30 22:15:42 +0000 |
3 | +++ plugin/regex_policy/docs/index.rst 2012-06-06 15:11:21 +0000 |
4 | @@ -4,7 +4,7 @@ |
5 | ========================= |
6 | |
7 | :program:`regex_policy` is an :doc:`/administration/authorization` plugin |
8 | -that uses regex patterns to match policies. |
9 | +that uses regex patterns to match policies. When :program:`drizzled` is started with ``--plugin-add=regex_policy``, the regex policy plugin is enabled with the default policy file. Policy file can be specified by either specifying ``--regex-policy.policy=<policy file>`` at the time of server startup or by changing the ``regex_policy_policy`` with ``SET GLOBAL``. |
10 | |
11 | .. _regex_policy_loading: |
12 | |
13 | @@ -84,6 +84,22 @@ |
14 | .+ schema=.+ DENY |
15 | .+ process=.+ DENY |
16 | |
17 | +Changing policy file at runtime |
18 | +------------------------------- |
19 | + |
20 | +Policy file can be reloaded by:: |
21 | + |
22 | + SET GLOBAL regex_policy_policy=@@regex_policy_policy |
23 | + |
24 | +Moreover, the policy file can be changed by:: |
25 | + |
26 | + SET GLOBAL regex_policy_policy=/path/to/new/policy/file |
27 | + |
28 | +Examples |
29 | +-------- |
30 | + |
31 | +Sorry, there are no examples for this plugin. |
32 | + |
33 | .. _regex_policy_authors: |
34 | |
35 | Authors |
36 | |
37 | === modified file 'plugin/regex_policy/module.cc' |
38 | --- plugin/regex_policy/module.cc 2012-04-08 17:16:29 +0000 |
39 | +++ plugin/regex_policy/module.cc 2012-06-06 15:11:21 +0000 |
40 | @@ -27,6 +27,7 @@ |
41 | #include <boost/unordered_set.hpp> |
42 | #include <boost/thread/locks.hpp> |
43 | |
44 | +#include <drizzled/item.h> |
45 | #include <drizzled/plugin/authorization.h> |
46 | #include <drizzled/module/option_map.h> |
47 | |
48 | @@ -44,59 +45,35 @@ |
49 | |
50 | uint64_t max_cache_buckets= DEFAULT_MAX_CACHE_BUCKETS; |
51 | uint64_t max_lru_length= DEFAULT_MAX_LRU_LENGTH; |
52 | - |
53 | -static int init(module::Context &context) |
54 | -{ |
55 | - const module::option_map &vm= context.getOptions(); |
56 | - |
57 | - max_cache_buckets= vm["max-cache-buckets"].as<uint64_t>(); |
58 | - if (max_cache_buckets < 1) |
59 | - { |
60 | - errmsg_printf(error::ERROR, _("max-cache-buckets is too low, must be greater than 0")); |
61 | - return 1; |
62 | - } |
63 | - max_lru_length= vm["max-lru-length"].as<uint64_t>(); |
64 | - if (max_lru_length < 1) |
65 | - { |
66 | - errmsg_printf(error::ERROR, _("max-lru-length is too low, must be greater than 0")); |
67 | - return 1; |
68 | - } |
69 | - Policy *policy= new Policy(fs::path(vm["policy"].as<string>())); |
70 | - if (not policy->loadFile()) |
71 | - { |
72 | - errmsg_printf(error::ERROR, _("Could not load regex policy file: %s\n"), |
73 | - (policy ? policy->getError().str().c_str() : _("Unknown"))); |
74 | - delete policy; |
75 | - return 1; |
76 | - } |
77 | - |
78 | - context.add(policy); |
79 | - context.registerVariable(new sys_var_const_string_val("policy", vm["policy"].as<string>())); |
80 | - |
81 | - return 0; |
82 | -} |
83 | - |
84 | -static void init_options(drizzled::module::option_context &context) |
85 | -{ |
86 | - context("policy", |
87 | - po::value<string>()->default_value(DEFAULT_POLICY_FILE.string()), |
88 | - N_("File to load for regex authorization policies")); |
89 | - context("max-cache-buckets", |
90 | - po::value<uint64_t>()->default_value(DEFAULT_MAX_CACHE_BUCKETS), |
91 | - N_("Maximum buckets for authorization cache")); |
92 | - context("max-lru-length", |
93 | - po::value<uint64_t>()->default_value(DEFAULT_MAX_LRU_LENGTH), |
94 | - N_("Maximum number of LRU entries to track at once")); |
95 | -} |
96 | - |
97 | -bool Policy::loadFile() |
98 | -{ |
99 | - ifstream file(policy_file.string().c_str()); |
100 | +bool updatePolicyFile(Session *, set_var *); |
101 | +bool parsePolicyFile(std::string, PolicyItemList&, PolicyItemList&, PolicyItemList&); |
102 | +Policy *policy= NULL; |
103 | + |
104 | +bool updatePolicyFile(Session *, set_var* var) |
105 | +{ |
106 | + if (not var->value->str_value.empty()) |
107 | + { |
108 | + std::string newPolicyFile(var->value->str_value.data()); |
109 | + if (policy->setPolicyFile(newPolicyFile)) |
110 | + return false; //success |
111 | + else |
112 | + return true; // error |
113 | + } |
114 | + errmsg_printf(error::ERROR, _("regex_policy file cannot be NULL")); |
115 | + return true; // error |
116 | +} |
117 | + |
118 | +bool parsePolicyFile(std::string new_policy_file, PolicyItemList& table_policies_dummy, PolicyItemList& schema_policies_dummy, PolicyItemList& process_policies_dummy) |
119 | +{ |
120 | + ifstream file(new_policy_file.c_str()); |
121 | boost::regex comment_re; |
122 | boost::regex empty_re; |
123 | boost::regex table_matches_re; |
124 | boost::regex process_matches_re; |
125 | boost::regex schema_matches_re; |
126 | + table_policies_dummy.clear(); |
127 | + schema_policies_dummy.clear(); |
128 | + process_policies_dummy.clear(); |
129 | |
130 | try |
131 | { |
132 | @@ -108,13 +85,14 @@ |
133 | } |
134 | catch (const std::exception &e) |
135 | { |
136 | - error << e.what(); |
137 | + errmsg_printf(error::ERROR, _(e.what())); |
138 | return false; |
139 | } |
140 | |
141 | if (! file.is_open()) |
142 | { |
143 | - error << "Unable to open regex policy file: " << policy_file.string(); |
144 | + string error_msg= "Unable to open regex policy file: " + new_policy_file; |
145 | + errmsg_printf(error::ERROR, _(error_msg.c_str())); |
146 | return false; |
147 | } |
148 | |
149 | @@ -136,15 +114,15 @@ |
150 | PolicyItemList *policies; |
151 | if (boost::regex_match(line, matches, table_matches_re, boost::match_extra)) |
152 | { |
153 | - policies= &table_policies; |
154 | + policies= &table_policies_dummy; |
155 | } |
156 | else if (boost::regex_match(line, matches, process_matches_re, boost::match_extra)) |
157 | { |
158 | - policies= &process_policies; |
159 | + policies= &process_policies_dummy; |
160 | } |
161 | else if (boost::regex_match(line, matches, schema_matches_re, boost::match_extra)) |
162 | { |
163 | - policies= &schema_policies; |
164 | + policies= &schema_policies_dummy; |
165 | } |
166 | else |
167 | { |
168 | @@ -159,7 +137,8 @@ |
169 | } |
170 | catch (const std::exception &e) |
171 | { |
172 | - error << "Bad policy item: user=" << user_regex << " object=" << object_regex << " action=" << action; |
173 | + string error_msg= "Bad policy item: user=" + user_regex + " object=" + object_regex + " action=" + action; |
174 | + errmsg_printf(error::ERROR, _(error_msg.c_str())); |
175 | throw std::exception(); |
176 | } |
177 | } |
178 | @@ -168,9 +147,95 @@ |
179 | catch (const std::exception &e) |
180 | { |
181 | /* On any non-EOF break, unparseable line */ |
182 | - error << "Unable to parse line " << lines << " of policy file " << policy_file.string() << ":" << e.what(); |
183 | + string error_msg= "Unable to parse policy file " + new_policy_file + ":" + e.what(); |
184 | + errmsg_printf(error::ERROR, _(error_msg.c_str())); |
185 | return false; |
186 | } |
187 | + |
188 | +} |
189 | + |
190 | +static int init(module::Context &context) |
191 | +{ |
192 | + const module::option_map &vm= context.getOptions(); |
193 | + |
194 | + max_cache_buckets= vm["max-cache-buckets"].as<uint64_t>(); |
195 | + if (max_cache_buckets < 1) |
196 | + { |
197 | + errmsg_printf(error::ERROR, _("max-cache-buckets is too low, must be greater than 0")); |
198 | + return 1; |
199 | + } |
200 | + max_lru_length= vm["max-lru-length"].as<uint64_t>(); |
201 | + if (max_lru_length < 1) |
202 | + { |
203 | + errmsg_printf(error::ERROR, _("max-lru-length is too low, must be greater than 0")); |
204 | + return 1; |
205 | + } |
206 | + policy= new Policy(vm["policy"].as<string>()); |
207 | + if (!policy->setPolicyFile(policy->getPolicyFile())) |
208 | + { |
209 | + errmsg_printf(error::ERROR, _("Could not load regex policy file: %s\n"), |
210 | + (policy ? policy->getError().str().c_str() : _("Unknown"))); |
211 | + delete policy; |
212 | + return 1; |
213 | + } |
214 | + context.add(policy); |
215 | + context.registerVariable(new sys_var_std_string("policy", policy->getPolicyFile(), NULL, &updatePolicyFile)); |
216 | + |
217 | + return 0; |
218 | +} |
219 | + |
220 | +static void init_options(drizzled::module::option_context &context) |
221 | +{ |
222 | + context("policy", |
223 | + po::value<string>()->default_value(DEFAULT_POLICY_FILE.string()), |
224 | + N_("File to load for regex authorization policies")); |
225 | + context("max-cache-buckets", |
226 | + po::value<uint64_t>()->default_value(DEFAULT_MAX_CACHE_BUCKETS), |
227 | + N_("Maximum buckets for authorization cache")); |
228 | + context("max-lru-length", |
229 | + po::value<uint64_t>()->default_value(DEFAULT_MAX_LRU_LENGTH), |
230 | + N_("Maximum number of LRU entries to track at once")); |
231 | +} |
232 | + |
233 | +void Policy::setPolicies(PolicyItemList new_table_policies, PolicyItemList new_schema_policies, PolicyItemList new_process_policies) |
234 | +{ |
235 | + policy->clearPolicies(); |
236 | + |
237 | + for (PolicyItemList::iterator it= new_table_policies.begin(); it!= new_table_policies.end(); it++) |
238 | + table_policies.push_back(*it); |
239 | + |
240 | + for (PolicyItemList::iterator it= new_schema_policies.begin(); it!= new_schema_policies.end(); it++) |
241 | + schema_policies.push_back(*it); |
242 | + |
243 | + for (PolicyItemList::iterator it= new_process_policies.begin(); it!= new_process_policies.end(); it++) |
244 | + process_policies.push_back(*it); |
245 | +} |
246 | + |
247 | +std::string& Policy::getPolicyFile() |
248 | +{ |
249 | + return sysvar_policy_file; |
250 | +} |
251 | + |
252 | +bool Policy::setPolicyFile(std::string &new_policy_file) |
253 | +{ |
254 | + if (new_policy_file.empty()) |
255 | + { |
256 | + errmsg_printf(error::ERROR, _("regex_policy file cannot be an empty string")); |
257 | + return false; // error |
258 | + } |
259 | + |
260 | + PolicyItemList new_table_policies; |
261 | + PolicyItemList new_schema_policies; |
262 | + PolicyItemList new_process_policies; |
263 | + if(parsePolicyFile(new_policy_file, new_table_policies, new_schema_policies, new_process_policies)) |
264 | + { |
265 | + policy->setPolicies(new_table_policies, new_schema_policies, new_process_policies); |
266 | + sysvar_policy_file= new_policy_file; |
267 | + fs::path newPolicyFile(getPolicyFile()); |
268 | + policy_file= newPolicyFile; |
269 | + return true; // success |
270 | + } |
271 | + return false; // error |
272 | } |
273 | |
274 | static void clearPolicyItemList(PolicyItemList& policies) |
275 | @@ -188,6 +253,21 @@ |
276 | clearPolicyItemList(schema_policies); |
277 | } |
278 | |
279 | +/* |
280 | +This function will be called when the policy file needs to be reloaded. |
281 | +This deletes all the policies stored and cached. |
282 | +*/ |
283 | +void Policy::clearPolicies() |
284 | +{ |
285 | + table_policies.clear(); |
286 | + process_policies.clear(); |
287 | + schema_policies.clear(); |
288 | + table_check_cache.clear(); |
289 | + process_check_cache.clear(); |
290 | + schema_check_cache.clear(); |
291 | +} |
292 | + |
293 | + |
294 | bool Policy::restrictObject(const drizzled::identifier::User &user_ctx, |
295 | const string &obj, const PolicyItemList &policies, |
296 | CheckMap &check_cache) |
297 | @@ -353,7 +433,7 @@ |
298 | { |
299 | DRIZZLE_VERSION_ID, |
300 | "regex_policy", |
301 | - "2.0", |
302 | + "2.1", |
303 | "Clint Byrum", |
304 | N_("Authorization using a regex-matched policy file"), |
305 | PLUGIN_LICENSE_GPL, |
306 | |
307 | === modified file 'plugin/regex_policy/policy.h' |
308 | --- plugin/regex_policy/policy.h 2012-04-08 17:16:29 +0000 |
309 | +++ plugin/regex_policy/policy.h 2012-06-06 15:11:21 +0000 |
310 | @@ -118,6 +118,10 @@ |
311 | public: |
312 | bool* find(std::string const&k); |
313 | void insert(std::string const &k, bool v); |
314 | + void clear() |
315 | + { |
316 | + map.clear(); |
317 | + } |
318 | }; |
319 | |
320 | class CheckItem |
321 | @@ -161,8 +165,8 @@ |
322 | public drizzled::plugin::Authorization |
323 | { |
324 | public: |
325 | - Policy(const fs::path &f_path) : |
326 | - drizzled::plugin::Authorization("regex_policy"), policy_file(f_path), error(), |
327 | + Policy(const std::string &f_path) : |
328 | + drizzled::plugin::Authorization("regex_policy"), sysvar_policy_file(f_path), policy_file(f_path), error(), |
329 | table_check_cache(), schema_check_cache(), process_check_cache() |
330 | { } |
331 | |
332 | @@ -175,15 +179,18 @@ |
333 | virtual bool restrictTable(const drizzled::identifier::User& user_ctx, |
334 | const drizzled::identifier::Table& table); |
335 | |
336 | - bool loadFile(); |
337 | + void setPolicies(PolicyItemList new_table_policies, PolicyItemList new_schema_policies, PolicyItemList new_process_policies); |
338 | + void clearPolicies(); |
339 | + std::string& getPolicyFile(); |
340 | + bool setPolicyFile(std::string& new_policy_file); |
341 | std::stringstream &getError() { return error; } |
342 | ~Policy(); |
343 | private: |
344 | bool restrictObject(const drizzled::identifier::User &user_ctx, |
345 | const std::string &obj, const PolicyItemList &policies, |
346 | CheckMap &check_cache); |
347 | + std::string sysvar_policy_file; |
348 | fs::path policy_file; |
349 | - |
350 | std::stringstream error; |
351 | PolicyItemList table_policies; |
352 | PolicyItemList schema_policies; |
353 | |
354 | === added file 'plugin/regex_policy/tests/r/dynamic_plugin.result' |
355 | --- plugin/regex_policy/tests/r/dynamic_plugin.result 1970-01-01 00:00:00 +0000 |
356 | +++ plugin/regex_policy/tests/r/dynamic_plugin.result 2012-06-06 15:11:21 +0000 |
357 | @@ -0,0 +1,13 @@ |
358 | +SHOW SCHEMAS; |
359 | +Database |
360 | +DATA_DICTIONARY |
361 | +INFORMATION_SCHEMA |
362 | +mysql |
363 | +test |
364 | +SET GLOBAL regex_policy_policy=""; |
365 | +ERROR HY000: Incorrect arguments to SET |
366 | +SET GLOBAL regex_policy_policy="TOP_SRCDIR/plugin/regex_policy/tests/t/dynamic.policy2"; |
367 | +SHOW SCHEMAS; |
368 | +ERROR 42000: Access denied for user 'root' to schema 'data_dictionary' |
369 | +SET GLOBAL regex_policy_policy="TOP_SRCDIR/plugin/regex_policy/tests/t/dynamic.policy3"; |
370 | +ERROR HY000: Incorrect arguments to SET |
371 | |
372 | === added file 'plugin/regex_policy/tests/t/dynamic.policy1' |
373 | --- plugin/regex_policy/tests/t/dynamic.policy1 1970-01-01 00:00:00 +0000 |
374 | +++ plugin/regex_policy/tests/t/dynamic.policy1 2012-06-06 15:11:21 +0000 |
375 | @@ -0,0 +1,3 @@ |
376 | +# Default to accept everything |
377 | +.+ schema=.+ ACCEPT |
378 | +.+ process=.+ ACCEPT |
379 | |
380 | === added file 'plugin/regex_policy/tests/t/dynamic.policy2' |
381 | --- plugin/regex_policy/tests/t/dynamic.policy2 1970-01-01 00:00:00 +0000 |
382 | +++ plugin/regex_policy/tests/t/dynamic.policy2 2012-06-06 15:11:21 +0000 |
383 | @@ -0,0 +1,3 @@ |
384 | +# Default to deny everything |
385 | +.+ schema=.+ DENY |
386 | +.+ process=.+ DENY |
387 | |
388 | === added file 'plugin/regex_policy/tests/t/dynamic.policy3' |
389 | --- plugin/regex_policy/tests/t/dynamic.policy3 1970-01-01 00:00:00 +0000 |
390 | +++ plugin/regex_policy/tests/t/dynamic.policy3 2012-06-06 15:11:21 +0000 |
391 | @@ -0,0 +1,3 @@ |
392 | +# Syntax error in the policy file. In line 1 in place of 'ACCEPT', 'ACCEP' is written. |
393 | +.+ schema=.+ ACCEP |
394 | +.+ process=.+ ACCEPT |
395 | |
396 | === added file 'plugin/regex_policy/tests/t/dynamic_plugin-master.opt' |
397 | --- plugin/regex_policy/tests/t/dynamic_plugin-master.opt 1970-01-01 00:00:00 +0000 |
398 | +++ plugin/regex_policy/tests/t/dynamic_plugin-master.opt 2012-06-06 15:11:21 +0000 |
399 | @@ -0,0 +1,1 @@ |
400 | +--plugin-add=regex_policy --regex-policy.policy=$TOP_SRCDIR/plugin/regex_policy/tests/t/dynamic.policy1 --verbose=INSPECT |
401 | |
402 | === added file 'plugin/regex_policy/tests/t/dynamic_plugin.test' |
403 | --- plugin/regex_policy/tests/t/dynamic_plugin.test 1970-01-01 00:00:00 +0000 |
404 | +++ plugin/regex_policy/tests/t/dynamic_plugin.test 2012-06-06 15:11:21 +0000 |
405 | @@ -0,0 +1,19 @@ |
406 | +# Test that the access to schemas is allowed according to policy file |
407 | +SHOW SCHEMAS; |
408 | + |
409 | +#Test that the regex_policy_policy can't be replaced with an empty value |
410 | +--error ER_WRONG_ARGUMENTS |
411 | +SET GLOBAL regex_policy_policy=""; |
412 | + |
413 | +#Test that the regex_policy_policy can be replaced with a different file |
414 | +--replace_result $TOP_SRCDIR TOP_SRCDIR |
415 | +eval SET GLOBAL regex_policy_policy="$TOP_SRCDIR/plugin/regex_policy/tests/t/dynamic.policy2"; |
416 | + |
417 | +#Test that the access to schemas is now denied according to the new policy file |
418 | +--error ER_DBACCESS_DENIED_ERROR |
419 | +SHOW SCHEMAS; |
420 | + |
421 | +#Test that the regex_policy_policy can't be changed to a file which is not correct in syntax |
422 | +--replace_result $TOP_SRCDIR TOP_SRCDIR |
423 | +--error ER_WRONG_ARGUMENTS |
424 | +eval SET GLOBAL regex_policy_policy="$TOP_SRCDIR/plugin/regex_policy/tests/t/dynamic.policy3"; |
> bool Policy: :setPolicyFile( std::string &new_policy_file)
Shouldn't this be a const&?
I also noticed some strings are passed by value while they should be passed by const& too.
Don't forget to use spaces instead of tabs.