~ubuntu-branches/ubuntu/quantal/sudo/quantal

« back to all changes in this revision

Viewing changes to plugins/sudoers/toke_util.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2011-11-20 12:07:45 UTC
  • mfrom: (1.3.17 sid)
  • Revision ID: package-import@ubuntu.com-20111120120745-o3qpklobmygytndc
Tags: 1.8.3p1-1ubuntu1
* Merge from debian/testing, remaining changes:
  - debian/patches/keep_home_by_default.patch:
    + Set HOME in initial_keepenv_table. (rebased for 1.8.3p1)
  - debian/patches/enable_badpass.patch: turn on "mail_badpass" by default:
    + attempting sudo without knowing a login password is as bad as not
      being listed in the sudoers file, especially if getting the password
      wrong means doing the access-check-email-notification never happens
      (rebased for 1.8.3p1)
  - debian/rules:
    + compile with --without-lecture --with-tty-tickets (Ubuntu specific)
    + install man/man8/sudo_root.8 (Ubuntu specific)
    + install apport hooks
    + The ubuntu-sudo-as-admin-successful.patch was taken upstream by
      Debian however it requires a --enable-admin-flag configure flag to
      actually enable it.
  - debian/sudoers: 
    + grant admin group sudo access
  - debian/sudo-ldap.dirs, debian/sudo.dirs: 
    + add usr/share/apport/package-hooks
  - debian/sudo.preinst:
    + avoid conffile prompt by checking for known default /etc/sudoers
      and if found installing the correct default /etc/sudoers file

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}