]> git.saurik.com Git - apple/security.git/blob - OSX/authd/rule.c
Security-57740.1.18.tar.gz
[apple/security.git] / OSX / authd / rule.c
1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
2
3 #include "rule.h"
4 #include "authutilities.h"
5 #include "mechanism.h"
6 #include "crc.h"
7 #include "debugging.h"
8 #include "authitems.h"
9 #include "process.h"
10
11 #include <Security/AuthorizationDB.h>
12 #include <Security/AuthorizationTagsPriv.h>
13 #include "server.h"
14
15 static void _sql_get_id(rule_t,authdb_connection_t);
16 static RuleClass _get_cf_rule_class(CFTypeRef);
17 static bool _copy_cf_rule_mechanisms(rule_t,CFTypeRef,authdb_connection_t);
18 static bool _copy_cf_rule_delegations(rule_t, CFTypeRef,authdb_connection_t);
19
20 #define kMaximumAuthorizationTries 10000
21
22 #define RULE_ID "id"
23 #define RULE_NAME "name"
24 #define RULE_TYPE "type"
25 #define RULE_CLASS "class"
26 #define RULE_GROUP "group"
27 #define RULE_KOFN "kofn"
28 #define RULE_TIMEOUT "timeout"
29 #define RULE_FLAGS "flags"
30 #define RULE_TRIES "tries"
31 #define RULE_COMMENT "comment"
32 #define RULE_VERSION "version"
33 #define RULE_CREATED "created"
34 #define RULE_MODIFIED "modified"
35 #define RULE_IDENTIFIER "identifier"
36 #define RULE_REQUIREMENT "requirement"
37 #define RULE_HASH "hash"
38
39 struct _rule_s {
40 __AUTH_BASE_STRUCT_HEADER__;
41
42 auth_items_t data;
43 CFMutableArrayRef mechanisms;
44 CFMutableArrayRef delegations;
45
46 CFMutableDictionaryRef loc_prompts;
47 CFMutableDictionaryRef loc_buttons;
48
49 CFDataRef requirement_data;
50 SecRequirementRef requirement;
51 };
52
53 static void
54 _rule_finalize(CFTypeRef value)
55 {
56 rule_t rule = (rule_t)value;
57 CFReleaseSafe(rule->data);
58 CFReleaseSafe(rule->mechanisms);
59 CFReleaseSafe(rule->delegations);
60 CFReleaseSafe(rule->loc_prompts);
61 CFReleaseSafe(rule->loc_buttons);
62 CFReleaseSafe(rule->requirement_data);
63 CFReleaseSafe(rule->requirement);
64 }
65
66 static Boolean
67 _rule_equal(CFTypeRef value1, CFTypeRef value2)
68 {
69 rule_t rule1 = (rule_t)value1;
70 rule_t rule2 = (rule_t)value2;
71
72 return strcasecmp(rule_get_name(rule1), rule_get_name(rule2)) == 0;
73 }
74
75 static CFStringRef
76 _rule_copy_description(CFTypeRef value)
77 {
78 rule_t rule = (rule_t)value;
79 CFMutableStringRef str = CFStringCreateMutable(kCFAllocatorDefault, 0);
80 CFStringRef tmp = CFCopyDescription(rule->data);
81 CFStringAppend(str, tmp);
82 CFReleaseNull(tmp);
83 tmp = CFCopyDescription(rule->mechanisms);
84 CFStringAppend(str, tmp);
85 CFReleaseNull(tmp);
86 tmp = CFCopyDescription(rule->delegations);
87 CFStringAppend(str, tmp);
88 CFReleaseNull(tmp);
89 return str;
90 }
91
92 static CFHashCode
93 _rule_hash(CFTypeRef value)
94 {
95 rule_t rule = (rule_t)value;
96 const char * str = rule_get_name(rule);
97 return (CFHashCode)crc64(str, strlen(str));
98 }
99
100 AUTH_TYPE_INSTANCE(rule,
101 .init = NULL,
102 .copy = NULL,
103 .finalize = _rule_finalize,
104 .equal = _rule_equal,
105 .hash = _rule_hash,
106 .copyFormattingDesc = NULL,
107 .copyDebugDesc = _rule_copy_description
108 );
109
110 static CFTypeID rule_get_type_id() {
111 static CFTypeID type_id = _kCFRuntimeNotATypeID;
112 static dispatch_once_t onceToken;
113
114 dispatch_once(&onceToken, ^{
115 type_id = _CFRuntimeRegisterClass(&_auth_type_rule);
116 });
117
118 return type_id;
119 }
120
121 static rule_t
122 _rule_create()
123 {
124 rule_t rule = (rule_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, rule_get_type_id(), AUTH_CLASS_SIZE(rule), NULL);
125 require(rule != NULL, done);
126
127 rule->data = auth_items_create();
128 rule->delegations = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
129 rule->mechanisms = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
130
131 done:
132 return rule;
133 }
134
135 static rule_t
136 _rule_create_with_sql(auth_items_t sql)
137 {
138 rule_t rule = NULL;
139 require(sql != NULL, done);
140
141 rule = _rule_create();
142 require(rule != NULL, done);
143
144 auth_items_copy(rule->data, sql);
145
146 done:
147 return rule;
148 }
149
150 rule_t
151 rule_create_default()
152 {
153 rule_t rule = _rule_create();
154 require(rule != NULL, done);
155
156 auth_items_set_int64(rule->data, RULE_TYPE, RT_RIGHT);
157 auth_items_set_string(rule->data, RULE_NAME, "(default)");
158 auth_items_set_int64(rule->data, RULE_CLASS, RC_USER);
159 auth_items_set_string(rule->data, RULE_GROUP, "admin");
160 auth_items_set_int64(rule->data, RULE_TIMEOUT, 300);
161 auth_items_set_int64(rule->data, RULE_TRIES, kMaximumAuthorizationTries);
162 auth_items_set_int64(rule->data, RULE_FLAGS, RuleFlagShared | RuleFlagAuthenticateUser);
163
164 mechanism_t mech = mechanism_create_with_string("builtin:authenticate", NULL);
165 CFArrayAppendValue(rule->mechanisms, mech);
166 CFReleaseNull(mech);
167
168 mech = mechanism_create_with_string("builtin:reset-password,privileged", NULL);
169 CFArrayAppendValue(rule->mechanisms, mech);
170 CFReleaseNull(mech);
171
172 mech = mechanism_create_with_string("builtin:authenticate,privileged", NULL);
173 CFArrayAppendValue(rule->mechanisms, mech);
174 CFReleaseNull(mech);
175
176 mech = mechanism_create_with_string("PKINITMechanism:auth,privileged", NULL);
177 CFArrayAppendValue(rule->mechanisms, mech);
178 CFReleaseNull(mech);
179
180 done:
181 return rule;
182 }
183
184 rule_t
185 rule_create_with_string(const char * str, authdb_connection_t dbconn)
186 {
187 rule_t rule = NULL;
188 require(str != NULL, done);
189
190 rule = _rule_create();
191 require(rule != NULL, done);
192
193 auth_items_set_string(rule->data, RULE_NAME, str);
194
195 if (dbconn) {
196 rule_sql_fetch(rule, dbconn);
197 }
198
199 done:
200 return rule;
201 }
202
203 static void _set_data_string(rule_t rule, const char * key, CFStringRef str)
204 {
205 char * tmpStr = _copy_cf_string(str, NULL);
206
207 if (tmpStr) {
208 auth_items_set_string(rule->data, key, tmpStr);
209 free_safe(tmpStr);
210 }
211 }
212
213 rule_t
214 rule_create_with_plist(RuleType type, CFStringRef name, CFDictionaryRef plist, authdb_connection_t dbconn)
215 {
216 rule_t rule = NULL;
217 require(name != NULL, done);
218 require(plist != NULL, done);
219
220 rule = _rule_create();
221 require(rule != NULL, done);
222
223 _set_data_string(rule, RULE_NAME, name);
224 require_action(rule_get_name(rule) != NULL, done, CFReleaseSafe(rule));
225
226 _sql_get_id(rule, dbconn);
227
228 auth_items_set_int64(rule->data, RULE_TYPE, type);
229
230 auth_items_set_int64(rule->data, RULE_CLASS, _get_cf_rule_class(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleClass))));
231 _set_data_string(rule, RULE_COMMENT, CFDictionaryGetValue(plist, CFSTR(kAuthorizationComment)));
232
233
234 CFTypeRef loc_tmp = CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterDefaultPrompt));
235 if (loc_tmp) {
236 rule->loc_prompts = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, loc_tmp);
237 }
238 loc_tmp = CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterDefaultButton));
239 if (loc_tmp) {
240 rule->loc_buttons = CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, loc_tmp);
241 }
242
243 auth_items_set_int64(rule->data, RULE_VERSION, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("version")), 0));
244
245 RuleFlags flags = 0;
246
247 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterEntitled)), false)) {
248 flags |= RuleFlagEntitled;
249 }
250
251 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterRequireAppleSigned)), false)) {
252 flags |= RuleFlagRequireAppleSigned;
253 }
254
255 switch (rule_get_class(rule)) {
256 case RC_USER:
257 _set_data_string(rule, RULE_GROUP, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterGroup)));
258 auth_items_set_int64(rule->data, RULE_TIMEOUT, _get_cf_int(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialTimeout)), INT32_MAX));
259 auth_items_set_int64(rule->data, RULE_TRIES, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("tries")), kMaximumAuthorizationTries));
260
261 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialShared)), false)) {
262 flags |= RuleFlagShared;
263 }
264 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterAllowRoot)), false)) {
265 flags |= RuleFlagAllowRoot;
266 }
267 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialSessionOwner)), false)) {
268 flags |= RuleFlagSessionOwner;
269 }
270 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterAuthenticateUser)), true)) {
271 flags |= RuleFlagAuthenticateUser;
272 }
273 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterExtractPassword)), false)) {
274 flags |= RuleFlagExtractPassword;
275 }
276 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterEntitledAndGroup)), false)) {
277 flags |= RuleFlagEntitledAndGroup;
278 }
279 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup)), false)) {
280 flags |= RuleFlagVPNEntitledAndGroup;
281 }
282 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterPasswordOnly)), false)) {
283 flags |= RuleFlagPasswordOnly;
284 }
285
286 _copy_cf_rule_mechanisms(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterMechanisms)), dbconn);
287
288 break;
289 case RC_RULE:
290 auth_items_set_int64(rule->data, RULE_KOFN, _get_cf_int(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterKofN)), 0));
291
292 _copy_cf_rule_delegations(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRightRule)), dbconn);
293 break;
294 case RC_MECHANISM:
295 auth_items_set_int64(rule->data, RULE_TRIES, _get_cf_int(CFDictionaryGetValue(plist, CFSTR("tries")), kMaximumAuthorizationTries));
296 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterCredentialShared)), true)) {
297 flags |= RuleFlagShared;
298 }
299 if (_get_cf_bool(CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterExtractPassword)), false)) {
300 flags |= RuleFlagExtractPassword;
301 }
302
303 _copy_cf_rule_mechanisms(rule, CFDictionaryGetValue(plist, CFSTR(kAuthorizationRuleParameterMechanisms)), dbconn);
304
305 break;
306 case RC_DENY:
307 break;
308 case RC_ALLOW:
309 break;
310 default:
311 LOGD("rule: invalid rule class");
312 break;
313 }
314
315 auth_items_set_int64(rule->data, RULE_FLAGS, flags);
316
317 done:
318 return rule;
319 }
320
321 static void
322 _sql_get_id(rule_t rule, authdb_connection_t dbconn)
323 {
324 authdb_step(dbconn, "SELECT id,created,identifier,requirement FROM rules WHERE name = ? LIMIT 1",
325 ^(sqlite3_stmt *stmt) {
326 sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL);
327 }, ^bool(auth_items_t data) {
328 auth_items_copy(rule->data, data);
329 return true;
330 });
331 }
332
333 static bool
334 _copy_cf_rule_delegations(rule_t rule, CFTypeRef value, authdb_connection_t dbconn)
335 {
336 bool result = false;
337 char * tmp_str = NULL;
338 require(value != NULL, done);
339
340 if (CFGetTypeID(value) == CFStringGetTypeID()) {
341 tmp_str = _copy_cf_string(value, NULL);
342 rule_t delegate = rule_create_with_string(tmp_str, dbconn);
343 free_safe(tmp_str);
344 if (delegate) {
345 CFArrayAppendValue(rule->delegations, delegate);
346 CFReleaseSafe(delegate);
347 }
348 } else { //array
349 CFIndex count = CFArrayGetCount(value);
350 for (CFIndex i = 0; i < count; i++) {
351 tmp_str = _copy_cf_string(CFArrayGetValueAtIndex(value,i), NULL);
352 rule_t delegate = rule_create_with_string(tmp_str, dbconn);
353 free_safe(tmp_str);
354 if (delegate) {
355 CFArrayAppendValue(rule->delegations, delegate);
356 CFReleaseSafe(delegate);
357 }
358 }
359 }
360
361 result = true;
362
363 done:
364 return result;
365 }
366
367 static bool
368 _copy_cf_rule_mechanisms(rule_t rule, CFTypeRef array, authdb_connection_t dbconn)
369 {
370 bool result = false;
371 require(array != NULL, done);
372 require(CFGetTypeID(array) == CFArrayGetTypeID(), done);
373
374 CFIndex count = CFArrayGetCount(array);
375 for (CFIndex i = 0; i < count; i++) {
376 mechanism_t mech = NULL;
377 char * string = _copy_cf_string(CFArrayGetValueAtIndex(array, i), NULL);
378
379 if (!string)
380 continue;
381
382 mech = mechanism_create_with_string(string, dbconn);
383 if (mech) {
384 CFArrayAppendValue(rule->mechanisms, mech);
385 CFReleaseSafe(mech);
386 }
387 free(string);
388 }
389
390 result = true;
391
392 done:
393 return result;
394 }
395
396 static RuleClass
397 _get_cf_rule_class(CFTypeRef str)
398 {
399 RuleClass rc = RC_RULE;
400 require(str != NULL, done);
401 require(CFGetTypeID(str) == CFStringGetTypeID(), done);
402
403 if (CFEqual(str, CFSTR(kAuthorizationRuleClassUser)))
404 return RC_USER;
405
406 if (CFEqual(str, CFSTR(kAuthorizationRightRule)))
407 return RC_RULE;
408
409 if (CFEqual(str, CFSTR(kAuthorizationRuleClassMechanisms)))
410 return RC_MECHANISM;
411
412 if (CFEqual(str, CFSTR(kAuthorizationRuleClassDeny)))
413 return RC_DENY;
414
415 if (CFEqual(str, CFSTR(kAuthorizationRuleClassAllow)))
416 return RC_ALLOW;
417
418 done:
419 return rc;
420 }
421
422 static bool
423 _sql_bind(rule_t rule, sqlite3_stmt * stmt)
424 {
425 int64_t n;
426 int32_t rc = 0;
427 require(stmt != NULL, err);
428
429 int32_t column = 1;
430 rc = sqlite3_bind_text(stmt, column++, rule_get_name(rule), -1, NULL);
431 require_noerr(rc, err);
432 rc = sqlite3_bind_int(stmt, column++, rule_get_type(rule));
433 require_noerr(rc, err);
434 rc = sqlite3_bind_int(stmt, column++, rule_get_class(rule));
435 require_noerr(rc, err);
436
437 switch (rule_get_class(rule)) {
438 case RC_USER:
439 rc = sqlite3_bind_text(stmt, column++, rule_get_group(rule), -1, NULL);
440 require_noerr(rc, err);
441 rc = sqlite3_bind_null(stmt, column++); // kofn
442 require_noerr(rc, err);
443 rc = sqlite3_bind_int64(stmt, column++, rule_get_timeout(rule));
444 require_noerr(rc, err);
445 rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
446 require_noerr(rc, err);
447 rc = sqlite3_bind_int64(stmt, column++, rule_get_tries(rule));
448 require_noerr(rc, err);
449 break;
450 case RC_RULE:
451 rc = sqlite3_bind_null(stmt, column++); // group
452 require_noerr(rc, err);
453 n = rule_get_kofn(rule);
454 if (n) {
455 rc = sqlite3_bind_int64(stmt, column++, n);
456 } else {
457 rc = sqlite3_bind_null(stmt, column++);
458 }
459 require_noerr(rc, err);
460 rc = sqlite3_bind_null(stmt, column++); // timeout
461 require_noerr(rc, err);
462 rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
463 require_noerr(rc, err);
464 rc = sqlite3_bind_null(stmt, column++); // tries
465 require_noerr(rc, err);
466 break;
467 case RC_MECHANISM:
468 rc = sqlite3_bind_null(stmt, column++); // group
469 require_noerr(rc, err);
470 rc = sqlite3_bind_null(stmt, column++); // kofn
471 require_noerr(rc, err);
472 rc = sqlite3_bind_null(stmt, column++); // timeout
473 require_noerr(rc, err);
474 rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
475 require_noerr(rc, err);
476 rc = sqlite3_bind_int64(stmt, column++, rule_get_tries(rule));
477 require_noerr(rc, err);
478 break;
479 case RC_DENY:
480 case RC_ALLOW:
481 rc = sqlite3_bind_null(stmt, column++); // group
482 require_noerr(rc, err);
483 rc = sqlite3_bind_null(stmt, column++); // kofn
484 require_noerr(rc, err);
485 rc = sqlite3_bind_null(stmt, column++); // timeout
486 require_noerr(rc, err);
487 rc = sqlite3_bind_int64(stmt, column++, auth_items_get_int64(rule->data, RULE_FLAGS));
488 require_noerr(rc, err);
489 rc = sqlite3_bind_null(stmt, column++); // tries
490 require_noerr(rc, err);
491 break;
492 default:
493 LOGD("rule: sql bind, invalid rule class");
494 break;
495 }
496
497 rc = sqlite3_bind_int64(stmt, column++, rule_get_version(rule)); // version
498 require_noerr(rc, err);
499 rc = sqlite3_bind_double(stmt, column++, rule_get_created(rule)); // created
500 require_noerr(rc, err);
501 rc = sqlite3_bind_double(stmt, column++, rule_get_modified(rule)); // modified
502 require_noerr(rc, err);
503 rc = sqlite3_bind_null(stmt, column++); // hash
504 require_noerr(rc, err);
505 rc = sqlite3_bind_text(stmt, column++, rule_get_identifier(rule), -1, NULL);
506 require_noerr(rc, err);
507
508 CFDataRef data = rule_get_requirement_data(rule);
509 if (data) {
510 rc = sqlite3_bind_blob(stmt, column++, CFDataGetBytePtr(data), (int32_t)CFDataGetLength(data), NULL);
511 } else {
512 rc = sqlite3_bind_null(stmt, column++);
513 }
514 require_noerr(rc, err);
515
516 rc = sqlite3_bind_text(stmt, column++, rule_get_comment(rule), -1, NULL);
517 require_noerr(rc, err);
518
519 return true;
520
521 err:
522 LOGD("rule: sql bind, error %i", rc);
523 return false;
524 }
525
526 static void
527 _get_sql_mechanisms(rule_t rule, authdb_connection_t dbconn)
528 {
529 CFArrayRemoveAllValues(rule->mechanisms);
530
531 authdb_step(dbconn, "SELECT mechanisms.* " \
532 "FROM mechanisms " \
533 "JOIN mechanisms_map ON mechanisms.id = mechanisms_map.m_id " \
534 "WHERE mechanisms_map.r_id = ? ORDER BY mechanisms_map.ord ASC",
535 ^(sqlite3_stmt *stmt) {
536 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
537 }, ^bool(auth_items_t data) {
538 mechanism_t mechanism = mechanism_create_with_sql(data);
539 CFArrayAppendValue(rule->mechanisms, mechanism);
540 CFReleaseSafe(mechanism);
541 return true;
542 });
543 }
544
545 static void
546 _get_sql_delegates(rule_t rule, authdb_connection_t dbconn)
547 {
548 CFArrayRemoveAllValues(rule->delegations);
549
550 authdb_step(dbconn, "SELECT rules.* " \
551 "FROM rules " \
552 "JOIN delegates_map ON rules.id = delegates_map.d_id " \
553 "WHERE delegates_map.r_id = ? ORDER BY delegates_map.ord ASC",
554 ^(sqlite3_stmt *stmt) {
555 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
556 }, ^bool(auth_items_t data) {
557 rule_t delegate = _rule_create_with_sql(data);
558 if (delegate) {
559 _get_sql_mechanisms(delegate, dbconn);
560
561 if (rule_get_class(rule) == RC_RULE) {
562 _get_sql_delegates(delegate, dbconn);
563 }
564
565 CFArrayAppendValue(rule->delegations, delegate);
566 CFReleaseSafe(delegate);
567 }
568 return true;
569 });
570 }
571
572 bool
573 rule_sql_fetch(rule_t rule, authdb_connection_t dbconn)
574 {
575 __block bool result = false;
576
577 authdb_step(dbconn, "SELECT * FROM rules WHERE name = ? LIMIT 1",
578 ^(sqlite3_stmt *stmt) {
579 sqlite3_bind_text(stmt, 1, rule_get_name(rule), -1, NULL);
580 }, ^bool(auth_items_t data) {
581 result = true;
582 auth_items_copy(rule->data, data);
583 return true;
584 });
585
586 if (rule_get_id(rule) != 0) {
587 _get_sql_mechanisms(rule,dbconn);
588
589 if (rule_get_class(rule) == RC_RULE) {
590 _get_sql_delegates(rule, dbconn);
591 }
592 }
593
594 return result;
595 }
596
597 static bool
598 _sql_update(rule_t rule, authdb_connection_t dbconn)
599 {
600 bool result = false;
601
602 result = authdb_step(dbconn, "UPDATE rules " \
603 "SET name=?,type=?,class=?,'group'=?,kofn=?,timeout=?,flags=?,tries=?,version=?,created=?,modified=?,hash=?,identifier=?,requirement=?,comment=? " \
604 "WHERE id = ?",
605 ^(sqlite3_stmt *stmt) {
606 _sql_bind(rule, stmt);
607 sqlite3_bind_int64(stmt, sqlite3_bind_parameter_count(stmt), rule_get_id(rule));
608 }, NULL);
609 return result;
610 }
611
612 static bool
613 _sql_insert(rule_t rule, authdb_connection_t dbconn)
614 {
615 bool result = false;
616
617 result = authdb_step(dbconn, "INSERT INTO rules VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)",
618 ^(sqlite3_stmt *stmt) {
619 _sql_bind(rule, stmt);
620 }, NULL);
621 return result;
622 }
623
624 static bool
625 _sql_commit_mechanisms_map(rule_t rule, authdb_connection_t dbconn)
626 {
627 bool result = false;
628
629 result = authdb_step(dbconn, "DELETE FROM mechanisms_map WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
630 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
631 }, NULL);
632 require(result == true, done);
633
634 CFIndex count = CFArrayGetCount(rule->mechanisms);
635 for(CFIndex i = 0; i < count; i++) {
636 mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
637 result = authdb_step(dbconn, "INSERT INTO mechanisms_map VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
638 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
639 sqlite3_bind_int64(stmt, 2, mechanism_get_id(mech));
640 sqlite3_bind_int64(stmt, 3, i);
641 }, NULL);
642 require(result == true, done);
643 }
644
645 done:
646 return result;
647 }
648
649 static bool
650 _sql_commit_delegates_map(rule_t rule, authdb_connection_t dbconn)
651 {
652 bool result = false;
653
654 result = authdb_step(dbconn, "DELETE FROM delegates_map WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
655 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
656 }, NULL);
657 require(result == true, done);
658
659 CFIndex count = CFArrayGetCount(rule->delegations);
660 for(CFIndex i = 0; i < count; i++) {
661 rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
662 result = authdb_step(dbconn, "INSERT INTO delegates_map VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
663 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
664 sqlite3_bind_int64(stmt, 2, rule_get_id(delegate));
665 sqlite3_bind_int64(stmt, 3, i);
666 }, NULL);
667 require(result == true, done);
668 }
669
670 done:
671 return result;
672 }
673
674 static void
675 _sql_commit_localization(rule_t rule, authdb_connection_t dbconn)
676 {
677
678 authdb_step(dbconn, "DELETE FROM prompts WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
679 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
680 }, NULL);
681
682 authdb_step(dbconn, "DELETE FROM buttons WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
683 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
684 }, NULL);
685
686 if (rule->loc_prompts) {
687 _cf_dictionary_iterate(rule->loc_prompts, ^bool(CFTypeRef key, CFTypeRef value) {
688 char * lang = _copy_cf_string(key, NULL);
689 char * str = _copy_cf_string(value, NULL);
690
691 authdb_step(dbconn, "INSERT INTO prompts VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
692 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
693 sqlite3_bind_text(stmt, 2, lang, -1, NULL);
694 sqlite3_bind_text(stmt, 3, str, -1, NULL);
695 }, NULL);
696
697 free_safe(lang);
698 free_safe(str);
699
700 return true;
701 });
702 }
703
704 if (rule->loc_buttons) {
705 _cf_dictionary_iterate(rule->loc_buttons, ^bool(CFTypeRef key, CFTypeRef value) {
706 char * lang = _copy_cf_string(key, NULL);
707 char * str = _copy_cf_string(value, NULL);
708
709 authdb_step(dbconn, "INSERT INTO buttons VALUES (?,?,?)", ^(sqlite3_stmt *stmt) {
710 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
711 sqlite3_bind_text(stmt, 2, lang, -1, NULL);
712 sqlite3_bind_text(stmt, 3, str, -1, NULL);
713 }, NULL);
714
715 free_safe(lang);
716 free_safe(str);
717 return true;
718 });
719 }
720
721 }
722
723 bool
724 rule_sql_commit(rule_t rule, authdb_connection_t dbconn, CFAbsoluteTime modified, process_t proc)
725 {
726 bool result = false;
727 // type and class required else rule is name only?
728 RuleClass rule_class = rule_get_class(rule);
729 require(rule_get_type(rule) != 0, done);
730 require(rule_class != 0, done);
731
732 CFIndex mechCount = 0;
733 if (rule_class == RC_USER || rule_class == RC_MECHANISM) {
734 // Validate mechanisms
735 mechCount = CFArrayGetCount(rule->mechanisms);
736 for (CFIndex i = 0; i < mechCount; i++) {
737 mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
738 if (mechanism_get_id(mech) == 0) {
739 if (!mechanism_sql_fetch(mech, dbconn)) {
740 mechanism_sql_commit(mech, dbconn);
741 mechanism_sql_fetch(mech, dbconn);
742 }
743 }
744 if (!mechanism_exists(mech)) {
745 LOGE("Warning mechanism not found on disk %s during import of %s", mechanism_get_string(mech), rule_get_name(rule));
746 }
747 require_action(mechanism_get_id(mech) != 0, done, LOGE("rule: commit, invalid mechanism %s:%s for %s", mechanism_get_plugin(mech), mechanism_get_param(mech), rule_get_name(rule)));
748 }
749 }
750
751 CFIndex delegateCount = 0;
752 if (rule_class == RC_RULE) {
753 // Validate delegates
754 delegateCount = CFArrayGetCount(rule->delegations);
755 for (CFIndex i = 0; i < delegateCount; i++) {
756 rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
757 if (rule_get_id(delegate) == 0) {
758 rule_sql_fetch(delegate, dbconn);
759 }
760 require_action(rule_get_id(delegate) != 0, done, LOGE("rule: commit, missing delegate %s for %s", rule_get_name(delegate), rule_get_name(rule)));
761 }
762 }
763
764 auth_items_set_double(rule->data, RULE_MODIFIED, modified);
765
766 result = authdb_transaction(dbconn, AuthDBTransactionNormal, ^bool{
767 bool update = false;
768
769 if (rule_get_id(rule)) {
770 update = _sql_update(rule, dbconn);
771 } else {
772 if (proc) {
773 const char * ident = process_get_identifier(proc);
774 if (ident) {
775 auth_items_set_string(rule->data, RULE_IDENTIFIER, ident);
776 }
777 CFDataRef req = process_get_requirement_data(proc);
778 if (req) {
779 auth_items_set_data(rule->data, RULE_REQUIREMENT, CFDataGetBytePtr(req), (size_t)CFDataGetLength(req));
780 }
781 }
782 auth_items_set_double(rule->data, RULE_CREATED, modified);
783 update = _sql_insert(rule, dbconn);
784 _sql_get_id(rule, dbconn);
785 }
786
787 _sql_commit_localization(rule, dbconn);
788
789 if (update) {
790 update = _sql_commit_mechanisms_map(rule, dbconn);
791 }
792
793 if (update) {
794 update = _sql_commit_delegates_map(rule,dbconn);
795 }
796
797 return update;
798 });
799
800
801 done:
802 if (!result) {
803 LOGV("rule: commit, failed for %s (%llu)", rule_get_name(rule), rule_get_id(rule));
804 }
805 return result;
806 }
807
808 bool
809 rule_sql_remove(rule_t rule, authdb_connection_t dbconn)
810 {
811 bool result = false;
812 int64_t id = rule_get_id(rule);
813
814 if (id == 0) {
815 rule_sql_fetch(rule, dbconn);
816 id = rule_get_id(rule);
817 require(id != 0, done);
818 }
819
820 result = authdb_step(dbconn, "DELETE FROM rules WHERE id = ?",
821 ^(sqlite3_stmt *stmt) {
822 sqlite3_bind_int64(stmt, 1, id);
823 }, NULL);
824 done:
825 return result;
826 }
827
828 CFMutableDictionaryRef
829 rule_copy_to_cfobject(rule_t rule, authdb_connection_t dbconn) {
830 CFMutableDictionaryRef dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
831
832 CFTypeRef tmp = NULL;
833 CFMutableArrayRef array = NULL;
834 CFIndex count = 0;
835 CFIndex i = 0;
836 int64_t n;
837 double d;
838
839 const char * comment = rule_get_comment(rule);
840 if (comment) {
841 tmp = CFStringCreateWithCString(kCFAllocatorDefault, comment, kCFStringEncodingUTF8);
842 CFDictionarySetValue(dict, CFSTR(kAuthorizationComment), tmp);
843 CFReleaseSafe(tmp);
844 }
845
846 n = rule_get_version(rule);
847 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
848 CFDictionarySetValue(dict, CFSTR(RULE_VERSION), tmp);
849 CFReleaseSafe(tmp);
850
851 d = rule_get_created(rule);
852 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &d);
853 CFDictionarySetValue(dict, CFSTR(RULE_CREATED), tmp);
854 CFReleaseSafe(tmp);
855
856 d = rule_get_modified(rule);
857 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloat64Type, &d);
858 CFDictionarySetValue(dict, CFSTR(RULE_MODIFIED), tmp);
859 CFReleaseSafe(tmp);
860
861 const char * identifier = rule_get_identifier(rule);
862 if (identifier) {
863 tmp = CFStringCreateWithCString(kCFAllocatorDefault, identifier, kCFStringEncodingUTF8);
864 CFDictionarySetValue(dict, CFSTR(RULE_IDENTIFIER), tmp);
865 CFReleaseSafe(tmp);
866 }
867
868 SecRequirementRef req = rule_get_requirement(rule);
869 if (req) {
870 CFStringRef reqStr = NULL;
871 SecRequirementCopyString(req, kSecCSDefaultFlags, &reqStr);
872 if (reqStr) {
873 CFDictionarySetValue(dict, CFSTR(RULE_REQUIREMENT), reqStr);
874 CFReleaseSafe(reqStr);
875 }
876 }
877
878 if (rule_check_flags(rule, RuleFlagEntitled)) {
879 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterEntitled), kCFBooleanTrue);
880 }
881
882 if (rule_check_flags(rule, RuleFlagRequireAppleSigned)) {
883 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterRequireAppleSigned), kCFBooleanTrue);
884 }
885
886 if (rule_get_type(rule) == RT_RIGHT) {
887 CFMutableDictionaryRef prompts = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
888 authdb_step(dbconn, "SELECT * FROM prompts WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
889 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
890 }, ^bool(auth_items_t data) {
891 CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "lang"), kCFStringEncodingUTF8);
892 CFStringRef value = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "value"), kCFStringEncodingUTF8);
893 CFDictionaryAddValue(prompts, key, value);
894 CFReleaseSafe(key);
895 CFReleaseSafe(value);
896 return true;
897 });
898
899 if (CFDictionaryGetCount(prompts)) {
900 CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterDefaultPrompt), prompts);
901 }
902 CFReleaseSafe(prompts);
903
904 CFMutableDictionaryRef buttons = CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
905 authdb_step(dbconn, "SELECT * FROM buttons WHERE r_id = ?", ^(sqlite3_stmt *stmt) {
906 sqlite3_bind_int64(stmt, 1, rule_get_id(rule));
907 }, ^bool(auth_items_t data) {
908 CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "lang"), kCFStringEncodingUTF8);
909 CFStringRef value = CFStringCreateWithCString(kCFAllocatorDefault, auth_items_get_string(data, "value"), kCFStringEncodingUTF8);
910 CFDictionaryAddValue(buttons, key, value);
911 CFReleaseSafe(key);
912 CFReleaseSafe(value);
913 return true;
914 });
915
916 if (CFDictionaryGetCount(buttons)) {
917 CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterDefaultButton), buttons);
918 }
919 CFReleaseSafe(buttons);
920 }
921
922 switch (rule_get_class(rule)) {
923 case RC_USER:
924 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassUser));
925
926 const char * group = rule_get_group(rule);
927 if (group) {
928 tmp = CFStringCreateWithCString(kCFAllocatorDefault, group, kCFStringEncodingUTF8);
929 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterGroup), tmp);
930 CFReleaseSafe(tmp);
931 }
932
933 n = rule_get_timeout(rule);
934 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
935 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialTimeout), tmp);
936 CFReleaseSafe(tmp);
937
938 n = rule_get_tries(rule);
939 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
940 CFDictionarySetValue(dict, CFSTR("tries"), tmp);
941 CFReleaseSafe(tmp);
942
943 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialShared), rule_get_shared(rule) ? kCFBooleanTrue : kCFBooleanFalse);
944 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterAllowRoot), rule_get_allow_root(rule) ? kCFBooleanTrue : kCFBooleanFalse);
945 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialSessionOwner), rule_get_session_owner(rule) ? kCFBooleanTrue : kCFBooleanFalse);
946 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterAuthenticateUser), rule_get_authenticate_user(rule) ? kCFBooleanTrue : kCFBooleanFalse);
947 if (rule_check_flags(rule, RuleFlagEntitledAndGroup)) {
948 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterEntitledAndGroup), kCFBooleanTrue);
949 }
950 if (rule_check_flags(rule, RuleFlagVPNEntitledAndGroup)) {
951 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup), kCFBooleanTrue);
952 }
953 if (rule_get_extract_password(rule)) {
954 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterExtractPassword), kCFBooleanTrue);
955 }
956 if (rule_get_password_only(rule)) {
957 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterPasswordOnly), kCFBooleanTrue);
958 }
959
960 count = CFArrayGetCount(rule->mechanisms);
961 if (count) {
962 array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
963 for (i = 0; i < count; i++) {
964 mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
965 tmp = CFStringCreateWithCString(kCFAllocatorDefault, mechanism_get_string(mech), kCFStringEncodingUTF8);
966 CFArrayAppendValue(array, tmp);
967 CFReleaseSafe(tmp);
968 }
969 CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterMechanisms), array);
970 CFRelease(array);
971 }
972 break;
973 case RC_RULE:
974 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRightRule));
975 int64_t kofn = rule_get_kofn(rule);
976 if (kofn) {
977 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &kofn);
978 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterKofN), tmp);
979 CFReleaseSafe(tmp);
980 }
981
982 count = CFArrayGetCount(rule->delegations);
983 if (count) {
984 array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
985 for (i = 0; i < count; i++) {
986 rule_t delegate = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
987 tmp = CFStringCreateWithCString(kCFAllocatorDefault, rule_get_name(delegate), kCFStringEncodingUTF8);
988 CFArrayAppendValue(array, tmp);
989 CFReleaseSafe(tmp);
990 }
991 CFDictionaryAddValue(dict, CFSTR(kAuthorizationRightRule), array);
992 CFRelease(array);
993 }
994 break;
995 case RC_MECHANISM:
996 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassMechanisms));
997
998 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterCredentialShared), rule_get_shared(rule) ? kCFBooleanTrue : kCFBooleanFalse);
999 if (rule_get_extract_password(rule)) {
1000 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleParameterExtractPassword), kCFBooleanTrue);
1001 }
1002
1003 n = rule_get_tries(rule);
1004 tmp = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt64Type, &n);
1005 CFDictionarySetValue(dict, CFSTR("tries"), tmp);
1006 CFReleaseSafe(tmp);
1007
1008 count = CFArrayGetCount(rule->mechanisms);
1009 if (count) {
1010 array = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
1011 for (i = 0; i < count; i++) {
1012 mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
1013 tmp = CFStringCreateWithCString(kCFAllocatorDefault, mechanism_get_string(mech), kCFStringEncodingUTF8);
1014 CFArrayAppendValue(array, tmp);
1015 CFReleaseSafe(tmp);
1016 }
1017 CFDictionaryAddValue(dict, CFSTR(kAuthorizationRuleParameterMechanisms), array);
1018 CFRelease(array);
1019 }
1020 break;
1021 case RC_DENY:
1022 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassDeny));
1023 break;
1024 case RC_ALLOW:
1025 CFDictionarySetValue(dict, CFSTR(kAuthorizationRuleClass), CFSTR(kAuthorizationRuleClassAllow));
1026 break;
1027 default:
1028 break;
1029 }
1030
1031 return dict;
1032 }
1033
1034
1035 CFArrayRef
1036 rule_get_mechanisms(rule_t rule)
1037 {
1038 return rule->mechanisms;
1039 }
1040
1041 size_t
1042 rule_get_mechanisms_count(rule_t rule)
1043 {
1044 return (size_t)CFArrayGetCount(rule->mechanisms);
1045 }
1046
1047 bool
1048 rule_mechanisms_iterator(rule_t rule, mechanism_iterator_t iter)
1049 {
1050 bool result = false;
1051
1052 CFIndex count = CFArrayGetCount(rule->mechanisms);
1053 for (CFIndex i = 0; i < count; i++) {
1054 mechanism_t mech = (mechanism_t)CFArrayGetValueAtIndex(rule->mechanisms, i);
1055 result = iter(mech);
1056 if (!result) {
1057 break;
1058 }
1059 }
1060
1061 return result;
1062 }
1063
1064 size_t
1065 rule_get_delegates_count(rule_t rule)
1066 {
1067 return (size_t)CFArrayGetCount(rule->delegations);
1068 }
1069
1070 bool
1071 rule_delegates_iterator(rule_t rule, delegate_iterator_t iter)
1072 {
1073 bool result = false;
1074
1075 CFIndex count = CFArrayGetCount(rule->delegations);
1076 for (CFIndex i = 0; i < count; i++) {
1077 rule_t tmp = (rule_t)CFArrayGetValueAtIndex(rule->delegations, i);
1078 result = iter(tmp);
1079 if (!result) {
1080 break;
1081 }
1082 }
1083
1084 return result;
1085 }
1086
1087 int64_t
1088 rule_get_id(rule_t rule)
1089 {
1090 return auth_items_get_int64(rule->data, RULE_ID);
1091 }
1092
1093 const char *
1094 rule_get_name(rule_t rule)
1095 {
1096 return auth_items_get_string(rule->data, RULE_NAME);
1097 }
1098
1099 RuleType
1100 rule_get_type(rule_t rule)
1101 {
1102 return (RuleType)auth_items_get_int64(rule->data, RULE_TYPE);
1103 }
1104
1105 RuleClass
1106 rule_get_class(rule_t rule)
1107 {
1108 return (RuleClass)auth_items_get_int64(rule->data, RULE_CLASS);
1109 }
1110
1111 const char *
1112 rule_get_group(rule_t rule)
1113 {
1114 return auth_items_get_string(rule->data, RULE_GROUP);
1115 }
1116
1117 int64_t
1118 rule_get_kofn(rule_t rule)
1119 {
1120 return auth_items_get_int64(rule->data, RULE_KOFN);
1121 }
1122
1123 int64_t
1124 rule_get_timeout(rule_t rule)
1125 {
1126 return auth_items_get_int64(rule->data, RULE_TIMEOUT);
1127 }
1128
1129 bool
1130 rule_check_flags(rule_t rule, RuleFlags flags)
1131 {
1132 return (auth_items_get_int64(rule->data, RULE_FLAGS) & flags) != 0;
1133 }
1134
1135 bool
1136 rule_get_shared(rule_t rule)
1137 {
1138 return rule_check_flags(rule, RuleFlagShared);
1139 }
1140
1141 bool
1142 rule_get_allow_root(rule_t rule)
1143 {
1144 return rule_check_flags(rule, RuleFlagAllowRoot);
1145 }
1146
1147 bool
1148 rule_get_session_owner(rule_t rule)
1149 {
1150 return rule_check_flags(rule, RuleFlagSessionOwner);
1151 }
1152
1153 bool
1154 rule_get_authenticate_user(rule_t rule)
1155 {
1156 return rule_check_flags(rule, RuleFlagAuthenticateUser);
1157 }
1158
1159 bool
1160 rule_get_extract_password(rule_t rule)
1161 {
1162 return rule_check_flags(rule, RuleFlagExtractPassword);
1163 }
1164
1165 bool
1166 rule_get_password_only(rule_t rule)
1167 {
1168 return rule_check_flags(rule, RuleFlagPasswordOnly);
1169 }
1170
1171 int64_t
1172 rule_get_tries(rule_t rule)
1173 {
1174 return auth_items_get_int64(rule->data, RULE_TRIES);
1175 }
1176
1177 const char *
1178 rule_get_comment(rule_t rule)
1179 {
1180 return auth_items_get_string(rule->data, RULE_COMMENT);
1181 }
1182
1183 int64_t
1184 rule_get_version(rule_t rule)
1185 {
1186 return auth_items_get_int64(rule->data, RULE_VERSION);
1187 }
1188
1189 double rule_get_created(rule_t rule)
1190 {
1191 return auth_items_get_double(rule->data, RULE_CREATED);
1192 }
1193
1194 double rule_get_modified(rule_t rule)
1195 {
1196 return auth_items_get_double(rule->data, RULE_MODIFIED);
1197 }
1198
1199 const char * rule_get_identifier(rule_t rule)
1200 {
1201 return auth_items_get_string(rule->data, RULE_IDENTIFIER);
1202 }
1203
1204 CFDataRef rule_get_requirement_data(rule_t rule)
1205 {
1206 if (!rule->requirement_data && auth_items_exist(rule->data, RULE_REQUIREMENT)) {
1207 size_t len;
1208 const void * data = auth_items_get_data(rule->data, RULE_REQUIREMENT, &len);
1209 rule->requirement_data = CFDataCreate(kCFAllocatorDefault, data, (CFIndex)len);
1210 }
1211
1212 return rule->requirement_data;
1213 }
1214
1215 SecRequirementRef rule_get_requirement(rule_t rule)
1216 {
1217 if (!rule->requirement) {
1218 CFDataRef data = rule_get_requirement_data(rule);
1219 if (data) {
1220 SecRequirementCreateWithData(data, kSecCSDefaultFlags, &rule->requirement);
1221 }
1222 }
1223
1224 return rule->requirement;
1225 }