From owner-p4-projects@FreeBSD.ORG Tue Feb 14 04:58:23 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 79A9F16A423; Tue, 14 Feb 2006 04:58:22 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 2B92B16A420 for ; Tue, 14 Feb 2006 04:58:22 +0000 (GMT) (envelope-from csjp@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id AB04043D4C for ; Tue, 14 Feb 2006 04:58:21 +0000 (GMT) (envelope-from csjp@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k1E4wLEv060180 for ; Tue, 14 Feb 2006 04:58:21 GMT (envelope-from csjp@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k1E4wLMM060174 for perforce@freebsd.org; Tue, 14 Feb 2006 04:58:21 GMT (envelope-from csjp@freebsd.org) Date: Tue, 14 Feb 2006 04:58:21 GMT Message-Id: <200602140458.k1E4wLMM060174@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to csjp@freebsd.org using -f From: "Christian S.J. Peron" To: Perforce Change Reviews Cc: Subject: PERFORCE change 91725 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Feb 2006 04:58:23 -0000 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 #include #include +#include #include #include @@ -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