summaryrefslogtreecommitdiffstats
path: root/usr.bin/su
diff options
context:
space:
mode:
authorcsjp <csjp@FreeBSD.org>2006-09-01 13:39:02 +0000
committercsjp <csjp@FreeBSD.org>2006-09-01 13:39:02 +0000
commit5c107d0b0f16ceb34133bd147f76cf9b5ff2aee7 (patch)
treec95ab3f3a6caf79ebf4ebf2e58216e5f9e665935 /usr.bin/su
parentc62317c442340f5e4627b6020679dc03d49a3918 (diff)
downloadFreeBSD-src-5c107d0b0f16ceb34133bd147f76cf9b5ff2aee7.zip
FreeBSD-src-5c107d0b0f16ceb34133bd147f76cf9b5ff2aee7.tar.gz
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
Diffstat (limited to 'usr.bin/su')
-rw-r--r--usr.bin/su/Makefile8
-rw-r--r--usr.bin/su/su.c74
2 files changed, 76 insertions, 6 deletions
diff --git a/usr.bin/su/Makefile b/usr.bin/su/Makefile
index 109b551..25216cf 100644
--- a/usr.bin/su/Makefile
+++ b/usr.bin/su/Makefile
@@ -1,11 +1,19 @@
# @(#)Makefile 8.1 (Berkeley) 7/19/93
# $FreeBSD$
+.include <bsd.own.mk>
+
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 dd1602d..937c514 100644
--- a/usr.bin/su/su.c
+++ b/usr.bin/su/su.c
@@ -81,6 +81,11 @@ __FBSDID("$FreeBSD$");
#include <sys/resource.h>
#include <sys/wait.h>
+#ifdef USE_BSM_AUDIT
+#include <bsm/libbsm.h>
+#include <bsm/audit_uevents.h>
+#endif
+
#include <err.h>
#include <errno.h>
#include <grp.h>
@@ -93,6 +98,7 @@ __FBSDID("$FreeBSD$");
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+#include <stdarg.h>
#include <security/pam_appl.h>
#include <security/openpam.h>
@@ -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);
OpenPOWER on IntegriCloud