summaryrefslogtreecommitdiffstats
path: root/usr.bin/sudo/find_path.c
diff options
context:
space:
mode:
authormillert <millert@openbsd.org>1999-11-18 16:29:01 +0000
committermillert <millert@openbsd.org>1999-11-18 16:29:01 +0000
commitee4a81dac7260aeb8b39c7b51d451b215a8821f1 (patch)
treee7ce36a1f0161cd43c76d6b6cc71a3721ed0b8cc /usr.bin/sudo/find_path.c
parentmore %d vs. %s in fmt-strings (diff)
downloadwireguard-openbsd-ee4a81dac7260aeb8b39c7b51d451b215a8821f1.tar.xz
wireguard-openbsd-ee4a81dac7260aeb8b39c7b51d451b215a8821f1.zip
sudo 1.6, now with a BSD license
Diffstat (limited to 'usr.bin/sudo/find_path.c')
-rw-r--r--usr.bin/sudo/find_path.c162
1 files changed, 162 insertions, 0 deletions
diff --git a/usr.bin/sudo/find_path.c b/usr.bin/sudo/find_path.c
new file mode 100644
index 00000000000..4d84b4e79dc
--- /dev/null
+++ b/usr.bin/sudo/find_path.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 4. Products derived from this software may not be called "Sudo" nor
+ * may "Sudo" appear in their names without specific prior written
+ * permission from the author.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#endif /* STDC_HEADERS */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include "sudo.h"
+
+#ifndef STDC_HEADERS
+extern char *getenv __P((const char *));
+extern char *strcpy __P((char *, const char *));
+extern int fprintf __P((FILE *, const char *, ...));
+extern ssize_t readlink __P((const char *, VOID *, size_t));
+extern int stat __P((const char *, struct stat *));
+extern int lstat __P((const char *, struct stat *));
+#endif /* !STDC_HEADERS */
+
+#ifndef lint
+static const char rcsid[] = "$Sudo: find_path.c,v 1.94 1999/10/07 21:20:57 millert Exp $";
+#endif /* lint */
+
+/*
+ * This function finds the full pathname for a command and
+ * 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 is set.
+ */
+int
+find_path(infile, outfile)
+ char *infile; /* file to find */
+ char **outfile; /* result parameter */
+{
+ static char command[MAXPATHLEN]; /* qualified filename */
+ 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 */
+ int checkdot = 0; /* check current dir? */
+
+ if (strlen(infile) >= MAXPATHLEN) {
+ (void) fprintf(stderr, "%s: path too long: %s\n", Argv[0], infile);
+ exit(1);
+ }
+
+ /*
+ * If we were given a fully qualified or relative path
+ * there is no need to look at $PATH.
+ */
+ if (strchr(infile, '/')) {
+ (void) strcpy(command, infile);
+ if (sudo_goodpath(command)) {
+ *outfile = command;
+ return(FOUND);
+ } else
+ return(NOT_FOUND);
+ }
+
+ /*
+ * Grab PATH out of the environment (or from the string table
+ * if SECURE_PATH is in effect) and make a local copy.
+ */
+ if (def_str(I_SECURE_PATH))
+ path = def_str(I_SECURE_PATH);
+ else if ((path = getenv("PATH")) == NULL)
+ return(NOT_FOUND);
+ path = estrdup(path);
+ origpath = path;
+
+ do {
+ if ((n = strchr(path, ':')))
+ *n = '\0';
+
+ /*
+ * Search current dir last if it is in PATH This will miss sneaky
+ * things like using './' or './/'
+ */
+ if (*path == '\0' || (*path == '.' && *(path + 1) == '\0')) {
+ checkdot = 1;
+ path = n + 1;
+ continue;
+ }
+
+ /*
+ * Resolve the path and exit the loop if found.
+ */
+ 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, infile);
+ if ((result = sudo_goodpath(command)))
+ break;
+
+ path = n + 1;
+
+ } while (n);
+ free(origpath);
+
+ /*
+ * Check current dir if dot was in the PATH
+ */
+ if (!result && checkdot) {
+ result = sudo_goodpath(infile);
+ if (result && def_flag(I_IGNORE_DOT))
+ return(NOT_FOUND_DOT);
+ }
+
+ if (result) {
+ *outfile = result;
+ return(FOUND);
+ } else
+ return(NOT_FOUND);
+}