Annotation of embedaddon/sudo/plugins/sudoers/toke_util.c, revision 1.1.1.1
1.1 misho 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: #include "sudoers.h"
52: #include "parse.h"
53: #include "toke.h"
54: #include <gram.h>
55:
56: static int arg_len = 0;
57: static int arg_size = 0;
58:
59: static unsigned char
60: hexchar(const char *s)
61: {
62: int i;
63: int result = 0;
64:
65: s += 2; /* skip \\x */
66: for (i = 0; i < 2; i++) {
67: switch (*s) {
68: case 'A':
69: case 'a':
70: result += 10;
71: break;
72: case 'B':
73: case 'b':
74: result += 11;
75: break;
76: case 'C':
77: case 'c':
78: result += 12;
79: break;
80: case 'D':
81: case 'd':
82: result += 13;
83: break;
84: case 'E':
85: case 'e':
86: result += 14;
87: break;
88: case 'F':
89: case 'f':
90: result += 15;
91: break;
92: default:
93: result += *s - '0';
94: break;
95: }
96: if (i == 0) {
97: result *= 16;
98: s++;
99: }
100: }
101: return (unsigned char)result;
102: }
103:
104: int
105: fill_txt(const char *src, int len, int olen)
106: {
107: char *dst;
108:
109: dst = olen ? realloc(yylval.string, olen + len + 1) : malloc(len + 1);
110: if (dst == NULL) {
111: yyerror(_("unable to allocate memory"));
112: return FALSE;
113: }
114: yylval.string = dst;
115:
116: /* Copy the string and collapse any escaped characters. */
117: dst += olen;
118: while (len--) {
119: if (*src == '\\' && len) {
120: if (src[1] == 'x' && len >= 3 &&
121: isxdigit((unsigned char) src[2]) &&
122: isxdigit((unsigned char) src[3])) {
123: *dst++ = hexchar(src);
124: src += 4;
125: len -= 3;
126: } else {
127: src++;
128: len--;
129: *dst++ = *src++;
130: }
131: } else {
132: *dst++ = *src++;
133: }
134: }
135: *dst = '\0';
136: return TRUE;
137: }
138:
139: int
140: append(const char *src, int len)
141: {
142: int olen = 0;
143:
144: if (yylval.string != NULL)
145: olen = strlen(yylval.string);
146:
147: return fill_txt(src, len, olen);
148: }
149:
150: #define SPECIAL(c) \
151: ((c) == ',' || (c) == ':' || (c) == '=' || (c) == ' ' || (c) == '\t' || (c) == '#')
152:
153: int
154: fill_cmnd(const char *src, int len)
155: {
156: char *dst;
157: int i;
158:
159: arg_len = arg_size = 0;
160:
161: dst = yylval.command.cmnd = (char *) malloc(len + 1);
162: if (yylval.command.cmnd == NULL) {
163: yyerror(_("unable to allocate memory"));
164: return FALSE;
165: }
166:
167: /* Copy the string and collapse any escaped sudo-specific characters. */
168: for (i = 0; i < len; i++) {
169: if (src[i] == '\\' && i != len - 1 && SPECIAL(src[i + 1]))
170: *dst++ = src[++i];
171: else
172: *dst++ = src[i];
173: }
174: *dst = '\0';
175:
176: yylval.command.args = NULL;
177: return TRUE;
178: }
179:
180: int
181: fill_args(const char *s, int len, int addspace)
182: {
183: int new_len;
184: char *p;
185:
186: if (yylval.command.args == NULL) {
187: addspace = 0;
188: new_len = len;
189: } else
190: new_len = arg_len + len + addspace;
191:
192: if (new_len >= arg_size) {
193: /* Allocate more space than we need for subsequent args */
194: while (new_len >= (arg_size += COMMANDARGINC))
195: ;
196:
197: p = yylval.command.args ?
198: (char *) realloc(yylval.command.args, arg_size) :
199: (char *) malloc(arg_size);
200: if (p == NULL) {
201: efree(yylval.command.args);
202: yyerror(_("unable to allocate memory"));
203: return FALSE;
204: } else
205: yylval.command.args = p;
206: }
207:
208: /* Efficiently append the arg (with a leading space if needed). */
209: p = yylval.command.args + arg_len;
210: if (addspace)
211: *p++ = ' ';
212: if (strlcpy(p, s, arg_size - (p - yylval.command.args)) != len) {
213: yyerror(_("fill_args: buffer overflow")); /* paranoia */
214: return FALSE;
215: }
216: arg_len = new_len;
217: return TRUE;
218: }
219:
220: /*
221: * Check to make sure an IPv6 address does not contain multiple instances
222: * of the string "::". Assumes strlen(s) >= 1.
223: * Returns TRUE if address is valid else FALSE.
224: */
225: int
226: ipv6_valid(const char *s)
227: {
228: int nmatch = 0;
229:
230: for (; *s != '\0'; s++) {
231: if (s[0] == ':' && s[1] == ':') {
232: if (++nmatch > 1)
233: break;
234: }
235: if (s[0] == '/')
236: nmatch = 0; /* reset if we hit netmask */
237: }
238:
239: return nmatch <= 1;
240: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>