Call rebuild_env() in call cases.

Pass original envp to sudo_edit().
Don't allow -E or env var setting in sudoedit mode.
More accurate usage() when called as sudoedit.
This commit is contained in:
Todd C. Miller
2007-07-08 18:44:28 +00:00
parent 16166fc5e6
commit 5919eb1fa6
2 changed files with 69 additions and 36 deletions

100
sudo.c
View File

@@ -114,7 +114,7 @@ static void usage __P((int))
static void usage_excl __P((int)) static void usage_excl __P((int))
__attribute__((__noreturn__)); __attribute__((__noreturn__));
static struct passwd *get_authpw __P((void)); static struct passwd *get_authpw __P((void));
extern int sudo_edit __P((int, char **)); extern int sudo_edit __P((int, char **, char **));
extern char **rebuild_env __P((char **, int, int)); extern char **rebuild_env __P((char **, int, int));
/* /*
@@ -146,9 +146,10 @@ sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
int int
main(argc, argv) main(argc, argv, envp)
int argc; int argc;
char **argv; char **argv;
char **envp;
{ {
int validated = 0; int validated = 0;
int fd; int fd;
@@ -342,13 +343,12 @@ main(argc, argv)
(void) close(fd); (void) close(fd);
} }
/* Build a new environment based on the rules in sudoers. */ /* User may have overriden environment resetting via the -E flag. */
if (ISSET(sudo_mode, MODE_RUN)) { if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)
/* User may have overrided environment resetting via the -E flag. */ def_env_reset = FALSE;
if (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv)
def_env_reset = FALSE; /* Build a new environment that avoids any nasty bits. */
environ = rebuild_env(environ, sudo_mode, def_noexec); environ = rebuild_env(environ, sudo_mode, def_noexec);
}
/* Fill in passwd struct based on user we are authenticating as. */ /* Fill in passwd struct based on user we are authenticating as. */
auth_pw = get_authpw(); auth_pw = get_authpw();
@@ -438,7 +438,7 @@ main(argc, argv)
} }
if (ISSET(sudo_mode, MODE_EDIT)) if (ISSET(sudo_mode, MODE_EDIT))
exit(sudo_edit(NewArgc, NewArgv)); exit(sudo_edit(NewArgc, NewArgv, envp));
/* Restore signal handlers before we exec. */ /* Restore signal handlers before we exec. */
(void) sigaction(SIGINT, &saved_sa_int, NULL); (void) sigaction(SIGINT, &saved_sa_int, NULL);
@@ -930,6 +930,15 @@ args_done:
if (NewArgc > 0 && rval == MODE_LIST) if (NewArgc > 0 && rval == MODE_LIST)
rval = MODE_CHECK; rval = MODE_CHECK;
if (ISSET(rval, MODE_EDIT) &&
(ISSET(rval, MODE_PRESERVE_ENV) || sudo_user.env_vars != NULL)) {
if (ISSET(rval, MODE_PRESERVE_ENV))
warningx("the `-E' option is not valid in edit mode");
if (sudo_user.env_vars != NULL)
warningx("you may not specify environment variables in edit mode");
usage(1);
}
if (user_runas != NULL && !ISSET(rval, (MODE_EDIT|MODE_RUN|MODE_CHECK))) { if (user_runas != NULL && !ISSET(rval, (MODE_EDIT|MODE_RUN|MODE_CHECK))) {
if (excl != '\0') if (excl != '\0')
warningx("the `-u' and '-%c' options may not be used together", warningx("the `-u' and '-%c' options may not be used together",
@@ -1290,9 +1299,17 @@ static void
usage(exit_val) usage(exit_val)
int exit_val; int exit_val;
{ {
char **p; char **p, **uvec[5];
int linelen, linemax, ulen; int i, linelen, linemax, ulen;
static char *uvec[] = { static char *uvec1[] = {
" -K | -L | -V | -h | -k | -v",
NULL
};
static char *uvec2[] = {
" [-U username] [-u username|#uid] -l [command]",
NULL
};
static char *uvec3[] = {
" [-bEHPS]", " [-bEHPS]",
#ifdef HAVE_BSD_AUTH_H #ifdef HAVE_BSD_AUTH_H
" [-a auth_type]", " [-a auth_type]",
@@ -1307,41 +1324,54 @@ usage(exit_val)
" { -e file [...] | -i | -s | <command> }", " { -e file [...] | -i | -s | <command> }",
NULL NULL
}; };
static char *uvec4[] = {
" [-S]",
#ifdef HAVE_BSD_AUTH_H
" [-a auth_type]",
#endif
" [-C fd]",
#ifdef HAVE_LOGIN_CAP_H
" [-c class|-]",
#endif
" [-p prompt]",
" [-u username|#uid]",
" file [...]",
NULL
};
/* /*
* For sudoedit, replace the last entry in the usage vector. * Use usage vectors appropriate to the progname.
* For sudo, print the secondary usage.
*/ */
if (strcmp(getprogname(), "sudoedit") == 0) { if (strcmp(getprogname(), "sudoedit") == 0) {
/* Replace the last entry in the usage vector. */ uvec[0] = uvec4;
for (p = uvec; p[1] != NULL; p++) uvec[1] = NULL;
continue;
*p = " file [...]";
} else { } else {
fprintf(stderr, "usage: %s -K | -L | -V | -h | -k | -v\n", uvec[0] = uvec1;
getprogname()); uvec[1] = uvec2;
fprintf(stderr, uvec[2] = uvec3;
"usage: %s [-U username] [-u username|#uid] -l [command]\n", uvec[3] = uvec4;
getprogname()); uvec[4] = NULL;
} }
/* /*
* Print the main usage and wrap lines as needed. * Print usage and wrap lines as needed.
* Assumes an 80-character wide terminal, which is kind of bogus... * Assumes an 80-character wide terminal, which is kind of bogus...
*/ */
ulen = (int)strlen(getprogname()) + 7; ulen = (int)strlen(getprogname()) + 7;
linemax = 80; linemax = 80;
linelen = linemax - ulen; for (i = 0; uvec[i] != NULL; i++) {
printf("usage: %s", getprogname()); linelen = linemax - ulen;
for (p = uvec; *p != NULL; p++) { printf("usage: %s", getprogname());
if (linelen == linemax || (linelen -= strlen(*p)) >= 0) { for (p = uvec[i]; *p != NULL; p++) {
fputs(*p, stdout); if (linelen == linemax || (linelen -= strlen(*p)) >= 0) {
} else { fputs(*p, stdout);
p--; } else {
linelen = linemax; p--;
printf("\n%*s", ulen, ""); linelen = linemax;
printf("\n%*s", ulen, "");
}
} }
putchar('\n');
} }
putchar('\n');
exit(exit_val); exit(exit_val);
} }

View File

@@ -60,13 +60,15 @@ __unused static const char rcsid[] = "$Sudo$";
#endif /* lint */ #endif /* lint */
extern sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld; extern sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp, saved_sa_chld;
extern char **environ;
/* /*
* Wrapper to allow users to edit privileged files with their own uid. * Wrapper to allow users to edit privileged files with their own uid.
*/ */
int sudo_edit(argc, argv) int sudo_edit(argc, argv, envp)
int argc; int argc;
char **argv; char **argv;
char **envp;
{ {
ssize_t nread, nwritten; ssize_t nread, nwritten;
pid_t kidpid, pid; pid_t kidpid, pid;
@@ -192,6 +194,7 @@ int sudo_edit(argc, argv)
* based on def_env_editor or def_editor since the editor runs with * based on def_env_editor or def_editor since the editor runs with
* the uid of the invoking user, not the runas (privileged) user. * the uid of the invoking user, not the runas (privileged) user.
*/ */
environ = envp;
if (((editor = getenv("VISUAL")) != NULL && *editor != '\0') || if (((editor = getenv("VISUAL")) != NULL && *editor != '\0') ||
((editor = getenv("EDITOR")) != NULL && *editor != '\0')) { ((editor = getenv("EDITOR")) != NULL && *editor != '\0')) {
editor = estrdup(editor); editor = estrdup(editor);