#include <pam/pam_appl.h>
#include <pam/pam_misc.h>
-#include <bsm/libbsm.h>
-#include <bsm/audit_uevents.h>
-
-
#define PAM_END() do { \
int local_ret; \
if (pamh != NULL && creds_set) { \
static int export_pam_environment(void);
static int ok_to_export(const char *);
-void audit_success(struct passwd *pwd);
-void audit_fail(struct passwd *pwd, char *errmsg);
-
extern char **environ;
int
if (user == NULL)
usage();
- if (strlen(user) > MAXLOGNAME - 1) {
- audit_fail(NULL, "username too long");
+ if (strlen(user) > MAXLOGNAME - 1)
errx(1, "username too long");
- }
nargv = malloc(sizeof(char *) * (argc + 4));
- if (nargv == NULL) {
- audit_fail(NULL, "malloc failure");
+ if (nargv == NULL)
errx(1, "malloc failure");
- }
nargv[argc + 3] = NULL;
for (i = argc; i >= optind; i--)
pwd = getpwnam(username);
if (username == NULL || pwd == NULL || pwd->pw_uid != ruid)
pwd = getpwuid(ruid);
- if (pwd == NULL) {
- audit_fail(NULL, "who are you?");
+ if (pwd == NULL)
errx(1, "who are you?");
- }
-
gid = pwd->pw_gid;
username = strdup(pwd->pw_name);
- if (username == NULL) {
- audit_fail(NULL, "strdup failure");
+ if (username == NULL)
err(1, "strdup failure");
- }
if (asme) {
if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') {
}
}
- pwd = getpwnam(user);
-
/* Do the whole PAM startup thing */
retcode = pam_start("su", user, &conv, &pamh);
if (retcode != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_start: %s", pam_strerror(pamh, retcode));
- audit_fail(pwd, "pam_start error");
errx(1, "pam_start: %s", pam_strerror(pamh, retcode));
}
if (retcode != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_authenticate: %s",
pam_strerror(pamh, retcode));
- audit_fail(pwd, "pam_authenticate error");
errx(1, "Sorry");
}
retcode = pam_get_item(pamh, PAM_USER, (const void **)&p);
if (retcode != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_chauthtok: %s",
pam_strerror(pamh, retcode));
- audit_fail(pwd, "pam_chauthtok error");
errx(1, "Sorry");
}
}
if (retcode != PAM_SUCCESS) {
syslog(LOG_ERR, "pam_acct_mgmt: %s",
pam_strerror(pamh, retcode));
- audit_fail(pwd, "pam_acct_mgmt error");
errx(1, "Sorry");
}
/* get target login information, default to root */
pwd = getpwnam(user);
- if (pwd == NULL) {
- audit_fail(NULL, "unknown login");
+ if (pwd == NULL)
errx(1, "unknown login: %s", user);
- }
/* if asme and non-standard target shell, must be root */
if (asme) {
- if (ruid != 0 && !chshell(pwd->pw_shell)) {
- audit_fail(pwd, "permission denied (shell)");
+ if (ruid != 0 && !chshell(pwd->pw_shell))
errx(1, "permission denied (shell).");
- }
}
else if (pwd->pw_shell && *pwd->pw_shell) {
- shell = pwd->pw_shell;
+ shell = strncpy(shellbuf, pwd->pw_shell, sizeof(shellbuf));
+ shellbuf[sizeof(shellbuf) - 1] = '\0';
iscsh = UNSET;
}
else {
* PAM modules might add supplementary groups in pam_setcred(), so
* initialize them first.
*/
- if( initgroups(user, pwd->pw_gid) ) {
- audit_fail(pwd, "initgroups failed");
+ if( initgroups(user, pwd->pw_gid) )
err(1, "initgroups failed");
- }
retcode = pam_open_session(pamh, 0);
if( retcode != PAM_SUCCESS ) {
PAM_END();
exit(WEXITSTATUS(statusp));
case -1:
- audit_fail(pwd, "fork() error");
err(1, "fork");
PAM_END();
exit(1);
case 0:
- /* audit before we relinquish privileges */
- audit_success(pwd);
if( setgid(pwd->pw_gid) )
err(1, "setgid");
if( setuid(pwd->pw_uid) )
snprintf(buf, sizeof(buf), " on %s", p);
return buf;
}
-
-/*
- * Include the following tokens in the audit record for successful su attempts
- * header
- * subject
- * return
- */
-void audit_success(struct passwd *pwd)
-{
- int aufd;
- token_t *tok;
- auditinfo_t auinfo;
- long au_cond;
- uid_t uid = pwd->pw_uid;
- gid_t gid = pwd->pw_gid;
- pid_t pid = getpid();
-
- /* If we are not auditing, don't cut an audit record; just return */
- if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
- fprintf(stderr, "su: Could not determine audit condition\n");
- exit(1);
- }
- if (au_cond == AUC_NOAUDIT)
- return;
-
- if(getaudit(&auinfo) != 0) {
- fprintf(stderr, "su: getaudit failed: %s\n", strerror(errno));
- exit(1);
- }
-
- if((aufd = au_open()) == -1) {
- fprintf(stderr, "su: Audit Error: au_open() failed\n");
- exit(1);
- }
-
- /* record the subject being created */
- if((tok = au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
- uid, gid, pid, auinfo.ai_asid, &auinfo.ai_termid)) == NULL) {
- fprintf(stderr, "su: Audit Error: au_to_subject32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if((tok = au_to_return32(0, 0)) == NULL) {
- fprintf(stderr, "su: Audit Error: au_to_return32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if(au_close(aufd, 1, AUE_su) == -1) {
- fprintf(stderr, "su: Audit Error: au_close() failed\n");
- exit(1);
- }
- return;
-}
-
-/*
- * Include the following tokens in the audit record for successful su attempts
- * header
- * subject
- * text
- * return
- */
-void audit_fail(struct passwd *pwd, char *errmsg)
-{
- int aufd;
- token_t *tok;
- auditinfo_t auinfo;
- long au_cond;
- /* If pwd is NULL, the event dont attribute it to any user */
- uid_t uid = pwd ? pwd->pw_uid : -1;
- gid_t gid = pwd ? pwd->pw_gid : -1;
- pid_t pid = getpid();
-
- /* If we are not auditing, don't cut an audit record; just return */
- if (auditon(A_GETCOND, &au_cond, sizeof(long)) < 0) {
- fprintf(stderr, "su: Could not determine audit condition\n");
- exit(1);
- }
- if (au_cond == AUC_NOAUDIT)
- return;
-
- if(getaudit(&auinfo) != 0) {
- fprintf(stderr, "su: getaudit failed: %s\n", strerror(errno));
- exit(1);
- }
-
- if((aufd = au_open()) == -1) {
- fprintf(stderr, "su: Audit Error: au_open() failed\n");
- exit(1);
- }
-
- /* subject token corresponds to the subject being created */
- if((tok = au_to_subject32(auinfo.ai_auid, geteuid(), getegid(),
- uid, gid, pid, auinfo.ai_asid, &auinfo.ai_termid)) == NULL) {
- fprintf(stderr, "su: Audit Error: au_to_subject32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- /* the actual error message text */
- if((tok = au_to_text(errmsg)) == NULL) {
- fprintf(stderr, "su: Audit Error: au_to_text() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if((tok = au_to_return32(1, errno)) == NULL) {
- fprintf(stderr, "su: Audit Error: au_to_return32() failed\n");
- exit(1);
- }
- au_write(aufd, tok);
-
- if(au_close(aufd, 1, AUE_su) == -1) {
- fprintf(stderr, "su: Audit Error: au_close() failed\n");
- exit(1);
- }
- return;
-}