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