version 1.1.1.1, 2012/02/21 16:23:02
|
version 1.1.1.4, 2014/06/15 16:12:54
|
Line 1
|
Line 1
|
/* |
/* |
* Copyright (c) 1996, 1998-2005, 2007-2011 | * Copyright (c) 1996, 1998-2005, 2007-2013 |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* Todd C. Miller <Todd.Miller@courtesan.com> |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 25
|
Line 25
|
#include <config.h> |
#include <config.h> |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/param.h> |
|
#include <stdio.h> |
#include <stdio.h> |
#ifdef STDC_HEADERS |
#ifdef STDC_HEADERS |
# include <stdlib.h> |
# include <stdlib.h> |
Line 48
|
Line 47
|
# include <malloc.h> |
# include <malloc.h> |
#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ |
#endif /* HAVE_MALLOC_H && !STDC_HEADERS */ |
#include <ctype.h> |
#include <ctype.h> |
|
#include <errno.h> |
|
|
#include "sudoers.h" |
#include "sudoers.h" |
#include "parse.h" |
#include "parse.h" |
#include "toke.h" |
#include "toke.h" |
Line 56
|
Line 57
|
static int arg_len = 0; |
static int arg_len = 0; |
static int arg_size = 0; |
static int arg_size = 0; |
|
|
static unsigned char | bool |
hexchar(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(const char *src, int len, int olen) |
fill_txt(const char *src, int len, int olen) |
{ |
{ |
char *dst; |
char *dst; |
|
debug_decl(fill_txt, SUDO_DEBUG_PARSER) |
|
|
dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1); | dst = olen ? realloc(sudoerslval.string, olen + len + 1) : malloc(len + 1); |
if (dst == NULL) { |
if (dst == NULL) { |
yyerror(_("unable to allocate memory")); | warning(NULL); |
return FALSE; | sudoerserror(NULL); |
| debug_return_bool(false); |
} |
} |
yylval.string = dst; | sudoerslval.string = dst; |
|
|
/* Copy the string and collapse any escaped characters. */ |
/* Copy the string and collapse any escaped characters. */ |
dst += olen; |
dst += olen; |
Line 120 fill_txt(const char *src, int len, int olen)
|
Line 78 fill_txt(const char *src, int len, int olen)
|
if (src[1] == 'x' && len >= 3 && |
if (src[1] == 'x' && len >= 3 && |
isxdigit((unsigned char) src[2]) && |
isxdigit((unsigned char) src[2]) && |
isxdigit((unsigned char) src[3])) { |
isxdigit((unsigned char) src[3])) { |
*dst++ = hexchar(src); | *dst++ = hexchar(src + 2); |
src += 4; |
src += 4; |
len -= 3; |
len -= 3; |
} else { |
} else { |
Line 133 fill_txt(const char *src, int len, int olen)
|
Line 91 fill_txt(const char *src, int len, int olen)
|
} |
} |
} |
} |
*dst = '\0'; |
*dst = '\0'; |
return TRUE; | debug_return_bool(true); |
} |
} |
|
|
int | bool |
append(const char *src, int len) |
append(const char *src, int len) |
{ |
{ |
int olen = 0; |
int olen = 0; |
|
debug_decl(append, SUDO_DEBUG_PARSER) |
|
|
if (yylval.string != NULL) | if (sudoerslval.string != NULL) |
olen = strlen(yylval.string); | olen = strlen(sudoerslval.string); |
|
|
return fill_txt(src, len, olen); | debug_return_bool(fill_txt(src, len, olen)); |
} |
} |
|
|
#define SPECIAL(c) \ |
#define SPECIAL(c) \ |
((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#') |
((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#') |
|
|
int | bool |
fill_cmnd(const char *src, int len) |
fill_cmnd(const char *src, int len) |
{ |
{ |
char *dst; |
char *dst; |
int i; |
int i; |
|
debug_decl(fill_cmnd, SUDO_DEBUG_PARSER) |
|
|
arg_len = arg_size = 0; |
arg_len = arg_size = 0; |
|
|
dst = yylval.command.cmnd = (char *) malloc(len + 1); | dst = sudoerslval.command.cmnd = (char *) malloc(len + 1); |
if (yylval.command.cmnd == NULL) { | if (sudoerslval.command.cmnd == NULL) { |
yyerror(_("unable to allocate memory")); | warning(NULL); |
return FALSE; | sudoerserror(NULL); |
| debug_return_bool(false); |
} |
} |
|
|
/* Copy the string and collapse any escaped sudo-specific characters. */ |
/* Copy the string and collapse any escaped sudo-specific characters. */ |
Line 173 fill_cmnd(const char *src, int len)
|
Line 134 fill_cmnd(const char *src, int len)
|
} |
} |
*dst = '\0'; |
*dst = '\0'; |
|
|
yylval.command.args = NULL; | sudoerslval.command.args = NULL; |
return TRUE; | debug_return_bool(true); |
} |
} |
|
|
int | bool |
fill_args(const char *s, int len, int addspace) |
fill_args(const char *s, int len, int addspace) |
{ |
{ |
int new_len; |
int new_len; |
char *p; |
char *p; |
|
debug_decl(fill_args, SUDO_DEBUG_PARSER) |
|
|
if (yylval.command.args == NULL) { | if (sudoerslval.command.args == NULL) { |
addspace = 0; |
addspace = 0; |
new_len = len; |
new_len = len; |
} else |
} else |
Line 194 fill_args(const char *s, int len, int addspace)
|
Line 156 fill_args(const char *s, int len, int addspace)
|
while (new_len >= (arg_size += COMMANDARGINC)) |
while (new_len >= (arg_size += COMMANDARGINC)) |
; |
; |
|
|
p = yylval.command.args ? | p = sudoerslval.command.args ? |
(char *) realloc(yylval.command.args, arg_size) : | (char *) realloc(sudoerslval.command.args, arg_size) : |
(char *) malloc(arg_size); |
(char *) malloc(arg_size); |
if (p == NULL) { |
if (p == NULL) { |
efree(yylval.command.args); | efree(sudoerslval.command.args); |
yyerror(_("unable to allocate memory")); | warning(NULL); |
return FALSE; | sudoerserror(NULL); |
| debug_return_bool(false); |
} else |
} else |
yylval.command.args = p; | sudoerslval.command.args = p; |
} |
} |
|
|
/* Efficiently append the arg (with a leading space if needed). */ |
/* Efficiently append the arg (with a leading space if needed). */ |
p = yylval.command.args + arg_len; | p = sudoerslval.command.args + arg_len; |
if (addspace) |
if (addspace) |
*p++ = ' '; |
*p++ = ' '; |
if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) { | if (strlcpy(p, s, arg_size - (p - sudoerslval.command.args)) != (size_t)len) { |
yyerror(_("fill_args: buffer overflow")); /* paranoia */ | warningx(U_("fill_args: buffer overflow")); /* paranoia */ |
return FALSE; | sudoerserror(NULL); |
| debug_return_bool(false); |
} |
} |
arg_len = new_len; |
arg_len = new_len; |
return TRUE; | debug_return_bool(true); |
} |
} |
|
|
/* |
/* |
* Check to make sure an IPv6 address does not contain multiple instances |
* Check to make sure an IPv6 address does not contain multiple instances |
* of the string "::". Assumes strlen(s) >= 1. |
* of the string "::". Assumes strlen(s) >= 1. |
* Returns TRUE if address is valid else FALSE. | * Returns true if address is valid else false. |
*/ |
*/ |
int | bool |
ipv6_valid(const char *s) |
ipv6_valid(const char *s) |
{ |
{ |
int nmatch = 0; |
int nmatch = 0; |
|
debug_decl(ipv6_valid, SUDO_DEBUG_PARSER) |
|
|
for (; *s != '\0'; s++) { |
for (; *s != '\0'; s++) { |
if (s[0] == ':' && s[1] == ':') { |
if (s[0] == ':' && s[1] == ':') { |
Line 236 ipv6_valid(const char *s)
|
Line 201 ipv6_valid(const char *s)
|
nmatch = 0; /* reset if we hit netmask */ |
nmatch = 0; /* reset if we hit netmask */ |
} |
} |
|
|
return nmatch <= 1; | debug_return_bool(nmatch <= 1); |
} |
} |