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

Annotation of src/usr.bin/sudo/defaults.c, Revision 1.1.1.1

1.1       millert     1: /*
                      2:  * Copyright (c) 1999 Todd C. Miller <Todd.Miller@courtesan.com>
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms, with or without
                      6:  * modification, are permitted provided that the following conditions
                      7:  * are met:
                      8:  *
                      9:  * 1. Redistributions of source code must retain the above copyright
                     10:  *    notice, this list of conditions and the following disclaimer.
                     11:  *
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  *
                     16:  * 3. The name of the author may not be used to endorse or promote products
                     17:  *    derived from this software without specific prior written permission.
                     18:  *
                     19:  * 4. Products derived from this software may not be called "Sudo" nor
                     20:  *    may "Sudo" appear in their names without specific prior written
                     21:  *    permission from the author.
                     22:  *
                     23:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     24:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     25:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
                     26:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     27:  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     28:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     29:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     30:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     31:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     32:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     33:  */
                     34:
                     35: #include "config.h"
                     36:
                     37: #include <stdio.h>
                     38: #ifdef STDC_HEADERS
                     39: #include <stdlib.h>
                     40: #endif /* STDC_HEADERS */
                     41: #ifdef HAVE_UNISTD_H
                     42: #include <unistd.h>
                     43: #endif /* HAVE_UNISTD_H */
                     44: #ifdef HAVE_STRING_H
                     45: #include <string.h>
                     46: #endif /* HAVE_STRING_H */
                     47: #ifdef HAVE_STRINGS_H
                     48: #include <strings.h>
                     49: #endif /* HAVE_STRINGS_H */
                     50: #include <sys/types.h>
                     51: #include <sys/param.h>
                     52:
                     53: #include "sudo.h"
                     54:
                     55: #ifndef lint
                     56: static const char rcsid[] = "$Sudo: defaults.c,v 1.12 1999/11/05 22:11:55 millert Exp $";
                     57: #endif /* lint */
                     58:
                     59: /*
                     60:  * For converting between syslog numbers and strings.
                     61:  */
                     62: struct strmap {
                     63:     char *name;
                     64:     int num;
                     65: };
                     66:
                     67: #ifdef LOG_NFACILITIES
                     68: static struct strmap facilities[] = {
                     69: #ifdef LOG_AUTHPRIV
                     70:        { "authpriv",   LOG_AUTHPRIV },
                     71: #endif
                     72:        { "auth",       LOG_AUTH },
                     73:        { "daemon",     LOG_DAEMON },
                     74:        { "user",       LOG_USER },
                     75:        { "local0",     LOG_LOCAL0 },
                     76:        { "local1",     LOG_LOCAL1 },
                     77:        { "local2",     LOG_LOCAL2 },
                     78:        { "local3",     LOG_LOCAL3 },
                     79:        { "local4",     LOG_LOCAL4 },
                     80:        { "local5",     LOG_LOCAL5 },
                     81:        { "local6",     LOG_LOCAL6 },
                     82:        { "local7",     LOG_LOCAL7 },
                     83:        { NULL,         -1 }
                     84: };
                     85: #endif /* LOG_NFACILITIES */
                     86:
                     87: static struct strmap priorities[] = {
                     88:        { "alert",      LOG_ALERT },
                     89:        { "crit",       LOG_CRIT },
                     90:        { "debug",      LOG_DEBUG },
                     91:        { "emerg",      LOG_EMERG },
                     92:        { "err",        LOG_ERR },
                     93:        { "info",       LOG_INFO },
                     94:        { "notice",     LOG_NOTICE },
                     95:        { "warning",    LOG_WARNING },
                     96:        { NULL,         -1 }
                     97: };
                     98:
                     99: extern int sudolineno;
                    100:
                    101: /*
                    102:  * Local prototypes.
                    103:  */
                    104: static int store_int __P((char *, struct sudo_defs_types *, int));
                    105: static int store_str __P((char *, struct sudo_defs_types *, int));
                    106: static int store_syslogfac __P((char *, struct sudo_defs_types *, int));
                    107: static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
                    108: static int store_mode __P((char *, struct sudo_defs_types *, int));
                    109:
                    110: /*
                    111:  * Table describing compile-time and run-time options.
                    112:  */
                    113: struct sudo_defs_types sudo_defs_table[] = {
                    114:     {
                    115:        "syslog_ifac", T_INT, { 0 },
                    116:        NULL
                    117:     }, {
                    118:        "syslog_igoodpri", T_INT, { 0 },
                    119:        NULL
                    120:     }, {
                    121:        "syslog_ibadpri", T_INT, { 0 },
                    122:        NULL
                    123:     }, {
                    124:        "syslog", T_LOGFAC|T_BOOL, { 0 },
                    125:        "Syslog facility if syslog is being used for logging: %s"
                    126:     }, {
                    127:        "syslog_goodpri", T_LOGPRI, { 0 },
                    128:        "Syslog priority to use when user authenticates successfully: %s"
                    129:     }, {
                    130:        "syslog_badpri", T_LOGPRI, { 0 },
                    131:        "Syslog priority to use when user authenticates unsuccessfully: %s"
                    132:     }, {
                    133:        "long_otp_prompt", T_FLAG, { 0 },
                    134:        "Put OTP prompt on its own line"
                    135:     }, {
                    136:        "ignore_dot", T_FLAG, { 0 },
                    137:        "Ignore '.' in $PATH"
                    138:     }, {
                    139:        "mail_always", T_FLAG, { 0 },
                    140:        "Always send mail when sudo is run"
                    141:     }, {
                    142:        "mail_no_user", T_FLAG, { 0 },
                    143:        "Send mail if the user is not in sudoers"
                    144:     }, {
                    145:        "mail_no_host", T_FLAG, { 0 },
                    146:        "Send mail if the user is not in sudoers for this host"
                    147:     }, {
                    148:        "mail_no_perms", T_FLAG, { 0 },
                    149:        "Send mail if the user is not allowed to run a command"
                    150:     }, {
                    151:        "tty_tickets", T_FLAG, { 0 },
                    152:        "Use a separate timestamp for each user/tty combo"
                    153:     }, {
                    154:        "lecture", T_FLAG, { 0 },
                    155:        "Lecture user the first time they run sudo"
                    156:     }, {
                    157:        "authenticate", T_FLAG, { 0 },
                    158:        "Require users to authenticate by default"
                    159:     }, {
                    160:        "root_sudo", T_FLAG, { 0 },
                    161:        "Root may run sudo"
                    162:     }, {
                    163:        "log_host", T_FLAG, { 0 },
                    164:        "Log the hostname in the (non-syslog) log file"
                    165:     }, {
                    166:        "log_year", T_FLAG, { 0 },
                    167:        "Log the year in the (non-syslog) log file"
                    168:     }, {
                    169:        "shell_noargs", T_FLAG, { 0 },
                    170:        "If sudo is invoked with no arguments, start a shell"
                    171:     }, {
                    172:        "set_home", T_FLAG, { 0 },
                    173:        "Set $HOME to the target user when starting a shell with -s"
                    174:     }, {
                    175:        "path_info", T_FLAG, { 0 },
                    176:        "Allow some information gathering to give useful error messages"
                    177:     }, {
                    178:        "fqdn", T_FLAG, { 0 },
                    179:        "Require fully-qualified hsotnames in the sudoers file"
                    180:     }, {
                    181:        "insults", T_FLAG, { 0 },
                    182:        "Insult the user when they enter an incorrect password"
                    183:     }, {
                    184:        "requiretty", T_FLAG, { 0 },
                    185:        "Only allow the user to run sudo if they have a tty"
                    186:     }, {
                    187:        "loglinelen", T_INT|T_BOOL, { 0 },
                    188:        "Length at which to wrap log file lines (0 for no wrap): %d"
                    189:     }, {
                    190:        "timestamp_timeout", T_INT|T_BOOL, { 0 },
                    191:        "Authentication timestamp timeout: %d minutes"
                    192:     }, {
                    193:        "passwd_timeout", T_INT|T_BOOL, { 0 },
                    194:        "Password prompt timeout: %d minutes"
                    195:     }, {
                    196:        "passwd_tries", T_INT, { 0 },
                    197:        "Number of tries to enter a password: %d"
                    198:     }, {
                    199:        "umask", T_MODE|T_BOOL, { 0 },
                    200:        "Umask to use or 0777 to use user's: 0%o"
                    201:     }, {
                    202:        "logfile", T_STR|T_BOOL|T_PATH, { 0 },
                    203:        "Path to log file: %s"
                    204:     }, {
                    205:        "mailerpath", T_STR|T_BOOL|T_PATH, { 0 },
                    206:        "Path to mail program: %s"
                    207:     }, {
                    208:        "mailerflags", T_STR|T_BOOL, { 0 },
                    209:        "Flags for mail program: %s"
                    210:     }, {
                    211:        "mailto", T_STR|T_BOOL, { 0 },
                    212:        "Address to send mail to: %s"
                    213:     }, {
                    214:        "mailsub", T_STR, { 0 },
                    215:        "Subject line for mail messages: %s"
                    216:     }, {
                    217:        "badpass_message", T_STR, { 0 },
                    218:        "Incorrect password message: %s"
                    219:     }, {
                    220:        "timestampdir", T_STR|T_PATH, { 0 },
                    221:        "Path to authentication timestamp dir: %s"
                    222:     }, {
                    223:        "exempt_group", T_STR|T_BOOL, { 0 },
                    224:        "Users in this group are exempt from password and PATH requirements: %s"
                    225:     }, {
                    226:        "passprompt", T_STR, { 0 },
                    227:        "Default password prompt: %s"
                    228:     }, {
                    229:        "runas_default", T_STR, { 0 },
                    230:        "Default user to run commands as: %s"
                    231:     }, {
                    232:        "secure_path", T_STR|T_BOOL, { 0 },
                    233:        "Value to override user's $PATH with: %s"
                    234:     }, {
                    235:        NULL, 0, { 0 }, NULL
                    236:     }
                    237: };
                    238:
                    239: /*
                    240:  * Print version and configure info.
                    241:  */
                    242: void
                    243: dump_defaults()
                    244: {
                    245:     struct sudo_defs_types *cur;
                    246:
                    247:     for (cur = sudo_defs_table; cur->name; cur++) {
                    248:        if (cur->desc) {
                    249:            switch (cur->type & T_MASK) {
                    250:                case T_FLAG:
                    251:                    if (cur->sd_un.flag)
                    252:                        puts(cur->desc);
                    253:                    break;
                    254:                case T_STR:
                    255:                case T_LOGFAC:
                    256:                case T_LOGPRI:
                    257:                    if (cur->sd_un.str) {
                    258:                        (void) printf(cur->desc, cur->sd_un.str);
                    259:                        putchar('\n');
                    260:                    }
                    261:                    break;
                    262:                case T_INT:
                    263:                    (void) printf(cur->desc, cur->sd_un.ival);
                    264:                    putchar('\n');
                    265:                    break;
                    266:                case T_MODE:
                    267:                    (void) printf(cur->desc, cur->sd_un.mode);
                    268:                    putchar('\n');
                    269:                    break;
                    270:            }
                    271:        }
                    272:     }
                    273:
                    274: #ifdef ENV_EDITOR
                    275:     (void) printf("Default editor for visudo: %s\n", EDITOR);
                    276: #else
                    277:     (void) printf("Editor for visudo: %s\n", EDITOR);
                    278: #endif
                    279: }
                    280:
                    281: /*
                    282:  * List each option along with its description.
                    283:  */
                    284: void
                    285: list_options()
                    286: {
                    287:     struct sudo_defs_types *cur;
                    288:     char *p;
                    289:
                    290:     (void) puts("Available options in a sudoers ``Defaults'' line:\n");
                    291:     for (cur = sudo_defs_table; cur->name; cur++) {
                    292:        if (cur->name && cur->desc) {
                    293:            switch (cur->type & T_MASK) {
                    294:                case T_FLAG:
                    295:                    (void) printf("%s: %s\n", cur->name, cur->desc);
                    296:                    break;
                    297:                default:
                    298:                    p = strrchr(cur->desc, ':');
                    299:                    if (p)
                    300:                        (void) printf("%s: %.*s\n", cur->name, p - cur->desc,
                    301:                            cur->desc);
                    302:                    else
                    303:                        (void) printf("%s: %s\n", cur->name, cur->desc);
                    304:                    break;
                    305:            }
                    306:        }
                    307:     }
                    308: }
                    309:
                    310: /*
                    311:  * Sets/clears an entry in the defaults structure
                    312:  * If a variable that takes a value is used in a boolean
                    313:  * context with op == 0, disable that variable.
                    314:  * Eg. you may want to turn off logging to a file for some hosts.
                    315:  * This is only meaningful for variables that are *optional*.
                    316:  */
                    317: int
                    318: set_default(var, val, op)
                    319:     char *var;
                    320:     char *val;
                    321:     int op;     /* TRUE or FALSE */
                    322: {
                    323:     struct sudo_defs_types *cur;
                    324:
                    325:     for (cur = sudo_defs_table; cur->name; cur++) {
                    326:        if (strcmp(var, cur->name) == 0)
                    327:            break;
                    328:     }
                    329:     if (!cur->name) {
                    330:        (void) fprintf(stderr,
                    331:            "%s: unknown defaults entry `%s' referenced near line %d\n", Argv[0],
                    332:            var, sudolineno);
                    333:        return(FALSE);
                    334:     }
                    335:
                    336:     switch (cur->type & T_MASK) {
                    337:        case T_LOGFAC:
                    338:            if (!store_syslogfac(val, cur, op)) {
                    339:                if (val)
                    340:                    (void) fprintf(stderr,
                    341:                        "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    342:                        val, var);
                    343:                else
                    344:                    (void) fprintf(stderr,
                    345:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    346:                        var, sudolineno);
                    347:                return(FALSE);
                    348:            }
                    349:            break;
                    350:        case T_LOGPRI:
                    351:            if (!store_syslogpri(val, cur, op)) {
                    352:                if (val)
                    353:                    (void) fprintf(stderr,
                    354:                        "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    355:                        val, var);
                    356:                else
                    357:                    (void) fprintf(stderr,
                    358:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    359:                        var, sudolineno);
                    360:                return(FALSE);
                    361:            }
                    362:            break;
                    363:        case T_STR:
                    364:            if (!val) {
                    365:                /* Check for bogus boolean usage or lack of a value. */
                    366:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    367:                    (void) fprintf(stderr,
                    368:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    369:                        var, sudolineno);
                    370:                    return(FALSE);
                    371:                }
                    372:            }
                    373:            if ((cur->type & T_PATH) && *val != '/') {
                    374:                (void) fprintf(stderr,
                    375:                    "%s: values for `%s' must start with a '/'\n", Argv[0],
                    376:                    var);
                    377:                return(FALSE);
                    378:            }
                    379:            if (!store_str(val, cur, op)) {
                    380:                (void) fprintf(stderr,
                    381:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    382:                    val, var);
                    383:                return(FALSE);
                    384:            }
                    385:            break;
                    386:        case T_INT:
                    387:            if (!val) {
                    388:                /* Check for bogus boolean usage or lack of a value. */
                    389:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    390:                    (void) fprintf(stderr,
                    391:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    392:                        var, sudolineno);
                    393:                    return(FALSE);
                    394:                }
                    395:            }
                    396:            if (!store_int(val, cur, op)) {
                    397:                (void) fprintf(stderr,
                    398:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    399:                    val, var);
                    400:                return(FALSE);
                    401:            }
                    402:            break;
                    403:        case T_MODE:
                    404:            if (!val) {
                    405:                /* Check for bogus boolean usage or lack of a value. */
                    406:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    407:                    (void) fprintf(stderr,
                    408:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    409:                        var, sudolineno);
                    410:                    return(FALSE);
                    411:                }
                    412:            }
                    413:            if (!store_mode(val, cur, op)) {
                    414:                (void) fprintf(stderr,
                    415:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    416:                    val, var);
                    417:                return(FALSE);
                    418:            }
                    419:            break;
                    420:        case T_FLAG:
                    421:            if (val) {
                    422:                (void) fprintf(stderr,
                    423:                    "%s: option `%s' does not take a value on line %d\n",
                    424:                    Argv[0], var, sudolineno);
                    425:                return(FALSE);
                    426:            }
                    427:            cur->sd_un.flag = op;
                    428:            break;
                    429:     }
                    430:
                    431:     return(TRUE);
                    432: }
                    433:
                    434: /*
                    435:  * Set default options to compiled-in values.
                    436:  * Any of these may be overridden at runtime by a "Defaults" file.
                    437:  */
                    438: void
                    439: init_defaults()
                    440: {
                    441:     static int firsttime = 1;
                    442:     struct sudo_defs_types *def;
                    443:
                    444:     /* Free any strings that were set. */
                    445:     if (!firsttime) {
                    446:        for (def = sudo_defs_table; def->name; def++)
                    447:            switch (def->type & T_MASK) {
                    448:                case T_STR:
                    449:                case T_LOGFAC:
                    450:                case T_LOGPRI:
                    451:                    if (def->sd_un.str) {
                    452:                        free(def->sd_un.str);
                    453:                        def->sd_un.str = NULL;
                    454:                    }
                    455:                    break;
                    456:            }
                    457:     }
                    458:
                    459:     /* First initialize the flags. */
                    460: #ifdef LONG_OTP_PROMPT
                    461:     def_flag(I_LONG_OTP_PROMPT) = TRUE;
                    462: #endif
                    463: #ifdef IGNORE_DOT_PATH
                    464:     def_flag(I_IGNORE_DOT) = TRUE;
                    465: #endif
                    466: #ifdef ALWAYS_SEND_MAIL
                    467:     def_flag(I_MAIL_ALWAYS) = TRUE;
                    468: #endif
                    469: #ifdef SEND_MAIL_WHEN_NO_USER
                    470:     def_flag(I_MAIL_NOUSER) = TRUE;
                    471: #endif
                    472: #ifdef SEND_MAIL_WHEN_NO_HOST
                    473:     def_flag(I_MAIL_NOHOST) = TRUE;
                    474: #endif
                    475: #ifdef SEND_MAIL_WHEN_NOT_OK
                    476:     def_flag(I_MAIL_NOPERMS) = TRUE;
                    477: #endif
                    478: #ifdef USE_TTY_TICKETS
                    479:     def_flag(I_TTY_TICKETS) = TRUE;
                    480: #endif
                    481: #ifndef NO_LECTURE
                    482:     def_flag(I_LECTURE) = TRUE;
                    483: #endif
                    484: #ifndef NO_AUTHENTICATION
                    485:     def_flag(I_AUTHENTICATE) = TRUE;
                    486: #endif
                    487: #ifndef NO_ROOT_SUDO
                    488:     def_flag(I_ROOT_SUDO) = TRUE;
                    489: #endif
                    490: #ifdef HOST_IN_LOG
                    491:     def_flag(I_LOG_HOST) = TRUE;
                    492: #endif
                    493: #ifdef SHELL_IF_NO_ARGS
                    494:     def_flag(I_SHELL_NOARGS) = TRUE;
                    495: #endif
                    496: #ifdef SHELL_SETS_HOME
                    497:     def_flag(I_SET_HOME) = TRUE;
                    498: #endif
                    499: #ifndef DONT_LEAK_PATH_INFO
                    500:     def_flag(I_PATH_INFO) = TRUE;
                    501: #endif
                    502: #ifdef FQDN
                    503:     def_flag(I_FQDN) = TRUE;
                    504: #endif
                    505: #ifdef USE_INSULTS
                    506:     def_flag(I_INSULTS) = TRUE;
                    507: #endif
                    508:
                    509:     /* Syslog options need special care since they both strings and ints */
                    510: #if (LOGGING & SLOG_SYSLOG)
                    511:     (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_LOGFACSTR], TRUE);
                    512:     (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_GOODPRISTR], TRUE);
                    513:     (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_BADPRISTR], TRUE);
                    514: #endif
                    515:
                    516:     /* Then initialize the int-like things. */
                    517: #ifdef SUDO_UMASK
                    518:     def_mode(I_UMASK) = SUDO_UMASK;
                    519: #else
                    520:     def_mode(I_UMASK) = 0777;
                    521: #endif
                    522:     def_ival(I_LOGLEN) = MAXLOGFILELEN;
                    523:     def_ival(I_TS_TIMEOUT) = TIMEOUT;
                    524:     def_ival(I_PW_TIMEOUT) = PASSWORD_TIMEOUT;
                    525:     def_ival(I_PW_TRIES) = TRIES_FOR_PASSWORD;
                    526:
                    527:     /* Finally do the strings */
                    528:     def_str(I_MAILTO) = estrdup(MAILTO);
                    529:     def_str(I_MAILSUB) = estrdup(MAILSUBJECT);
                    530:     def_str(I_BADPASS_MSG) = estrdup(INCORRECT_PASSWORD);
                    531:     def_str(I_TIMESTAMPDIR) = estrdup(_PATH_SUDO_TIMEDIR);
                    532:     def_str(I_PASSPROMPT) = estrdup(PASSPROMPT);
                    533:     def_str(I_RUNAS_DEF) = estrdup(RUNAS_DEFAULT);
                    534: #ifdef _PATH_SENDMAIL
                    535:     def_str(I_MAILERPATH) = estrdup(_PATH_SENDMAIL);
                    536:     def_str(I_MAILERFLAGS) = estrdup("-t");
                    537: #endif
                    538: #if (LOGGING & SLOG_FILE)
                    539:     def_str(I_LOGFILE) = estrdup(_PATH_SUDO_LOGFILE);
                    540: #endif
                    541: #ifdef EXEMPTGROUP
                    542:     def_str(I_EXEMPT_GRP) = estrdup(EXEMPTGROUP);
                    543: #endif
                    544: #ifdef SECURE_PATH
                    545:     def_str(I_SECURE_PATH) = estrdup(SECURE_PATH);
                    546: #endif
                    547:
                    548:     /*
                    549:      * The following depend on the above values.
                    550:      * We use a pointer to the string so that if its
                    551:      * value changes we get the change.
                    552:      */
                    553:     if (user_runas == NULL)
                    554:        user_runas = &def_str(I_RUNAS_DEF);
                    555:
                    556:     firsttime = 0;
                    557: }
                    558:
                    559: static int
                    560: store_int(val, def, op)
                    561:     char *val;
                    562:     struct sudo_defs_types *def;
                    563:     int op;
                    564: {
                    565:     char *endp;
                    566:     long l;
                    567:
                    568:     if (op == FALSE) {
                    569:        def->sd_un.ival = 0;
                    570:     } else {
                    571:        l = strtol(val, &endp, 10);
                    572:        if (*endp != '\0' || l < 0)
                    573:            return(FALSE);
                    574:        /* XXX - should check against INT_MAX */
                    575:        def->sd_un.ival = (unsigned int)l;
                    576:     }
                    577:     return(TRUE);
                    578: }
                    579:
                    580: static int
                    581: store_str(val, def, op)
                    582:     char *val;
                    583:     struct sudo_defs_types *def;
                    584:     int op;
                    585: {
                    586:
                    587:     if (def->sd_un.str)
                    588:        free(def->sd_un.str);
                    589:     if (op == FALSE)
                    590:        def->sd_un.str = NULL;
                    591:     else
                    592:        def->sd_un.str = estrdup(val);
                    593:     return(TRUE);
                    594: }
                    595:
                    596: static int
                    597: store_syslogfac(val, def, op)
                    598:     char *val;
                    599:     struct sudo_defs_types *def;
                    600:     int op;
                    601: {
                    602:     struct strmap *fac;
                    603:
                    604:     if (op == FALSE) {
                    605:        free(def->sd_un.str);
                    606:        def->sd_un.str = NULL;
                    607:        return(TRUE);
                    608:     }
                    609: #ifdef LOG_NFACILITIES
                    610:     if (!val)
                    611:        return(FALSE);
                    612:     for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
                    613:        ;
                    614:     if (fac->name == NULL)
                    615:        return(FALSE);                          /* not found */
                    616:
                    617:     /* Store both name and number. */
                    618:     if (def->sd_un.str)
                    619:        free(def->sd_un.str);
                    620:     def->sd_un.str = estrdup(fac->name);
                    621:     sudo_defs_table[I_LOGFAC].sd_un.ival = fac->num;
                    622: #else
                    623:     if (def->sd_un.str)
                    624:        free(def->sd_un.str);
                    625:     def->sd_un.str = estrdup("default");
                    626: #endif /* LOG_NFACILITIES */
                    627:     return(TRUE);
                    628: }
                    629:
                    630: static int
                    631: store_syslogpri(val, def, op)
                    632:     char *val;
                    633:     struct sudo_defs_types *def;
                    634:     int op;
                    635: {
                    636:     struct strmap *pri;
                    637:     struct sudo_defs_types *idef;
                    638:
                    639:     if (op == FALSE || !val)
                    640:        return(FALSE);
                    641:     if (def == &sudo_defs_table[I_GOODPRISTR])
                    642:        idef = &sudo_defs_table[I_GOODPRI];
                    643:     else if (def == &sudo_defs_table[I_BADPRISTR])
                    644:        idef = &sudo_defs_table[I_BADPRI];
                    645:     else
                    646:        return(FALSE);
                    647:
                    648:     for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
                    649:        ;
                    650:     if (pri->name == NULL)
                    651:        return(FALSE);                          /* not found */
                    652:
                    653:     /* Store both name and number. */
                    654:     if (def->sd_un.str)
                    655:        free(def->sd_un.str);
                    656:     def->sd_un.str = estrdup(pri->name);
                    657:     idef->sd_un.ival = pri->num;
                    658:     return(TRUE);
                    659: }
                    660:
                    661: static int
                    662: store_mode(val, def, op)
                    663:     char *val;
                    664:     struct sudo_defs_types *def;
                    665:     int op;
                    666: {
                    667:     char *endp;
                    668:     long l;
                    669:
                    670:     if (op == FALSE) {
                    671:        def->sd_un.mode = (mode_t)0777;
                    672:     } else {
                    673:        l = strtol(val, &endp, 8);
                    674:        if (*endp != '\0' || l < 0 || l >= 0777)
                    675:            return(FALSE);
                    676:        def->sd_un.mode = (mode_t)l;
                    677:     }
                    678:     return(TRUE);
                    679: }