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