From 6319ad282f8646a845d2a8d9c01e31309a2e7a9a Mon Sep 17 00:00:00 2001 From: "Christian S.J. Peron" Date: Fri, 1 Sep 2006 13:39:02 +0000 Subject: [PATCH] Integrate audit_submit(3) bits into su. This means that records for successful and failed su attempts will be recorded using the AUE_su event type (login or lo class) if auditing is present in the system. Currently, the records will have a header, subject, text (with the actual diagnostics), a return and trailer token. See audit_submit(3) for more information. Reviewed by: rwatson Obtained from: TrustedBSD Project --- usr.bin/su/Makefile | 8 +++++ usr.bin/su/su.c | 74 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 76 insertions(+), 6 deletions(-) diff --git a/usr.bin/su/Makefile b/usr.bin/su/Makefile index 109b55153d65..25216cf44f1d 100644 --- a/usr.bin/su/Makefile +++ b/usr.bin/su/Makefile @@ -1,11 +1,19 @@ # @(#)Makefile 8.1 (Berkeley) 7/19/93 # $FreeBSD$ +.include + PROG= su DPADD= ${LIBUTIL} ${LIBPAM} LDADD= -lutil ${MINUSLPAM} +.if ${MK_AUDIT} != "no" +CFLAGS+= -DUSE_BSM_AUDIT +DPADD+= ${LIBBSM} +LDADD+= -lbsm +.endif + BINOWN= root BINMODE=4555 PRECIOUSPROG= diff --git a/usr.bin/su/su.c b/usr.bin/su/su.c index dd1602db15ab..937c51420e5b 100644 --- a/usr.bin/su/su.c +++ b/usr.bin/su/su.c @@ -81,6 +81,11 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef USE_BSM_AUDIT +#include +#include +#endif + #include #include #include @@ -93,6 +98,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -164,6 +170,10 @@ main(int argc, char *argv[]) const char *p, *user, *shell, *mytty, **nargv; struct sigaction sa, sa_int, sa_quit, sa_pipe; int temp, fds[2]; +#ifdef USE_BSM_AUDIT + const char *aerr; + au_id_t auid; +#endif shell = class = cleanenv = NULL; asme = asthem = fastlogin = statusp = 0; @@ -204,9 +214,6 @@ main(int argc, char *argv[]) usage(); /* NOTREACHED */ - if (strlen(user) > MAXLOGNAME - 1) - errx(1, "username too long"); - /* * Try to provide more helpful debugging output if su(1) is running * non-setuid, or was run from a file system not mounted setuid. @@ -214,6 +221,21 @@ main(int argc, char *argv[]) if (geteuid() != 0) errx(1, "not running setuid"); +#ifdef USE_BSM_AUDIT + if (getauid(&auid) < 0 && errno != ENOSYS) { + syslog(LOG_AUTH | LOG_ERR, "getauid: %s", strerror(errno)); + errx(1, "Permission denied"); + } +#endif + if (strlen(user) > MAXLOGNAME - 1) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, + 1, EPERM, "username too long: '%s'", user)) + errx(1, "Permission denied"); +#endif + errx(1, "username too long"); + } + nargv = malloc(sizeof(char *) * (size_t)(argc + 4)); if (nargv == NULL) errx(1, "malloc failure"); @@ -239,8 +261,14 @@ main(int argc, char *argv[]) pwd = getpwnam(username); if (username == NULL || pwd == NULL || pwd->pw_uid != ruid) pwd = getpwuid(ruid); - if (pwd == NULL) + if (pwd == NULL) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 1, EPERM, + "unable to determine invoking subject: '%s'", username)) + errx(1, "Permission denied"); +#endif errx(1, "who are you?"); + } username = strdup(pwd->pw_name); if (username == NULL) @@ -275,10 +303,19 @@ main(int argc, char *argv[]) retcode = pam_authenticate(pamh, 0); if (retcode != PAM_SUCCESS) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 1, EPERM, "bad su %s to %s on %s", + username, user, mytty)) + errx(1, "Permission denied"); +#endif syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s on %s", username, user, mytty); errx(1, "Sorry"); } +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 0, 0, "successful authentication")) + errx(1, "Permission denied"); +#endif retcode = pam_get_item(pamh, PAM_USER, (const void **)&p); if (retcode == PAM_SUCCESS) user = p; @@ -286,20 +323,39 @@ main(int argc, char *argv[]) syslog(LOG_ERR, "pam_get_item(PAM_USER): %s", pam_strerror(pamh, retcode)); pwd = getpwnam(user); - if (pwd == NULL) + if (pwd == NULL) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 1, EPERM, + "unknown subject: %s", user)) + errx(1, "Permission denied"); +#endif errx(1, "unknown login: %s", user); + } retcode = pam_acct_mgmt(pamh, 0); if (retcode == PAM_NEW_AUTHTOK_REQD) { retcode = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); if (retcode != PAM_SUCCESS) { +#ifdef USE_BSM_AUDIT + aerr = pam_strerror(pamh, retcode); + if (aerr == NULL) + aerr = "Unknown PAM error"; + if (audit_submit(AUE_su, auid, 1, EPERM, + "pam_chauthtok: %s", aerr)) + errx(1, "Permission denied"); +#endif syslog(LOG_ERR, "pam_chauthtok: %s", pam_strerror(pamh, retcode)); errx(1, "Sorry"); } } if (retcode != PAM_SUCCESS) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 1, EPERM, "pam_acct_mgmt: %s", + pam_strerror(pamh, retcode))) + errx(1, "Permission denied"); +#endif syslog(LOG_ERR, "pam_acct_mgmt: %s", pam_strerror(pamh, retcode)); errx(1, "Sorry"); @@ -309,8 +365,14 @@ main(int argc, char *argv[]) if (class == NULL) lc = login_getpwclass(pwd); else { - if (ruid != 0) + if (ruid != 0) { +#ifdef USE_BSM_AUDIT + if (audit_submit(AUE_su, auid, 1, EPERM, + "only root may use -c")) + errx(1, "Permission denied"); +#endif errx(1, "only root may use -c"); + } lc = login_getclass(class); if (lc == NULL) errx(1, "unknown class: %s", class);