]> git.saurik.com Git - apple/security.git/blame - authd/session.c
Security-55471.14.18.tar.gz
[apple/security.git] / authd / session.c
CommitLineData
427c49bc
A
1/* Copyright (c) 2012 Apple Inc. All rights reserved. */
2
3#include "session.h"
4#include "process.h"
5#include "debugging.h"
6#include <dispatch/dispatch.h>
7#include <CoreFoundation/CoreFoundation.h>
8
9struct _session_s {
10 __AUTH_BASE_STRUCT_HEADER__;
11
12 CFMutableSetRef credentials;
13 CFMutableSetRef processes;
14 auditinfo_addr_t auditinfo;
15
16 dispatch_queue_t dispatch_queue;
17
18};
19
20static void
21_session_finalize(CFTypeRef value)
22{
23 session_t session = (session_t)value;
24
25 LOGV("session: %i deallocated %p", session->auditinfo.ai_asid, session);
26
27 // make sure queue is empty
28 dispatch_barrier_sync(session->dispatch_queue, ^{});
29
30 dispatch_release(session->dispatch_queue);
31 CFReleaseSafe(session->credentials);
32 CFReleaseSafe(session->processes);
33}
34
35AUTH_TYPE_INSTANCE(session,
36 .init = NULL,
37 .copy = NULL,
38 .finalize = _session_finalize,
39 .equal = NULL,
40 .hash = NULL,
41 .copyFormattingDesc = NULL,
42 .copyDebugDesc = NULL
43 );
44
45static CFTypeID session_get_type_id() {
46 static CFTypeID type_id = _kCFRuntimeNotATypeID;
47 static dispatch_once_t onceToken;
48
49 dispatch_once(&onceToken, ^{
50 type_id = _CFRuntimeRegisterClass(&_auth_type_session);
51 });
52
53 return type_id;
54}
55
56session_t
57session_create(session_id_t sid)
58{
59 session_t session = NULL;
60
61 session = (session_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, session_get_type_id(), AUTH_CLASS_SIZE(session), NULL);
62 require(session != NULL, done);
63
64 session->auditinfo.ai_asid = sid;
65
66 if (!session_update(session)) {
67 LOGE("session: failed to get session info");
68 }
69
70 session->dispatch_queue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
71 check(session->dispatch_queue != NULL);
72
73 session->credentials = CFSetCreateMutable(kCFAllocatorDefault, 0, &kCFTypeSetCallBacks);
74 session->processes = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
75
76 LOGV("session: %i created (uid=%i) %p", session->auditinfo.ai_asid, session->auditinfo.ai_auid, session);
77
78done:
79 return session;
80}
81
82bool session_update(session_t session)
83{
84 return auditon(A_GETSINFO_ADDR, &session->auditinfo, sizeof(session->auditinfo)) == 0;
85}
86
87uint64_t session_get_attributes(session_t session)
88{
89 session_update(session);
90
91 return session->auditinfo.ai_flags;
92}
93
94static void _set_attributes(session_t session, uint64_t flags)
95{
96 session->auditinfo.ai_flags = flags;
97 int32_t rc = setaudit_addr(&session->auditinfo, sizeof(session->auditinfo));
98 if (rc != 0) {
99 LOGV("session: failed to update session info (%d)", rc);
100 }
101}
102
103void session_set_attributes(session_t session, uint64_t flags)
104{
105 session_update(session);
106 _set_attributes(session,session->auditinfo.ai_flags | flags);
107}
108
109void session_clear_attributes(session_t session, uint64_t flags)
110{
111 session_update(session);
112 _set_attributes(session,session->auditinfo.ai_flags & ~flags);
113}
114
115
116const void *
117session_get_key(session_t session)
118{
119 return &session->auditinfo.ai_asid;
120}
121
122session_id_t
123session_get_id(session_t session)
124{
125 return session ? session->auditinfo.ai_asid : -1;
126}
127
128uid_t
129session_get_uid(session_t session)
130{
131 return session ? session->auditinfo.ai_auid : (uid_t)-2;
132}
133
134CFIndex
135session_add_process(session_t session, process_t proc)
136{
137 __block CFIndex count = 0;
138 dispatch_sync(session->dispatch_queue, ^{
139 CFSetAddValue(session->processes, proc);
140 count = CFSetGetCount(session->processes);
141 });
142 return count;
143}
144
145CFIndex
146session_remove_process(session_t session, process_t proc)
147{
148 __block CFIndex count = 0;
149 dispatch_sync(session->dispatch_queue, ^{
150 CFSetRemoveValue(session->processes, proc);
151 count = CFSetGetCount(session->processes);
152 });
153 return count;
154}
155
156CFIndex
157session_get_process_count(session_t session)
158{
159 __block CFIndex count = 0;
160 dispatch_sync(session->dispatch_queue, ^{
161 count = CFSetGetCount(session->processes);
162 });
163 return count;
164}
165
166void
167session_set_credential(session_t session, credential_t cred)
168{
169 if (!credential_get_valid(cred))
170 return;
171
172 dispatch_sync(session->dispatch_queue, ^{
173 CFSetSetValue(session->credentials, cred);
174 });
175}
176
177void
178session_credentials_purge(session_t session)
179{
180 session_credentials_iterate(session, ^bool(credential_t cred) {
181 if (!credential_get_valid(cred)) {
182 CFSetRemoveValue(session->credentials, cred);
183 }
184 return true;
185 });
186}
187
188bool
189session_credentials_iterate(session_t session, credential_iterator_t iter)
190{
191 __block bool result = false;
192
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];
199 result = iter(cred);
200 if (!result) {
201 break;
202 }
203 }
204 });
205
206
207 return result;
208}