File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / find_path.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:12 2013 UTC (10 years, 11 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 1996, 1998-2005, 2010-2013
    3:  *	Todd C. Miller <Todd.Miller@courtesan.com>
    4:  *
    5:  * Permission to use, copy, modify, and distribute this software for any
    6:  * purpose with or without fee is hereby granted, provided that the above
    7:  * copyright notice and this permission notice appear in all copies.
    8:  *
    9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16:  *
   17:  * Sponsored in part by the Defense Advanced Research Projects
   18:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   19:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
   20:  */
   21: 
   22: #include <config.h>
   23: 
   24: #include <sys/types.h>
   25: #include <sys/stat.h>
   26: #include <stdio.h>
   27: #ifdef STDC_HEADERS
   28: # include <stdlib.h>
   29: # include <stddef.h>
   30: #else
   31: # ifdef HAVE_STDLIB_H
   32: #  include <stdlib.h>
   33: # endif
   34: #endif /* STDC_HEADERS */
   35: #ifdef HAVE_STRING_H
   36: # include <string.h>
   37: #endif /* HAVE_STRING_H */
   38: #ifdef HAVE_STRINGS_H
   39: # include <strings.h>
   40: #endif /* HAVE_STRINGS_H */
   41: #ifdef HAVE_UNISTD_H
   42: # include <unistd.h>
   43: #endif /* HAVE_UNISTD_H */
   44: #include <errno.h>
   45: 
   46: #include "sudoers.h"
   47: 
   48: /*
   49:  * This function finds the full pathname for a command and
   50:  * stores it in a statically allocated array, filling in a pointer
   51:  * to the array.  Returns FOUND if the command was found, NOT_FOUND
   52:  * if it was not found, or NOT_FOUND_DOT if it would have been found
   53:  * but it is in '.' and IGNORE_DOT is set.
   54:  */
   55: int
   56: find_path(char *infile, char **outfile, struct stat *sbp, char *path,
   57:     int ignore_dot)
   58: {
   59:     static char command[PATH_MAX]; /* qualified filename */
   60:     char *n;			/* for traversing path */
   61:     char *origpath;		/* so we can free path later */
   62:     bool found = false;		/* did we find the command? */
   63:     bool checkdot = false;	/* check current dir? */
   64:     int len;			/* length parameter */
   65:     debug_decl(find_path, SUDO_DEBUG_UTIL)
   66: 
   67:     if (strlen(infile) >= PATH_MAX) {
   68: 	errno = ENAMETOOLONG;
   69: 	fatal("%s", infile);
   70:     }
   71: 
   72:     /*
   73:      * If we were given a fully qualified or relative path
   74:      * there is no need to look at $PATH.
   75:      */
   76:     if (strchr(infile, '/')) {
   77: 	strlcpy(command, infile, sizeof(command));	/* paranoia */
   78: 	if (sudo_goodpath(command, sbp)) {
   79: 	    *outfile = command;
   80: 	    debug_return_int(FOUND);
   81: 	} else
   82: 	    debug_return_int(NOT_FOUND);
   83:     }
   84: 
   85:     if (path == NULL)
   86: 	debug_return_int(NOT_FOUND);
   87:     path = estrdup(path);
   88:     origpath = path;
   89: 
   90:     do {
   91: 	if ((n = strchr(path, ':')))
   92: 	    *n = '\0';
   93: 
   94: 	/*
   95: 	 * Search current dir last if it is in PATH This will miss sneaky
   96: 	 * things like using './' or './/'
   97: 	 */
   98: 	if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
   99: 	    checkdot = 1;
  100: 	    path = n + 1;
  101: 	    continue;
  102: 	}
  103: 
  104: 	/*
  105: 	 * Resolve the path and exit the loop if found.
  106: 	 */
  107: 	len = snprintf(command, sizeof(command), "%s/%s", path, infile);
  108: 	if (len <= 0 || len >= sizeof(command)) {
  109: 	    errno = ENAMETOOLONG;
  110: 	    fatal("%s", infile);
  111: 	}
  112: 	if ((found = sudo_goodpath(command, sbp)))
  113: 	    break;
  114: 
  115: 	path = n + 1;
  116: 
  117:     } while (n);
  118:     efree(origpath);
  119: 
  120:     /*
  121:      * Check current dir if dot was in the PATH
  122:      */
  123:     if (!found && checkdot) {
  124: 	len = snprintf(command, sizeof(command), "./%s", infile);
  125: 	if (len <= 0 || len >= sizeof(command)) {
  126: 	    errno = ENAMETOOLONG;
  127: 	    fatal("%s", infile);
  128: 	}
  129: 	found = sudo_goodpath(command, sbp);
  130: 	if (found && ignore_dot)
  131: 	    debug_return_int(NOT_FOUND_DOT);
  132:     }
  133: 
  134:     if (found) {
  135: 	*outfile = command;
  136: 	debug_return_int(FOUND);
  137:     } else
  138: 	debug_return_int(NOT_FOUND);
  139: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>