pwutil.c set_perms.c setsid.c sigaction.c snprintf.c strcasecmp.c \
strerror.c strlcat.c strlcpy.c strsignal.c sudo.c sudo_noexec.c \
sudo_edit.c sudo_nss.c term.c testsudoers.c tgetpass.c toke.c toke.l \
- tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c redblack.c \
- selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \
+ toke_util.c tsgetgrpw.c utimes.c vasgroups.c visudo.c zero_bytes.c \
+ redblack.c selinux.c sesh.c sudoreplay.c getdate.c getdate.y getline.c \
timestr.c $(AUTH_SRCS)
AUTH_SRCS = auth/afs.c auth/aix_auth.c auth/bsdauth.c auth/dce.c auth/fwtk.c \
HDRS = alloc.h bsm_audit.h def_data.h defaults.h error.h ins_2001.h \
ins_classic.h ins_csops.h ins_goons.h insults.h interfaces.h lbuf.h \
linux_audit.h list.h logging.h missing.h mksiglist.h nonunix.h \
- redblack.h parse.h sudo.h sudo_exec.h sudo_nss.h gram.h \
+ redblack.h parse.h sudo.h sudo_exec.h sudo_nss.h gram.h toke.h \
auth/sudo_auth.h emul/charclass.h emul/fnmatch.h emul/glob.h \
emul/timespec.h emul/utime.h
AUTH_OBJS = sudo_auth.o @AUTH_OBJS@
COMMON_OBJS = alias.o alloc.o defaults.o error.o gram.o \
- list.o match.o pwutil.o timestr.o toke.o redblack.o \
+ list.o match.o pwutil.o timestr.o toke.o toke_util.o redblack.o \
term.o zero_bytes.o @COMMON_OBJS@
SUDO_OBJS = $(AUTH_OBJS) @SUDO_OBJS@ audit.o boottime.o check.o env.o \
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tgetpass.c
timestr.o: $(srcdir)/timestr.c $(srcdir)/missing.h config.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/timestr.c
-toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(devdir)/gram.h
+toke.o: $(devdir)/toke.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/toke.h $(devdir)/gram.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke.c
+toke_util.o: $(devdir)/toke_util.c $(SUDODEP) $(srcdir)/parse.h $(srcdir)/list.h $(srcdir)/toke.h $(devdir)/gram.h
+ $(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(devdir)/toke_util.c
tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(SUDODEP)
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(DEFS) $(OPTIONS) $(srcdir)/tsgetgrpw.c
utimes.o: $(srcdir)/utimes.c $(srcdir)/missing.h $(srcdir)/emul/utime.h config.h
--- /dev/null
+/*
+ * Copyright (c) 2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SUDO_TOKE_H
+#define _SUDO_TOKE_H
+
+int append(char *, int);
+int fill_args(char *, int, int);
+int fill_cmnd(char *, int);
+int fill_txt(char *, int, int);
+int ipv6_valid(const char *s);
+void yyerror(const char *);
+
+/* realloc() to size + COMMANDARGINC to make room for command args */
+#define COMMANDARGINC 64
+
+#endif /* _SUDO_TOKE_H */
#include <ctype.h>
#include "sudo.h"
#include "parse.h"
+#include "toke.h"
#include <gram.h>
extern YYSTYPE yylval;
char *sudoers;
static int sawspace = 0;
static int prev_state = INITIAL;
-static int arg_len = 0;
-static int arg_size = 0;
-static int append __P((char *, int));
-static int _fill __P((char *, int, int));
-static int fill_cmnd __P((char *, int));
-static int fill_args __P((char *, int, int));
static int _push_include __P((char *, int));
static int pop_include __P((void));
-static int ipv6_valid __P((const char *s));
static char *parse_include __P((char *));
-extern void yyerror __P((const char *));
-#define fill(a, b) _fill(a, b, 0)
+#define fill(a, b) fill_txt(a, b, 0)
#define push_include(_p) (_push_include((_p), FALSE))
#define push_includedir(_p) (_push_include((_p), TRUE))
-/* realloc() to size + COMMANDARGINC to make room for command args */
-#define COMMANDARGINC 64
-
#ifdef TRACELEXER
#define LEXTRACE(msg) fputs(msg, stderr)
#else
}
%%
-static unsigned char
-hexchar(s)
- const char *s;
-{
- int i;
- int result = 0;
-
- s += 2; /* skip \\x */
- for (i = 0; i < 2; i++) {
- switch (*s) {
- case 'A':
- case 'a':
- result += 10;
- break;
- case 'B':
- case 'b':
- result += 11;
- break;
- case 'C':
- case 'c':
- result += 12;
- break;
- case 'D':
- case 'd':
- result += 13;
- break;
- case 'E':
- case 'e':
- result += 14;
- break;
- case 'F':
- case 'f':
- result += 15;
- break;
- default:
- result += *s - '0';
- break;
- }
- if (i == 0) {
- result *= 16;
- s++;
- }
- }
- return (unsigned char)result;
-}
-
-static int
-_fill(src, len, olen)
- char *src;
- int len, olen;
-{
- char *dst;
-
- dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
- if (dst == NULL) {
- yyerror("unable to allocate memory");
- return FALSE;
- }
- yylval.string = dst;
-
- /* Copy the string and collapse any escaped characters. */
- dst += olen;
- while (len--) {
- if (*src == '\\' && len) {
- if (src[1] == 'x' && len >= 3 &&
- isxdigit((unsigned char) src[2]) &&
- isxdigit((unsigned char) src[3])) {
- *dst++ = hexchar(src);
- src += 4;
- len -= 3;
- } else {
- src++;
- len--;
- *dst++ = *src++;
- }
- } else {
- *dst++ = *src++;
- }
- }
- *dst = '\0';
- return TRUE;
-}
-
-static int
-append(src, len)
- char *src;
- int len;
-{
- int olen = 0;
-
- if (yylval.string != NULL)
- olen = strlen(yylval.string);
-
- return _fill(src, len, olen);
-}
-
-#define SPECIAL(c) \
- ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
-
-static int
-fill_cmnd(src, len)
- char *src;
- int len;
-{
- char *dst;
- int i;
-
- arg_len = arg_size = 0;
-
- dst = yylval.command.cmnd = (char *) malloc(len + 1);
- if (yylval.command.cmnd == NULL) {
- yyerror("unable to allocate memory");
- return FALSE;
- }
-
- /* Copy the string and collapse any escaped sudo-specific characters. */
- for (i = 0; i < len; i++) {
- if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
- *dst++ = src[++i];
- else
- *dst++ = src[i];
- }
- *dst = '\0';
-
- yylval.command.args = NULL;
- return TRUE;
-}
-
-static int
-fill_args(s, len, addspace)
- char *s;
- int len;
- int addspace;
-{
- int new_len;
- char *p;
-
- if (yylval.command.args == NULL) {
- addspace = 0;
- new_len = len;
- } else
- new_len = arg_len + len + addspace;
-
- if (new_len >= arg_size) {
- /* Allocate more space than we need for subsequent args */
- while (new_len >= (arg_size += COMMANDARGINC))
- ;
-
- p = yylval.command.args ?
- (char *) realloc(yylval.command.args, arg_size) :
- (char *) malloc(arg_size);
- if (p == NULL) {
- efree(yylval.command.args);
- yyerror("unable to allocate memory");
- return FALSE;
- } else
- yylval.command.args = p;
- }
-
- /* Efficiently append the arg (with a leading space if needed). */
- p = yylval.command.args + arg_len;
- if (addspace)
- *p++ = ' ';
- if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
- yyerror("fill_args: buffer overflow"); /* paranoia */
- return FALSE;
- }
- arg_len = new_len;
- return TRUE;
-}
-
struct path_list {
char *path;
struct path_list *next;
return path;
}
-
-/*
- * Check to make sure an IPv6 address does not contain multiple instances
- * of the string "::". Assumes strlen(s) >= 1.
- * Returns TRUE if address is valid else FALSE.
- */
-static int
-ipv6_valid(s)
- const char *s;
-{
- int nmatch = 0;
-
- for (; *s != '\0'; s++) {
- if (s[0] == ':' && s[1] == ':') {
- if (++nmatch > 1)
- break;
- }
- if (s[0] == '/')
- nmatch = 0; /* reset if we hit netmask */
- }
-
- return nmatch <= 1;
-}
--- /dev/null
+/*
+ * Copyright (c) 1996, 1998-2005, 2007-2011
+ * Todd C. Miller <Todd.Miller@courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ * 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.
+ *
+ * Sponsored in part by the Defense Advanced Research Projects
+ * Agency (DARPA) and Air Force Research Laboratory, Air Force
+ * Materiel Command, USAF, under agreement number F39502-99-1-0512.
+ */
+
+#include <config.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <stddef.h>
+#else
+# ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+# endif
+#endif /* STDC_HEADERS */
+#ifdef HAVE_STRING_H
+# include <string.h>
+#endif /* HAVE_STRING_H */
+#ifdef HAVE_STRINGS_H
+# include <strings.h>
+#endif /* HAVE_STRINGS_H */
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
+# include <malloc.h>
+#endif /* HAVE_MALLOC_H && !STDC_HEADERS */
+#include <ctype.h>
+#include "sudo.h"
+#include "parse.h"
+#include "toke.h"
+#include <gram.h>
+
+static int arg_len = 0;
+static int arg_size = 0;
+
+static unsigned char
+hexchar(s)
+ const char *s;
+{
+ int i;
+ int result = 0;
+
+ s += 2; /* skip \\x */
+ for (i = 0; i < 2; i++) {
+ switch (*s) {
+ case 'A':
+ case 'a':
+ result += 10;
+ break;
+ case 'B':
+ case 'b':
+ result += 11;
+ break;
+ case 'C':
+ case 'c':
+ result += 12;
+ break;
+ case 'D':
+ case 'd':
+ result += 13;
+ break;
+ case 'E':
+ case 'e':
+ result += 14;
+ break;
+ case 'F':
+ case 'f':
+ result += 15;
+ break;
+ default:
+ result += *s - '0';
+ break;
+ }
+ if (i == 0) {
+ result *= 16;
+ s++;
+ }
+ }
+ return (unsigned char)result;
+}
+
+int
+fill_txt(src, len, olen)
+ char *src;
+ int len, olen;
+{
+ char *dst;
+
+ dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
+ if (dst == NULL) {
+ yyerror("unable to allocate memory");
+ return FALSE;
+ }
+ yylval.string = dst;
+
+ /* Copy the string and collapse any escaped characters. */
+ dst += olen;
+ while (len--) {
+ if (*src == '\\' && len) {
+ if (src[1] == 'x' && len >= 3 &&
+ isxdigit((unsigned char) src[2]) &&
+ isxdigit((unsigned char) src[3])) {
+ *dst++ = hexchar(src);
+ src += 4;
+ len -= 3;
+ } else {
+ src++;
+ len--;
+ *dst++ = *src++;
+ }
+ } else {
+ *dst++ = *src++;
+ }
+ }
+ *dst = '\0';
+ return TRUE;
+}
+
+int
+append(src, len)
+ char *src;
+ int len;
+{
+ int olen = 0;
+
+ if (yylval.string != NULL)
+ olen = strlen(yylval.string);
+
+ return fill_txt(src, len, olen);
+}
+
+#define SPECIAL(c) \
+ ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
+
+int
+fill_cmnd(src, len)
+ char *src;
+ int len;
+{
+ char *dst;
+ int i;
+
+ arg_len = arg_size = 0;
+
+ dst = yylval.command.cmnd = (char *) malloc(len + 1);
+ if (yylval.command.cmnd == NULL) {
+ yyerror("unable to allocate memory");
+ return FALSE;
+ }
+
+ /* Copy the string and collapse any escaped sudo-specific characters. */
+ for (i = 0; i < len; i++) {
+ if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
+ *dst++ = src[++i];
+ else
+ *dst++ = src[i];
+ }
+ *dst = '\0';
+
+ yylval.command.args = NULL;
+ return TRUE;
+}
+
+int
+fill_args(s, len, addspace)
+ char *s;
+ int len;
+ int addspace;
+{
+ int new_len;
+ char *p;
+
+ if (yylval.command.args == NULL) {
+ addspace = 0;
+ new_len = len;
+ } else
+ new_len = arg_len + len + addspace;
+
+ if (new_len >= arg_size) {
+ /* Allocate more space than we need for subsequent args */
+ while (new_len >= (arg_size += COMMANDARGINC))
+ ;
+
+ p = yylval.command.args ?
+ (char *) realloc(yylval.command.args, arg_size) :
+ (char *) malloc(arg_size);
+ if (p == NULL) {
+ efree(yylval.command.args);
+ yyerror("unable to allocate memory");
+ return FALSE;
+ } else
+ yylval.command.args = p;
+ }
+
+ /* Efficiently append the arg (with a leading space if needed). */
+ p = yylval.command.args + arg_len;
+ if (addspace)
+ *p++ = ' ';
+ if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
+ yyerror("fill_args: buffer overflow"); /* paranoia */
+ return FALSE;
+ }
+ arg_len = new_len;
+ return TRUE;
+}
+
+/*
+ * Check to make sure an IPv6 address does not contain multiple instances
+ * of the string "::". Assumes strlen(s) >= 1.
+ * Returns TRUE if address is valid else FALSE.
+ */
+int
+ipv6_valid(s)
+ const char *s;
+{
+ int nmatch = 0;
+
+ for (; *s != '\0'; s++) {
+ if (s[0] == ':' && s[1] == ':') {
+ if (++nmatch > 1)
+ break;
+ }
+ if (s[0] == '/')
+ nmatch = 0; /* reset if we hit netmask */
+ }
+
+ return nmatch <= 1;
+}