]> git.saurik.com Git - apple/security.git/blob - OSX/authd/session.c
Security-57740.20.22.tar.gz
[apple/security.git] / OSX / authd / session.c
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
9 struct _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
20 static 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
35 AUTH_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
45 static 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
56 session_t
57 session_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
78 done:
79 return session;
80 }
81
82 bool session_update(session_t session)
83 {
84 return auditon(A_GETSINFO_ADDR, &session->auditinfo, sizeof(session->auditinfo)) == 0;
85 }
86
87 uint64_t session_get_attributes(session_t session)
88 {
89 session_update(session);
90
91 return session->auditinfo.ai_flags;
92 }
93
94 static 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
103 void 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
109 void 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
116 const void *
117 session_get_key(session_t session)
118 {
119 return &session->auditinfo.ai_asid;
120 }
121
122 session_id_t
123 session_get_id(session_t session)
124 {
125 assert(session); // marked non-null
126 return session->auditinfo.ai_asid;
127 }
128
129 uid_t
130 session_get_uid(session_t session)
131 {
132 assert(session); // marked non-null
133 return session->auditinfo.ai_auid;
134 }
135
136 CFIndex
137 session_add_process(session_t session, process_t proc)
138 {
139 __block CFIndex count = 0;
140 dispatch_sync(session->dispatch_queue, ^{
141 CFSetAddValue(session->processes, proc);
142 count = CFSetGetCount(session->processes);
143 });
144 return count;
145 }
146
147 CFIndex
148 session_remove_process(session_t session, process_t proc)
149 {
150 __block CFIndex count = 0;
151 dispatch_sync(session->dispatch_queue, ^{
152 CFSetRemoveValue(session->processes, proc);
153 count = CFSetGetCount(session->processes);
154 });
155 return count;
156 }
157
158 CFIndex
159 session_get_process_count(session_t session)
160 {
161 __block CFIndex count = 0;
162 dispatch_sync(session->dispatch_queue, ^{
163 count = CFSetGetCount(session->processes);
164 });
165 return count;
166 }
167
168 void
169 session_set_credential(session_t session, credential_t cred)
170 {
171 if (!credential_get_valid(cred))
172 return;
173
174 dispatch_sync(session->dispatch_queue, ^{
175 CFSetSetValue(session->credentials, cred);
176 });
177 }
178
179 void
180 session_credentials_purge(session_t session)
181 {
182 session_credentials_iterate(session, ^bool(credential_t cred) {
183 if (!credential_get_valid(cred)) {
184 CFSetRemoveValue(session->credentials, cred);
185 }
186 return true;
187 });
188 }
189
190 bool
191 session_credentials_iterate(session_t session, credential_iterator_t iter)
192 {
193 __block bool result = false;
194
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];
201 result = iter(cred);
202 if (!result) {
203 break;
204 }
205 }
206 });
207
208
209 return result;
210 }