File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / toke_util.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue May 29 12:26:49 2012 UTC (12 years, 3 months ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_5p1, HEAD
sudo 1.8.5p1

    1: /*
    2:  * Copyright (c) 1996, 1998-2005, 2007-2011
    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:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   17:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
   18:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   19:  *
   20:  * Sponsored in part by the Defense Advanced Research Projects
   21:  * Agency (DARPA) and Air Force Research Laboratory, Air Force
   22:  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
   23:  */
   24: 
   25: #include <config.h>
   26: 
   27: #include <sys/types.h>
   28: #include <sys/param.h>
   29: #include <stdio.h>
   30: #ifdef STDC_HEADERS
   31: # include <stdlib.h>
   32: # include <stddef.h>
   33: #else
   34: # ifdef HAVE_STDLIB_H
   35: #  include <stdlib.h>
   36: # endif
   37: #endif /* STDC_HEADERS */
   38: #ifdef HAVE_STRING_H
   39: # include <string.h>
   40: #endif /* HAVE_STRING_H */
   41: #ifdef HAVE_STRINGS_H
   42: # include <strings.h>
   43: #endif /* HAVE_STRINGS_H */
   44: #ifdef HAVE_UNISTD_H
   45: # include <unistd.h>
   46: #endif /* HAVE_UNISTD_H */
   47: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
   48: # include <malloc.h>
   49: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
   50: #include <ctype.h>
   51: 
   52: #include "sudoers.h"
   53: #include "parse.h"
   54: #include "toke.h"
   55: #include <gram.h>
   56: 
   57: static int arg_len = 0;
   58: static int arg_size = 0;
   59: 
   60: static int
   61: hexchar(const char *s)
   62: {
   63:     int i, result = 0;
   64:     debug_decl(hexchar, SUDO_DEBUG_PARSER)
   65: 
   66:     s += 2; /* skip \\x */
   67:     for (i = 0; i < 2; i++) {
   68: 	switch (*s) {
   69: 	case 'A':
   70: 	case 'a':
   71: 	    result += 10;
   72: 	    break;
   73: 	case 'B':
   74: 	case 'b':
   75: 	    result += 11;
   76: 	    break;
   77: 	case 'C':
   78: 	case 'c':
   79: 	    result += 12;
   80: 	    break;
   81: 	case 'D':
   82: 	case 'd':
   83: 	    result += 13;
   84: 	    break;
   85: 	case 'E':
   86: 	case 'e':
   87: 	    result += 14;
   88: 	    break;
   89: 	case 'F':
   90: 	case 'f':
   91: 	    result += 15;
   92: 	    break;
   93: 	default:
   94: 	    result += *s - '0';
   95: 	    break;
   96: 	}
   97: 	if (i == 0) {
   98: 	    result *= 16;
   99: 	    s++;
  100: 	}
  101:     }
  102:     debug_return_int(result);
  103: }
  104: 
  105: bool
  106: fill_txt(const char *src, int len, int olen)
  107: {
  108:     char *dst;
  109:     debug_decl(fill_txt, SUDO_DEBUG_PARSER)
  110: 
  111:     dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
  112:     if (dst == NULL) {
  113: 	yyerror(_("unable to allocate memory"));
  114: 	debug_return_bool(false);
  115:     }
  116:     yylval.string = dst;
  117: 
  118:     /* Copy the string and collapse any escaped characters. */
  119:     dst += olen;
  120:     while (len--) {
  121: 	if (*src == '\\' && len) {
  122: 	    if (src[1] == 'x' && len >= 3 && 
  123: 		isxdigit((unsigned char) src[2]) &&
  124: 		isxdigit((unsigned char) src[3])) {
  125: 		*dst++ = hexchar(src);
  126: 		src += 4;
  127: 		len -= 3;
  128: 	    } else {
  129: 		src++;
  130: 		len--;
  131: 		*dst++ = *src++;
  132: 	    }
  133: 	} else {
  134: 	    *dst++ = *src++;
  135: 	}
  136:     }
  137:     *dst = '\0';
  138:     debug_return_bool(true);
  139: }
  140: 
  141: bool
  142: append(const char *src, int len)
  143: {
  144:     int olen = 0;
  145:     debug_decl(append, SUDO_DEBUG_PARSER)
  146: 
  147:     if (yylval.string != NULL)
  148: 	olen = strlen(yylval.string);
  149: 
  150:     debug_return_bool(fill_txt(src, len, olen));
  151: }
  152: 
  153: #define SPECIAL(c) \
  154:     ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
  155: 
  156: bool
  157: fill_cmnd(const char *src, int len)
  158: {
  159:     char *dst;
  160:     int i;
  161:     debug_decl(fill_cmnd, SUDO_DEBUG_PARSER)
  162: 
  163:     arg_len = arg_size = 0;
  164: 
  165:     dst = yylval.command.cmnd = (char *) malloc(len + 1);
  166:     if (yylval.command.cmnd == NULL) {
  167: 	yyerror(_("unable to allocate memory"));
  168: 	debug_return_bool(false);
  169:     }
  170: 
  171:     /* Copy the string and collapse any escaped sudo-specific characters. */
  172:     for (i = 0; i < len; i++) {
  173: 	if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
  174: 	    *dst++ = src[++i];
  175: 	else
  176: 	    *dst++ = src[i];
  177:     }
  178:     *dst = '\0';
  179: 
  180:     yylval.command.args = NULL;
  181:     debug_return_bool(true);
  182: }
  183: 
  184: bool
  185: fill_args(const char *s, int len, int addspace)
  186: {
  187:     int new_len;
  188:     char *p;
  189:     debug_decl(fill_args, SUDO_DEBUG_PARSER)
  190: 
  191:     if (yylval.command.args == NULL) {
  192: 	addspace = 0;
  193: 	new_len = len;
  194:     } else
  195: 	new_len = arg_len + len + addspace;
  196: 
  197:     if (new_len >= arg_size) {
  198: 	/* Allocate more space than we need for subsequent args */
  199: 	while (new_len >= (arg_size += COMMANDARGINC))
  200: 	    ;
  201: 
  202: 	p = yylval.command.args ?
  203: 	    (char *) realloc(yylval.command.args, arg_size) :
  204: 	    (char *) malloc(arg_size);
  205: 	if (p == NULL) {
  206: 	    efree(yylval.command.args);
  207: 	    yyerror(_("unable to allocate memory"));
  208: 	    debug_return_bool(false);
  209: 	} else
  210: 	    yylval.command.args = p;
  211:     }
  212: 
  213:     /* Efficiently append the arg (with a leading space if needed). */
  214:     p = yylval.command.args + arg_len;
  215:     if (addspace)
  216: 	*p++ = ' ';
  217:     if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
  218: 	yyerror(_("fill_args: buffer overflow"));	/* paranoia */
  219: 	debug_return_bool(false);
  220:     }
  221:     arg_len = new_len;
  222:     debug_return_bool(true);
  223: }
  224: 
  225: /*
  226:  * Check to make sure an IPv6 address does not contain multiple instances
  227:  * of the string "::".  Assumes strlen(s) >= 1.
  228:  * Returns true if address is valid else false.
  229:  */
  230: bool
  231: ipv6_valid(const char *s)
  232: {
  233:     int nmatch = 0;
  234:     debug_decl(ipv6_valid, SUDO_DEBUG_PARSER)
  235: 
  236:     for (; *s != '\0'; s++) {
  237: 	if (s[0] == ':' && s[1] == ':') {
  238: 	    if (++nmatch > 1)
  239: 		break;
  240: 	}
  241: 	if (s[0] == '/')
  242: 	    nmatch = 0;			/* reset if we hit netmask */
  243:     }
  244: 
  245:     debug_return_bool(nmatch <= 1);
  246: }

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