+
+/*
+ * Include the following tokens in the audit record for successful su attempts
+ * header
+ * subject
+ * return
+ */
+void audit_success(struct passwd *pwd)
+{
+ int aufd;
+ token_t *tok;
+ auditinfo_t auinfo;
+ long au_cond;
+ uid_t uid = pwd->pw_uid;
+ gid_t gid = pwd->pw_gid;
+ pid_t pid = getpid();
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "su: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ if(getaudit(&auinfo) != 0) {
+ fprintf(stderr, "su: getaudit failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "su: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ /* record the subject being created */
+ if((tok = au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
+ uid, gid, pid, auinfo.ai_asid, &auinfo.ai_termid)) == NULL) {
+ fprintf(stderr, "su: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(0, 0)) == NULL) {
+ fprintf(stderr, "su: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_su) == -1) {
+ fprintf(stderr, "su: Audit Error: au_close() failed\n");
+ exit(1);
+ }
+ return;
+}
+
+/*
+ * Include the following tokens in the audit record for successful su attempts
+ * header
+ * subject
+ * text
+ * return
+ */
+void audit_fail(struct passwd *pwd, char *errmsg)
+{
+ int aufd;
+ token_t *tok;
+ auditinfo_t auinfo;
+ long au_cond;
+ /* If pwd is NULL, the event dont attribute it to any user */
+ uid_t uid = pwd ? pwd->pw_uid : -1;
+ gid_t gid = pwd ? pwd->pw_gid : -1;
+ pid_t pid = getpid();
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "su: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ if(getaudit(&auinfo) != 0) {
+ fprintf(stderr, "su: getaudit failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "su: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ /* subject token corresponds to the subject being created */
+ if((tok = au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
+ uid, gid, pid, auinfo.ai_asid, &auinfo.ai_termid)) == NULL) {
+ fprintf(stderr, "su: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ /* the actual error message text */
+ if((tok = au_to_text(errmsg)) == NULL) {
+ fprintf(stderr, "su: Audit Error: au_to_text() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(1, errno)) == NULL) {
+ fprintf(stderr, "su: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_su) == -1) {
+ fprintf(stderr, "su: Audit Error: au_close() failed\n");
+ exit(1);
+ }
+ return;
+}