mirror of
https://github.com/sudo-project/sudo.git
synced 2025-08-31 14:25:15 +00:00
go back to printing "command not found" unless --disable-path-info
specified. Also, tell user when we ignore '.' in their path and it would have been used but for --with-ignore-dot.
This commit is contained in:
6
INSTALL
6
INSTALL
@@ -412,6 +412,12 @@ Special features/options:
|
|||||||
unless the "-u" option is used). This option effectively makes the
|
unless the "-u" option is used). This option effectively makes the
|
||||||
"-s" flag imply "-H".
|
"-s" flag imply "-H".
|
||||||
|
|
||||||
|
--disable-path-info
|
||||||
|
Normally, sudo will tell the user when a command could not be found
|
||||||
|
in their $PATH. Some sites may wish to disable this as it could
|
||||||
|
be used to gather information on the location of executables that
|
||||||
|
the normal user does not have access to.
|
||||||
|
|
||||||
--disable-sia
|
--disable-sia
|
||||||
Disable SIA support. This is the "Security Integration Architecture"
|
Disable SIA support. This is the "Security Integration Architecture"
|
||||||
on Digital UNIX.
|
on Digital UNIX.
|
||||||
|
@@ -395,6 +395,9 @@
|
|||||||
/* Define if you want to ignore '.' and '' in $PATH */
|
/* Define if you want to ignore '.' and '' in $PATH */
|
||||||
#undef IGNORE_DOT_PATH
|
#undef IGNORE_DOT_PATH
|
||||||
|
|
||||||
|
/* Define if you want "command not allowed" instead of "command not found" */
|
||||||
|
#undef DONT_LEAK_PATH_INFO
|
||||||
|
|
||||||
/* Define SHORT_MESSAGE for a short lecture or NO_MESSAGE for none. */
|
/* Define SHORT_MESSAGE for a short lecture or NO_MESSAGE for none. */
|
||||||
#undef SHORT_MESSAGE
|
#undef SHORT_MESSAGE
|
||||||
#undef NO_MESSAGE
|
#undef NO_MESSAGE
|
||||||
|
15
configure.in
15
configure.in
@@ -887,6 +887,21 @@ AC_ARG_ENABLE(shell-sets-home,
|
|||||||
esac
|
esac
|
||||||
], AC_MSG_RESULT(no))
|
], AC_MSG_RESULT(no))
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(whether to disable 'command not found' messages)
|
||||||
|
AC_ARG_ENABLE(path_info,
|
||||||
|
[ --disable-path-info Print 'command not allowed' not 'command not found'],
|
||||||
|
[ case "$enableval" in
|
||||||
|
yes) AC_MSG_RESULT(no)
|
||||||
|
;;
|
||||||
|
no) AC_MSG_RESULT(yes)
|
||||||
|
AC_DEFINE(DONT_LEAK_PATH_INFO)
|
||||||
|
;;
|
||||||
|
*) AC_MSG_RESULT(no)
|
||||||
|
echo "Ignoring unknown argument to --enable-path-info: $enableval"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
], AC_MSG_RESULT(no))
|
||||||
|
|
||||||
dnl
|
dnl
|
||||||
dnl If we don't have egrep we can't do anything...
|
dnl If we don't have egrep we can't do anything...
|
||||||
dnl
|
dnl
|
||||||
|
62
find_path.c
62
find_path.c
@@ -86,27 +86,28 @@ extern char *strdup __P((const char *));
|
|||||||
* find_path()
|
* find_path()
|
||||||
*
|
*
|
||||||
* this function finds the full pathname for a command and
|
* this function finds the full pathname for a command and
|
||||||
* stores it in a statically allocated array, returning a pointer
|
* stores it in a statically allocated array, filling in a pointer
|
||||||
* to the array.
|
* to the array. Returns FOUND if the command was found, NOT_FOUND
|
||||||
|
* if it was not found, or NOT_FOUND_DOT if it would have been found
|
||||||
|
* but it is in '.' and IGNORE_DOT_PATH is in effect.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
char * find_path(file)
|
int find_path(infile, outfile)
|
||||||
char *file; /* file to find */
|
char *infile; /* file to find */
|
||||||
|
char **outfile; /* result parameter */
|
||||||
{
|
{
|
||||||
static char command[MAXPATHLEN]; /* qualified filename */
|
static char command[MAXPATHLEN]; /* qualified filename */
|
||||||
register char *n; /* for traversing path */
|
register char *n; /* for traversing path */
|
||||||
char *path = NULL; /* contents of PATH env var */
|
char *path = NULL; /* contents of PATH env var */
|
||||||
char *origpath; /* so we can free path later */
|
char *origpath; /* so we can free path later */
|
||||||
char *result = NULL; /* result of path/file lookup */
|
char *result = NULL; /* result of path/file lookup */
|
||||||
#ifndef IGNORE_DOT_PATH
|
|
||||||
int checkdot = 0; /* check current dir? */
|
int checkdot = 0; /* check current dir? */
|
||||||
#endif /* IGNORE_DOT_PATH */
|
|
||||||
|
|
||||||
command[0] = '\0';
|
command[0] = '\0';
|
||||||
|
|
||||||
if (strlen(file) >= MAXPATHLEN) {
|
if (strlen(infile) >= MAXPATHLEN) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
(void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], file);
|
(void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,10 +117,11 @@ char * find_path(file)
|
|||||||
* We really want to fall back if !sudo_goodpath() but then
|
* We really want to fall back if !sudo_goodpath() but then
|
||||||
* the error is "not found" -- this way we get the correct error.
|
* the error is "not found" -- this way we get the correct error.
|
||||||
*/
|
*/
|
||||||
if (strchr(file, '/')) {
|
if (strchr(infile, '/')) {
|
||||||
(void) strcpy(command, file);
|
(void) strcpy(command, infile);
|
||||||
if (sudo_goodpath(command)) {
|
if (sudo_goodpath(command)) {
|
||||||
return(command);
|
*outfile = command;
|
||||||
|
return(FOUND);
|
||||||
} else {
|
} else {
|
||||||
(void) fprintf(stderr, "%s: %s: ", Argv[0], command);
|
(void) fprintf(stderr, "%s: %s: ", Argv[0], command);
|
||||||
perror("");
|
perror("");
|
||||||
@@ -131,13 +133,13 @@ char * find_path(file)
|
|||||||
* grab PATH out of environment and make a local copy
|
* grab PATH out of environment and make a local copy
|
||||||
*/
|
*/
|
||||||
if ((path = getenv("PATH")) == NULL)
|
if ((path = getenv("PATH")) == NULL)
|
||||||
return(NULL);
|
return(NOT_FOUND);
|
||||||
|
|
||||||
if ((path = (char *) strdup(path)) == NULL) {
|
if ((path = (char *) strdup(path)) == NULL) {
|
||||||
(void) fprintf(stderr, "%s: out of memory!\n", Argv[0]);
|
(void) fprintf(stderr, "%s: out of memory!\n", Argv[0]);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
origpath=path;
|
origpath = path;
|
||||||
|
|
||||||
/* XXX use strtok() */
|
/* XXX use strtok() */
|
||||||
do {
|
do {
|
||||||
@@ -149,9 +151,7 @@ char * find_path(file)
|
|||||||
* things like using './' or './/'
|
* things like using './' or './/'
|
||||||
*/
|
*/
|
||||||
if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
|
if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
|
||||||
#ifndef IGNORE_DOT_PATH
|
|
||||||
checkdot = 1;
|
checkdot = 1;
|
||||||
#endif /* IGNORE_DOT_PATH */
|
|
||||||
path = n + 1;
|
path = n + 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -159,27 +159,33 @@ char * find_path(file)
|
|||||||
/*
|
/*
|
||||||
* resolve the path and exit the loop if found
|
* resolve the path and exit the loop if found
|
||||||
*/
|
*/
|
||||||
if (strlen(path) + strlen(file) + 1 >= MAXPATHLEN) {
|
if (strlen(path) + strlen(infile) + 1 >= MAXPATHLEN) {
|
||||||
(void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], file);
|
(void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
(void) sprintf(command, "%s/%s", path, file);
|
(void) sprintf(command, "%s/%s", path, infile);
|
||||||
if ((result = sudo_goodpath(command)))
|
if ((result = sudo_goodpath(command)))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
path = n + 1;
|
path = n + 1;
|
||||||
|
|
||||||
} while (n);
|
} while (n);
|
||||||
|
|
||||||
#ifndef IGNORE_DOT_PATH
|
|
||||||
/*
|
|
||||||
* check current dir if dot was in the PATH
|
|
||||||
*/
|
|
||||||
if (!result && checkdot)
|
|
||||||
result = sudo_goodpath(file);
|
|
||||||
#endif /* IGNORE_DOT_PATH */
|
|
||||||
|
|
||||||
(void) free(origpath);
|
(void) free(origpath);
|
||||||
|
|
||||||
return(result);
|
/*
|
||||||
|
* Check current dir if dot was in the PATH
|
||||||
|
*/
|
||||||
|
if (!result && checkdot) {
|
||||||
|
result = sudo_goodpath(infile);
|
||||||
|
#ifdef IGNORE_DOT_PATH
|
||||||
|
if (result)
|
||||||
|
return(NOT_FOUND_DOT);
|
||||||
|
#endif /* IGNORE_DOT_PATH */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
*outfile = result;
|
||||||
|
return(FOUND);
|
||||||
|
} else
|
||||||
|
return(NOT_FOUND);
|
||||||
}
|
}
|
||||||
|
37
sudo.c
37
sudo.c
@@ -179,7 +179,7 @@ int main(argc, argv)
|
|||||||
int argc;
|
int argc;
|
||||||
char **argv;
|
char **argv;
|
||||||
{
|
{
|
||||||
int rtn, found_cmnd;
|
int rtn, cmnd_status = FOUND;
|
||||||
int sudo_mode = MODE_RUN;
|
int sudo_mode = MODE_RUN;
|
||||||
extern char ** environ;
|
extern char ** environ;
|
||||||
|
|
||||||
@@ -293,7 +293,7 @@ int main(argc, argv)
|
|||||||
#endif /* SECURE_PATH */
|
#endif /* SECURE_PATH */
|
||||||
|
|
||||||
if ((sudo_mode & MODE_RUN)) {
|
if ((sudo_mode & MODE_RUN)) {
|
||||||
found_cmnd = load_cmnd(sudo_mode); /* load the cmnd global variable */
|
cmnd_status = load_cmnd(sudo_mode); /* load the cmnd global variable */
|
||||||
} else if (sudo_mode == MODE_KILL) {
|
} else if (sudo_mode == MODE_KILL) {
|
||||||
remove_timestamp(); /* remove the timestamp ticket file */
|
remove_timestamp(); /* remove the timestamp ticket file */
|
||||||
exit(0);
|
exit(0);
|
||||||
@@ -301,18 +301,18 @@ int main(argc, argv)
|
|||||||
|
|
||||||
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */
|
add_env(!(sudo_mode & MODE_SHELL)); /* add in SUDO_* envariables */
|
||||||
|
|
||||||
/* validate the user but don't search for "validate" */
|
/* validate the user but don't search for pseudo-commands */
|
||||||
rtn = validate((sudo_mode != MODE_VALIDATE && sudo_mode != MODE_LIST));
|
rtn = validate((sudo_mode != MODE_VALIDATE && sudo_mode != MODE_LIST));
|
||||||
|
|
||||||
switch (rtn) {
|
switch (rtn) {
|
||||||
|
|
||||||
case VALIDATE_OK:
|
case VALIDATE_OK:
|
||||||
case VALIDATE_OK_NOPASS:
|
check_user();
|
||||||
if (rtn != VALIDATE_OK_NOPASS)
|
/* fallthrough */
|
||||||
check_user();
|
|
||||||
|
|
||||||
|
case VALIDATE_OK_NOPASS:
|
||||||
/* finally tell the user if the command did not exist */
|
/* finally tell the user if the command did not exist */
|
||||||
if ((sudo_mode & MODE_RUN) && !found_cmnd) {
|
if (cmnd_status != FOUND) {
|
||||||
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
|
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
|
||||||
cmnd);
|
cmnd);
|
||||||
exit(1);
|
exit(1);
|
||||||
@@ -372,9 +372,22 @@ int main(argc, argv)
|
|||||||
exit(-1);
|
exit(-1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VALIDATE_NOT_OK:
|
||||||
|
check_user();
|
||||||
|
|
||||||
|
#ifndef DONT_LEAK_PATH_INFO
|
||||||
|
if (cmnd_status == NOT_FOUND_DOT)
|
||||||
|
(void) fprintf(stderr, "%s: ignoring %s found in '.'\nUse `sudo ./%s' if this is the %s you wish to run.\n", Argv[0], cmnd, cmnd);
|
||||||
|
else if (cmnd_status == NOT_FOUND)
|
||||||
|
(void) fprintf(stderr, "%s: %s: command not found\n", Argv[0],
|
||||||
|
cmnd);
|
||||||
|
log_error(rtn);
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
#endif /* DONT_LEAK_PATH_INFO */
|
||||||
|
|
||||||
default:
|
default:
|
||||||
log_error(rtn);
|
log_error(rtn);
|
||||||
set_perms(PERM_FULL_USER, sudo_mode);
|
|
||||||
inform_user(rtn);
|
inform_user(rtn);
|
||||||
exit(1);
|
exit(1);
|
||||||
break;
|
break;
|
||||||
@@ -745,6 +758,8 @@ static void add_env(contiguous)
|
|||||||
static int load_cmnd(sudo_mode)
|
static int load_cmnd(sudo_mode)
|
||||||
int sudo_mode;
|
int sudo_mode;
|
||||||
{
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
if (strlen(NewArgv[0]) >= MAXPATHLEN) {
|
if (strlen(NewArgv[0]) >= MAXPATHLEN) {
|
||||||
errno = ENAMETOOLONG;
|
errno = ENAMETOOLONG;
|
||||||
(void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0],
|
(void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0],
|
||||||
@@ -755,11 +770,9 @@ static int load_cmnd(sudo_mode)
|
|||||||
/*
|
/*
|
||||||
* Resolve the path
|
* Resolve the path
|
||||||
*/
|
*/
|
||||||
if ((cmnd = find_path(NewArgv[0])) == NULL) {
|
if ((retval = find_path(NewArgv[0], &cmnd)) != FOUND)
|
||||||
cmnd = NewArgv[0];
|
cmnd = NewArgv[0];
|
||||||
return(0);
|
return(retval);
|
||||||
} else
|
|
||||||
return(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
13
sudo.h
13
sudo.h
@@ -168,9 +168,16 @@ struct generic_alias {
|
|||||||
* Boolean values
|
* Boolean values
|
||||||
*/
|
*/
|
||||||
#undef TRUE
|
#undef TRUE
|
||||||
#define TRUE 0x01
|
#define TRUE 1
|
||||||
#undef FALSE
|
#undef FALSE
|
||||||
#define FALSE 0x00
|
#define FALSE 0
|
||||||
|
|
||||||
|
/*
|
||||||
|
* find_path()/load_cmnd() return values
|
||||||
|
*/
|
||||||
|
#define FOUND 1
|
||||||
|
#define NOT_FOUND 0
|
||||||
|
#define NOT_FOUND_DOT -1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Various modes sudo can be in (based on arguments) in octal
|
* Various modes sudo can be in (based on arguments) in octal
|
||||||
@@ -221,7 +228,7 @@ int putenv __P((const char *));
|
|||||||
char *sudo_goodpath __P((const char *));
|
char *sudo_goodpath __P((const char *));
|
||||||
int sudo_setenv __P((char *, char *));
|
int sudo_setenv __P((char *, char *));
|
||||||
char *tgetpass __P((char *, int));
|
char *tgetpass __P((char *, int));
|
||||||
char * find_path __P((char *));
|
int find_path __P((char *, char **));
|
||||||
void log_error __P((int));
|
void log_error __P((int));
|
||||||
void inform_user __P((int));
|
void inform_user __P((int));
|
||||||
void check_user __P((void));
|
void check_user __P((void));
|
||||||
|
Reference in New Issue
Block a user