/* * This is OK for those callers who have only one token to write. If you * have multiple tokens that logically form part of the same audit record, * you need to use the existing au_open()/au_write()/au_close() API: * * aufd = au_open(); * tok = au_to_random_token_1(...); * au_write(aufd, tok); * tok = au_to_random_token_2(...); * au_write(aufd, tok); * ... * au_close(aufd, 1, AUE_your_event_type); * * Assumes, like all wrapper calls, that the caller has previously checked * that auditing is enabled via the audit_get_state() call. * * XXX Should be more robust against bad arguments */ int audit_write(short event_code, token_t *subject, token_t *misctok, char retval, int errcode) { int aufd; char *func = "audit_write()"; token_t *rettok; if ((aufd = au_open()) == -1) { au_free_token(subject); au_free_token(misctok); syslog(LOG_ERR, "%s: au_open() failed", func); return kAUOpenErr; } /* save subject */ if (subject && au_write(aufd, subject) == -1) { au_free_token(subject); au_free_token(misctok); (void)au_close(aufd, 0, event_code); syslog(LOG_ERR, "%s: write of subject failed", func); return kAUWriteSubjectTokErr; } /* save the event-specific token */ if (misctok && au_write(aufd, misctok) == -1) { au_free_token(misctok); (void)au_close(aufd, 0, event_code); syslog(LOG_ERR, "%s: write of caller token failed", func); return kAUWriteCallerTokErr; } /* tokenize and save the return value */ if ((rettok = au_to_return32(retval, errcode)) == NULL) { (void)au_close(aufd, 0, event_code); syslog(LOG_ERR, "%s: au_to_return32() failed", func); return kAUMakeReturnTokErr; } if (au_write(aufd, rettok) == -1) { au_free_token(rettok); (void)au_close(aufd, 0, event_code); syslog(LOG_ERR, "%s: write of return code failed", func); return kAUWriteReturnTokErr; } /* * au_close()'s second argument is "keep": if keep == 0, the record is * discarded. We assume the caller wouldn't have bothered with this * function if it hadn't already decided to keep the record. */ if (au_close(aufd, 1, event_code) < 0) { syslog(LOG_ERR, "%s: au_close() failed", func); return kAUCloseErr; } return kAUNoErr; }
/* * Same caveats as audit_write(). In addition, this function explicitly * assumes failure; use audit_write_success_self() otherwise. * * XXX This should let the caller pass an error return value rather than * hard-coding -1. */ int audit_write_failure_self(short event_code, char *errmsg, int errret) { char *func = "audit_write_failure_self()"; token_t *subject, *errtok; if ((subject = au_to_me()) == NULL) { syslog(LOG_ERR, "%s: au_to_me() failed", func); return (kAUMakeSubjectTokErr); } /* tokenize and save the error message */ if ((errtok = au_to_text(errmsg)) == NULL) { au_free_token(subject); syslog(LOG_ERR, "%s: au_to_text() failed", func); return (kAUMakeTextTokErr); } return (audit_write(event_code, subject, errtok, -1, errret)); }
/* * Same caveats as audit_write(). In addition, this function explicitly * assumes failure; use audit_write_success() otherwise. * * XXX This should let the caller pass an error return value rather than * hard-coding -1. */ int audit_write_failure(short event_code, char *errmsg, int errcode, au_id_t auid, uid_t euid, gid_t egid, uid_t ruid, gid_t rgid, pid_t pid, au_asid_t sid, au_tid_t *tid) { char *func = "audit_write_failure()"; token_t *subject, *errtok; subject = au_to_subject32(auid, euid, egid, ruid, rgid, pid, sid, tid); if (subject == NULL) { syslog(LOG_ERR, "%s: au_to_subject32() failed", func); return (kAUMakeSubjectTokErr); } /* tokenize and save the error message */ if ((errtok = au_to_text(errmsg)) == NULL) { au_free_token(subject); syslog(LOG_ERR, "%s: au_to_text() failed", func); return (kAUMakeTextTokErr); } return (audit_write(event_code, subject, errtok, -1, errcode)); }