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