From daf87b50ec10700cc80dfaa3984870f3418db7c8 Mon Sep 17 00:00:00 2001 From: Apple Date: Sat, 28 Feb 2004 00:18:08 +0000 Subject: [PATCH] shell_cmds-56.tar.gz --- chroot/chroot.8 | 2 +- date/date.1 | 2 +- nohup/nohup.1 | 4 +- renice/renice.8 | 6 +- su/Makefile | 2 +- su/su.c | 164 +++++++++++++++++++++++++++++++++++++++++++++--- time/time.1 | 2 +- who/who.1 | 2 +- 8 files changed, 167 insertions(+), 17 deletions(-) diff --git a/chroot/chroot.8 b/chroot/chroot.8 index 9375bfd..fce026b 100644 --- a/chroot/chroot.8 +++ b/chroot/chroot.8 @@ -73,7 +73,7 @@ Note, or the shell are run as your real-user-id. .Sh ENVIRONMENT The following environment variable is referenced by -.Nm "" : +.Nm : .Bl -tag -width SHELL .It Ev SHELL If set, diff --git a/date/date.1 b/date/date.1 index a396b15..d21d8d8 100644 --- a/date/date.1 +++ b/date/date.1 @@ -47,7 +47,7 @@ .Op Fl nu .Op Fl r Ar seconds .Op Cm + Ns Ar format -.Nm "" +.Nm .Ar [[[[[cc]yy]mm]dd]hh]mm[\&.ss] .Sh DESCRIPTION .Nm diff --git a/nohup/nohup.1 b/nohup/nohup.1 index c60a263..fba4399 100644 --- a/nohup/nohup.1 +++ b/nohup/nohup.1 @@ -64,7 +64,7 @@ If standard error is a terminal, it is directed to the same place as the standard output. .Sh ENVIRONMENT The following variable is utilized by -.Nm "" . +.Nm . .Bl -tag -width flag .It Ev HOME If the output file @@ -88,7 +88,7 @@ was found but could not be invoked. The .Ar utility could not be found or an error occurred in -.Nm "" . +.Nm . .El .Pp Otherwise, the exit status of diff --git a/renice/renice.8 b/renice/renice.8 index ef9cb20..395b097 100644 --- a/renice/renice.8 +++ b/renice/renice.8 @@ -63,17 +63,17 @@ The following .Ar who parameters are interpreted as process ID's, process group ID's, or user names. -.Nm "" Ns 'ing +.Nm Ns 'ing a process group causes all processes in the process group to have their scheduling priority altered. -.Nm "" Ns 'ing +.Nm Ns 'ing a user causes all processes owned by the user to have their scheduling priority altered. By default, the processes to be affected are specified by their process ID's. .Pp Options supported by -.Nm "" : +.Nm : .Bl -tag -width Ds .It Fl g Force diff --git a/su/Makefile b/su/Makefile index 838e729..7ee3946 100644 --- a/su/Makefile +++ b/su/Makefile @@ -21,7 +21,7 @@ MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles CODE_GEN_STYLE = DYNAMIC MAKEFILE = tool.make NEXTSTEP_INSTALLDIR = /usr/bin -LIBS = -lpam -lpam_misc +LIBS = -lpam -lpam_misc -lbsm DEBUG_LIBS = $(LIBS) PROF_LIBS = $(LIBS) diff --git a/su/su.c b/su/su.c index aad3cad..71e7a6c 100644 --- a/su/su.c +++ b/su/su.c @@ -65,6 +65,10 @@ static const char rcsid[] = #include #include +#include +#include + + #define PAM_END() do { \ int local_ret; \ if (pamh != NULL && creds_set) { \ @@ -104,6 +108,9 @@ static void usage(void); 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 @@ -156,12 +163,16 @@ main(int argc, char *argv[]) if (user == NULL) usage(); - if (strlen(user) > MAXLOGNAME - 1) + if (strlen(user) > MAXLOGNAME - 1) { + audit_fail(NULL, "username too long"); errx(1, "username too long"); + } nargv = malloc(sizeof(char *) * (argc + 4)); - if (nargv == NULL) + if (nargv == NULL) { + audit_fail(NULL, "malloc failure"); errx(1, "malloc failure"); + } nargv[argc + 3] = NULL; for (i = argc; i >= optind; i--) @@ -184,13 +195,18 @@ main(int argc, char *argv[]) pwd = getpwnam(username); if (username == NULL || pwd == NULL || pwd->pw_uid != ruid) pwd = getpwuid(ruid); - if (pwd == NULL) + if (pwd == NULL) { + audit_fail(NULL, "who are you?"); errx(1, "who are you?"); + } + gid = pwd->pw_gid; username = strdup(pwd->pw_name); - if (username == NULL) + if (username == NULL) { + audit_fail(NULL, "strdup failure"); err(1, "strdup failure"); + } if (asme) { if (pwd->pw_shell != NULL && *pwd->pw_shell != '\0') { @@ -205,10 +221,13 @@ main(int argc, char *argv[]) } } + 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)); } @@ -223,6 +242,7 @@ main(int argc, char *argv[]) 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); @@ -239,24 +259,30 @@ main(int argc, char *argv[]) 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) + if (pwd == NULL) { + audit_fail(NULL, "unknown login"); 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)) + if (ruid != 0 && !chshell(pwd->pw_shell)) { + audit_fail(pwd, "permission denied (shell)"); errx(1, "permission denied (shell)."); + } } else if (pwd->pw_shell && *pwd->pw_shell) { shell = pwd->pw_shell; @@ -282,8 +308,10 @@ main(int argc, char *argv[]) * PAM modules might add supplementary groups in pam_setcred(), so * initialize them first. */ - if( initgroups(user, pwd->pw_gid) ) + if( initgroups(user, pwd->pw_gid) ) { + audit_fail(pwd, "initgroups failed"); err(1, "initgroups failed"); + } retcode = pam_open_session(pamh, 0); if( retcode != PAM_SUCCESS ) { @@ -323,10 +351,13 @@ main(int argc, char *argv[]) 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) ) @@ -452,3 +483,122 @@ ontty(void) 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; +} diff --git a/time/time.1 b/time/time.1 index 4596a8f..52e2fef 100644 --- a/time/time.1 +++ b/time/time.1 @@ -75,7 +75,7 @@ The output is formatted as specified by The .Xr csh 1 has its own and syntactically different builtin version of -.Nm "" . +.Nm . The utility described here is available as .Pa /usr/bin/time diff --git a/who/who.1 b/who/who.1 index 22ccda5..9d16881 100644 --- a/who/who.1 +++ b/who/who.1 @@ -43,7 +43,7 @@ .Nm .Op Fl mTuH .Op Ar file -.Nm "" +.Nm .Ar am i .Sh DESCRIPTION The -- 2.45.2