Annotation of src/usr.bin/sudo/defaults.c, Revision 1.11
1.1 millert 1: /*
1.11 ! millert 2: * Copyright (c) 1999-2001, 2003-2004 Todd C. Miller <Todd.Miller@courtesan.com>
1.1 millert 3: *
1.11 ! millert 4: * Permission to use, copy, modify, and distribute this software for any
! 5: * purpose with or without fee is hereby granted, provided that the above
! 6: * copyright notice and this permission notice appear in all copies.
1.1 millert 7: *
1.11 ! millert 8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
! 9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
! 10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
! 11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
! 12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
! 13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
! 14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.10 millert 15: *
16: * Sponsored in part by the Defense Advanced Research Projects
17: * Agency (DARPA) and Air Force Research Laboratory, Air Force
18: * Materiel Command, USAF, under agreement number F39502-99-1-0512.
1.1 millert 19: */
20:
21: #include "config.h"
22:
1.8 millert 23: #include <sys/types.h>
24: #include <sys/param.h>
1.1 millert 25: #include <stdio.h>
26: #ifdef STDC_HEADERS
1.8 millert 27: # include <stdlib.h>
28: # include <stddef.h>
29: #else
30: # ifdef HAVE_STDLIB_H
31: # include <stdlib.h>
32: # endif
1.1 millert 33: #endif /* STDC_HEADERS */
1.8 millert 34: #ifdef HAVE_STRING_H
35: # include <string.h>
36: #else
37: # ifdef HAVE_STRINGS_H
38: # include <strings.h>
39: # endif
40: #endif /* HAVE_STRING_H */
41: # ifdef HAVE_UNISTD_H
1.1 millert 42: #include <unistd.h>
43: #endif /* HAVE_UNISTD_H */
1.11 ! millert 44: #include <pwd.h>
1.9 millert 45: #ifdef HAVE_ERR_H
46: # include <err.h>
47: #else
48: # include "emul/err.h"
49: #endif /* HAVE_ERR_H */
1.8 millert 50: #include <ctype.h>
1.1 millert 51:
52: #include "sudo.h"
53:
54: #ifndef lint
1.11 ! millert 55: static const char rcsid[] = "$Sudo: defaults.c,v 1.48 2004/06/06 23:58:10 millert Exp $";
1.1 millert 56: #endif /* lint */
57:
58: /*
59: * For converting between syslog numbers and strings.
60: */
61: struct strmap {
62: char *name;
63: int num;
64: };
65:
66: #ifdef LOG_NFACILITIES
67: static struct strmap facilities[] = {
68: #ifdef LOG_AUTHPRIV
69: { "authpriv", LOG_AUTHPRIV },
70: #endif
71: { "auth", LOG_AUTH },
72: { "daemon", LOG_DAEMON },
73: { "user", LOG_USER },
74: { "local0", LOG_LOCAL0 },
75: { "local1", LOG_LOCAL1 },
76: { "local2", LOG_LOCAL2 },
77: { "local3", LOG_LOCAL3 },
78: { "local4", LOG_LOCAL4 },
79: { "local5", LOG_LOCAL5 },
80: { "local6", LOG_LOCAL6 },
81: { "local7", LOG_LOCAL7 },
82: { NULL, -1 }
83: };
84: #endif /* LOG_NFACILITIES */
85:
86: static struct strmap priorities[] = {
87: { "alert", LOG_ALERT },
88: { "crit", LOG_CRIT },
89: { "debug", LOG_DEBUG },
90: { "emerg", LOG_EMERG },
91: { "err", LOG_ERR },
92: { "info", LOG_INFO },
93: { "notice", LOG_NOTICE },
94: { "warning", LOG_WARNING },
95: { NULL, -1 }
96: };
97:
98: extern int sudolineno;
99:
100: /*
101: * Local prototypes.
102: */
103: static int store_int __P((char *, struct sudo_defs_types *, int));
1.11 ! millert 104: static int store_list __P((char *, struct sudo_defs_types *, int));
! 105: static int store_mode __P((char *, struct sudo_defs_types *, int));
1.1 millert 106: static int store_str __P((char *, struct sudo_defs_types *, int));
107: static int store_syslogfac __P((char *, struct sudo_defs_types *, int));
108: static int store_syslogpri __P((char *, struct sudo_defs_types *, int));
1.11 ! millert 109: static int store_tuple __P((char *, struct sudo_defs_types *, int));
! 110: static int store_uint __P((char *, struct sudo_defs_types *, int));
1.8 millert 111: static void list_op __P((char *, size_t, struct sudo_defs_types *, enum list_ops));
1.11 ! millert 112: static const char *logfac2str __P((int));
! 113: static const char *logpri2str __P((int));
1.1 millert 114:
115: /*
116: * Table describing compile-time and run-time options.
117: */
1.8 millert 118: #include <def_data.c>
1.1 millert 119:
120: /*
121: * Print version and configure info.
122: */
123: void
124: dump_defaults()
125: {
126: struct sudo_defs_types *cur;
1.8 millert 127: struct list_member *item;
1.11 ! millert 128: struct def_values *def;
1.1 millert 129:
130: for (cur = sudo_defs_table; cur->name; cur++) {
131: if (cur->desc) {
132: switch (cur->type & T_MASK) {
133: case T_FLAG:
134: if (cur->sd_un.flag)
135: puts(cur->desc);
136: break;
137: case T_STR:
1.11 ! millert 138: if (cur->sd_un.str) {
! 139: (void) printf(cur->desc, cur->sd_un.str);
! 140: putchar('\n');
! 141: }
! 142: break;
1.1 millert 143: case T_LOGFAC:
1.11 ! millert 144: if (cur->sd_un.ival) {
! 145: (void) printf(cur->desc, logfac2str(cur->sd_un.ival));
! 146: putchar('\n');
! 147: }
! 148: break;
1.1 millert 149: case T_LOGPRI:
1.11 ! millert 150: if (cur->sd_un.ival) {
! 151: (void) printf(cur->desc, logpri2str(cur->sd_un.ival));
1.1 millert 152: putchar('\n');
153: }
154: break;
1.8 millert 155: case T_UINT:
1.1 millert 156: case T_INT:
157: (void) printf(cur->desc, cur->sd_un.ival);
158: putchar('\n');
159: break;
160: case T_MODE:
161: (void) printf(cur->desc, cur->sd_un.mode);
162: putchar('\n');
163: break;
1.8 millert 164: case T_LIST:
165: if (cur->sd_un.list) {
166: puts(cur->desc);
167: for (item = cur->sd_un.list; item; item = item->next)
168: printf("\t%s\n", item->value);
169: }
170: break;
1.11 ! millert 171: case T_TUPLE:
! 172: for (def = cur->values; def->sval; def++) {
! 173: if (cur->sd_un.ival == def->ival) {
! 174: (void) printf(cur->desc, def->sval);
! 175: break;
! 176: }
! 177: }
! 178: putchar('\n');
! 179: break;
1.1 millert 180: }
181: }
182: }
183: }
184:
185: /*
186: * List each option along with its description.
187: */
188: void
189: list_options()
190: {
191: struct sudo_defs_types *cur;
192: char *p;
193:
194: (void) puts("Available options in a sudoers ``Defaults'' line:\n");
195: for (cur = sudo_defs_table; cur->name; cur++) {
196: if (cur->name && cur->desc) {
197: switch (cur->type & T_MASK) {
198: case T_FLAG:
199: (void) printf("%s: %s\n", cur->name, cur->desc);
200: break;
201: default:
202: p = strrchr(cur->desc, ':');
203: if (p)
1.8 millert 204: (void) printf("%s: %.*s\n", cur->name,
205: (int) (p - cur->desc), cur->desc);
1.1 millert 206: else
207: (void) printf("%s: %s\n", cur->name, cur->desc);
208: break;
209: }
210: }
211: }
212: }
213:
214: /*
215: * Sets/clears an entry in the defaults structure
216: * If a variable that takes a value is used in a boolean
217: * context with op == 0, disable that variable.
218: * Eg. you may want to turn off logging to a file for some hosts.
219: * This is only meaningful for variables that are *optional*.
220: */
221: int
222: set_default(var, val, op)
223: char *var;
224: char *val;
225: int op; /* TRUE or FALSE */
226: {
227: struct sudo_defs_types *cur;
1.2 millert 228: int num;
1.1 millert 229:
1.2 millert 230: for (cur = sudo_defs_table, num = 0; cur->name; cur++, num++) {
1.1 millert 231: if (strcmp(var, cur->name) == 0)
232: break;
233: }
234: if (!cur->name) {
1.9 millert 235: warnx("unknown defaults entry `%s' referenced near line %d",
1.1 millert 236: var, sudolineno);
237: return(FALSE);
238: }
239:
240: switch (cur->type & T_MASK) {
241: case T_LOGFAC:
242: if (!store_syslogfac(val, cur, op)) {
243: if (val)
1.9 millert 244: warnx("value `%s' is invalid for option `%s'", val, var);
1.1 millert 245: else
1.9 millert 246: warnx("no value specified for `%s' on line %d",
1.1 millert 247: var, sudolineno);
248: return(FALSE);
249: }
250: break;
251: case T_LOGPRI:
252: if (!store_syslogpri(val, cur, op)) {
253: if (val)
1.9 millert 254: warnx("value `%s' is invalid for option `%s'", val, var);
1.1 millert 255: else
1.9 millert 256: warnx("no value specified for `%s' on line %d",
1.1 millert 257: var, sudolineno);
258: return(FALSE);
259: }
260: break;
261: case T_STR:
262: if (!val) {
263: /* Check for bogus boolean usage or lack of a value. */
1.11 ! millert 264: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
1.9 millert 265: warnx("no value specified for `%s' on line %d",
1.1 millert 266: var, sudolineno);
267: return(FALSE);
268: }
269: }
1.11 ! millert 270: if (ISSET(cur->type, T_PATH) && val && *val != '/') {
1.9 millert 271: warnx("values for `%s' must start with a '/'", var);
1.1 millert 272: return(FALSE);
273: }
274: if (!store_str(val, cur, op)) {
1.9 millert 275: warnx("value `%s' is invalid for option `%s'", val, var);
1.1 millert 276: return(FALSE);
277: }
278: break;
279: case T_INT:
280: if (!val) {
281: /* Check for bogus boolean usage or lack of a value. */
1.11 ! millert 282: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
1.9 millert 283: warnx("no value specified for `%s' on line %d",
1.1 millert 284: var, sudolineno);
285: return(FALSE);
286: }
287: }
288: if (!store_int(val, cur, op)) {
1.9 millert 289: warnx("value `%s' is invalid for option `%s'", val, var);
1.1 millert 290: return(FALSE);
291: }
292: break;
1.8 millert 293: case T_UINT:
294: if (!val) {
295: /* Check for bogus boolean usage or lack of a value. */
1.11 ! millert 296: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
1.9 millert 297: warnx("no value specified for `%s' on line %d",
1.8 millert 298: var, sudolineno);
299: return(FALSE);
300: }
301: }
302: if (!store_uint(val, cur, op)) {
1.9 millert 303: warnx("value `%s' is invalid for option `%s'", val, var);
1.8 millert 304: return(FALSE);
305: }
306: break;
1.1 millert 307: case T_MODE:
308: if (!val) {
309: /* Check for bogus boolean usage or lack of a value. */
1.11 ! millert 310: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
1.9 millert 311: warnx("no value specified for `%s' on line %d",
1.1 millert 312: var, sudolineno);
313: return(FALSE);
314: }
315: }
316: if (!store_mode(val, cur, op)) {
1.9 millert 317: warnx("value `%s' is invalid for option `%s'", val, var);
1.1 millert 318: return(FALSE);
319: }
320: break;
321: case T_FLAG:
322: if (val) {
1.9 millert 323: warnx("option `%s' does not take a value on line %d",
324: var, sudolineno);
1.1 millert 325: return(FALSE);
326: }
327: cur->sd_un.flag = op;
1.2 millert 328:
329: /* Special action for I_FQDN. Move to own switch if we get more */
330: if (num == I_FQDN && op)
331: set_fqdn();
1.1 millert 332: break;
1.8 millert 333: case T_LIST:
334: if (!val) {
335: /* Check for bogus boolean usage or lack of a value. */
1.11 ! millert 336: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
1.9 millert 337: warnx("no value specified for `%s' on line %d",
1.8 millert 338: var, sudolineno);
339: return(FALSE);
340: }
341: }
342: if (!store_list(val, cur, op)) {
1.9 millert 343: warnx("value `%s' is invalid for option `%s'", val, var);
1.8 millert 344: return(FALSE);
345: }
1.11 ! millert 346: break;
! 347: case T_TUPLE:
! 348: if (!val) {
! 349: /* Check for bogus boolean usage or lack of a value. */
! 350: if (!ISSET(cur->type, T_BOOL) || op != FALSE) {
! 351: warnx("no value specified for `%s' on line %d",
! 352: var, sudolineno);
! 353: return(FALSE);
! 354: }
! 355: }
! 356: if (!store_tuple(val, cur, op)) {
! 357: warnx("value `%s' is invalid for option `%s'", val, var);
! 358: return(FALSE);
! 359: }
! 360: break;
1.1 millert 361: }
362:
363: return(TRUE);
364: }
365:
366: /*
367: * Set default options to compiled-in values.
368: * Any of these may be overridden at runtime by a "Defaults" file.
369: */
370: void
371: init_defaults()
372: {
373: static int firsttime = 1;
374: struct sudo_defs_types *def;
375:
376: /* Free any strings that were set. */
377: if (!firsttime) {
378: for (def = sudo_defs_table; def->name; def++)
379: switch (def->type & T_MASK) {
380: case T_STR:
381: if (def->sd_un.str) {
382: free(def->sd_un.str);
383: def->sd_un.str = NULL;
384: }
385: break;
1.8 millert 386: case T_LIST:
387: list_op(NULL, 0, def, freeall);
388: break;
1.1 millert 389: }
390: }
391:
392: /* First initialize the flags. */
393: #ifdef LONG_OTP_PROMPT
1.11 ! millert 394: def_long_otp_prompt = TRUE;
1.1 millert 395: #endif
396: #ifdef IGNORE_DOT_PATH
1.11 ! millert 397: def_ignore_dot = TRUE;
1.1 millert 398: #endif
399: #ifdef ALWAYS_SEND_MAIL
1.11 ! millert 400: def_mail_always = TRUE;
1.1 millert 401: #endif
402: #ifdef SEND_MAIL_WHEN_NO_USER
1.11 ! millert 403: def_mail_no_user = TRUE;
1.1 millert 404: #endif
405: #ifdef SEND_MAIL_WHEN_NO_HOST
1.11 ! millert 406: def_mail_no_host = TRUE;
1.1 millert 407: #endif
408: #ifdef SEND_MAIL_WHEN_NOT_OK
1.11 ! millert 409: def_mail_no_perms = TRUE;
1.1 millert 410: #endif
411: #ifdef USE_TTY_TICKETS
1.11 ! millert 412: def_tty_tickets = TRUE;
1.1 millert 413: #endif
414: #ifndef NO_LECTURE
1.11 ! millert 415: def_lecture = once;
1.1 millert 416: #endif
417: #ifndef NO_AUTHENTICATION
1.11 ! millert 418: def_authenticate = TRUE;
1.1 millert 419: #endif
420: #ifndef NO_ROOT_SUDO
1.11 ! millert 421: def_root_sudo = TRUE;
1.1 millert 422: #endif
423: #ifdef HOST_IN_LOG
1.11 ! millert 424: def_log_host = TRUE;
1.1 millert 425: #endif
1.3 millert 426: #ifdef SHELL_IF_NO_ARGS
1.11 ! millert 427: def_shell_noargs = TRUE;
1.3 millert 428: #endif
1.1 millert 429: #ifdef SHELL_SETS_HOME
1.11 ! millert 430: def_set_home = TRUE;
1.1 millert 431: #endif
432: #ifndef DONT_LEAK_PATH_INFO
1.11 ! millert 433: def_path_info = TRUE;
1.1 millert 434: #endif
435: #ifdef FQDN
1.11 ! millert 436: def_fqdn = TRUE;
1.1 millert 437: #endif
438: #ifdef USE_INSULTS
1.11 ! millert 439: def_insults = TRUE;
1.1 millert 440: #endif
1.4 millert 441: #ifdef ENV_EDITOR
1.11 ! millert 442: def_env_editor = TRUE;
1.4 millert 443: #endif
1.11 ! millert 444: def_set_logname = TRUE;
1.1 millert 445:
446: /* Syslog options need special care since they both strings and ints */
447: #if (LOGGING & SLOG_SYSLOG)
1.8 millert 448: (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], TRUE);
449: (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI],
450: TRUE);
451: (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI],
452: TRUE);
1.1 millert 453: #endif
454:
1.3 millert 455: /* Password flags also have a string and integer component. */
1.11 ! millert 456: (void) store_tuple("any", &sudo_defs_table[I_LISTPW], TRUE);
! 457: (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], TRUE);
1.3 millert 458:
1.1 millert 459: /* Then initialize the int-like things. */
460: #ifdef SUDO_UMASK
1.11 ! millert 461: def_umask = SUDO_UMASK;
1.1 millert 462: #else
1.11 ! millert 463: def_umask = 0777;
1.1 millert 464: #endif
1.11 ! millert 465: def_loglinelen = MAXLOGFILELEN;
! 466: def_timestamp_timeout = TIMEOUT;
! 467: def_passwd_timeout = PASSWORD_TIMEOUT;
! 468: def_passwd_tries = TRIES_FOR_PASSWORD;
1.1 millert 469:
1.8 millert 470: /* Now do the strings */
1.11 ! millert 471: def_mailto = estrdup(MAILTO);
! 472: def_mailsub = estrdup(MAILSUBJECT);
! 473: def_badpass_message = estrdup(INCORRECT_PASSWORD);
! 474: def_timestampdir = estrdup(_PATH_SUDO_TIMEDIR);
! 475: def_passprompt = estrdup(PASSPROMPT);
! 476: def_runas_default = estrdup(RUNAS_DEFAULT);
1.8 millert 477: #ifdef _PATH_SUDO_SENDMAIL
1.11 ! millert 478: def_mailerpath = estrdup(_PATH_SUDO_SENDMAIL);
! 479: def_mailerflags = estrdup("-t");
1.1 millert 480: #endif
481: #if (LOGGING & SLOG_FILE)
1.11 ! millert 482: def_logfile = estrdup(_PATH_SUDO_LOGFILE);
1.1 millert 483: #endif
484: #ifdef EXEMPTGROUP
1.11 ! millert 485: def_exempt_group = estrdup(EXEMPTGROUP);
! 486: #endif
! 487: def_editor = estrdup(EDITOR);
! 488: #ifdef _PATH_SUDO_NOEXEC
! 489: def_noexec_file = estrdup(_PATH_SUDO_NOEXEC);
1.1 millert 490: #endif
491:
1.8 millert 492: /* Finally do the lists (currently just environment tables). */
493: init_envtables();
494:
1.1 millert 495: /*
496: * The following depend on the above values.
497: * We use a pointer to the string so that if its
498: * value changes we get the change.
499: */
500: if (user_runas == NULL)
1.11 ! millert 501: user_runas = &def_runas_default;
1.1 millert 502:
503: firsttime = 0;
504: }
505:
506: static int
507: store_int(val, def, op)
508: char *val;
509: struct sudo_defs_types *def;
510: int op;
511: {
512: char *endp;
513: long l;
514:
515: if (op == FALSE) {
516: def->sd_un.ival = 0;
517: } else {
518: l = strtol(val, &endp, 10);
1.8 millert 519: if (*endp != '\0')
520: return(FALSE);
521: /* XXX - should check against INT_MAX */
522: def->sd_un.ival = (unsigned int)l;
523: }
1.11 ! millert 524: if (def->callback)
! 525: return(def->callback(val));
1.8 millert 526: return(TRUE);
527: }
528:
529: static int
530: store_uint(val, def, op)
531: char *val;
532: struct sudo_defs_types *def;
533: int op;
534: {
535: char *endp;
536: long l;
537:
538: if (op == FALSE) {
539: def->sd_un.ival = 0;
540: } else {
541: l = strtol(val, &endp, 10);
1.1 millert 542: if (*endp != '\0' || l < 0)
543: return(FALSE);
544: /* XXX - should check against INT_MAX */
545: def->sd_un.ival = (unsigned int)l;
546: }
1.11 ! millert 547: if (def->callback)
! 548: return(def->callback(val));
! 549: return(TRUE);
! 550: }
! 551:
! 552: static int
! 553: store_tuple(val, def, op)
! 554: char *val;
! 555: struct sudo_defs_types *def;
! 556: int op;
! 557: {
! 558: struct def_values *v;
! 559:
! 560: /*
! 561: * Since enums are really just ints we store the value as an ival.
! 562: * In the future, there may be multiple enums for different tuple
! 563: * types we want to avoid and special knowledge of the tuple type.
! 564: * This does assume that the first entry in the tuple enum will
! 565: * be the equivalent to a boolean "false".
! 566: */
! 567: if (op == FALSE) {
! 568: def->sd_un.ival = 0;
! 569: } else {
! 570: for (v = def->values; v != NULL; v++) {
! 571: if (strcmp(v->sval, val) == 0) {
! 572: def->sd_un.ival = v->ival;
! 573: break;
! 574: }
! 575: }
! 576: if (v == NULL)
! 577: return(FALSE);
! 578: }
! 579: if (def->callback)
! 580: return(def->callback(val));
1.1 millert 581: return(TRUE);
582: }
583:
584: static int
585: store_str(val, def, op)
586: char *val;
587: struct sudo_defs_types *def;
588: int op;
589: {
590:
591: if (def->sd_un.str)
592: free(def->sd_un.str);
593: if (op == FALSE)
594: def->sd_un.str = NULL;
595: else
596: def->sd_un.str = estrdup(val);
1.11 ! millert 597: if (def->callback)
! 598: return(def->callback(val));
1.1 millert 599: return(TRUE);
600: }
601:
602: static int
1.8 millert 603: store_list(str, def, op)
604: char *str;
605: struct sudo_defs_types *def;
606: int op;
607: {
608: char *start, *end;
609:
610: /* Remove all old members. */
611: if (op == FALSE || op == TRUE)
612: list_op(NULL, 0, def, freeall);
613:
614: /* Split str into multiple space-separated words and act on each one. */
615: if (op != FALSE) {
616: end = str;
617: do {
618: /* Remove leading blanks, if nothing but blanks we are done. */
619: for (start = end; isblank(*start); start++)
620: ;
621: if (*start == '\0')
622: break;
623:
624: /* Find end position and perform operation. */
1.11 ! millert 625: for (end = start; *end && !isblank(*end); end++)
1.8 millert 626: ;
627: list_op(start, end - start, def, op == '-' ? delete : add);
628: } while (*end++ != '\0');
629: }
630: return(TRUE);
631: }
632:
633: static int
1.1 millert 634: store_syslogfac(val, def, op)
635: char *val;
636: struct sudo_defs_types *def;
637: int op;
638: {
639: struct strmap *fac;
640:
641: if (op == FALSE) {
1.11 ! millert 642: def->sd_un.ival = FALSE;
1.1 millert 643: return(TRUE);
644: }
645: #ifdef LOG_NFACILITIES
646: if (!val)
647: return(FALSE);
648: for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
649: ;
650: if (fac->name == NULL)
651: return(FALSE); /* not found */
652:
1.11 ! millert 653: def->sd_un.ival = fac->num;
1.1 millert 654: #else
1.11 ! millert 655: def->sd_un.ival = -1;
1.1 millert 656: #endif /* LOG_NFACILITIES */
657: return(TRUE);
658: }
659:
1.11 ! millert 660: static const char *
! 661: logfac2str(n)
! 662: int n;
! 663: {
! 664: #ifdef LOG_NFACILITIES
! 665: struct strmap *fac;
! 666:
! 667: for (fac = facilities; fac->name && fac->num != n; fac++)
! 668: ;
! 669: return (fac->name);
! 670: #else
! 671: return ("default");
! 672: #endif /* LOG_NFACILITIES */
! 673: }
! 674:
1.1 millert 675: static int
676: store_syslogpri(val, def, op)
677: char *val;
678: struct sudo_defs_types *def;
679: int op;
680: {
681: struct strmap *pri;
682:
683: if (op == FALSE || !val)
684: return(FALSE);
685:
686: for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
687: ;
688: if (pri->name == NULL)
689: return(FALSE); /* not found */
690:
1.11 ! millert 691: def->sd_un.ival = pri->num;
1.1 millert 692: return(TRUE);
693: }
694:
1.11 ! millert 695: static const char *
! 696: logpri2str(n)
! 697: int n;
! 698: {
! 699: struct strmap *pri;
! 700:
! 701: for (pri = priorities; pri->name && pri->num != n; pri++)
! 702: ;
! 703: return (pri->name);
! 704: }
! 705:
1.1 millert 706: static int
707: store_mode(val, def, op)
708: char *val;
709: struct sudo_defs_types *def;
710: int op;
711: {
712: char *endp;
713: long l;
714:
715: if (op == FALSE) {
716: def->sd_un.mode = (mode_t)0777;
717: } else {
718: l = strtol(val, &endp, 8);
1.5 millert 719: if (*endp != '\0' || l < 0 || l > 0777)
1.1 millert 720: return(FALSE);
721: def->sd_un.mode = (mode_t)l;
722: }
1.11 ! millert 723: if (def->callback)
! 724: return(def->callback(val));
1.1 millert 725: return(TRUE);
1.8 millert 726: }
727:
728: static void
729: list_op(val, len, def, op)
730: char *val;
731: size_t len;
732: struct sudo_defs_types *def;
733: enum list_ops op;
734: {
735: struct list_member *cur, *prev, *tmp;
736:
737: if (op == freeall) {
738: for (cur = def->sd_un.list; cur; ) {
739: tmp = cur;
740: cur = tmp->next;
741: free(tmp->value);
742: free(tmp);
743: }
744: def->sd_un.list = NULL;
745: return;
746: }
747:
748: for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
749: if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
750:
751: if (op == add)
752: return; /* already exists */
753:
754: /* Delete node */
755: if (prev != NULL)
756: prev->next = cur->next;
757: else
758: def->sd_un.list = cur->next;
759: free(cur->value);
760: free(cur);
761: break;
762: }
763: }
764:
765: /* Add new node to the head of the list. */
766: if (op == add) {
767: cur = emalloc(sizeof(struct list_member));
768: cur->value = emalloc(len + 1);
769: (void) memcpy(cur->value, val, len);
770: cur->value[len] = '\0';
771: cur->next = def->sd_un.list;
772: def->sd_un.list = cur;
773: }
1.1 millert 774: }