1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */ 
   4 #include "authutilities.h" 
  11 #include <Security/AuthorizationDB.h> 
  12 #include <Security/AuthorizationTagsPriv.h> 
  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
); 
  20 #define kMaximumAuthorizationTries 10000 
  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" 
  40     __AUTH_BASE_STRUCT_HEADER__
; 
  43     CFMutableArrayRef mechanisms
; 
  44     CFMutableArrayRef delegations
; 
  46     CFMutableDictionaryRef loc_prompts
; 
  47     CFMutableDictionaryRef loc_buttons
; 
  49     CFDataRef requirement_data
; 
  50     SecRequirementRef requirement
; 
  54 _rule_finalize(CFTypeRef value
) 
  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
); 
  67 _rule_equal(CFTypeRef value1
, CFTypeRef value2
) 
  69     rule_t rule1 
= (rule_t
)value1
; 
  70     rule_t rule2 
= (rule_t
)value2
; 
  72     return strcasecmp(rule_get_name(rule1
), rule_get_name(rule2
)) == 0; 
  76 _rule_copy_description(CFTypeRef value
) 
  78     rule_t rule 
= (rule_t
)value
; 
  79     CFMutableStringRef str 
= CFStringCreateMutable(kCFAllocatorDefault
, 0); 
  80     CFStringRef tmp 
= CFCopyDescription(rule
->data
); 
  81     CFStringAppend(str
, tmp
); 
  83     tmp 
= CFCopyDescription(rule
->mechanisms
); 
  84     CFStringAppend(str
, tmp
); 
  86     tmp 
= CFCopyDescription(rule
->delegations
); 
  87     CFStringAppend(str
, tmp
); 
  93 _rule_hash(CFTypeRef value
) 
  95     rule_t rule 
= (rule_t
)value
; 
  96     const char * str 
= rule_get_name(rule
); 
  97     return (CFHashCode
)crc64(str
, strlen(str
)); 
 100 AUTH_TYPE_INSTANCE(rule
, 
 103                    .finalize 
= _rule_finalize
, 
 104                    .equal 
= _rule_equal
, 
 106                    .copyFormattingDesc 
= NULL
, 
 107                    .copyDebugDesc 
= _rule_copy_description
 
 110 static CFTypeID 
rule_get_type_id() { 
 111     static CFTypeID type_id 
= _kCFRuntimeNotATypeID
; 
 112     static dispatch_once_t onceToken
; 
 114     dispatch_once(&onceToken
, ^{ 
 115         type_id 
= _CFRuntimeRegisterClass(&_auth_type_rule
); 
 124     rule_t rule 
= (rule_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, rule_get_type_id(), AUTH_CLASS_SIZE(rule
), NULL
); 
 125     require(rule 
!= NULL
, done
); 
 127     rule
->data 
= auth_items_create(); 
 128     rule
->delegations 
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
); 
 129     rule
->mechanisms 
= CFArrayCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeArrayCallBacks
); 
 136 _rule_create_with_sql(auth_items_t sql
) 
 139     require(sql 
!= NULL
, done
); 
 141     rule 
= _rule_create(); 
 142     require(rule 
!= NULL
, done
); 
 144     auth_items_copy(rule
->data
, sql
); 
 151 rule_create_default() 
 153     rule_t rule 
= _rule_create(); 
 154     require(rule 
!= NULL
, done
); 
 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
); 
 164     mechanism_t mech 
= mechanism_create_with_string("builtin:authenticate", NULL
); 
 165     CFArrayAppendValue(rule
->mechanisms
, mech
); 
 168     mech 
= mechanism_create_with_string("builtin:reset-password,privileged", NULL
); 
 169     CFArrayAppendValue(rule
->mechanisms
, mech
); 
 172     mech 
= mechanism_create_with_string("builtin:authenticate,privileged", NULL
); 
 173     CFArrayAppendValue(rule
->mechanisms
, mech
); 
 176     mech 
= mechanism_create_with_string("PKINITMechanism:auth,privileged", NULL
); 
 177     CFArrayAppendValue(rule
->mechanisms
, mech
); 
 185 rule_create_with_string(const char * str
, authdb_connection_t dbconn
) 
 188     require(str 
!= NULL
, done
); 
 190     rule 
= _rule_create(); 
 191     require(rule 
!= NULL
, done
); 
 193     auth_items_set_string(rule
->data
, RULE_NAME
, str
); 
 196         rule_sql_fetch(rule
, dbconn
); 
 203 static void _set_data_string(rule_t rule
, const char * key
, CFStringRef str
) 
 205     char * tmpStr 
= _copy_cf_string(str
, NULL
); 
 208         auth_items_set_string(rule
->data
, key
, tmpStr
); 
 214 rule_create_with_plist(RuleType type
, CFStringRef name
, CFDictionaryRef plist
, authdb_connection_t dbconn
) 
 217     require(name 
!= NULL
, done
); 
 218     require(plist 
!= NULL
, done
); 
 220     rule 
= _rule_create(); 
 221     require(rule 
!= NULL
, done
); 
 223     _set_data_string(rule
, RULE_NAME
, name
); 
 224     require_action(rule_get_name(rule
) != NULL
, done
, CFReleaseSafe(rule
)); 
 226     _sql_get_id(rule
, dbconn
); 
 228     auth_items_set_int64(rule
->data
, RULE_TYPE
, type
); 
 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
))); 
 234     CFTypeRef loc_tmp 
= CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterDefaultPrompt
)); 
 236         rule
->loc_prompts 
= CFDictionaryCreateMutableCopy(kCFAllocatorDefault
, 0, loc_tmp
); 
 238     loc_tmp 
= CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterDefaultButton
)); 
 240         rule
->loc_buttons 
= CFDictionaryCreateMutableCopy(kCFAllocatorDefault
, 0, loc_tmp
); 
 243     auth_items_set_int64(rule
->data
, RULE_VERSION
, _get_cf_int(CFDictionaryGetValue(plist
, CFSTR("version")), 0)); 
 247     if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterEntitled
)), false)) { 
 248         flags 
|= RuleFlagEntitled
; 
 251     if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterRequireAppleSigned
)), false)) { 
 252         flags 
|= RuleFlagRequireAppleSigned
; 
 255     switch (rule_get_class(rule
)) { 
 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
)); 
 261             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterCredentialShared
)), false)) { 
 262                 flags 
|= RuleFlagShared
; 
 264             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterAllowRoot
)), false)) { 
 265                 flags 
|= RuleFlagAllowRoot
; 
 267             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterCredentialSessionOwner
)), false)) { 
 268                 flags 
|= RuleFlagSessionOwner
; 
 270             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterAuthenticateUser
)), true)) { 
 271                 flags 
|= RuleFlagAuthenticateUser
; 
 273             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterExtractPassword
)), false)) { 
 274                 flags 
|= RuleFlagExtractPassword
; 
 276             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterEntitledAndGroup
)), false)) { 
 277                 flags 
|= RuleFlagEntitledAndGroup
; 
 279             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup
)), false)) { 
 280                 flags 
|= RuleFlagVPNEntitledAndGroup
; 
 282                         if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterPasswordOnly
)), false)) { 
 283                                 flags 
|= RuleFlagPasswordOnly
; 
 286             _copy_cf_rule_mechanisms(rule
, CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterMechanisms
)), dbconn
); 
 290             auth_items_set_int64(rule
->data
, RULE_KOFN
, _get_cf_int(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterKofN
)), 0)); 
 292             _copy_cf_rule_delegations(rule
, CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRightRule
)), dbconn
); 
 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
; 
 299             if (_get_cf_bool(CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterExtractPassword
)), false)) { 
 300                 flags 
|= RuleFlagExtractPassword
; 
 303                         _copy_cf_rule_mechanisms(rule
, CFDictionaryGetValue(plist
, CFSTR(kAuthorizationRuleParameterMechanisms
)), dbconn
); 
 311             LOGD("rule: invalid rule class"); 
 315     auth_items_set_int64(rule
->data
, RULE_FLAGS
, flags
); 
 322 _sql_get_id(rule_t rule
, authdb_connection_t dbconn
) 
 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
); 
 334 _copy_cf_rule_delegations(rule_t rule
, CFTypeRef value
, authdb_connection_t dbconn
) 
 337     char * tmp_str 
= NULL
; 
 338     require(value 
!= NULL
, done
); 
 340     if (CFGetTypeID(value
) == CFStringGetTypeID()) { 
 341         tmp_str 
= _copy_cf_string(value
, NULL
); 
 342         rule_t delegate 
= rule_create_with_string(tmp_str
, dbconn
); 
 345             CFArrayAppendValue(rule
->delegations
, delegate
); 
 346             CFReleaseSafe(delegate
); 
 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
); 
 355                 CFArrayAppendValue(rule
->delegations
, delegate
); 
 356                 CFReleaseSafe(delegate
); 
 368 _copy_cf_rule_mechanisms(rule_t rule
, CFTypeRef array
, authdb_connection_t dbconn
) 
 371     require(array 
!= NULL
, done
); 
 372     require(CFGetTypeID(array
) == CFArrayGetTypeID(), done
); 
 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
); 
 382         mech 
= mechanism_create_with_string(string
, dbconn
); 
 384             CFArrayAppendValue(rule
->mechanisms
, mech
); 
 397 _get_cf_rule_class(CFTypeRef str
) 
 399     RuleClass rc 
= RC_RULE
; 
 400     require(str 
!= NULL
, done
); 
 401     require(CFGetTypeID(str
) == CFStringGetTypeID(), done
); 
 403     if (CFEqual(str
, CFSTR(kAuthorizationRuleClassUser
))) 
 406     if (CFEqual(str
, CFSTR(kAuthorizationRightRule
))) 
 409     if (CFEqual(str
, CFSTR(kAuthorizationRuleClassMechanisms
))) 
 412     if (CFEqual(str
, CFSTR(kAuthorizationRuleClassDeny
))) 
 415     if (CFEqual(str
, CFSTR(kAuthorizationRuleClassAllow
))) 
 423 _sql_bind(rule_t rule
, sqlite3_stmt 
* stmt
) 
 427     require(stmt 
!= NULL
, err
); 
 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
); 
 437     switch (rule_get_class(rule
)) { 
 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
); 
 451             rc 
= sqlite3_bind_null(stmt
, column
++); // group 
 452             require_noerr(rc
, err
); 
 453             n 
= rule_get_kofn(rule
); 
 455                 rc 
= sqlite3_bind_int64(stmt
, column
++, n
); 
 457                 rc 
= sqlite3_bind_null(stmt
, column
++); 
 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
); 
 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
); 
 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
); 
 493             LOGD("rule: sql bind, invalid rule class"); 
 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
); 
 508     CFDataRef data 
= rule_get_requirement_data(rule
); 
 510         rc 
= sqlite3_bind_blob(stmt
, column
++, CFDataGetBytePtr(data
), (int32_t)CFDataGetLength(data
), NULL
); 
 512         rc 
= sqlite3_bind_null(stmt
, column
++); 
 514     require_noerr(rc
, err
); 
 516     rc 
= sqlite3_bind_text(stmt
, column
++, rule_get_comment(rule
), -1, NULL
); 
 517     require_noerr(rc
, err
); 
 522     LOGD("rule: sql bind, error %i", rc
); 
 527 _get_sql_mechanisms(rule_t rule
, authdb_connection_t dbconn
) 
 529     CFArrayRemoveAllValues(rule
->mechanisms
); 
 531     authdb_step(dbconn
, "SELECT 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
); 
 546 _get_sql_delegates(rule_t rule
, authdb_connection_t dbconn
) 
 548     CFArrayRemoveAllValues(rule
->delegations
); 
 550     authdb_step(dbconn
, "SELECT 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
); 
 559                         _get_sql_mechanisms(delegate
, dbconn
); 
 561                         if (rule_get_class(rule
) == RC_RULE
) { 
 562                             _get_sql_delegates(delegate
, dbconn
); 
 565                         CFArrayAppendValue(rule
->delegations
, delegate
); 
 566                         CFReleaseSafe(delegate
); 
 573 rule_sql_fetch(rule_t rule
, authdb_connection_t dbconn
) 
 575     __block 
bool result 
= false; 
 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
) { 
 582         auth_items_copy(rule
->data
, data
); 
 586     if (rule_get_id(rule
) != 0) { 
 587         _get_sql_mechanisms(rule
,dbconn
); 
 589         if (rule_get_class(rule
) == RC_RULE
) { 
 590             _get_sql_delegates(rule
, dbconn
); 
 598 _sql_update(rule_t rule
, authdb_connection_t dbconn
) 
 602     result 
= authdb_step(dbconn
, "UPDATE rules " \
 
 603                          "SET name=?,type=?,class=?,'group'=?,kofn=?,timeout=?,flags=?,tries=?,version=?,created=?,modified=?,hash=?,identifier=?,requirement=?,comment=? " \
 
 605                          ^(sqlite3_stmt 
*stmt
) { 
 606                              _sql_bind(rule
, stmt
); 
 607                              sqlite3_bind_int64(stmt
, sqlite3_bind_parameter_count(stmt
), rule_get_id(rule
)); 
 613 _sql_insert(rule_t rule
, authdb_connection_t dbconn
) 
 617     result 
= authdb_step(dbconn
, "INSERT INTO rules VALUES (NULL,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", 
 618                          ^(sqlite3_stmt 
*stmt
) { 
 619                              _sql_bind(rule
, stmt
); 
 625 _sql_commit_mechanisms_map(rule_t rule
, authdb_connection_t dbconn
) 
 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
)); 
 632     require(result 
== true, done
); 
 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
); 
 642         require(result 
== true, done
); 
 650 _sql_commit_delegates_map(rule_t rule
, authdb_connection_t dbconn
) 
 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
)); 
 657     require(result 
== true, done
); 
 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
); 
 667         require(result 
== true, done
); 
 675 _sql_commit_localization(rule_t rule
, authdb_connection_t dbconn
) 
 678     authdb_step(dbconn
, "DELETE FROM prompts WHERE r_id = ?", ^(sqlite3_stmt 
*stmt
) { 
 679         sqlite3_bind_int64(stmt
, 1, rule_get_id(rule
)); 
 682     authdb_step(dbconn
, "DELETE FROM buttons WHERE r_id = ?", ^(sqlite3_stmt 
*stmt
) { 
 683         sqlite3_bind_int64(stmt
, 1, rule_get_id(rule
)); 
 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
); 
 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
); 
 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
); 
 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
); 
 724 rule_sql_commit(rule_t rule
, authdb_connection_t dbconn
, CFAbsoluteTime modified
, process_t proc
) 
 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
); 
 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
); 
 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
)); 
 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
))); 
 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
); 
 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
))); 
 764     auth_items_set_double(rule
->data
, RULE_MODIFIED
, modified
); 
 766     result 
= authdb_transaction(dbconn
, AuthDBTransactionNormal
, ^bool{ 
 769         if (rule_get_id(rule
)) { 
 770             update 
= _sql_update(rule
, dbconn
); 
 773                 const char * ident 
= process_get_identifier(proc
); 
 775                     auth_items_set_string(rule
->data
, RULE_IDENTIFIER
, ident
); 
 777                 CFDataRef req 
= process_get_requirement_data(proc
); 
 779                     auth_items_set_data(rule
->data
, RULE_REQUIREMENT
, CFDataGetBytePtr(req
), (size_t)CFDataGetLength(req
)); 
 782             auth_items_set_double(rule
->data
, RULE_CREATED
, modified
); 
 783             update 
= _sql_insert(rule
, dbconn
); 
 784             _sql_get_id(rule
, dbconn
); 
 787         _sql_commit_localization(rule
, dbconn
); 
 790             update 
= _sql_commit_mechanisms_map(rule
, dbconn
); 
 794             update 
= _sql_commit_delegates_map(rule
,dbconn
); 
 803         LOGV("rule: commit, failed for %s (%llu)", rule_get_name(rule
), rule_get_id(rule
)); 
 809 rule_sql_remove(rule_t rule
, authdb_connection_t dbconn
) 
 812     int64_t id 
= rule_get_id(rule
); 
 815         rule_sql_fetch(rule
, dbconn
); 
 816         id 
= rule_get_id(rule
); 
 817         require(id 
!= 0, done
); 
 820     result 
= authdb_step(dbconn
, "DELETE FROM rules WHERE id = ?", 
 821                          ^(sqlite3_stmt 
*stmt
) { 
 822                              sqlite3_bind_int64(stmt
, 1, id
); 
 828 CFMutableDictionaryRef
 
 829 rule_copy_to_cfobject(rule_t rule
, authdb_connection_t dbconn
) { 
 830     CFMutableDictionaryRef dict 
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
); 
 832     CFTypeRef tmp 
= NULL
; 
 833     CFMutableArrayRef array 
= NULL
; 
 839     const char * comment 
= rule_get_comment(rule
); 
 841         tmp 
= CFStringCreateWithCString(kCFAllocatorDefault
, comment
, kCFStringEncodingUTF8
); 
 842         CFDictionarySetValue(dict
, CFSTR(kAuthorizationComment
), tmp
); 
 846     n 
= rule_get_version(rule
); 
 847     tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt64Type
, &n
); 
 848     CFDictionarySetValue(dict
, CFSTR(RULE_VERSION
), tmp
); 
 851     d 
= rule_get_created(rule
); 
 852     tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberFloat64Type
, &d
); 
 853     CFDictionarySetValue(dict
, CFSTR(RULE_CREATED
), tmp
); 
 856     d 
= rule_get_modified(rule
); 
 857     tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberFloat64Type
, &d
); 
 858     CFDictionarySetValue(dict
, CFSTR(RULE_MODIFIED
), tmp
); 
 861     const char * identifier 
= rule_get_identifier(rule
); 
 863         tmp 
= CFStringCreateWithCString(kCFAllocatorDefault
, identifier
, kCFStringEncodingUTF8
); 
 864         CFDictionarySetValue(dict
, CFSTR(RULE_IDENTIFIER
), tmp
); 
 868     SecRequirementRef req 
= rule_get_requirement(rule
); 
 870         CFStringRef reqStr 
= NULL
; 
 871         SecRequirementCopyString(req
, kSecCSDefaultFlags
, &reqStr
); 
 873             CFDictionarySetValue(dict
, CFSTR(RULE_REQUIREMENT
), reqStr
); 
 874             CFReleaseSafe(reqStr
); 
 878     if (rule_check_flags(rule
, RuleFlagEntitled
)) { 
 879         CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterEntitled
), kCFBooleanTrue
); 
 882     if (rule_check_flags(rule
, RuleFlagRequireAppleSigned
)) { 
 883         CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterRequireAppleSigned
), kCFBooleanTrue
); 
 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
); 
 895             CFReleaseSafe(value
); 
 899         if (CFDictionaryGetCount(prompts
)) { 
 900             CFDictionaryAddValue(dict
, CFSTR(kAuthorizationRuleParameterDefaultPrompt
), prompts
); 
 902         CFReleaseSafe(prompts
); 
 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
); 
 912             CFReleaseSafe(value
); 
 916         if (CFDictionaryGetCount(buttons
)) { 
 917             CFDictionaryAddValue(dict
, CFSTR(kAuthorizationRuleParameterDefaultButton
), buttons
); 
 919         CFReleaseSafe(buttons
); 
 922     switch (rule_get_class(rule
)) { 
 924             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleClass
), CFSTR(kAuthorizationRuleClassUser
)); 
 926             const char * group 
= rule_get_group(rule
); 
 928                 tmp 
= CFStringCreateWithCString(kCFAllocatorDefault
, group
, kCFStringEncodingUTF8
); 
 929                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterGroup
), tmp
); 
 933             n 
= rule_get_timeout(rule
); 
 934             tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt64Type
, &n
); 
 935             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterCredentialTimeout
), tmp
); 
 938             n 
= rule_get_tries(rule
); 
 939             tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt64Type
, &n
); 
 940             CFDictionarySetValue(dict
, CFSTR("tries"), tmp
); 
 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
); 
 950             if (rule_check_flags(rule
, RuleFlagVPNEntitledAndGroup
)) { 
 951                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterVPNEntitledAndGroup
), kCFBooleanTrue
); 
 953             if (rule_get_extract_password(rule
)) { 
 954                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterExtractPassword
), kCFBooleanTrue
); 
 956                         if (rule_get_password_only(rule
)) { 
 957                                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterPasswordOnly
), kCFBooleanTrue
); 
 960             count 
= CFArrayGetCount(rule
->mechanisms
); 
 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
); 
 969                 CFDictionaryAddValue(dict
, CFSTR(kAuthorizationRuleParameterMechanisms
), array
); 
 974             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleClass
), CFSTR(kAuthorizationRightRule
)); 
 975             int64_t kofn 
= rule_get_kofn(rule
); 
 977                 tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt64Type
, &kofn
); 
 978                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterKofN
), tmp
); 
 982             count 
= CFArrayGetCount(rule
->delegations
); 
 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
); 
 991                 CFDictionaryAddValue(dict
, CFSTR(kAuthorizationRightRule
), array
); 
 996             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleClass
), CFSTR(kAuthorizationRuleClassMechanisms
)); 
 998             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterCredentialShared
), rule_get_shared(rule
) ? kCFBooleanTrue 
: kCFBooleanFalse
); 
 999             if (rule_get_extract_password(rule
)) { 
1000                 CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleParameterExtractPassword
), kCFBooleanTrue
); 
1003             n 
= rule_get_tries(rule
); 
1004             tmp 
= CFNumberCreate(kCFAllocatorDefault
, kCFNumberSInt64Type
, &n
); 
1005             CFDictionarySetValue(dict
, CFSTR("tries"), tmp
); 
1008             count 
= CFArrayGetCount(rule
->mechanisms
); 
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
); 
1017                 CFDictionaryAddValue(dict
, CFSTR(kAuthorizationRuleParameterMechanisms
), array
); 
1022             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleClass
), CFSTR(kAuthorizationRuleClassDeny
)); 
1025             CFDictionarySetValue(dict
, CFSTR(kAuthorizationRuleClass
), CFSTR(kAuthorizationRuleClassAllow
)); 
1036 rule_get_mechanisms(rule_t rule
) 
1038     return rule
->mechanisms
; 
1042 rule_get_mechanisms_count(rule_t rule
) 
1044     return (size_t)CFArrayGetCount(rule
->mechanisms
); 
1048 rule_mechanisms_iterator(rule_t rule
, mechanism_iterator_t iter
) 
1050     bool result 
= false; 
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
); 
1065 rule_get_delegates_count(rule_t rule
) 
1067     return (size_t)CFArrayGetCount(rule
->delegations
); 
1071 rule_delegates_iterator(rule_t rule
, delegate_iterator_t iter
) 
1073     bool result 
= false; 
1075     CFIndex count 
= CFArrayGetCount(rule
->delegations
); 
1076     for (CFIndex i 
= 0; i 
< count
; i
++) { 
1077         rule_t tmp 
= (rule_t
)CFArrayGetValueAtIndex(rule
->delegations
, i
); 
1088 rule_get_id(rule_t rule
) 
1090     return auth_items_get_int64(rule
->data
, RULE_ID
); 
1094 rule_get_name(rule_t rule
) 
1096     return auth_items_get_string(rule
->data
, RULE_NAME
); 
1100 rule_get_type(rule_t rule
) 
1102     return (RuleType
)auth_items_get_int64(rule
->data
, RULE_TYPE
); 
1106 rule_get_class(rule_t rule
) 
1108     return (RuleClass
)auth_items_get_int64(rule
->data
, RULE_CLASS
); 
1112 rule_get_group(rule_t rule
) 
1114     return auth_items_get_string(rule
->data
, RULE_GROUP
); 
1118 rule_get_kofn(rule_t rule
) 
1120     return auth_items_get_int64(rule
->data
, RULE_KOFN
); 
1124 rule_get_timeout(rule_t rule
) 
1126     return auth_items_get_int64(rule
->data
, RULE_TIMEOUT
); 
1130 rule_check_flags(rule_t rule
, RuleFlags flags
) 
1132     return (auth_items_get_int64(rule
->data
, RULE_FLAGS
) & flags
) != 0; 
1136 rule_get_shared(rule_t rule
) 
1138     return rule_check_flags(rule
, RuleFlagShared
); 
1142 rule_get_allow_root(rule_t rule
) 
1144     return rule_check_flags(rule
, RuleFlagAllowRoot
); 
1148 rule_get_session_owner(rule_t rule
) 
1150     return rule_check_flags(rule
, RuleFlagSessionOwner
); 
1154 rule_get_authenticate_user(rule_t rule
) 
1156     return rule_check_flags(rule
, RuleFlagAuthenticateUser
); 
1160 rule_get_extract_password(rule_t rule
) 
1162     return rule_check_flags(rule
, RuleFlagExtractPassword
); 
1166 rule_get_password_only(rule_t rule
) 
1168         return rule_check_flags(rule
, RuleFlagPasswordOnly
); 
1172 rule_get_tries(rule_t rule
) 
1174     return auth_items_get_int64(rule
->data
, RULE_TRIES
); 
1178 rule_get_comment(rule_t rule
) 
1180     return auth_items_get_string(rule
->data
, RULE_COMMENT
); 
1184 rule_get_version(rule_t rule
) 
1186     return auth_items_get_int64(rule
->data
, RULE_VERSION
); 
1189 double rule_get_created(rule_t rule
) 
1191     return auth_items_get_double(rule
->data
, RULE_CREATED
); 
1194 double rule_get_modified(rule_t rule
) 
1196     return auth_items_get_double(rule
->data
, RULE_MODIFIED
); 
1199 const char * rule_get_identifier(rule_t rule
) 
1201     return auth_items_get_string(rule
->data
, RULE_IDENTIFIER
); 
1204 CFDataRef 
rule_get_requirement_data(rule_t rule
) 
1206     if (!rule
->requirement_data 
&& auth_items_exist(rule
->data
, RULE_REQUIREMENT
)) { 
1208         const void * data 
= auth_items_get_data(rule
->data
, RULE_REQUIREMENT
, &len
); 
1209         rule
->requirement_data 
= CFDataCreate(kCFAllocatorDefault
, data
, (CFIndex
)len
); 
1212     return rule
->requirement_data
; 
1215 SecRequirementRef 
rule_get_requirement(rule_t rule
) 
1217     if (!rule
->requirement
) { 
1218         CFDataRef data 
= rule_get_requirement_data(rule
); 
1220             SecRequirementCreateWithData(data
, kSecCSDefaultFlags
, &rule
->requirement
); 
1224     return rule
->requirement
;