PERFORCE change 65760 for review

Wayne Salamon wsalamon at FreeBSD.org
Wed Nov 24 02:48:16 GMT 2004


http://perforce.freebsd.org/chv.cgi?CH=65760

Change 65760 by wsalamon at rickenbacker on 2004/11/24 02:47:47

	Add auditing to login, which is required to set up the user process
	audit state. Update the man page to include audit info for login.

Affected files ...

.. //depot/projects/trustedbsd/audit3/usr.bin/login/Makefile#2 edit
.. //depot/projects/trustedbsd/audit3/usr.bin/login/login.1#3 edit
.. //depot/projects/trustedbsd/audit3/usr.bin/login/login.c#2 edit

Differences ...

==== //depot/projects/trustedbsd/audit3/usr.bin/login/Makefile#2 (text+ko) ====

@@ -5,7 +5,7 @@
 SRCS=	login.c login_fbtab.c
 CFLAGS+=-DLOGALL
 DPADD=	${LIBUTIL} ${LIBPAM}
-LDADD=	-lutil ${MINUSLPAM}
+LDADD=	-lutil -lbsm ${MINUSLPAM}
 MAN=	login.1 login.access.5
 .if !defined(NO_SETUID_LOGIN)
 BINOWN=	root

==== //depot/projects/trustedbsd/audit3/usr.bin/login/login.1#3 (text+ko) ====

@@ -124,6 +124,12 @@
 Consult the
 .Xr builtin 1
 manual page.
+.Pp
+The 
+.Nm
+utility will submit an audit record when login succeeds or fails. Failure to
+determine the current auditing state will result in an error exit from
+.Nm .
 .Sh FILES
 .Bl -tag -width ".Pa /etc/login.access" -compact
 .It Pa /etc/fbtab
@@ -143,6 +149,10 @@
 .It Pa /etc/pam.d/login
 .Xr pam 8
 configuration file
+.It Pa /etc/security/audit_user
+user flags for auditing
+.It Pa /etc/security/audit_control
+global flags for auditing
 .El
 .Sh SEE ALSO
 .Xr builtin 1 ,

==== //depot/projects/trustedbsd/audit3/usr.bin/login/login.c#2 (text+ko) ====

@@ -61,6 +61,9 @@
 #include <sys/resource.h>
 #include <sys/wait.h>
 
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+
 #include <err.h>
 #include <errno.h>
 #include <grp.h>
@@ -96,6 +99,8 @@
 static void		 sigint(int);
 static void		 timedout(int);
 static void		 usage(void);
+static void		 au_success();
+static void		 au_fail(char *, int);
 
 #define	TTYGRPNAME		"tty"			/* group to own ttys */
 #define	DEFAULT_BACKOFF		3
@@ -155,6 +160,11 @@
 static int		 pam_cred_established;
 static int		 pam_session_established;
 
+/*
+ * Audit data
+ */
+au_tid_t tid;
+
 int
 main(int argc, char *argv[])
 {
@@ -172,6 +182,7 @@
 	const char *shell = NULL;
 	login_cap_t *lc = NULL;
 	pid_t pid;
+	char auditsuccess = 1;
 
 	(void)signal(SIGQUIT, SIG_IGN);
 	(void)signal(SIGINT, SIG_IGN);
@@ -290,16 +301,19 @@
 		pam_err = pam_start("login", username, &pamc, &pamh);
 		if (pam_err != PAM_SUCCESS) {
 			pam_syslog("pam_start()");
+			au_fail("PAM Error", 1);
 			bail(NO_SLEEP_EXIT, 1);
 		}
 		pam_err = pam_set_item(pamh, PAM_TTY, tty);
 		if (pam_err != PAM_SUCCESS) {
 			pam_syslog("pam_set_item(PAM_TTY)");
+			au_fail("PAM Error", 1);
 			bail(NO_SLEEP_EXIT, 1);
 		}
 		pam_err = pam_set_item(pamh, PAM_RHOST, hostname);
 		if (pam_err != PAM_SUCCESS) {
 			pam_syslog("pam_set_item(PAM_RHOST)");
+			au_fail("PAM Error", 1);
 			bail(NO_SLEEP_EXIT, 1);
 		}
 
@@ -316,6 +330,7 @@
 		    (uid == (uid_t)0 || uid == (uid_t)pwd->pw_uid)) {
 			/* already authenticated */
 			rval = 0;
+			auditsuccess = 0; /* opened a terminal window only */
 		} else {
 			fflag = 0;
 			(void)setpriority(PRIO_PROCESS, 0, -4);
@@ -328,6 +343,12 @@
 
 		pam_cleanup();
 
+		/*
+		 * we are not exiting here, but this corresponds to
+		 * a failed login event, so set exitstatus to 1
+		 */
+		au_fail("Login incorrect", 1);
+
 		(void)printf("Login incorrect\n");
 		failures++;
 
@@ -350,6 +371,10 @@
 
 	endpwent();
 
+	/* Audit successful login */
+	if (auditsuccess)
+		au_success();
+
 	/*
 	 * Establish the login class.
 	 */
@@ -746,6 +771,154 @@
 	return (1);
 }
 
+/*
+ * The following tokens are included in the audit record for a successful 
+ * login:
+ * header
+ * subject
+ * return
+ */ 
+static void
+au_success()
+{
+	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);
+	}
+}
+
+/*
+ * The following tokens are included in the audit record for failed 
+ * login attempts:
+ * header
+ * subject
+ * text
+ * return
+ */ 
+static void
+au_fail(char *errmsg, int na)
+{
+	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 user's 
+		 * 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);
+	}
+}
+
 static void
 usage()
 {
To Unsubscribe: send mail to majordomo at trustedbsd.org
with "unsubscribe trustedbsd-cvs" in the body of the message



More information about the trustedbsd-cvs mailing list