Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 14 Feb 2006 04:58:21 GMT
From:      "Christian S.J. Peron" <csjp@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 91725 for review
Message-ID:  <200602140458.k1E4wLMM060174@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=91725

Change 91725 by csjp@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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200602140458.k1E4wLMM060174>