]> granicus.if.org Git - sudo/commitdiff
go back to printing "command not found" unless --disable-path-info
authorTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 8 Nov 1998 20:56:52 +0000 (20:56 +0000)
committerTodd C. Miller <Todd.Miller@courtesan.com>
Sun, 8 Nov 1998 20:56:52 +0000 (20:56 +0000)
specified.  Also, tell user when we ignore '.' in their path and
it would have been used but for --with-ignore-dot.

INSTALL
config.h.in
configure.in
find_path.c
sudo.c
sudo.h

diff --git a/INSTALL b/INSTALL
index 5f566929eaafaad6641541032174f19cad4070b1..cebb42a81a82728f0b4c49074990c177872d3999 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -412,6 +412,12 @@ Special features/options:
        unless the "-u" option is used).  This option effectively makes the
        "-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 support.  This is the "Security Integration Architecture"
        on Digital UNIX.
index a21038c495d1d863e71fe3155c6621bcb46a2bf9..bcad1aca7c5dad3178ae64f96d2d7744d69c68bd 100644 (file)
 /* Define if you want to ignore '.' and '' in $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.  */
 #undef SHORT_MESSAGE
 #undef NO_MESSAGE
index 81bbee153e827adf662928924c6da1e6cd14cb89..21d1345be491a491b644cd8d7e73d56fdde505e1 100644 (file)
@@ -887,6 +887,21 @@ AC_ARG_ENABLE(shell-sets-home,
   esac
 ], 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 If we don't have egrep we can't do anything...
 dnl
index 5e125423abc53fbbeaa0b4a9757d2f97cac56864..08c4fbd0bf1964c03e12cdc9ba897bdeeea4c1a5 100644 (file)
@@ -86,27 +86,28 @@ extern char *strdup __P((const char *));
  *  find_path()
  *
  *  this function finds the full pathname for a command and
- *  stores it in a statically allocated array, returning a pointer
- *  to the array.
+ *  stores it in a statically allocated array, filling in a pointer
+ *  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)
-    char *file;                        /* file to find */
+int find_path(infile, outfile)
+    char *infile;              /* file to find */
+    char **outfile;            /* result parameter */
 {
     static char command[MAXPATHLEN]; /* qualified filename */
     register char *n;          /* for traversing path */
     char *path = NULL;         /* contents of PATH env var */
     char *origpath;            /* so we can free path later */
     char *result = NULL;       /* result of path/file lookup */
-#ifndef IGNORE_DOT_PATH
     int checkdot = 0;          /* check current dir? */
-#endif /* IGNORE_DOT_PATH */
 
     command[0] = '\0';
 
-    if (strlen(file) >= MAXPATHLEN) {
+    if (strlen(infile) >= MAXPATHLEN) {
        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);
     }
 
@@ -116,10 +117,11 @@ char * find_path(file)
      * We really want to fall back if !sudo_goodpath() but then
      * the error is "not found" -- this way we get the correct error.
      */
-    if (strchr(file, '/')) {
-       (void) strcpy(command, file);
+    if (strchr(infile, '/')) {
+       (void) strcpy(command, infile);
        if (sudo_goodpath(command)) {
-           return(command);
+           *outfile = command;
+           return(FOUND);
        } else {
            (void) fprintf(stderr, "%s: %s: ", Argv[0], command);
            perror("");
@@ -131,13 +133,13 @@ char * find_path(file)
      * grab PATH out of environment and make a local copy
      */
     if ((path = getenv("PATH")) == NULL)
-       return(NULL);
+       return(NOT_FOUND);
 
     if ((path = (char *) strdup(path)) == NULL) {
        (void) fprintf(stderr, "%s: out of memory!\n", Argv[0]);
        exit(1);
     }
-    origpath=path;
+    origpath = path;
 
     /* XXX use strtok() */
     do {
@@ -149,9 +151,7 @@ char * find_path(file)
         * things like using './' or './/' 
         */
        if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
-#ifndef IGNORE_DOT_PATH
            checkdot = 1;
-#endif /* IGNORE_DOT_PATH */
            path = n + 1;
            continue;
        }
@@ -159,27 +159,33 @@ char * find_path(file)
        /*
         * resolve the path and exit the loop if found
         */
-       if (strlen(path) + strlen(file) + 1 >= MAXPATHLEN) {
-           (void) fprintf(stderr, "%s:  path too long:  %s\n", Argv[0], file);
+       if (strlen(path) + strlen(infile) + 1 >= MAXPATHLEN) {
+           (void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
            exit(1);
        }
-       (void) sprintf(command, "%s/%s", path, file);
+       (void) sprintf(command, "%s/%s", path, infile);
        if ((result = sudo_goodpath(command)))
            break;
 
        path = n + 1;
 
     } while (n);
+    (void) free(origpath);
 
-#ifndef IGNORE_DOT_PATH
     /*
-     * check current dir if dot was in the PATH
+     * Check current dir if dot was in the PATH
      */
-    if (!result && checkdot)
-       result = sudo_goodpath(file);
+    if (!result && checkdot) {
+       result = sudo_goodpath(infile);
+#ifdef IGNORE_DOT_PATH
+       if (result)
+           return(NOT_FOUND_DOT);
 #endif /* IGNORE_DOT_PATH */
+    }
 
-    (void) free(origpath);
-
-    return(result);
+    if (result) {
+       *outfile = result;
+       return(FOUND);
+    } else
+       return(NOT_FOUND);
 }
diff --git a/sudo.c b/sudo.c
index 050b07d897c957fa7823109ca226ff0fd3dd7b44..01bc559ecb4468957908c823a4b909258c233260 100644 (file)
--- a/sudo.c
+++ b/sudo.c
@@ -179,7 +179,7 @@ int main(argc, argv)
     int argc;
     char **argv;
 {
-    int rtn, found_cmnd;
+    int rtn, cmnd_status = FOUND;
     int sudo_mode = MODE_RUN;
     extern char ** environ;
 
@@ -293,7 +293,7 @@ int main(argc, argv)
 #endif /* SECURE_PATH */
 
     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) {
        remove_timestamp();     /* remove the timestamp ticket file */
        exit(0);
@@ -301,18 +301,18 @@ int main(argc, argv)
 
     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));
 
     switch (rtn) {
 
        case VALIDATE_OK:
-       case VALIDATE_OK_NOPASS:
-           if (rtn != VALIDATE_OK_NOPASS) 
-               check_user();
+           check_user();
+           /* fallthrough */
 
+       case VALIDATE_OK_NOPASS:
            /* 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],
                               cmnd);
                exit(1);
@@ -372,9 +372,22 @@ int main(argc, argv)
            exit(-1);
            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:
            log_error(rtn);
-           set_perms(PERM_FULL_USER, sudo_mode);
            inform_user(rtn);
            exit(1);
            break;
@@ -745,6 +758,8 @@ static void add_env(contiguous)
 static int load_cmnd(sudo_mode)
     int sudo_mode;
 {
+    int retval;
+
     if (strlen(NewArgv[0]) >= MAXPATHLEN) {
        errno = ENAMETOOLONG;
        (void) fprintf(stderr, "%s: %s: Pathname too long\n", Argv[0],
@@ -755,11 +770,9 @@ static int load_cmnd(sudo_mode)
     /*
      * Resolve the path
      */
-    if ((cmnd = find_path(NewArgv[0])) == NULL) {
+    if ((retval = find_path(NewArgv[0], &cmnd)) != FOUND)
        cmnd = NewArgv[0];
-       return(0);
-    } else
-       return(1);
+    return(retval);
 }
 
 
diff --git a/sudo.h b/sudo.h
index ce147475f7368d8f6aebd7e50ded587cb0fccfd8..1d1ebce035f7c5c0b683c760df1985fa8593fffa 100644 (file)
--- a/sudo.h
+++ b/sudo.h
@@ -168,9 +168,16 @@ struct generic_alias {
  * Boolean values
  */
 #undef TRUE
-#define TRUE                     0x01
+#define TRUE                     1
 #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
@@ -221,7 +228,7 @@ int putenv          __P((const char *));
 char *sudo_goodpath    __P((const char *));
 int sudo_setenv                __P((char *, char *));
 char *tgetpass         __P((char *, int));
-char * find_path       __P((char *));
+int find_path          __P((char *, char **));
 void log_error         __P((int));
 void inform_user       __P((int));
 void check_user                __P((void));