1 /* Copyright (c) 2012 Apple Inc. All rights reserved. */
8 #include <Security/Authorization.h>
9 #include <Security/AuthorizationPlugin.h>
10 #include <bsm/libbsm.h>
14 __AUTH_BASE_STRUCT_HEADER__
;
21 audit_info_s auditInfo
;
26 _ccaudit_finalizer(CFTypeRef value
)
28 ccaudit_t ccaudit
= (ccaudit_t
)value
;
30 CFReleaseSafe(ccaudit
->auth
);
31 CFReleaseSafe(ccaudit
->proc
);
34 AUTH_TYPE_INSTANCE(ccaudit
,
37 .finalize
= _ccaudit_finalizer
,
40 .copyFormattingDesc
= NULL
,
44 static CFTypeID
ccaudit_get_type_id() {
45 static CFTypeID type_id
= _kCFRuntimeNotATypeID
;
46 static dispatch_once_t onceToken
;
48 dispatch_once(&onceToken
, ^{
49 type_id
= _CFRuntimeRegisterClass(&_auth_type_ccaudit
);
56 ccaudit_create(process_t proc
, auth_token_t auth
, int32_t event
)
58 ccaudit_t ccaudit
= NULL
;
60 require(auth
!= NULL
, done
);
62 ccaudit
= (ccaudit_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, ccaudit_get_type_id(), AUTH_CLASS_SIZE(ccaudit
), NULL
);
63 require(ccaudit
!= NULL
, done
);
65 ccaudit
->auth
= (auth_token_t
)CFRetain(auth
);
66 ccaudit
->proc
= (process_t
)CFRetain(proc
);
68 ccaudit
->event
= event
;
70 ccaudit
->auditInfo
= *auth_token_get_audit_info(auth
);
71 ccaudit
->tid
.port
= ccaudit
->auditInfo
.tid
;
77 static bool _enabled()
79 static dispatch_once_t onceToken
;
80 static bool enabled
= false;
82 dispatch_once(&onceToken
, ^{
83 int acond
= au_get_state();
91 LOGE("ccaudit: error checking auditing status (%d)", acond
);
98 static bool _open(ccaudit_t ccaudit
)
104 if (-1 != ccaudit
->fd
)
107 if ((ccaudit
->fd
= au_open()) < 0) {
108 LOGE("ccaudit: au_open() failed (%s)", strerror(errno
));
115 static void _close(ccaudit_t ccaudit
)
117 if (-1 != ccaudit
->fd
) {
118 int err
= au_close(ccaudit
->fd
, AU_TO_WRITE
, (short)ccaudit
->event
);
121 LOGE("ccaudit: au_close() failed; record not committed");
126 static bool _write(ccaudit_t ccaudit
, token_t
* token
, const char * name
)
128 const char *tokenName
= name
? name
: "<unidentified>";
131 LOGE("ccaudit: invalid '%s' token", tokenName
);
134 if (au_write(ccaudit
->fd
, token
) < 0) {
135 LOGE("ccaudit: error writing '%s' token (%s)", tokenName
, strerror(errno
));
141 static bool _subject(ccaudit_t ccaudit
)
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");
148 void ccaudit_log_authorization(ccaudit_t ccaudit
, const char * right
, OSStatus err
)
151 if (!_open(ccaudit
)) {
154 char buf
[PATH_MAX
+1];
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");
163 if (auth_token_least_privileged(ccaudit
->auth
)) {
164 _write(ccaudit
, au_to_text("least-privilege"), "least-privilege");
167 if (err
== errAuthorizationSuccess
) {
168 _write(ccaudit
, au_to_return32(0, 0), "return");
170 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)err
), "return");
176 void ccaudit_log_success(ccaudit_t ccaudit
, credential_t cred
, const char * right
)
179 if (!_open(ccaudit
)) {
182 char buf
[PATH_MAX
+1];
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");
194 void ccaudit_log_failure(ccaudit_t ccaudit
, const char * credName
, const char * right
)
197 if (!_open(ccaudit
)) {
201 _write(ccaudit
, au_to_text(right
), "right");
202 _write(ccaudit
, au_to_arg32(1, "authenticated as ", auth_token_get_uid(ccaudit
->auth
)), "authenticator");
204 if (NULL
== credName
) {
205 _write(ccaudit
, au_to_text("<unknown user>"), "target username");
207 _write(ccaudit
, au_to_text(credName
), "target username");
209 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)errAuthorizationDenied
), "return");
214 void ccaudit_log_mechanism(ccaudit_t ccaudit
, const char * right
, const char * mech
, uint32_t status
, const char * interrupted
)
217 if (!_open(ccaudit
)) {
220 char buf
[PATH_MAX
+1];
223 _write(ccaudit
, au_to_text(right
), "right");
224 snprintf(buf
, sizeof(buf
), "mechanism %s", mech
);
225 _write(ccaudit
, au_to_text(buf
), "mechanism");
228 _write(ccaudit
, au_to_text(interrupted
), "interrupt");
231 if (status
== kAuthorizationResultAllow
) {
232 _write(ccaudit
, au_to_return32(0, 0), "return");
234 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)status
), "return");
240 void ccaudit_log(ccaudit_t ccaudit
, const char * right
, const char * msg
, OSStatus err
)
242 if (!_open(ccaudit
)) {
247 _write(ccaudit
, au_to_text(right
), "right");
250 _write(ccaudit
, au_to_text(msg
), "evaluation error");
253 if (err
== errAuthorizationSuccess
) {
254 _write(ccaudit
, au_to_return32(0, 0), "return");
256 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)err
), "return");