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
];