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");