1 /* Copyright (c) 2012 Apple Inc. All Rights Reserved. */ 
   6 #include <dispatch/dispatch.h> 
   7 #include <CoreFoundation/CoreFoundation.h> 
  10     __AUTH_BASE_STRUCT_HEADER__
; 
  12     CFMutableSetRef credentials
; 
  13     CFMutableSetRef processes
; 
  14     auditinfo_addr_t auditinfo
; 
  16     dispatch_queue_t dispatch_queue
; 
  21 _session_finalize(CFTypeRef value
) 
  23     session_t session 
= (session_t
)value
; 
  25     LOGV("session: %i deallocated %p", session
->auditinfo
.ai_asid
, session
); 
  27     // make sure queue is empty 
  28     dispatch_barrier_sync(session
->dispatch_queue
, ^{}); 
  30     dispatch_release(session
->dispatch_queue
); 
  31     CFReleaseSafe(session
->credentials
); 
  32     CFReleaseSafe(session
->processes
); 
  35 AUTH_TYPE_INSTANCE(session
, 
  38                    .finalize 
= _session_finalize
, 
  41                    .copyFormattingDesc 
= NULL
, 
  45 static CFTypeID 
session_get_type_id() { 
  46     static CFTypeID type_id 
= _kCFRuntimeNotATypeID
; 
  47     static dispatch_once_t onceToken
; 
  49     dispatch_once(&onceToken
, ^{ 
  50         type_id 
= _CFRuntimeRegisterClass(&_auth_type_session
); 
  57 session_create(session_id_t sid
) 
  59     session_t session 
= NULL
; 
  61     session 
= (session_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, session_get_type_id(), AUTH_CLASS_SIZE(session
), NULL
); 
  62     require(session 
!= NULL
, done
); 
  64     session
->auditinfo
.ai_asid 
= sid
; 
  66     if (!session_update(session
)) { 
  67         LOGE("session: failed to get session info"); 
  70     session
->dispatch_queue 
= dispatch_queue_create(NULL
, DISPATCH_QUEUE_SERIAL
); 
  71     check(session
->dispatch_queue 
!= NULL
); 
  73     session
->credentials 
= CFSetCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeSetCallBacks
); 
  74     session
->processes 
= CFSetCreateMutable(kCFAllocatorDefault
, 0, NULL
); 
  76     LOGV("session: %i created (uid=%i) %p", session
->auditinfo
.ai_asid
, session
->auditinfo
.ai_auid
, session
); 
  82 bool session_update(session_t session
) 
  84     return auditon(A_GETSINFO_ADDR
, &session
->auditinfo
, sizeof(session
->auditinfo
)) == 0; 
  87 uint64_t session_get_attributes(session_t session
) 
  89     session_update(session
); 
  91     return session
->auditinfo
.ai_flags
; 
  94 static void _set_attributes(session_t session
, uint64_t flags
) 
  96     session
->auditinfo
.ai_flags 
= flags
; 
  97     int32_t rc 
= setaudit_addr(&session
->auditinfo
, sizeof(session
->auditinfo
)); 
  99         LOGV("session: failed to update session info (%d)", rc
); 
 103 void session_set_attributes(session_t session
, uint64_t flags
) 
 105     session_update(session
); 
 106     _set_attributes(session
,session
->auditinfo
.ai_flags 
| flags
); 
 109 void session_clear_attributes(session_t session
, uint64_t flags
) 
 111     session_update(session
); 
 112     _set_attributes(session
,session
->auditinfo
.ai_flags 
& ~flags
); 
 117 session_get_key(session_t session
) 
 119     return &session
->auditinfo
.ai_asid
; 
 123 session_get_id(session_t session
) 
 125     assert(session
); // marked non-null 
 126     return session
->auditinfo
.ai_asid
; 
 130 session_get_uid(session_t session
) 
 132     assert(session
); // marked non-null 
 133     return session
->auditinfo
.ai_auid
; 
 137 session_add_process(session_t session
, process_t proc
) 
 139     __block CFIndex count 
= 0; 
 140     dispatch_sync(session
->dispatch_queue
, ^{ 
 141         CFSetAddValue(session
->processes
, proc
); 
 142         count 
= CFSetGetCount(session
->processes
); 
 148 session_remove_process(session_t session
, process_t proc
) 
 150     __block CFIndex count 
= 0; 
 151     dispatch_sync(session
->dispatch_queue
, ^{ 
 152         CFSetRemoveValue(session
->processes
, proc
); 
 153         count 
= CFSetGetCount(session
->processes
); 
 159 session_get_process_count(session_t session
) 
 161     __block CFIndex count 
= 0; 
 162     dispatch_sync(session
->dispatch_queue
, ^{ 
 163         count 
= CFSetGetCount(session
->processes
); 
 169 session_set_credential(session_t session
, credential_t cred
) 
 171     if (!credential_get_valid(cred
)) 
 174     dispatch_sync(session
->dispatch_queue
, ^{ 
 175         CFSetSetValue(session
->credentials
, cred
); 
 180 session_credentials_purge(session_t session
) 
 182     session_credentials_iterate(session
, ^bool(credential_t cred
) { 
 183         if (!credential_get_valid(cred
)) { 
 184             CFSetRemoveValue(session
->credentials
, cred
); 
 191 session_credentials_iterate(session_t session
, credential_iterator_t iter
) 
 193     __block 
bool result 
= false; 
 195     dispatch_sync(session
->dispatch_queue
, ^{ 
 196         CFIndex count 
= CFSetGetCount(session
->credentials
); 
 197         CFTypeRef values
[count
]; 
 198         CFSetGetValues(session
->credentials
, values
); 
 199         for (CFIndex i 
= 0; i 
< count
; i
++) { 
 200             credential_t cred 
= (credential_t
)values
[i
];