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 return session
? session
->auditinfo
.ai_asid
: -1;
129 session_get_uid(session_t session
)
131 return session
? session
->auditinfo
.ai_auid
: (uid_t
)-2;
135 session_add_process(session_t session
, process_t proc
)
137 __block CFIndex count
= 0;
138 dispatch_sync(session
->dispatch_queue
, ^{
139 CFSetAddValue(session
->processes
, proc
);
140 count
= CFSetGetCount(session
->processes
);
146 session_remove_process(session_t session
, process_t proc
)
148 __block CFIndex count
= 0;
149 dispatch_sync(session
->dispatch_queue
, ^{
150 CFSetRemoveValue(session
->processes
, proc
);
151 count
= CFSetGetCount(session
->processes
);
157 session_get_process_count(session_t session
)
159 __block CFIndex count
= 0;
160 dispatch_sync(session
->dispatch_queue
, ^{
161 count
= CFSetGetCount(session
->processes
);
167 session_set_credential(session_t session
, credential_t cred
)
169 if (!credential_get_valid(cred
))
172 dispatch_sync(session
->dispatch_queue
, ^{
173 CFSetSetValue(session
->credentials
, cred
);
178 session_credentials_purge(session_t session
)
180 session_credentials_iterate(session
, ^bool(credential_t cred
) {
181 if (!credential_get_valid(cred
)) {
182 CFSetRemoveValue(session
->credentials
, cred
);
189 session_credentials_iterate(session_t session
, credential_iterator_t iter
)
191 __block
bool result
= false;
193 dispatch_sync(session
->dispatch_queue
, ^{
194 CFIndex count
= CFSetGetCount(session
->credentials
);
195 CFTypeRef values
[count
];
196 CFSetGetValues(session
->credentials
, values
);
197 for (CFIndex i
= 0; i
< count
; i
++) {
198 credential_t cred
= (credential_t
)values
[i
];