1 /* Copyright (c) 2012 Apple Inc. All Rights Reserved. */
6 #include <dispatch/dispatch.h>
7 #include <CoreFoundation/CoreFoundation.h>
12 __AUTH_BASE_STRUCT_HEADER__
;
14 CFMutableSetRef credentials
;
15 CFMutableSetRef processes
;
16 auditinfo_addr_t auditinfo
;
18 dispatch_queue_t dispatch_queue
;
23 _session_finalize(CFTypeRef value
)
25 session_t session
= (session_t
)value
;
27 os_log_debug(AUTHD_LOG
, "session: %i deallocated", session
->auditinfo
.ai_asid
);
29 // make sure queue is empty
30 dispatch_barrier_sync(session
->dispatch_queue
, ^{});
32 dispatch_release(session
->dispatch_queue
);
33 CFReleaseNull(session
->credentials
);
34 CFReleaseNull(session
->processes
);
37 AUTH_TYPE_INSTANCE(session
,
40 .finalize
= _session_finalize
,
43 .copyFormattingDesc
= NULL
,
47 static CFTypeID
session_get_type_id() {
48 static CFTypeID type_id
= _kCFRuntimeNotATypeID
;
49 static dispatch_once_t onceToken
;
51 dispatch_once(&onceToken
, ^{
52 type_id
= _CFRuntimeRegisterClass(&_auth_type_session
);
59 session_create(session_id_t sid
)
61 session_t session
= NULL
;
63 session
= (session_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, session_get_type_id(), AUTH_CLASS_SIZE(session
), NULL
);
64 require(session
!= NULL
, done
);
66 session
->auditinfo
.ai_asid
= sid
;
68 if (!session_update(session
)) {
69 os_log_error(AUTHD_LOG
, "session: failed to get session info");
72 session
->dispatch_queue
= dispatch_queue_create(NULL
, DISPATCH_QUEUE_SERIAL
);
73 check(session
->dispatch_queue
!= NULL
);
75 session
->credentials
= CFSetCreateMutable(kCFAllocatorDefault
, 0, &kCFTypeSetCallBacks
);
76 session
->processes
= CFSetCreateMutable(kCFAllocatorDefault
, 0, NULL
);
78 os_log_debug(AUTHD_LOG
, "session: %i created (uid=%i)", session
->auditinfo
.ai_asid
, session
->auditinfo
.ai_auid
);
84 bool session_update(session_t session
)
86 return auditon(A_GETSINFO_ADDR
, &session
->auditinfo
, sizeof(session
->auditinfo
)) == 0;
89 uint64_t session_get_attributes(session_t session
)
91 session_update(session
);
93 return session
->auditinfo
.ai_flags
;
96 static void _set_attributes(session_t session
, uint64_t flags
)
98 session
->auditinfo
.ai_flags
= flags
;
99 int32_t rc
= setaudit_addr(&session
->auditinfo
, sizeof(session
->auditinfo
));
101 os_log_debug(AUTHD_LOG
, "session: failed to update session info (%d)", rc
);
105 void session_set_attributes(session_t session
, uint64_t flags
)
107 session_update(session
);
108 _set_attributes(session
,session
->auditinfo
.ai_flags
| flags
);
111 void session_clear_attributes(session_t session
, uint64_t flags
)
113 session_update(session
);
114 _set_attributes(session
,session
->auditinfo
.ai_flags
& ~flags
);
119 session_get_key(session_t session
)
121 return &session
->auditinfo
.ai_asid
;
125 session_get_id(session_t session
)
127 assert(session
); // marked non-null
128 return session
->auditinfo
.ai_asid
;
132 session_get_uid(session_t session
)
134 assert(session
); // marked non-null
135 return session
->auditinfo
.ai_auid
;
139 session_add_process(session_t session
, process_t proc
)
141 __block CFIndex count
= 0;
142 dispatch_sync(session
->dispatch_queue
, ^{
143 CFSetAddValue(session
->processes
, proc
);
144 count
= CFSetGetCount(session
->processes
);
150 session_remove_process(session_t session
, process_t proc
)
152 __block CFIndex count
= 0;
153 dispatch_sync(session
->dispatch_queue
, ^{
154 CFSetRemoveValue(session
->processes
, proc
);
155 count
= CFSetGetCount(session
->processes
);
161 session_get_process_count(session_t session
)
163 __block CFIndex count
= 0;
164 dispatch_sync(session
->dispatch_queue
, ^{
165 count
= CFSetGetCount(session
->processes
);
171 session_set_credential(session_t session
, credential_t cred
)
173 if (!credential_get_valid(cred
))
176 dispatch_sync(session
->dispatch_queue
, ^{
177 CFSetSetValue(session
->credentials
, cred
);
182 session_credentials_purge(session_t session
)
184 session_credentials_iterate(session
, ^bool(credential_t cred
) {
185 if (!credential_get_valid(cred
)) {
186 CFSetRemoveValue(session
->credentials
, cred
);
193 session_credentials_iterate(session_t session
, credential_iterator_t iter
)
195 __block
bool result
= false;
197 dispatch_sync(session
->dispatch_queue
, ^{
198 CFIndex count
= CFSetGetCount(session
->credentials
);
199 CFTypeRef values
[count
];
200 CFSetGetValues(session
->credentials
, values
);
201 for (CFIndex i
= 0; i
< count
; i
++) {
202 credential_t cred
= (credential_t
)values
[i
];