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>