[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.4

1.1       millert     1: /*
1.3       millert     2:  * Copyright (c) 1999-2000 Todd C. Miller <Todd.Miller@courtesan.com>
1.1       millert     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
1.4     ! millert    56: static const char rcsid[] = "$Sudo: defaults.c,v 1.23 2000/03/22 23:40:09 millert Exp $";
1.1       millert    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));
1.3       millert   109: static int store_pwflag __P((char *, struct sudo_defs_types *, int));
1.1       millert   110:
                    111: /*
                    112:  * Table describing compile-time and run-time options.
                    113:  */
                    114: struct sudo_defs_types sudo_defs_table[] = {
                    115:     {
1.3       millert   116:        "syslog_ifac", T_INT, NULL
1.1       millert   117:     }, {
1.3       millert   118:        "syslog_igoodpri", T_INT, NULL
1.1       millert   119:     }, {
1.3       millert   120:        "syslog_ibadpri", T_INT, NULL
1.1       millert   121:     }, {
1.3       millert   122:        "syslog", T_LOGFAC|T_BOOL,
1.1       millert   123:        "Syslog facility if syslog is being used for logging: %s"
                    124:     }, {
1.3       millert   125:        "syslog_goodpri", T_LOGPRI,
1.1       millert   126:        "Syslog priority to use when user authenticates successfully: %s"
                    127:     }, {
1.3       millert   128:        "syslog_badpri", T_LOGPRI,
1.1       millert   129:        "Syslog priority to use when user authenticates unsuccessfully: %s"
                    130:     }, {
1.3       millert   131:        "long_otp_prompt", T_FLAG,
1.1       millert   132:        "Put OTP prompt on its own line"
                    133:     }, {
1.3       millert   134:        "ignore_dot", T_FLAG,
1.1       millert   135:        "Ignore '.' in $PATH"
                    136:     }, {
1.3       millert   137:        "mail_always", T_FLAG,
1.1       millert   138:        "Always send mail when sudo is run"
                    139:     }, {
1.3       millert   140:        "mail_no_user", T_FLAG,
1.1       millert   141:        "Send mail if the user is not in sudoers"
                    142:     }, {
1.3       millert   143:        "mail_no_host", T_FLAG,
1.1       millert   144:        "Send mail if the user is not in sudoers for this host"
                    145:     }, {
1.3       millert   146:        "mail_no_perms", T_FLAG,
1.1       millert   147:        "Send mail if the user is not allowed to run a command"
                    148:     }, {
1.3       millert   149:        "tty_tickets", T_FLAG,
1.1       millert   150:        "Use a separate timestamp for each user/tty combo"
                    151:     }, {
1.3       millert   152:        "lecture", T_FLAG,
1.1       millert   153:        "Lecture user the first time they run sudo"
                    154:     }, {
1.3       millert   155:        "authenticate", T_FLAG,
1.1       millert   156:        "Require users to authenticate by default"
                    157:     }, {
1.3       millert   158:        "root_sudo", T_FLAG,
1.1       millert   159:        "Root may run sudo"
                    160:     }, {
1.3       millert   161:        "log_host", T_FLAG,
1.1       millert   162:        "Log the hostname in the (non-syslog) log file"
                    163:     }, {
1.3       millert   164:        "log_year", T_FLAG,
1.1       millert   165:        "Log the year in the (non-syslog) log file"
                    166:     }, {
1.3       millert   167:        "shell_noargs", T_FLAG,
                    168:        "If sudo is invoked with no arguments, start a shell"
                    169:     }, {
                    170:        "set_home", T_FLAG,
1.1       millert   171:        "Set $HOME to the target user when starting a shell with -s"
                    172:     }, {
1.3       millert   173:        "path_info", T_FLAG,
1.1       millert   174:        "Allow some information gathering to give useful error messages"
                    175:     }, {
1.3       millert   176:        "fqdn", T_FLAG,
1.1       millert   177:        "Require fully-qualified hsotnames in the sudoers file"
                    178:     }, {
1.3       millert   179:        "insults", T_FLAG,
1.1       millert   180:        "Insult the user when they enter an incorrect password"
                    181:     }, {
1.3       millert   182:        "requiretty", T_FLAG,
1.1       millert   183:        "Only allow the user to run sudo if they have a tty"
                    184:     }, {
1.4     ! millert   185:        "env_editor", T_FLAG,
        !           186:        "Visudo will honor the EDITOR environment variable"
        !           187:     }, {
        !           188:        "rootpw", T_FLAG,
        !           189:        "Prompt for root's password, not the users's"
        !           190:     }, {
        !           191:        "runaspw", T_FLAG,
        !           192:        "Prompt for the runas_default user's password, not the users's"
        !           193:     }, {
        !           194:        "targetpw", T_FLAG,
        !           195:        "Prompt for the target user's password, not the users's"
        !           196:     }, {
        !           197:        "use_loginclass", T_FLAG,
        !           198:        "Apply defaults in the target user's login class if there is one"
        !           199:     }, {
        !           200:        "set_logname", T_FLAG,
        !           201:        "Set the LOGNAME and USER environment variables"
        !           202:     }, {
1.3       millert   203:        "loglinelen", T_INT|T_BOOL,
1.1       millert   204:        "Length at which to wrap log file lines (0 for no wrap): %d"
                    205:     }, {
1.3       millert   206:        "timestamp_timeout", T_INT|T_BOOL,
1.1       millert   207:        "Authentication timestamp timeout: %d minutes"
                    208:     }, {
1.3       millert   209:        "passwd_timeout", T_INT|T_BOOL,
1.1       millert   210:        "Password prompt timeout: %d minutes"
                    211:     }, {
1.3       millert   212:        "passwd_tries", T_INT,
1.1       millert   213:        "Number of tries to enter a password: %d"
                    214:     }, {
1.3       millert   215:        "umask", T_MODE|T_BOOL,
1.1       millert   216:        "Umask to use or 0777 to use user's: 0%o"
                    217:     }, {
1.3       millert   218:        "logfile", T_STR|T_BOOL|T_PATH,
1.1       millert   219:        "Path to log file: %s"
                    220:     }, {
1.3       millert   221:        "mailerpath", T_STR|T_BOOL|T_PATH,
1.1       millert   222:        "Path to mail program: %s"
                    223:     }, {
1.3       millert   224:        "mailerflags", T_STR|T_BOOL,
1.1       millert   225:        "Flags for mail program: %s"
                    226:     }, {
1.3       millert   227:        "mailto", T_STR|T_BOOL,
1.1       millert   228:        "Address to send mail to: %s"
                    229:     }, {
1.3       millert   230:        "mailsub", T_STR,
1.1       millert   231:        "Subject line for mail messages: %s"
                    232:     }, {
1.3       millert   233:        "badpass_message", T_STR,
1.1       millert   234:        "Incorrect password message: %s"
                    235:     }, {
1.3       millert   236:        "timestampdir", T_STR|T_PATH,
1.1       millert   237:        "Path to authentication timestamp dir: %s"
                    238:     }, {
1.3       millert   239:        "exempt_group", T_STR|T_BOOL,
1.1       millert   240:        "Users in this group are exempt from password and PATH requirements: %s"
                    241:     }, {
1.3       millert   242:        "passprompt", T_STR,
1.1       millert   243:        "Default password prompt: %s"
                    244:     }, {
1.3       millert   245:        "runas_default", T_STR,
1.1       millert   246:        "Default user to run commands as: %s"
                    247:     }, {
1.3       millert   248:        "secure_path", T_STR|T_BOOL,
1.1       millert   249:        "Value to override user's $PATH with: %s"
                    250:     }, {
1.4     ! millert   251:        "editor", T_STR|T_PATH,
        !           252:        "Path to the editor for use by visudo: %s"
        !           253:     }, {
1.3       millert   254:        "listpw_i", T_INT, NULL
                    255:     }, {
                    256:        "verifypw_i", T_INT, NULL
                    257:     }, {
                    258:        "listpw", T_PWFLAG,
                    259:        "When to require a password for 'list' pseudocommand: %s"
                    260:     }, {
                    261:        "verifypw", T_PWFLAG,
                    262:        "When to require a password for 'verify' pseudocommand: %s"
                    263:     }, {
                    264:        NULL, 0, NULL
1.1       millert   265:     }
                    266: };
                    267:
                    268: /*
                    269:  * Print version and configure info.
                    270:  */
                    271: void
                    272: dump_defaults()
                    273: {
                    274:     struct sudo_defs_types *cur;
                    275:
                    276:     for (cur = sudo_defs_table; cur->name; cur++) {
                    277:        if (cur->desc) {
                    278:            switch (cur->type & T_MASK) {
                    279:                case T_FLAG:
                    280:                    if (cur->sd_un.flag)
                    281:                        puts(cur->desc);
                    282:                    break;
                    283:                case T_STR:
                    284:                case T_LOGFAC:
                    285:                case T_LOGPRI:
1.3       millert   286:                case T_PWFLAG:
1.1       millert   287:                    if (cur->sd_un.str) {
                    288:                        (void) printf(cur->desc, cur->sd_un.str);
                    289:                        putchar('\n');
                    290:                    }
                    291:                    break;
                    292:                case T_INT:
                    293:                    (void) printf(cur->desc, cur->sd_un.ival);
                    294:                    putchar('\n');
                    295:                    break;
                    296:                case T_MODE:
                    297:                    (void) printf(cur->desc, cur->sd_un.mode);
                    298:                    putchar('\n');
                    299:                    break;
                    300:            }
                    301:        }
                    302:     }
                    303: }
                    304:
                    305: /*
                    306:  * List each option along with its description.
                    307:  */
                    308: void
                    309: list_options()
                    310: {
                    311:     struct sudo_defs_types *cur;
                    312:     char *p;
                    313:
                    314:     (void) puts("Available options in a sudoers ``Defaults'' line:\n");
                    315:     for (cur = sudo_defs_table; cur->name; cur++) {
                    316:        if (cur->name && cur->desc) {
                    317:            switch (cur->type & T_MASK) {
                    318:                case T_FLAG:
                    319:                    (void) printf("%s: %s\n", cur->name, cur->desc);
                    320:                    break;
                    321:                default:
                    322:                    p = strrchr(cur->desc, ':');
                    323:                    if (p)
                    324:                        (void) printf("%s: %.*s\n", cur->name, p - cur->desc,
                    325:                            cur->desc);
                    326:                    else
                    327:                        (void) printf("%s: %s\n", cur->name, cur->desc);
                    328:                    break;
                    329:            }
                    330:        }
                    331:     }
                    332: }
                    333:
                    334: /*
                    335:  * Sets/clears an entry in the defaults structure
                    336:  * If a variable that takes a value is used in a boolean
                    337:  * context with op == 0, disable that variable.
                    338:  * Eg. you may want to turn off logging to a file for some hosts.
                    339:  * This is only meaningful for variables that are *optional*.
                    340:  */
                    341: int
                    342: set_default(var, val, op)
                    343:     char *var;
                    344:     char *val;
                    345:     int op;     /* TRUE or FALSE */
                    346: {
                    347:     struct sudo_defs_types *cur;
1.2       millert   348:     int num;
1.1       millert   349:
1.2       millert   350:     for (cur = sudo_defs_table, num = 0; cur->name; cur++, num++) {
1.1       millert   351:        if (strcmp(var, cur->name) == 0)
                    352:            break;
                    353:     }
                    354:     if (!cur->name) {
                    355:        (void) fprintf(stderr,
                    356:            "%s: unknown defaults entry `%s' referenced near line %d\n", Argv[0],
                    357:            var, sudolineno);
                    358:        return(FALSE);
                    359:     }
                    360:
                    361:     switch (cur->type & T_MASK) {
                    362:        case T_LOGFAC:
                    363:            if (!store_syslogfac(val, cur, op)) {
                    364:                if (val)
                    365:                    (void) fprintf(stderr,
                    366:                        "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    367:                        val, var);
                    368:                else
                    369:                    (void) fprintf(stderr,
                    370:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    371:                        var, sudolineno);
                    372:                return(FALSE);
                    373:            }
                    374:            break;
                    375:        case T_LOGPRI:
                    376:            if (!store_syslogpri(val, cur, op)) {
                    377:                if (val)
                    378:                    (void) fprintf(stderr,
                    379:                        "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    380:                        val, var);
                    381:                else
                    382:                    (void) fprintf(stderr,
                    383:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    384:                        var, sudolineno);
                    385:                return(FALSE);
                    386:            }
                    387:            break;
1.3       millert   388:        case T_PWFLAG:
                    389:            if (!store_pwflag(val, cur, op)) {
                    390:                if (val)
                    391:                    (void) fprintf(stderr,
                    392:                        "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    393:                        val, var);
                    394:                else
                    395:                    (void) fprintf(stderr,
                    396:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    397:                        var, sudolineno);
                    398:                return(FALSE);
                    399:            }
                    400:            break;
1.1       millert   401:        case T_STR:
                    402:            if (!val) {
                    403:                /* Check for bogus boolean usage or lack of a value. */
                    404:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    405:                    (void) fprintf(stderr,
                    406:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    407:                        var, sudolineno);
                    408:                    return(FALSE);
                    409:                }
                    410:            }
                    411:            if ((cur->type & T_PATH) && *val != '/') {
                    412:                (void) fprintf(stderr,
                    413:                    "%s: values for `%s' must start with a '/'\n", Argv[0],
                    414:                    var);
                    415:                return(FALSE);
                    416:            }
                    417:            if (!store_str(val, cur, op)) {
                    418:                (void) fprintf(stderr,
                    419:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    420:                    val, var);
                    421:                return(FALSE);
                    422:            }
                    423:            break;
                    424:        case T_INT:
                    425:            if (!val) {
                    426:                /* Check for bogus boolean usage or lack of a value. */
                    427:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    428:                    (void) fprintf(stderr,
                    429:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    430:                        var, sudolineno);
                    431:                    return(FALSE);
                    432:                }
                    433:            }
                    434:            if (!store_int(val, cur, op)) {
                    435:                (void) fprintf(stderr,
                    436:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    437:                    val, var);
                    438:                return(FALSE);
                    439:            }
                    440:            break;
                    441:        case T_MODE:
                    442:            if (!val) {
                    443:                /* Check for bogus boolean usage or lack of a value. */
                    444:                if (!(cur->type & T_BOOL) || op != FALSE) {
                    445:                    (void) fprintf(stderr,
                    446:                        "%s: no value specified for `%s' on line %d\n", Argv[0],
                    447:                        var, sudolineno);
                    448:                    return(FALSE);
                    449:                }
                    450:            }
                    451:            if (!store_mode(val, cur, op)) {
                    452:                (void) fprintf(stderr,
                    453:                    "%s: value '%s' is invalid for option '%s'\n", Argv[0],
                    454:                    val, var);
                    455:                return(FALSE);
                    456:            }
                    457:            break;
                    458:        case T_FLAG:
                    459:            if (val) {
                    460:                (void) fprintf(stderr,
                    461:                    "%s: option `%s' does not take a value on line %d\n",
                    462:                    Argv[0], var, sudolineno);
                    463:                return(FALSE);
                    464:            }
                    465:            cur->sd_un.flag = op;
1.2       millert   466:
                    467:            /* Special action for I_FQDN.  Move to own switch if we get more */
                    468:            if (num == I_FQDN && op)
                    469:                set_fqdn();
1.1       millert   470:            break;
                    471:     }
                    472:
                    473:     return(TRUE);
                    474: }
                    475:
                    476: /*
                    477:  * Set default options to compiled-in values.
                    478:  * Any of these may be overridden at runtime by a "Defaults" file.
                    479:  */
                    480: void
                    481: init_defaults()
                    482: {
                    483:     static int firsttime = 1;
                    484:     struct sudo_defs_types *def;
                    485:
                    486:     /* Free any strings that were set. */
                    487:     if (!firsttime) {
                    488:        for (def = sudo_defs_table; def->name; def++)
                    489:            switch (def->type & T_MASK) {
                    490:                case T_STR:
                    491:                case T_LOGFAC:
                    492:                case T_LOGPRI:
1.3       millert   493:                case T_PWFLAG:
1.1       millert   494:                    if (def->sd_un.str) {
                    495:                        free(def->sd_un.str);
                    496:                        def->sd_un.str = NULL;
                    497:                    }
                    498:                    break;
                    499:            }
                    500:     }
                    501:
                    502:     /* First initialize the flags. */
                    503: #ifdef LONG_OTP_PROMPT
                    504:     def_flag(I_LONG_OTP_PROMPT) = TRUE;
                    505: #endif
                    506: #ifdef IGNORE_DOT_PATH
                    507:     def_flag(I_IGNORE_DOT) = TRUE;
                    508: #endif
                    509: #ifdef ALWAYS_SEND_MAIL
                    510:     def_flag(I_MAIL_ALWAYS) = TRUE;
                    511: #endif
                    512: #ifdef SEND_MAIL_WHEN_NO_USER
                    513:     def_flag(I_MAIL_NOUSER) = TRUE;
                    514: #endif
                    515: #ifdef SEND_MAIL_WHEN_NO_HOST
                    516:     def_flag(I_MAIL_NOHOST) = TRUE;
                    517: #endif
                    518: #ifdef SEND_MAIL_WHEN_NOT_OK
                    519:     def_flag(I_MAIL_NOPERMS) = TRUE;
                    520: #endif
                    521: #ifdef USE_TTY_TICKETS
                    522:     def_flag(I_TTY_TICKETS) = TRUE;
                    523: #endif
                    524: #ifndef NO_LECTURE
                    525:     def_flag(I_LECTURE) = TRUE;
                    526: #endif
                    527: #ifndef NO_AUTHENTICATION
                    528:     def_flag(I_AUTHENTICATE) = TRUE;
                    529: #endif
                    530: #ifndef NO_ROOT_SUDO
                    531:     def_flag(I_ROOT_SUDO) = TRUE;
                    532: #endif
                    533: #ifdef HOST_IN_LOG
                    534:     def_flag(I_LOG_HOST) = TRUE;
                    535: #endif
1.3       millert   536: #ifdef SHELL_IF_NO_ARGS
                    537:     def_flag(I_SHELL_NOARGS) = TRUE;
                    538: #endif
1.1       millert   539: #ifdef SHELL_SETS_HOME
                    540:     def_flag(I_SET_HOME) = TRUE;
                    541: #endif
                    542: #ifndef DONT_LEAK_PATH_INFO
                    543:     def_flag(I_PATH_INFO) = TRUE;
                    544: #endif
                    545: #ifdef FQDN
                    546:     def_flag(I_FQDN) = TRUE;
                    547: #endif
                    548: #ifdef USE_INSULTS
                    549:     def_flag(I_INSULTS) = TRUE;
                    550: #endif
1.4     ! millert   551: #ifdef ENV_EDITOR
        !           552:     def_flag(I_ENV_EDITOR) = TRUE;
        !           553: #endif
        !           554:     def_flag(I_LOGNAME) = TRUE;
1.1       millert   555:
                    556:     /* Syslog options need special care since they both strings and ints */
                    557: #if (LOGGING & SLOG_SYSLOG)
                    558:     (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_LOGFACSTR], TRUE);
                    559:     (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_GOODPRISTR], TRUE);
                    560:     (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_BADPRISTR], TRUE);
                    561: #endif
                    562:
1.3       millert   563:     /* Password flags also have a string and integer component. */
                    564:     (void) store_pwflag("any", &sudo_defs_table[I_LISTPWSTR], TRUE);
                    565:     (void) store_pwflag("all", &sudo_defs_table[I_VERIFYPWSTR], TRUE);
                    566:
1.1       millert   567:     /* Then initialize the int-like things. */
                    568: #ifdef SUDO_UMASK
                    569:     def_mode(I_UMASK) = SUDO_UMASK;
                    570: #else
                    571:     def_mode(I_UMASK) = 0777;
                    572: #endif
                    573:     def_ival(I_LOGLEN) = MAXLOGFILELEN;
                    574:     def_ival(I_TS_TIMEOUT) = TIMEOUT;
                    575:     def_ival(I_PW_TIMEOUT) = PASSWORD_TIMEOUT;
                    576:     def_ival(I_PW_TRIES) = TRIES_FOR_PASSWORD;
                    577:
                    578:     /* Finally do the strings */
                    579:     def_str(I_MAILTO) = estrdup(MAILTO);
                    580:     def_str(I_MAILSUB) = estrdup(MAILSUBJECT);
                    581:     def_str(I_BADPASS_MSG) = estrdup(INCORRECT_PASSWORD);
                    582:     def_str(I_TIMESTAMPDIR) = estrdup(_PATH_SUDO_TIMEDIR);
                    583:     def_str(I_PASSPROMPT) = estrdup(PASSPROMPT);
                    584:     def_str(I_RUNAS_DEF) = estrdup(RUNAS_DEFAULT);
                    585: #ifdef _PATH_SENDMAIL
                    586:     def_str(I_MAILERPATH) = estrdup(_PATH_SENDMAIL);
                    587:     def_str(I_MAILERFLAGS) = estrdup("-t");
                    588: #endif
                    589: #if (LOGGING & SLOG_FILE)
                    590:     def_str(I_LOGFILE) = estrdup(_PATH_SUDO_LOGFILE);
                    591: #endif
                    592: #ifdef EXEMPTGROUP
                    593:     def_str(I_EXEMPT_GRP) = estrdup(EXEMPTGROUP);
                    594: #endif
                    595: #ifdef SECURE_PATH
                    596:     def_str(I_SECURE_PATH) = estrdup(SECURE_PATH);
                    597: #endif
1.4     ! millert   598:     def_str(I_EDITOR) = estrdup(EDITOR);
1.1       millert   599:
                    600:     /*
                    601:      * The following depend on the above values.
                    602:      * We use a pointer to the string so that if its
                    603:      * value changes we get the change.
                    604:      */
                    605:     if (user_runas == NULL)
                    606:        user_runas = &def_str(I_RUNAS_DEF);
                    607:
                    608:     firsttime = 0;
                    609: }
                    610:
                    611: static int
                    612: store_int(val, def, op)
                    613:     char *val;
                    614:     struct sudo_defs_types *def;
                    615:     int op;
                    616: {
                    617:     char *endp;
                    618:     long l;
                    619:
                    620:     if (op == FALSE) {
                    621:        def->sd_un.ival = 0;
                    622:     } else {
                    623:        l = strtol(val, &endp, 10);
                    624:        if (*endp != '\0' || l < 0)
                    625:            return(FALSE);
                    626:        /* XXX - should check against INT_MAX */
                    627:        def->sd_un.ival = (unsigned int)l;
                    628:     }
                    629:     return(TRUE);
                    630: }
                    631:
                    632: static int
                    633: store_str(val, def, op)
                    634:     char *val;
                    635:     struct sudo_defs_types *def;
                    636:     int op;
                    637: {
                    638:
                    639:     if (def->sd_un.str)
                    640:        free(def->sd_un.str);
                    641:     if (op == FALSE)
                    642:        def->sd_un.str = NULL;
                    643:     else
                    644:        def->sd_un.str = estrdup(val);
                    645:     return(TRUE);
                    646: }
                    647:
                    648: static int
                    649: store_syslogfac(val, def, op)
                    650:     char *val;
                    651:     struct sudo_defs_types *def;
                    652:     int op;
                    653: {
                    654:     struct strmap *fac;
                    655:
                    656:     if (op == FALSE) {
1.3       millert   657:        if (def->sd_un.str) {
                    658:            free(def->sd_un.str);
                    659:            def->sd_un.str = NULL;
                    660:        }
1.1       millert   661:        return(TRUE);
                    662:     }
                    663: #ifdef LOG_NFACILITIES
                    664:     if (!val)
                    665:        return(FALSE);
                    666:     for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
                    667:        ;
                    668:     if (fac->name == NULL)
                    669:        return(FALSE);                          /* not found */
                    670:
                    671:     /* Store both name and number. */
1.2       millert   672:     if (def->sd_un.str) {
1.1       millert   673:        free(def->sd_un.str);
1.2       millert   674:        closelog();
                    675:     }
1.4     ! millert   676:     openlog(Argv[0], 0, fac->num);
1.1       millert   677:     def->sd_un.str = estrdup(fac->name);
                    678:     sudo_defs_table[I_LOGFAC].sd_un.ival = fac->num;
                    679: #else
1.2       millert   680:     if (def->sd_un.str) {
1.1       millert   681:        free(def->sd_un.str);
1.2       millert   682:        closelog();
                    683:     }
1.4     ! millert   684:     openlog(Argv[0], 0);
1.1       millert   685:     def->sd_un.str = estrdup("default");
                    686: #endif /* LOG_NFACILITIES */
                    687:     return(TRUE);
                    688: }
                    689:
                    690: static int
                    691: store_syslogpri(val, def, op)
                    692:     char *val;
                    693:     struct sudo_defs_types *def;
                    694:     int op;
                    695: {
                    696:     struct strmap *pri;
                    697:     struct sudo_defs_types *idef;
                    698:
                    699:     if (op == FALSE || !val)
                    700:        return(FALSE);
                    701:     if (def == &sudo_defs_table[I_GOODPRISTR])
                    702:        idef = &sudo_defs_table[I_GOODPRI];
                    703:     else if (def == &sudo_defs_table[I_BADPRISTR])
                    704:        idef = &sudo_defs_table[I_BADPRI];
                    705:     else
                    706:        return(FALSE);
                    707:
                    708:     for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
                    709:        ;
                    710:     if (pri->name == NULL)
                    711:        return(FALSE);                          /* not found */
                    712:
                    713:     /* Store both name and number. */
                    714:     if (def->sd_un.str)
                    715:        free(def->sd_un.str);
                    716:     def->sd_un.str = estrdup(pri->name);
                    717:     idef->sd_un.ival = pri->num;
                    718:     return(TRUE);
                    719: }
                    720:
                    721: static int
                    722: store_mode(val, def, op)
                    723:     char *val;
                    724:     struct sudo_defs_types *def;
                    725:     int op;
                    726: {
                    727:     char *endp;
                    728:     long l;
                    729:
                    730:     if (op == FALSE) {
                    731:        def->sd_un.mode = (mode_t)0777;
                    732:     } else {
                    733:        l = strtol(val, &endp, 8);
                    734:        if (*endp != '\0' || l < 0 || l >= 0777)
                    735:            return(FALSE);
                    736:        def->sd_un.mode = (mode_t)l;
                    737:     }
1.3       millert   738:     return(TRUE);
                    739: }
                    740:
                    741: static int
                    742: store_pwflag(val, def, op)
                    743:     char *val;
                    744:     struct sudo_defs_types *def;
                    745:     int op;
                    746: {
                    747:     int isub, flags;
                    748:
                    749:     if (strcmp(def->name, "verifypw") == 0)
                    750:        isub = I_VERIFYPW;
                    751:     else
                    752:        isub = I_LISTPW;
                    753:
                    754:     /* Handle !foo. */
                    755:     if (op == FALSE) {
                    756:        if (def->sd_un.str) {
                    757:            free(def->sd_un.str);
                    758:            def->sd_un.str = NULL;
                    759:        }
                    760:        def->sd_un.str = estrdup("never");
                    761:        sudo_defs_table[isub].sd_un.ival = PWCHECK_NEVER;
                    762:        return(TRUE);
                    763:     }
                    764:     if (!val)
                    765:        return(FALSE);
                    766:
                    767:     /* Convert strings to integer values. */
                    768:     if (strcmp(val, "all") == 0)
                    769:        flags = PWCHECK_ALL;
                    770:     else if (strcmp(val, "any") == 0)
                    771:        flags = PWCHECK_ANY;
                    772:     else if (strcmp(val, "never") == 0)
                    773:        flags = PWCHECK_NEVER;
                    774:     else if (strcmp(val, "always") == 0)
                    775:        flags = PWCHECK_ALWAYS;
                    776:     else
                    777:        return(FALSE);
                    778:
                    779:     /* Store both name and number. */
                    780:     if (def->sd_un.str)
                    781:        free(def->sd_un.str);
                    782:     def->sd_un.str = estrdup(val);
                    783:     sudo_defs_table[isub].sd_un.ival = flags;
                    784:
1.1       millert   785:     return(TRUE);
                    786: }