1 /* Copyright (c) 2012-2013 Apple Inc. All Rights Reserved. */
8 #include <Security/Authorization.h>
9 #include <Security/AuthorizationPlugin.h>
10 #include <bsm/libbsm.h>
16 __AUTH_BASE_STRUCT_HEADER__
;
23 audit_info_s auditInfo
;
28 _ccaudit_finalizer(CFTypeRef value
)
30 ccaudit_t ccaudit
= (ccaudit_t
)value
;
32 CFReleaseNull(ccaudit
->auth
);
33 CFReleaseNull(ccaudit
->proc
);
36 AUTH_TYPE_INSTANCE(ccaudit
,
39 .finalize
= _ccaudit_finalizer
,
42 .copyFormattingDesc
= NULL
,
46 static CFTypeID
ccaudit_get_type_id() {
47 static CFTypeID type_id
= _kCFRuntimeNotATypeID
;
48 static dispatch_once_t onceToken
;
50 dispatch_once(&onceToken
, ^{
51 type_id
= _CFRuntimeRegisterClass(&_auth_type_ccaudit
);
58 ccaudit_create(process_t proc
, auth_token_t auth
, int32_t event
)
60 ccaudit_t ccaudit
= NULL
;
62 require(auth
!= NULL
, done
);
64 ccaudit
= (ccaudit_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, ccaudit_get_type_id(), AUTH_CLASS_SIZE(ccaudit
), NULL
);
65 require(ccaudit
!= NULL
, done
);
67 ccaudit
->auth
= (auth_token_t
)CFRetain(auth
);
68 ccaudit
->proc
= (process_t
)CFRetain(proc
);
70 ccaudit
->event
= event
;
72 ccaudit
->auditInfo
= *auth_token_get_audit_info(auth
);
73 ccaudit
->tid
.port
= ccaudit
->auditInfo
.tid
;
79 static bool _enabled()
81 static dispatch_once_t onceToken
;
82 static bool enabled
= false;
84 dispatch_once(&onceToken
, ^{
85 int acond
= au_get_state();
93 os_log_error(AUTHD_LOG
, "ccaudit: error checking auditing status (%d)", acond
);
100 static bool _open(ccaudit_t ccaudit
)
106 if (-1 != ccaudit
->fd
)
109 if ((ccaudit
->fd
= au_open()) < 0) {
110 os_log_error(AUTHD_LOG
, "ccaudit: au_open() failed (%{public}s)", strerror(errno
));
117 static void _close(ccaudit_t ccaudit
)
119 if (-1 != ccaudit
->fd
) {
120 int err
= au_close(ccaudit
->fd
, AU_TO_WRITE
, (short)ccaudit
->event
);
123 os_log_error(AUTHD_LOG
, "ccaudit: au_close() failed; record not committed");
128 static bool _write(ccaudit_t ccaudit
, token_t
* token
, const char * name
)
130 const char *tokenName
= name
? name
: "<unidentified>";
133 os_log_error(AUTHD_LOG
, "ccaudit: invalid '%{public}s' token", tokenName
);
136 if (au_write(ccaudit
->fd
, token
) < 0) {
137 os_log_error(AUTHD_LOG
, "ccaudit: error writing '%{public}s' token (%{public}s)", tokenName
, strerror(errno
));
143 static bool _subject(ccaudit_t ccaudit
)
145 token_t
* token
= au_to_subject32(ccaudit
->auditInfo
.auid
, ccaudit
->auditInfo
.euid
, ccaudit
->auditInfo
.egid
,
146 ccaudit
->auditInfo
.ruid
, ccaudit
->auditInfo
.rgid
, ccaudit
->auditInfo
.pid
, ccaudit
->auditInfo
.asid
, &ccaudit
->tid
);
147 return _write(ccaudit
, token
, "subject");
150 void ccaudit_log_authorization(ccaudit_t ccaudit
, const char * right
, OSStatus err
)
153 if (!_open(ccaudit
)) {
156 char buf
[PATH_MAX
+1];
159 _write(ccaudit
, au_to_text(right
), "right");
160 snprintf(buf
, sizeof(buf
), "client %s", process_get_code_url(ccaudit
->proc
));
161 _write(ccaudit
, au_to_text(buf
), "Authorization client");
162 snprintf(buf
, sizeof(buf
), "creator %s", auth_token_get_code_url(ccaudit
->auth
));
163 _write(ccaudit
, au_to_text(buf
), "Authorization creator");
165 if (auth_token_least_privileged(ccaudit
->auth
)) {
166 _write(ccaudit
, au_to_text("least-privilege"), "least-privilege");
169 if (err
== errAuthorizationSuccess
) {
170 _write(ccaudit
, au_to_return32(0, 0), "return");
172 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)err
), "return");
178 void ccaudit_log_success(ccaudit_t ccaudit
, credential_t cred
, const char * right
)
181 if (!_open(ccaudit
)) {
184 char buf
[PATH_MAX
+1];
187 _write(ccaudit
, au_to_text(right
), "right");
188 _write(ccaudit
, au_to_arg32(1, "known UID ", auth_token_get_uid(ccaudit
->auth
)), "authenticator");
189 snprintf(buf
, sizeof(buf
), "authenticated as %s", credential_get_name(cred
));
190 _write(ccaudit
, au_to_arg32(2, buf
, credential_get_uid(cred
)), "target");
191 _write(ccaudit
, au_to_return32(0, 0), "return");
196 #pragma clang diagnostic push
197 #pragma clang diagnostic ignored "-Wunused-parameter"
199 void ccaudit_log_failure(ccaudit_t ccaudit
, const char * credName
, const char * right
)
202 if (!_open(ccaudit
)) {
206 _write(ccaudit
, au_to_text(right
), "right");
207 _write(ccaudit
, au_to_arg32(1, "authenticated as ", auth_token_get_uid(ccaudit
->auth
)), "authenticator");
209 _write(ccaudit
, au_to_text("<unknown user>"), "target username");
210 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)errAuthorizationDenied
), "return");
215 #pragma clang diagnostic pop
217 void ccaudit_log_mechanism(ccaudit_t ccaudit
, const char * right
, const char * mech
, uint32_t status
, const char * interrupted
)
220 if (!_open(ccaudit
)) {
223 char buf
[PATH_MAX
+1];
226 _write(ccaudit
, au_to_text(right
), "right");
227 snprintf(buf
, sizeof(buf
), "mechanism %s", mech
);
228 _write(ccaudit
, au_to_text(buf
), "mechanism");
231 _write(ccaudit
, au_to_text(interrupted
), "interrupt");
234 if (status
== kAuthorizationResultAllow
) {
235 _write(ccaudit
, au_to_return32(0, 0), "return");
237 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)status
), "return");
243 void ccaudit_log(ccaudit_t ccaudit
, const char * right
, const char * msg
, OSStatus err
)
245 if (!_open(ccaudit
)) {
250 _write(ccaudit
, au_to_text(right
), "right");
253 _write(ccaudit
, au_to_text(msg
), "evaluation error");
256 if (err
== errAuthorizationSuccess
) {
257 _write(ccaudit
, au_to_return32(0, 0), "return");
259 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)err
), "return");