Apply and execute: perl -pi -e 's|/\* #undef HAVE_PCRE \*/|#define HAVE_PCRE 1|g' config.h perl -pi -e 's|^LIBS = |LIBS = -lpcre |g' Makefile diff -Nur sudo-1.7.1-orig/config.h.in sudo-1.7.1/config.h.in --- sudo-1.7.1-orig/config.h.in 2009-03-14 01:51:12.000000000 +0100 +++ sudo-1.7.1/config.h.in 2009-05-14 00:32:50.000000000 +0200 @@ -110,6 +110,9 @@ /* Define to 1 if you have the `fnmatch' function. */ #undef HAVE_FNMATCH +/* Define to 1 if you have the `pcre' function. */ +#undef HAVE_PCRE + /* Define to 1 if you have the `freeifaddrs' function. */ #undef HAVE_FREEIFADDRS diff -Nur sudo-1.7.1-orig/Makefile.in sudo-1.7.1/Makefile.in --- sudo-1.7.1-orig/Makefile.in 2009-03-12 00:19:56.000000000 +0100 +++ sudo-1.7.1/Makefile.in 2009-05-14 00:49:39.000000000 +0200 @@ -103,7 +103,7 @@ PROGS = @PROGS@ SRCS = aix.c alias.c alloc.c audit.c bsm_audit.c check.c closefrom.c \ - def_data.c defaults.c env.c error.c fileops.c find_path.c fnmatch.c \ + def_data.c defaults.c env.c error.c fileops.c find_path.c fnmatch.c pcre.c \ getcwd.c getprogname.c getspwuid.c gettime.c glob.c goodpath.c gram.c \ gram.y interfaces.c isblank.c lbuf.c ldap.c list.c logging.c match.c \ mkstemp.c memrchr.c parse.c pwutil.c set_perms.c sigaction.c \ @@ -127,7 +127,7 @@ # Note: gram.o must come first here COMMON_OBJS = gram.o alias.o alloc.o defaults.o error.o list.o match.o \ - toke.o redblack.o zero_bytes.o + toke.o redblack.o zero_bytes.o pcre.o SUDO_OBJS = $(COMMON_OBJS) $(AUTH_OBJS) @SUDO_OBJS@ audit.o check.o env.o \ getspwuid.o gettime.o goodpath.o fileops.o find_path.o \ @@ -247,6 +247,8 @@ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/find_path.c fnmatch.o: $(srcdir)/fnmatch.c $(srcdir)/emul/fnmatch.h $(srcdir)/compat.h config.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/fnmatch.c +pcre.o: $(srcdir)/pcre.c $(srcdir)/compat.h config.h + $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/pcre.c getcwd.o: $(srcdir)/getcwd.c $(srcdir)/compat.h config.h $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/getcwd.c getprogname.o: $(srcdir)/getprogname.c config.h diff -Nur sudo-1.7.1-orig/match.c sudo-1.7.1/match.c --- sudo-1.7.1-orig/match.c 2009-03-28 14:07:36.000000000 +0100 +++ sudo-1.7.1/match.c 2009-05-14 01:12:37.000000000 +0200 @@ -104,7 +104,11 @@ /* * Returns TRUE if string 's' contains meta characters. */ +#ifdef HAVE_PCRE +#define has_meta(s) (strpbrk(s, "\\?*[]{}(|).") != NULL) +#else #define has_meta(s) (strpbrk(s, "\\?*[]") != NULL) +#endif /* * Check for user described by pw in a list of members. @@ -387,7 +391,7 @@ if (!sudoers_args || (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) || (sudoers_args && - fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) { + pcrewrapper(sudoers_args, user_args ? user_args : "", 0) == 0)) { efree(safe_cmnd); safe_cmnd = estrdup(sudoers_cmnd); return(TRUE); @@ -424,7 +428,7 @@ if (!sudoers_args || (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) || (sudoers_args && - fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) { + pcrewrapper(sudoers_args, user_args ? user_args : "", 0) == 0)) { if (safe_cmnd) free(safe_cmnd); safe_cmnd = estrdup(user_cmnd); @@ -501,7 +505,7 @@ if (!sudoers_args || (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) || (sudoers_args && - fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) { + pcrewrapper(sudoers_args, user_args ? user_args : "", 0) == 0)) { efree(safe_cmnd); safe_cmnd = estrdup(user_cmnd); return(TRUE); @@ -545,7 +549,7 @@ if (!sudoers_args || (!user_args && sudoers_args && !strcmp("\"\"", sudoers_args)) || (sudoers_args && - fnmatch(sudoers_args, user_args ? user_args : "", 0) == 0)) { + pcrewrapper(sudoers_args, user_args ? user_args : "", 0) == 0)) { efree(safe_cmnd); safe_cmnd = estrdup(sudoers_cmnd); return(TRUE); diff -Nur sudo-1.7.1-orig/pcre.c sudo-1.7.1/pcre.c --- sudo-1.7.1-orig/pcre.c 1970-01-01 01:00:00.000000000 +0100 +++ sudo-1.7.1/pcre.c 2009-05-14 01:17:08.000000000 +0200 @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2005 + * Sven Strickroth + * thanks to the pcredemo-program + * + * This software is licensed under the GNU General Public License (GPL) + * See: http://www.gnu.org/copyleft/gpl.html + * + * 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. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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 +#include +#ifdef HAVE_STRING_H +# include +#else +# ifdef HAVE_STRINGS_H +# include +# endif +#endif /* HAVE_STRING_H */ + +#include "compat.h" + +#ifdef HAVE_FNMATCH +# include +#endif /* HAVE_FNMATCH */ + +#ifdef HAVE_PCRE +#include +#define OVECCOUNT 30 +#endif + +int +pcrewrapper(patterne, string, flags) + const char *patterne, *string; + int flags; +{ +#ifdef HAVE_PCRE + const size_t pattern_length = strlen(patterne)+2; + char *pattern = malloc(pattern_length+1); + (void)snprintf(pattern, pattern_length, "^%s$", patterne); + + int ovector[OVECCOUNT]; + int rc; + pcre *exclude_re; + + const char *error; + int erroffset; + + exclude_re = pcre_compile( + pattern, /* the pattern */ + 0, /* default options */ + &error, /* for error message */ + &erroffset, /* for error offset */ + NULL); /* use default character tables */ + + if (exclude_re == NULL) { + (void) fprintf(stderr,"PCRE compilation of pattern \"%s\" failed at offset %d: %s\n", pattern , erroffset, error); + return 1; + } + + free(pattern); + + rc = pcre_exec( + exclude_re, /* the compiled pattern */ + NULL, /* no extra data - we didn't study the pattern */ + string , /* the subject string */ + strlen(string), /* the length of the subject */ + 0, /* start at offset 0 in the subject */ + 0, /* default options */ + ovector, /* output vector for substring information */ + OVECCOUNT); /* number of elements in the output vector */ + + /* Matching failed: handle error cases */ + + if (rc < 0) + { + switch(rc) + { + case PCRE_ERROR_NOMATCH: return 1; break; + /* + Handle other special cases if you like + */ + default: return 2; break; + } + free(exclude_re); /* Release memory used for the compiled pattern */ + return 1; + } + + /* Match succeded */ + return 0; +#else + return fnmatch(patterne,string,flags); +#endif +} diff -Nur sudo-1.7.1-orig/sudo.c sudo-1.7.1/sudo.c --- sudo-1.7.1-orig/sudo.c 2009-04-16 12:31:34.000000000 +0200 +++ sudo-1.7.1/sudo.c 2009-05-14 00:38:41.000000000 +0200 @@ -1436,7 +1436,11 @@ static void show_version() { - (void) printf("Sudo version %s\n", version); + (void) printf("Sudo version %s", version); +#ifdef HAVE_PCRE + (void) printf("-pcre"); +#endif + (void) printf("\n"); if (getuid() == 0) { putchar('\n'); (void) printf("Sudoers path: %s\n", _PATH_SUDOERS);