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