PERFORCE change 91725 for review
Christian S.J. Peron
csjp at FreeBSD.org
Mon Feb 13 20:58:25 PST 2006
http://perforce.freebsd.org/chv.cgi?CH=91725
Change 91725 by csjp at csjp_xor on 2006/02/14 04:57:23
- Remove some more audits around PAM failures which really wouldn't be a
result of the user input
- Implement stdargs to audit_su() so we can specify messages which will
be used to create text tokens to give more verbose information for the
nature of the failures or success.
- Add strings to audi_su() calls for text tokens
- The user must never know about auditing operations. So change any writes
to stderr to syslog(3) calls and simply return. It should be noted that this
is what Solaris is doing, however CAPP is pretty clear about failed audits
having to result in a failed operation. That said, I am not sure what an
appropriate error message would be to report to the user in the event that
we have to abort the entire operation due to a audit failure.
Thoughts?
Discussed with: wsalamon
Affected files ...
.. //depot/projects/trustedbsd/audit3/usr.bin/su/su.c#8 edit
Differences ...
==== //depot/projects/trustedbsd/audit3/usr.bin/su/su.c#8 (text+ko) ====
@@ -96,6 +96,7 @@
#include <string.h>
#include <syslog.h>
#include <unistd.h>
+#include <stdarg.h>
#include <security/pam_appl.h>
#include <security/openpam.h>
@@ -144,7 +145,7 @@
static void usage(void) __dead2;
static void export_pam_environment(void);
static int ok_to_export(const char *);
-static void audit_su(au_id_t, int);
+static void audit_su(au_id_t, int, const char *, ...);
extern char **environ;
@@ -219,7 +220,7 @@
if (strlen(user) > MAXLOGNAME - 1) {
#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
+ audit_su(getuid(), AUDIT_SU_FAILURE, "username too long");
#endif
errx(1, "username too long");
}
@@ -252,7 +253,8 @@
pwd = getpwuid(ruid);
if (pwd == NULL) {
#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
+ audit_su(getuid(), AUDIT_SU_FAILURE,
+ "unable to determain invoking subject");
#endif
errx(1, "who are you?");
}
@@ -278,9 +280,6 @@
/* Do the whole PAM startup thing */
retcode = pam_start("su", user, &conv, &pamh);
if (retcode != PAM_SUCCESS) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, retcode));
errx(1, "pam_start: %s", pam_strerror(pamh, retcode));
}
@@ -295,14 +294,15 @@
retcode = pam_authenticate(pamh, 0);
if (retcode != PAM_SUCCESS) {
#ifdef USE_BSM_AUDIT
- audit_su(ruid, AUDIT_SU_FAILURE);
+ audit_su(ruid, AUDIT_SU_FAILURE, "bad su %s to %s on %s",
+ username, user, mytty);
#endif
syslog(LOG_AUTH|LOG_WARNING, "BAD SU %s to %s on %s",
username, user, mytty);
errx(1, "Sorry");
}
#ifdef USE_BSM_AUDIT
- audit_su(ruid, AUDIT_SU_SUCCESS);
+ audit_su(ruid, AUDIT_SU_SUCCESS, "successful authentication");
#endif
retcode = pam_get_item(pamh, PAM_USER, (const void **)&p);
if (retcode == PAM_SUCCESS)
@@ -313,7 +313,8 @@
pwd = getpwnam(user);
if (pwd == NULL) {
#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
+ audit_su(getuid(), AUDIT_SU_FAILURE,
+ "unknown subject: %s", user);
#endif
errx(1, "unknown login: %s", user);
}
@@ -323,17 +324,20 @@
retcode = pam_chauthtok(pamh,
PAM_CHANGE_EXPIRED_AUTHTOK);
if (retcode != PAM_SUCCESS) {
+#ifdef USE_BSM_AUDIT
+ audit_su(getuid(), AUDIT_SU_FAILURE,
+ "pam_chauthtok: %s",
+ pam_strerror(pamh, retcode));
+#endif
syslog(LOG_ERR, "pam_chauthtok: %s",
pam_strerror(pamh, retcode));
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
errx(1, "Sorry");
}
}
if (retcode != PAM_SUCCESS) {
#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
+ audit_su(getuid(), AUDIT_SU_FAILURE, "pam_acct_mgmt: %s",
+ pam_strerror(pamh, retcode));
#endif
syslog(LOG_ERR, "pam_acct_mgmt: %s",
pam_strerror(pamh, retcode));
@@ -346,15 +350,13 @@
else {
if (ruid != 0) {
#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
+ audit_su(getuid(), AUDIT_SU_FAILURE,
+ "only root may use -c");
#endif
errx(1, "only root may use -c");
}
lc = login_getclass(class);
if (lc == NULL) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
errx(1, "unknown class: %s", class);
}
}
@@ -362,9 +364,6 @@
/* if asme and non-standard target shell, must be root */
if (asme) {
if (ruid != 0 && !chshell(pwd->pw_shell)) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
errx(1, "permission denied (shell)");
}
}
@@ -391,9 +390,6 @@
/* Switch to home directory */
if (asthem) {
if (chdir(pwd->pw_dir) < 0) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
errx(1, "no directory");
}
}
@@ -403,17 +399,11 @@
* initialize them first.
*/
if (setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETGROUP) < 0) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
err(1, "setusercontext");
}
retcode = pam_setcred(pamh, PAM_ESTABLISH_CRED);
if (retcode != PAM_SUCCESS) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
syslog(LOG_ERR, "pam_setcred: %s",
pam_strerror(pamh, retcode));
errx(1, "failed to establish credentials.");
@@ -421,9 +411,6 @@
if (asthem) {
retcode = pam_open_session(pamh, 0);
if (retcode != PAM_SUCCESS) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
syslog(LOG_ERR, "pam_open_session: %s",
pam_strerror(pamh, retcode));
errx(1, "failed to open session.");
@@ -512,9 +499,6 @@
if ((asme || (!asthem && class == NULL)) && pwd->pw_uid)
setwhat &= ~(LOGIN_SETPRIORITY | LOGIN_SETRESOURCES);
if (setusercontext(lc, pwd, pwd->pw_uid, setwhat) < 0) {
-#ifdef USE_BSM_AUDIT
- audit_su(getuid(), AUDIT_SU_FAILURE);
-#endif
err(1, "setusercontext");
}
@@ -647,13 +631,15 @@
#ifdef USE_BSM_AUDIT
static void
-audit_su(au_id_t au_ctx, int what)
+audit_su(au_id_t au_ctx, int what, const char *fmt, ...)
{
token_t *token;
long acond;
int afd;
au_tid_t termid;
pid_t pid;
+ char text[1024];
+ va_list ap;
if (auditon(A_GETCOND, &acond, sizeof(long)) < 0) {
/*
@@ -662,20 +648,40 @@
*/
if (errno == ENOSYS)
return;
- err(1, "auditon failed");
+ syslog(LOG_AUTH | LOG_ERR, "audit: auditon failed: %s",
+ strerror(errno));
+ return;
}
afd = au_open();
- if (afd < 0)
- err(1, "au_open failed");
+ if (afd < 0) {
+ syslog(LOG_AUTH | LOG_ERR, "au_open failed: %s",
+ strerror(errno));
+ return;
+ }
/* XXX what should we do for termid? */
bzero(&termid, sizeof(termid));
pid = getpid();
token = au_to_subject32(au_ctx, geteuid(), getegid(),
getuid(), getgid(), pid, pid, &termid);
- if (token == NULL)
- errx(1, "audit: unable to build subject token");
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: unable to build subject token");
+ return;
+ }
/* XXX what if au_fails? */
(void) au_write(afd, token);
+ if (fmt != NULL) {
+ va_start(ap, fmt);
+ vsnprintf(&text[0], sizeof(text) - 1, fmt, ap);
+ va_end(ap);
+ token = au_to_text(&text[0]);
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "failed to generate text token");
+ return;
+ }
+ (void) au_write(afd, token);
+ }
switch (what) {
case AUDIT_SU_FAILURE:
token = au_to_return32(1, EPERM);
@@ -684,10 +690,13 @@
token = au_to_return32(0, 0);
break;
}
- if (token == NULL)
- errx(1, "audit: unable to build return32 token");
+ if (token == NULL) {
+ syslog(LOG_AUTH | LOG_ERR,
+ "audit: enable to build return token");
+ return;
+ }
(void) au_write(afd, token);
- if (au_close(afd, 1, AUE_su) < 0)
- errx(1, "audit: record not committed");
+ if (au_close(afd, 1, AUE_su) < 0)
+ syslog(LOG_AUTH | LOG_ERR, "audit: record not committed");
}
#endif
More information about the trustedbsd-cvs
mailing list