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>
15 __AUTH_BASE_STRUCT_HEADER__
;
22 audit_info_s auditInfo
;
27 _ccaudit_finalizer(CFTypeRef value
)
29 ccaudit_t ccaudit
= (ccaudit_t
)value
;
31 CFReleaseNull(ccaudit
->auth
);
32 CFReleaseNull(ccaudit
->proc
);
35 AUTH_TYPE_INSTANCE(ccaudit
,
38 .finalize
= _ccaudit_finalizer
,
41 .copyFormattingDesc
= NULL
,
45 static CFTypeID
ccaudit_get_type_id() {
46 static CFTypeID type_id
= _kCFRuntimeNotATypeID
;
47 static dispatch_once_t onceToken
;
49 dispatch_once(&onceToken
, ^{
50 type_id
= _CFRuntimeRegisterClass(&_auth_type_ccaudit
);
57 ccaudit_create(process_t proc
, auth_token_t auth
, int32_t event
)
59 ccaudit_t ccaudit
= NULL
;
61 require(auth
!= NULL
, done
);
63 ccaudit
= (ccaudit_t
)_CFRuntimeCreateInstance(kCFAllocatorDefault
, ccaudit_get_type_id(), AUTH_CLASS_SIZE(ccaudit
), NULL
);
64 require(ccaudit
!= NULL
, done
);
66 ccaudit
->auth
= (auth_token_t
)CFRetain(auth
);
67 ccaudit
->proc
= (process_t
)CFRetain(proc
);
69 ccaudit
->event
= event
;
71 ccaudit
->auditInfo
= *auth_token_get_audit_info(auth
);
72 ccaudit
->tid
.port
= ccaudit
->auditInfo
.tid
;
78 static bool _enabled()
80 static dispatch_once_t onceToken
;
81 static bool enabled
= false;
83 dispatch_once(&onceToken
, ^{
84 int acond
= au_get_state();
92 os_log_error(AUTHD_LOG
, "ccaudit: error checking auditing status (%d)", acond
);
99 static bool _open(ccaudit_t ccaudit
)
105 if (-1 != ccaudit
->fd
)
108 if ((ccaudit
->fd
= au_open()) < 0) {
109 os_log_error(AUTHD_LOG
, "ccaudit: au_open() failed (%{public}s)", strerror(errno
));
116 static void _close(ccaudit_t ccaudit
)
118 if (-1 != ccaudit
->fd
) {
119 int err
= au_close(ccaudit
->fd
, AU_TO_WRITE
, (short)ccaudit
->event
);
122 os_log_error(AUTHD_LOG
, "ccaudit: au_close() failed; record not committed");
127 static bool _write(ccaudit_t ccaudit
, token_t
* token
, const char * name
)
129 const char *tokenName
= name
? name
: "<unidentified>";
132 os_log_error(AUTHD_LOG
, "ccaudit: invalid '%{public}s' token", tokenName
);
135 if (au_write(ccaudit
->fd
, token
) < 0) {
136 os_log_error(AUTHD_LOG
, "ccaudit: error writing '%{public}s' token (%{public}s)", tokenName
, strerror(errno
));
142 static bool _subject(ccaudit_t ccaudit
)
144 token_t
* token
= au_to_subject32(ccaudit
->auditInfo
.auid
, ccaudit
->auditInfo
.euid
, ccaudit
->auditInfo
.egid
,
145 ccaudit
->auditInfo
.ruid
, ccaudit
->auditInfo
.rgid
, ccaudit
->auditInfo
.pid
, ccaudit
->auditInfo
.asid
, &ccaudit
->tid
);
146 return _write(ccaudit
, token
, "subject");
149 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
)
178 if (!_open(ccaudit
)) {
181 char buf
[PATH_MAX
+1];
184 _write(ccaudit
, au_to_text(right
), "right");
185 _write(ccaudit
, au_to_arg32(1, "known UID ", auth_token_get_uid(ccaudit
->auth
)), "authenticator");
186 snprintf(buf
, sizeof(buf
), "authenticated as %s", credential_get_name(cred
));
187 _write(ccaudit
, au_to_arg32(2, buf
, credential_get_uid(cred
)), "target");
188 _write(ccaudit
, au_to_return32(0, 0), "return");
193 #pragma clang diagnostic push
194 #pragma clang diagnostic ignored "-Wunused-parameter"
196 void ccaudit_log_failure(ccaudit_t ccaudit
, const char * credName
, const char * right
)
198 if (!_open(ccaudit
)) {
202 _write(ccaudit
, au_to_text(right
), "right");
203 _write(ccaudit
, au_to_arg32(1, "authenticated as ", auth_token_get_uid(ccaudit
->auth
)), "authenticator");
205 _write(ccaudit
, au_to_text("<unknown user>"), "target username");
206 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)errAuthorizationDenied
), "return");
211 #pragma clang diagnostic pop
213 void ccaudit_log_mechanism(ccaudit_t ccaudit
, const char * right
, const char * mech
, uint32_t status
, const char * interrupted
)
215 if (!_open(ccaudit
)) {
218 char buf
[PATH_MAX
+1];
221 _write(ccaudit
, au_to_text(right
), "right");
222 snprintf(buf
, sizeof(buf
), "mechanism %s", mech
);
223 _write(ccaudit
, au_to_text(buf
), "mechanism");
226 _write(ccaudit
, au_to_text(interrupted
), "interrupt");
229 if (status
== kAuthorizationResultAllow
) {
230 _write(ccaudit
, au_to_return32(0, 0), "return");
232 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)status
), "return");
238 void ccaudit_log(ccaudit_t ccaudit
, const char * right
, const char * msg
, OSStatus err
)
240 if (!_open(ccaudit
)) {
245 _write(ccaudit
, au_to_text(right
), "right");
248 _write(ccaudit
, au_to_text(msg
), "evaluation error");
251 if (err
== errAuthorizationSuccess
) {
252 _write(ccaudit
, au_to_return32(0, 0), "return");
254 _write(ccaudit
, au_to_return32(EPERM
, (uint32_t)err
), "return");