File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers / toke_util.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 10:46:12 2013 UTC (11 years ago) by misho
Branches: sudo, MAIN
CVS tags: v1_8_8p0, v1_8_8, v1_8_7p0, v1_8_7, HEAD
1.8.7

    1: /*
    2:  * Copyright (c) 1996, 1998-2005, 2007-2013
    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 <stdio.h>
   29: #ifdef STDC_HEADERS
   30: # include <stdlib.h>
   31: # include <stddef.h>
   32: #else
   33: # ifdef HAVE_STDLIB_H
   34: #  include <stdlib.h>
   35: # endif
   36: #endif /* STDC_HEADERS */
   37: #ifdef HAVE_STRING_H
   38: # include <string.h>
   39: #endif /* HAVE_STRING_H */
   40: #ifdef HAVE_STRINGS_H
   41: # include <strings.h>
   42: #endif /* HAVE_STRINGS_H */
   43: #ifdef HAVE_UNISTD_H
   44: # include <unistd.h>
   45: #endif /* HAVE_UNISTD_H */
   46: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
   47: # include <malloc.h>
   48: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
   49: #include <ctype.h>
   50: #include <errno.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: bool
   61: fill_txt(const char *src, int len, int olen)
   62: {
   63:     char *dst;
   64:     debug_decl(fill_txt, SUDO_DEBUG_PARSER)
   65: 
   66:     dst = olen ? realloc(sudoerslval.string, olen + len + 1) : malloc(len + 1);
   67:     if (dst == NULL) {
   68: 	warning(NULL);
   69: 	sudoerserror(NULL);
   70: 	debug_return_bool(false);
   71:     }
   72:     sudoerslval.string = dst;
   73: 
   74:     /* Copy the string and collapse any escaped characters. */
   75:     dst += olen;
   76:     while (len--) {
   77: 	if (*src == '\\' && len) {
   78: 	    if (src[1] == 'x' && len >= 3 && 
   79: 		isxdigit((unsigned char) src[2]) &&
   80: 		isxdigit((unsigned char) src[3])) {
   81: 		*dst++ = hexchar(src + 2);
   82: 		src += 4;
   83: 		len -= 3;
   84: 	    } else {
   85: 		src++;
   86: 		len--;
   87: 		*dst++ = *src++;
   88: 	    }
   89: 	} else {
   90: 	    *dst++ = *src++;
   91: 	}
   92:     }
   93:     *dst = '\0';
   94:     debug_return_bool(true);
   95: }
   96: 
   97: bool
   98: append(const char *src, int len)
   99: {
  100:     int olen = 0;
  101:     debug_decl(append, SUDO_DEBUG_PARSER)
  102: 
  103:     if (sudoerslval.string != NULL)
  104: 	olen = strlen(sudoerslval.string);
  105: 
  106:     debug_return_bool(fill_txt(src, len, olen));
  107: }
  108: 
  109: #define SPECIAL(c) \
  110:     ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
  111: 
  112: bool
  113: fill_cmnd(const char *src, int len)
  114: {
  115:     char *dst;
  116:     int i;
  117:     debug_decl(fill_cmnd, SUDO_DEBUG_PARSER)
  118: 
  119:     arg_len = arg_size = 0;
  120: 
  121:     dst = sudoerslval.command.cmnd = (char *) malloc(len + 1);
  122:     if (sudoerslval.command.cmnd == NULL) {
  123: 	warning(NULL);
  124: 	sudoerserror(NULL);
  125: 	debug_return_bool(false);
  126:     }
  127: 
  128:     /* Copy the string and collapse any escaped sudo-specific characters. */
  129:     for (i = 0; i < len; i++) {
  130: 	if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
  131: 	    *dst++ = src[++i];
  132: 	else
  133: 	    *dst++ = src[i];
  134:     }
  135:     *dst = '\0';
  136: 
  137:     sudoerslval.command.args = NULL;
  138:     debug_return_bool(true);
  139: }
  140: 
  141: bool
  142: fill_args(const char *s, int len, int addspace)
  143: {
  144:     int new_len;
  145:     char *p;
  146:     debug_decl(fill_args, SUDO_DEBUG_PARSER)
  147: 
  148:     if (sudoerslval.command.args == NULL) {
  149: 	addspace = 0;
  150: 	new_len = len;
  151:     } else
  152: 	new_len = arg_len + len + addspace;
  153: 
  154:     if (new_len >= arg_size) {
  155: 	/* Allocate more space than we need for subsequent args */
  156: 	while (new_len >= (arg_size += COMMANDARGINC))
  157: 	    ;
  158: 
  159: 	p = sudoerslval.command.args ?
  160: 	    (char *) realloc(sudoerslval.command.args, arg_size) :
  161: 	    (char *) malloc(arg_size);
  162: 	if (p == NULL) {
  163: 	    efree(sudoerslval.command.args);
  164: 	    warning(NULL);
  165: 	    sudoerserror(NULL);
  166: 	    debug_return_bool(false);
  167: 	} else
  168: 	    sudoerslval.command.args = p;
  169:     }
  170: 
  171:     /* Efficiently append the arg (with a leading space if needed). */
  172:     p = sudoerslval.command.args + arg_len;
  173:     if (addspace)
  174: 	*p++ = ' ';
  175:     if (strlcpy(p, s, arg_size - (p - sudoerslval.command.args)) != len) {
  176: 	warningx(_("fill_args: buffer overflow"));	/* paranoia */
  177: 	sudoerserror(NULL);
  178: 	debug_return_bool(false);
  179:     }
  180:     arg_len = new_len;
  181:     debug_return_bool(true);
  182: }
  183: 
  184: /*
  185:  * Check to make sure an IPv6 address does not contain multiple instances
  186:  * of the string "::".  Assumes strlen(s) >= 1.
  187:  * Returns true if address is valid else false.
  188:  */
  189: bool
  190: ipv6_valid(const char *s)
  191: {
  192:     int nmatch = 0;
  193:     debug_decl(ipv6_valid, SUDO_DEBUG_PARSER)
  194: 
  195:     for (; *s != '\0'; s++) {
  196: 	if (s[0] == ':' && s[1] == ':') {
  197: 	    if (++nmatch > 1)
  198: 		break;
  199: 	}
  200: 	if (s[0] == '/')
  201: 	    nmatch = 0;			/* reset if we hit netmask */
  202:     }
  203: 
  204:     debug_return_bool(nmatch <= 1);
  205: }

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