+/*
+ * The following tokens are included in the audit record for successful login attempts
+ * header
+ * subject
+ * return
+ */
+void au_success()
+{
+#ifdef USE_BSM
+ token_t *tok;
+ int aufd;
+ au_mask_t aumask;
+ auditinfo_t auinfo;
+ uid_t uid = pwd->pw_uid;
+ gid_t gid = pwd->pw_gid;
+ pid_t pid = getpid();
+ long au_cond;
+
+ /* If we are not auditing, don't cut an audit record; just return */
+ if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
+ fprintf(stderr, "login: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ /* Compute and Set the user's preselection mask */
+ if(au_user_mask(pwd->pw_name, &aumask) == -1) {
+ fprintf(stderr, "login: Could not set audit mask\n");
+ exit(1);
+ }
+
+ /* Set the audit info for the user */
+ auinfo.ai_auid = uid;
+ auinfo.ai_asid = pid;
+ bcopy(&tid, &auinfo.ai_termid, sizeof(auinfo.ai_termid));
+ bcopy(&aumask, &auinfo.ai_mask, sizeof(auinfo.ai_mask));
+ if(setaudit(&auinfo) != 0) {
+ fprintf(stderr, "login: setaudit failed: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "login: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ /* The subject that is created (euid, egid of the current process) */
+ if((tok = au_to_subject32(uid, geteuid(), getegid(),
+ uid, gid, pid, pid, &tid)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(0, 0)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_login) == -1) {
+ fprintf(stderr, "login: Audit Record was not committed.\n");
+ exit(1);
+ }
+#endif
+}
+
+/*
+ * The following tokens are included in the audit record for successful login attempts
+ * header
+ * subject
+ * text
+ * return
+ */
+void au_fail(char *errmsg, int na)
+{
+#ifdef USE_BSM
+ token_t *tok;
+ int aufd;
+ long au_cond;
+ uid_t uid;
+ gid_t 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, "login: Could not determine audit condition\n");
+ exit(1);
+ }
+ if (au_cond == AUC_NOAUDIT)
+ return;
+
+ if((aufd = au_open()) == -1) {
+ fprintf(stderr, "login: Audit Error: au_open() failed\n");
+ exit(1);
+ }
+
+ if(na) {
+ /* Non attributable event */
+ /* Assuming that login is not called within a users' session => auid,asid == -1 */
+ if((tok = au_to_subject32(-1, geteuid(), getegid(), -1, -1,
+ pid, -1, &tid)) == NULL) {
+
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ }
+ else {
+ /* we know the subject -- so use its value instead */
+ uid = pwd->pw_uid;
+ gid = pwd->pw_gid;
+ if((tok = au_to_subject32(uid, geteuid(), getegid(),
+ uid, gid, pid, pid, &tid)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_subject32() failed\n");
+ exit(1);
+ }
+ }
+ au_write(aufd, tok);
+
+ /* Include the error message */
+ if((tok = au_to_text(errmsg)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_text() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if((tok = au_to_return32(1, errno)) == NULL) {
+ fprintf(stderr, "login: Audit Error: au_to_return32() failed\n");
+ exit(1);
+ }
+ au_write(aufd, tok);
+
+ if(au_close(aufd, 1, AUE_login) == -1) {
+ fprintf(stderr, "login: Audit Error: au_close() was not committed\n");
+ exit(1);
+ }
+#endif
+}
+