]> git.saurik.com Git - apple/security.git/blame - OSX/authd/ccaudit.c
Security-57740.60.18.tar.gz
[apple/security.git] / OSX / authd / ccaudit.c
CommitLineData
d8f41ccd 1/* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
427c49bc
A
2
3#include "ccaudit.h"
4#include "debugging.h"
5#include "process.h"
6#include "authtoken.h"
7
8#include <Security/Authorization.h>
9#include <Security/AuthorizationPlugin.h>
10#include <bsm/libbsm.h>
11
12
13struct _ccaudit_s {
14 __AUTH_BASE_STRUCT_HEADER__;
15
16 int fd;
17 int32_t event;
18
19 auth_token_t auth;
20 process_t proc;
21 audit_info_s auditInfo;
22 au_tid_t tid;
23};
24
25static void
26_ccaudit_finalizer(CFTypeRef value)
27{
28 ccaudit_t ccaudit = (ccaudit_t)value;
29
30 CFReleaseSafe(ccaudit->auth);
31 CFReleaseSafe(ccaudit->proc);
32}
33
34AUTH_TYPE_INSTANCE(ccaudit,
35 .init = NULL,
36 .copy = NULL,
37 .finalize = _ccaudit_finalizer,
38 .equal = NULL,
39 .hash = NULL,
40 .copyFormattingDesc = NULL,
41 .copyDebugDesc = NULL
42 );
43
44static CFTypeID ccaudit_get_type_id() {
45 static CFTypeID type_id = _kCFRuntimeNotATypeID;
46 static dispatch_once_t onceToken;
47
48 dispatch_once(&onceToken, ^{
49 type_id = _CFRuntimeRegisterClass(&_auth_type_ccaudit);
50 });
51
52 return type_id;
53}
54
55ccaudit_t
56ccaudit_create(process_t proc, auth_token_t auth, int32_t event)
57{
58 ccaudit_t ccaudit = NULL;
59
60 require(auth != NULL, done);
61
62 ccaudit = (ccaudit_t)_CFRuntimeCreateInstance(kCFAllocatorDefault, ccaudit_get_type_id(), AUTH_CLASS_SIZE(ccaudit), NULL);
63 require(ccaudit != NULL, done);
64
65 ccaudit->auth = (auth_token_t)CFRetain(auth);
66 ccaudit->proc = (process_t)CFRetain(proc);
67 ccaudit->fd = -1;
68 ccaudit->event = event;
69
70 ccaudit->auditInfo = *auth_token_get_audit_info(auth);
71 ccaudit->tid.port = ccaudit->auditInfo.tid;
72
73done:
74 return ccaudit;
75}
76
77static bool _enabled()
78{
79 static dispatch_once_t onceToken;
80 static bool enabled = false;
81
82 dispatch_once(&onceToken, ^{
83 int acond = au_get_state();
84 switch (acond) {
85 case AUC_NOAUDIT:
86 break;
87 case AUC_AUDITING:
88 enabled = true;
89 break;
90 default:
91 LOGE("ccaudit: error checking auditing status (%d)", acond);
92 }
93 });
94
95 return enabled;
96}
97
98static bool _open(ccaudit_t ccaudit)
99{
100 if (!_enabled()) {
101 return false;
102 }
103
104 if (-1 != ccaudit->fd)
105 return true;
106
107 if ((ccaudit->fd = au_open()) < 0) {
108 LOGE("ccaudit: au_open() failed (%s)", strerror(errno));
109 return false;
110 }
111
112 return true;
113}
114
115static void _close(ccaudit_t ccaudit)
116{
117 if (-1 != ccaudit->fd) {
118 int err = au_close(ccaudit->fd, AU_TO_WRITE, (short)ccaudit->event);
119 ccaudit->fd = -1;
120 if (err < 0) {
121 LOGE("ccaudit: au_close() failed; record not committed");
122 }
123 }
124}
125
126static bool _write(ccaudit_t ccaudit, token_t * token, const char * name)
127{
128 const char *tokenName = name ? name : "<unidentified>";
129 if (NULL == token)
130 {
131 LOGE("ccaudit: invalid '%s' token", tokenName);
132 return false;
133 }
134 if (au_write(ccaudit->fd, token) < 0) {
135 LOGE("ccaudit: error writing '%s' token (%s)", tokenName, strerror(errno));
136 return false;
137 }
138 return true;
139}
140
141static bool _subject(ccaudit_t ccaudit)
142{
143 token_t * token = au_to_subject32(ccaudit->auditInfo.auid, ccaudit->auditInfo.euid, ccaudit->auditInfo.egid,
144 ccaudit->auditInfo.ruid, ccaudit->auditInfo.rgid, ccaudit->auditInfo.pid, ccaudit->auditInfo.asid, &ccaudit->tid);
145 return _write(ccaudit, token, "subject");
146}
147
148void ccaudit_log_authorization(ccaudit_t ccaudit, const char * right, OSStatus err)
149{
150
151 if (!_open(ccaudit)) {
152 return;
153 }
154 char buf[PATH_MAX+1];
155
156 _subject(ccaudit);
157 _write(ccaudit, au_to_text(right), "right");
158 snprintf(buf, sizeof(buf), "client %s", process_get_code_url(ccaudit->proc));
159 _write(ccaudit, au_to_text(buf), "Authorization client");
160 snprintf(buf, sizeof(buf), "creator %s", auth_token_get_code_url(ccaudit->auth));
161 _write(ccaudit, au_to_text(buf), "Authorization creator");
162
163 if (auth_token_least_privileged(ccaudit->auth)) {
164 _write(ccaudit, au_to_text("least-privilege"), "least-privilege");
165 }
166
167 if (err == errAuthorizationSuccess) {
168 _write(ccaudit, au_to_return32(0, 0), "return");
169 } else {
170 _write(ccaudit, au_to_return32(EPERM, (uint32_t)err), "return");
171 }
172
173 _close(ccaudit);
174}
175
176void ccaudit_log_success(ccaudit_t ccaudit, credential_t cred, const char * right)
177{
178
179 if (!_open(ccaudit)) {
180 return;
181 }
182 char buf[PATH_MAX+1];
183
184 _subject(ccaudit);
185 _write(ccaudit, au_to_text(right), "right");
186 _write(ccaudit, au_to_arg32(1, "known UID ", auth_token_get_uid(ccaudit->auth)), "authenticator");
187 snprintf(buf, sizeof(buf), "authenticated as %s", credential_get_name(cred));
188 _write(ccaudit, au_to_arg32(2, buf, credential_get_uid(cred)), "target");
189 _write(ccaudit, au_to_return32(0, 0), "return");
190
191 _close(ccaudit);
192}
193
fa7225c8
A
194#pragma clang diagnostic push
195#pragma clang diagnostic ignored "-Wunused-parameter"
196
427c49bc
A
197void ccaudit_log_failure(ccaudit_t ccaudit, const char * credName, const char * right)
198{
199
200 if (!_open(ccaudit)) {
201 return;
202 }
203 _subject(ccaudit);
204 _write(ccaudit, au_to_text(right), "right");
205 _write(ccaudit, au_to_arg32(1, "authenticated as ", auth_token_get_uid(ccaudit->auth)), "authenticator");
206
fa7225c8 207 _write(ccaudit, au_to_text("<unknown user>"), "target username");
427c49bc
A
208 _write(ccaudit, au_to_return32(EPERM, (uint32_t)errAuthorizationDenied), "return");
209
210 _close(ccaudit);
211}
212
fa7225c8
A
213#pragma clang diagnostic pop
214
427c49bc
A
215void ccaudit_log_mechanism(ccaudit_t ccaudit, const char * right, const char * mech, uint32_t status, const char * interrupted)
216{
217
218 if (!_open(ccaudit)) {
219 return;
220 }
221 char buf[PATH_MAX+1];
222
223 _subject(ccaudit);
224 _write(ccaudit, au_to_text(right), "right");
225 snprintf(buf, sizeof(buf), "mechanism %s", mech);
226 _write(ccaudit, au_to_text(buf), "mechanism");
227
228 if (interrupted) {
229 _write(ccaudit, au_to_text(interrupted), "interrupt");
230 }
231
232 if (status == kAuthorizationResultAllow) {
233 _write(ccaudit, au_to_return32(0, 0), "return");
234 } else {
235 _write(ccaudit, au_to_return32(EPERM, (uint32_t)status), "return");
236 }
237
238 _close(ccaudit);
239}
240
241void ccaudit_log(ccaudit_t ccaudit, const char * right, const char * msg, OSStatus err)
242{
243 if (!_open(ccaudit)) {
244 return;
245 }
246
247 _subject(ccaudit);
248 _write(ccaudit, au_to_text(right), "right");
249
250 if (msg) {
251 _write(ccaudit, au_to_text(msg), "evaluation error");
252 }
253
254 if (err == errAuthorizationSuccess) {
255 _write(ccaudit, au_to_return32(0, 0), "return");
256 } else {
257 _write(ccaudit, au_to_return32(EPERM, (uint32_t)err), "return");
258 }
259
260 _close(ccaudit);
261}