[BACK]Return to parse.lex CVS log [TXT][DIR] Up to [local] / src / usr.bin / sudo

Annotation of src/usr.bin/sudo/parse.lex, Revision 1.1

1.1     ! millert     1: %{
        !             2: /*
        !             3:  * Copyright (c) 1996, 1998, 1999 Todd C. Miller <Todd.Miller@courtesan.com>
        !             4:  * All rights reserved.
        !             5:  *
        !             6:  * This code is derived from software contributed by Chris Jepeway
        !             7:  * <jepeway@cs.utk.edu>
        !             8:  *
        !             9:  * This code is derived from software contributed by Chris Jepeway
        !            10:  * Redistribution and use in source and binary forms, with or without
        !            11:  * modification, are permitted provided that the following conditions
        !            12:  * are met:
        !            13:  *
        !            14:  * 1. Redistributions of source code must retain the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer.
        !            16:  *
        !            17:  * 2. Redistributions in binary form must reproduce the above copyright
        !            18:  *    notice, this list of conditions and the following disclaimer in the
        !            19:  *    documentation and/or other materials provided with the distribution.
        !            20:  *
        !            21:  * 3. The name of the author may not be used to endorse or promote products
        !            22:  *    derived from this software without specific prior written permission.
        !            23:  *
        !            24:  * 4. Products derived from this software may not be called "Sudo" nor
        !            25:  *    may "Sudo" appear in their names without specific prior written
        !            26:  *    permission from the author.
        !            27:  *
        !            28:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
        !            29:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
        !            30:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
        !            31:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
        !            32:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
        !            33:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
        !            34:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
        !            35:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
        !            36:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
        !            37:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            38:  */
        !            39:
        !            40: #include "config.h"
        !            41:
        !            42: #ifdef STDC_HEADERS
        !            43: #include <stdlib.h>
        !            44: #endif /* STDC_HEADERS */
        !            45: #ifdef HAVE_UNISTD_H
        !            46: #include <unistd.h>
        !            47: #endif /* HAVE_UNISTD_H */
        !            48: #ifdef HAVE_STRING_H
        !            49: #include <string.h>
        !            50: #endif /* HAVE_STRING_H */
        !            51: #ifdef HAVE_STRINGS_H
        !            52: #include <strings.h>
        !            53: #endif /* HAVE_STRINGS_H */
        !            54: #if defined(HAVE_MALLOC_H) && !defined(STDC_HEADERS)
        !            55: #include <malloc.h>
        !            56: #endif /* HAVE_MALLOC_H && !STDC_HEADERS */
        !            57: #include <ctype.h>
        !            58: #include <sys/types.h>
        !            59: #include <sys/param.h>
        !            60: #include "sudo.h"
        !            61: #include "parse.h"
        !            62: #include "sudo.tab.h"
        !            63:
        !            64: #ifndef lint
        !            65: static const char rcsid[] = "$Sudo: parse.lex,v 1.109 1999/11/09 20:06:52 millert Exp $";
        !            66: #endif /* lint */
        !            67:
        !            68: #undef yywrap          /* guard against a yywrap macro */
        !            69:
        !            70: extern YYSTYPE yylval;
        !            71: extern int clearaliases;
        !            72: int sudolineno = 1;
        !            73: static int sawspace = 0;
        !            74: static int arg_len = 0;
        !            75: static int arg_size = 0;
        !            76:
        !            77: static void fill               __P((char *, int));
        !            78: static void fill_cmnd          __P((char *, int));
        !            79: static void fill_args          __P((char *, int, int));
        !            80: extern void reset_aliases      __P((void));
        !            81: extern void yyerror            __P((char *));
        !            82:
        !            83: /* realloc() to size + COMMANDARGINC to make room for command args */
        !            84: #define COMMANDARGINC  64
        !            85:
        !            86: #ifdef TRACELEXER
        !            87: #define LEXTRACE(msg)  fputs(msg, stderr)
        !            88: #else
        !            89: #define LEXTRACE(msg)
        !            90: #endif
        !            91: %}
        !            92:
        !            93: OCTET                  (1?[0-9]{1,2})|(2[0-4][0-9])|(25[0-5])
        !            94: DOTTEDQUAD             {OCTET}(\.{OCTET}){3}
        !            95: HOSTNAME               [[:alnum:]_-]+
        !            96: WORD                   ([^@!=:,\(\) \t\n\\]|\\[^\n])+
        !            97:
        !            98: %s     GOTCMND
        !            99: %s     GOTRUNAS
        !           100: %s     GOTDEFS
        !           101:
        !           102: %%
        !           103: [ \t]+                 {                       /* throw away space/tabs */
        !           104:                            sawspace = TRUE;    /* but remember for fill_args */
        !           105:                        }
        !           106:
        !           107: \\[ \t]*\n             {
        !           108:                            sawspace = TRUE;    /* remember for fill_args */
        !           109:                            ++sudolineno;
        !           110:                            LEXTRACE("\n\t");
        !           111:                        }                       /* throw away EOL after \ */
        !           112:
        !           113: <GOTCMND>\\[:\,=\\ \t] {
        !           114:                            LEXTRACE("QUOTEDCHAR ");
        !           115:                            fill_args(yytext + 1, 1, sawspace);
        !           116:                            sawspace = FALSE;
        !           117:                        }
        !           118:
        !           119: <GOTDEFS>\"([^\"]|\\\")+\"     {
        !           120:                            LEXTRACE("WORD(1) ");
        !           121:                            fill(yytext + 1, yyleng - 2);
        !           122:                            return(WORD);
        !           123:                        }
        !           124:
        !           125: <GOTDEFS>(#.*)?\n      {
        !           126:                            BEGIN INITIAL;
        !           127:                            ++sudolineno;
        !           128:                            LEXTRACE("\n");
        !           129:                            return(COMMENT);
        !           130:                        }
        !           131:
        !           132: <GOTCMND>[:\,=\n]      {
        !           133:                            BEGIN INITIAL;
        !           134:                            unput(*yytext);
        !           135:                            return(COMMAND);
        !           136:                        }                       /* end of command line args */
        !           137:
        !           138: \n                     {
        !           139:                            ++sudolineno;
        !           140:                            LEXTRACE("\n");
        !           141:                            return(COMMENT);
        !           142:                        }                       /* return newline */
        !           143:
        !           144: <INITIAL>#.*\n         {
        !           145:                            ++sudolineno;
        !           146:                            LEXTRACE("\n");
        !           147:                            return(COMMENT);
        !           148:                        }                       /* return comments */
        !           149:
        !           150: <GOTCMND>[^\\:, \t\n]+ {
        !           151:                            LEXTRACE("ARG ");
        !           152:                            fill_args(yytext, yyleng, sawspace);
        !           153:                            sawspace = FALSE;
        !           154:                          }                     /* a command line arg */
        !           155:
        !           156: ,                      {
        !           157:                            LEXTRACE(", ");
        !           158:                            return(',');
        !           159:                        }                       /* return ',' */
        !           160:
        !           161: !+                     {
        !           162:                            if (yyleng % 2 == 1)
        !           163:                                return('!');    /* return '!' */
        !           164:                        }
        !           165:
        !           166: =                      {
        !           167:                            LEXTRACE("= ");
        !           168:                            return('=');
        !           169:                        }                       /* return '=' */
        !           170:
        !           171: :                      {
        !           172:                            LEXTRACE(": ");
        !           173:                            return(':');
        !           174:                        }                       /* return ':' */
        !           175:
        !           176: NOPASSWD[[:blank:]]*:  {
        !           177:                                /* cmnd does not require passwd for this user */
        !           178:                                LEXTRACE("NOPASSWD ");
        !           179:                                return(NOPASSWD);
        !           180:                        }
        !           181:
        !           182: PASSWD[[:blank:]]*:    {
        !           183:                                /* cmnd requires passwd for this user */
        !           184:                                LEXTRACE("PASSWD ");
        !           185:                                return(PASSWD);
        !           186:                        }
        !           187:
        !           188: \+{WORD}               {
        !           189:                            /* netgroup */
        !           190:                            fill(yytext, yyleng);
        !           191:                            LEXTRACE("NETGROUP ");
        !           192:                            return(NETGROUP);
        !           193:                        }
        !           194:
        !           195: \%{WORD}               {
        !           196:                            /* UN*X group */
        !           197:                            fill(yytext, yyleng);
        !           198:                            LEXTRACE("GROUP ");
        !           199:                            return(USERGROUP);
        !           200:                        }
        !           201:
        !           202: {DOTTEDQUAD}(\/{DOTTEDQUAD})? {
        !           203:                            fill(yytext, yyleng);
        !           204:                            LEXTRACE("NTWKADDR ");
        !           205:                            return(NTWKADDR);
        !           206:                        }
        !           207:
        !           208: {DOTTEDQUAD}\/([12][0-9]*|3[0-2]*) {
        !           209:                            fill(yytext, yyleng);
        !           210:                            LEXTRACE("NTWKADDR ");
        !           211:                            return(NTWKADDR);
        !           212:                        }
        !           213:
        !           214: [[:alpha:]][[:alnum:]_-]*(\.{HOSTNAME})+ {
        !           215:                            fill(yytext, yyleng);
        !           216:                            LEXTRACE("FQHOST ");
        !           217:                            return(FQHOST);
        !           218:                        }
        !           219:
        !           220: <INITIAL>\(            {
        !           221:                                BEGIN GOTRUNAS;
        !           222:                                LEXTRACE("RUNAS ");
        !           223:                                return (RUNAS);
        !           224:                        }
        !           225:
        !           226: <GOTRUNAS>[[:upper:]][[:upper:][:digit:]_]* {
        !           227:                            /* Runas_Alias user can run command as or ALL */
        !           228:                            if (strcmp(yytext, "ALL") == 0) {
        !           229:                                LEXTRACE("ALL ");
        !           230:                                return(ALL);
        !           231:                            } else {
        !           232:                                fill(yytext, yyleng);
        !           233:                                LEXTRACE("ALIAS ");
        !           234:                                return(ALIAS);
        !           235:                            }
        !           236:                        }
        !           237:
        !           238: <GOTRUNAS>#?{WORD}     {
        !           239:                            /* username/uid that user can run command as */
        !           240:                            fill(yytext, yyleng);
        !           241:                            LEXTRACE("WORD(2) ");
        !           242:                            return(WORD);
        !           243:                        }
        !           244:
        !           245: <GOTRUNAS>\)           {
        !           246:                            BEGIN INITIAL;
        !           247:                        }
        !           248:
        !           249: [[:upper:]][[:upper:][:digit:]_]*      {
        !           250:                            if (strcmp(yytext, "ALL") == 0) {
        !           251:                                LEXTRACE("ALL ");
        !           252:                                return(ALL);
        !           253:                            } else {
        !           254:                                fill(yytext, yyleng);
        !           255:                                LEXTRACE("ALIAS ");
        !           256:                                return(ALIAS);
        !           257:                            }
        !           258:                        }
        !           259:
        !           260: <GOTDEFS>{WORD}        {
        !           261:                            LEXTRACE("WORD(3) ");
        !           262:                            fill(yytext, yyleng);
        !           263:                            return(WORD);
        !           264:                        }
        !           265:
        !           266: <INITIAL>^Defaults[:@]?        {
        !           267:                            BEGIN GOTDEFS;
        !           268:                            if (yyleng == 9) {
        !           269:                                switch (yytext[8]) {
        !           270:                                    case ':' :
        !           271:                                        LEXTRACE("DEFAULTS_USER ");
        !           272:                                        return(DEFAULTS_USER);
        !           273:                                    case '@' :
        !           274:                                        LEXTRACE("DEFAULTS_HOST ");
        !           275:                                        return(DEFAULTS_HOST);
        !           276:                                }
        !           277:                            } else {
        !           278:                                LEXTRACE("DEFAULTS ");
        !           279:                                return(DEFAULTS);
        !           280:                            }
        !           281:                        }
        !           282:
        !           283: <INITIAL>^(Host|Cmnd|User|Runas)_Alias {
        !           284:                            fill(yytext, yyleng);
        !           285:                            if (*yytext == 'H') {
        !           286:                                LEXTRACE("HOSTALIAS ");
        !           287:                                return(HOSTALIAS);
        !           288:                            }
        !           289:                            if (*yytext == 'C') {
        !           290:                                LEXTRACE("CMNDALIAS ");
        !           291:                                return(CMNDALIAS);
        !           292:                            }
        !           293:                            if (*yytext == 'U') {
        !           294:                                LEXTRACE("USERALIAS ");
        !           295:                                return(USERALIAS);
        !           296:                            }
        !           297:                            if (*yytext == 'R') {
        !           298:                                LEXTRACE("RUNASALIAS ");
        !           299:                                return(RUNASALIAS);
        !           300:                            }
        !           301:                        }
        !           302:
        !           303: \/[^\,:=\\ \t\n#]+     {
        !           304:                            /* directories can't have args... */
        !           305:                            if (yytext[yyleng - 1] == '/') {
        !           306:                                LEXTRACE("COMMAND ");
        !           307:                                fill_cmnd(yytext, yyleng);
        !           308:                                return(COMMAND);
        !           309:                            } else {
        !           310:                                BEGIN GOTCMND;
        !           311:                                LEXTRACE("COMMAND ");
        !           312:                                fill_cmnd(yytext, yyleng);
        !           313:                            }
        !           314:                        }                       /* a pathname */
        !           315:
        !           316: <INITIAL>{WORD}                {
        !           317:                            /* a word */
        !           318:                            fill(yytext, yyleng);
        !           319:                            LEXTRACE("WORD(4) ");
        !           320:                            return(WORD);
        !           321:                        }
        !           322:
        !           323: .                      {
        !           324:                            LEXTRACE("ERROR ");
        !           325:                            return(ERROR);
        !           326:                        }       /* parse error */
        !           327:
        !           328: %%
        !           329: static void
        !           330: fill(s, len)
        !           331:     char *s;
        !           332:     int len;
        !           333: {
        !           334:     int i, j;
        !           335:
        !           336:     yylval.string = (char *) malloc(len + 1);
        !           337:     if (yylval.string == NULL)
        !           338:        yyerror("unable to allocate memory");
        !           339:
        !           340:     /* Copy the string and collapse any escaped characters. */
        !           341:     for (i = 0, j = 0; i < len; i++, j++) {
        !           342:        if (s[i] == '\\' && i != len - 1)
        !           343:            yylval.string[j] = s[++i];
        !           344:        else
        !           345:            yylval.string[j] = s[i];
        !           346:     }
        !           347:     yylval.string[j] = '\0';
        !           348: }
        !           349:
        !           350: static void
        !           351: fill_cmnd(s, len)
        !           352:     char *s;
        !           353:     int len;
        !           354: {
        !           355:     arg_len = arg_size = 0;
        !           356:
        !           357:     yylval.command.cmnd = (char *) malloc(len + 1);
        !           358:     if (yylval.command.cmnd == NULL)
        !           359:        yyerror("unable to allocate memory");
        !           360:
        !           361:     /* copy the string and NULL-terminate it */
        !           362:     (void) strncpy(yylval.command.cmnd, s, len);
        !           363:     yylval.command.cmnd[len] = '\0';
        !           364:
        !           365:     yylval.command.args = NULL;
        !           366: }
        !           367:
        !           368: static void
        !           369: fill_args(s, len, addspace)
        !           370:     char *s;
        !           371:     int len;
        !           372:     int addspace;
        !           373: {
        !           374:     int new_len;
        !           375:     char *p;
        !           376:
        !           377:     /*
        !           378:      * If first arg, malloc() some room, else if we don't
        !           379:      * have enough space realloc() some more.
        !           380:      */
        !           381:     if (yylval.command.args == NULL) {
        !           382:        addspace = 0;
        !           383:        new_len = len;
        !           384:
        !           385:        while (new_len >= (arg_size += COMMANDARGINC))
        !           386:            ;
        !           387:
        !           388:        yylval.command.args = (char *) malloc(arg_size);
        !           389:        if (yylval.command.args == NULL)
        !           390:            yyerror("unable to allocate memory");
        !           391:     } else {
        !           392:        new_len = arg_len + len + addspace;
        !           393:
        !           394:        if (new_len >= arg_size) {
        !           395:            /* Allocate more space than we need for subsequent args */
        !           396:            while (new_len >= (arg_size += COMMANDARGINC))
        !           397:                ;
        !           398:
        !           399:            if ((p = (char *) realloc(yylval.command.args, arg_size)) == NULL) {
        !           400:                free(yylval.command.args);
        !           401:                yyerror("unable to allocate memory");
        !           402:            } else
        !           403:                yylval.command.args = p;
        !           404:        }
        !           405:     }
        !           406:
        !           407:     /* Efficiently append the arg (with a leading space if needed). */
        !           408:     p = yylval.command.args + arg_len;
        !           409:     if (addspace)
        !           410:        *p++ = ' ';
        !           411:     (void) strcpy(p, s);
        !           412:     arg_len = new_len;
        !           413: }
        !           414:
        !           415: int
        !           416: yywrap()
        !           417: {
        !           418:
        !           419:     /* Free space used by the aliases unless called by testsudoers. */
        !           420:     if (clearaliases)
        !           421:        reset_aliases();
        !           422:
        !           423:     return(TRUE);
        !           424: }