Annotation of embedaddon/sudo/plugins/sudoers/defaults.c, revision 1.1.1.2
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: */
488: int
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) &&
510: runaslist_matches(&def->binding, NULL) == ALLOW &&
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.2 ! misho 531: static bool
1.1 misho 532: store_int(char *val, struct sudo_defs_types *def, int op)
533: {
534: char *endp;
535: long l;
1.1.1.2 ! misho 536: debug_decl(store_int, SUDO_DEBUG_DEFAULTS)
1.1 misho 537:
1.1.1.2 ! misho 538: if (op == false) {
1.1 misho 539: def->sd_un.ival = 0;
540: } else {
541: l = strtol(val, &endp, 10);
542: if (*endp != '\0')
1.1.1.2 ! misho 543: debug_return_bool(false);
1.1 misho 544: /* XXX - should check against INT_MAX */
545: def->sd_un.ival = (int)l;
546: }
547: if (def->callback)
1.1.1.2 ! misho 548: debug_return_bool(def->callback(val));
! 549: debug_return_bool(true);
1.1 misho 550: }
551:
1.1.1.2 ! misho 552: static bool
1.1 misho 553: store_uint(char *val, struct sudo_defs_types *def, int op)
554: {
555: char *endp;
556: long l;
1.1.1.2 ! misho 557: debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
1.1 misho 558:
1.1.1.2 ! misho 559: if (op == false) {
1.1 misho 560: def->sd_un.ival = 0;
561: } else {
562: l = strtol(val, &endp, 10);
563: if (*endp != '\0' || l < 0)
1.1.1.2 ! misho 564: debug_return_bool(false);
1.1 misho 565: /* XXX - should check against INT_MAX */
566: def->sd_un.ival = (unsigned int)l;
567: }
568: if (def->callback)
1.1.1.2 ! misho 569: debug_return_bool(def->callback(val));
! 570: debug_return_bool(true);
1.1 misho 571: }
572:
1.1.1.2 ! misho 573: static bool
1.1 misho 574: store_float(char *val, struct sudo_defs_types *def, int op)
575: {
576: char *endp;
577: double d;
1.1.1.2 ! misho 578: debug_decl(store_float, SUDO_DEBUG_DEFAULTS)
1.1 misho 579:
1.1.1.2 ! misho 580: if (op == false) {
1.1 misho 581: def->sd_un.fval = 0.0;
582: } else {
583: d = strtod(val, &endp);
584: if (*endp != '\0')
1.1.1.2 ! misho 585: debug_return_bool(false);
1.1 misho 586: /* XXX - should check against HUGE_VAL */
587: def->sd_un.fval = d;
588: }
589: if (def->callback)
1.1.1.2 ! misho 590: debug_return_bool(def->callback(val));
! 591: debug_return_bool(true);
1.1 misho 592: }
593:
1.1.1.2 ! misho 594: static bool
1.1 misho 595: store_tuple(char *val, struct sudo_defs_types *def, int op)
596: {
597: struct def_values *v;
1.1.1.2 ! misho 598: debug_decl(store_tuple, SUDO_DEBUG_DEFAULTS)
1.1 misho 599:
600: /*
601: * Since enums are really just ints we store the value as an ival.
602: * In the future, there may be multiple enums for different tuple
603: * types we want to avoid and special knowledge of the tuple type.
604: * This does assume that the first entry in the tuple enum will
605: * be the equivalent to a boolean "false".
606: */
607: if (!val) {
1.1.1.2 ! misho 608: def->sd_un.ival = (op == false) ? 0 : 1;
1.1 misho 609: } else {
610: for (v = def->values; v->sval != NULL; v++) {
611: if (strcmp(v->sval, val) == 0) {
612: def->sd_un.ival = v->ival;
613: break;
614: }
615: }
616: if (v->sval == NULL)
1.1.1.2 ! misho 617: debug_return_bool(false);
1.1 misho 618: }
619: if (def->callback)
1.1.1.2 ! misho 620: debug_return_bool(def->callback(val));
! 621: debug_return_bool(true);
1.1 misho 622: }
623:
1.1.1.2 ! misho 624: static bool
1.1 misho 625: store_str(char *val, struct sudo_defs_types *def, int op)
626: {
1.1.1.2 ! misho 627: debug_decl(store_str, SUDO_DEBUG_DEFAULTS)
1.1 misho 628:
629: efree(def->sd_un.str);
1.1.1.2 ! misho 630: if (op == false)
1.1 misho 631: def->sd_un.str = NULL;
632: else
633: def->sd_un.str = estrdup(val);
634: if (def->callback)
1.1.1.2 ! misho 635: debug_return_bool(def->callback(val));
! 636: debug_return_bool(true);
1.1 misho 637: }
638:
1.1.1.2 ! misho 639: static bool
1.1 misho 640: store_list(char *str, struct sudo_defs_types *def, int op)
641: {
642: char *start, *end;
1.1.1.2 ! misho 643: debug_decl(store_list, SUDO_DEBUG_DEFAULTS)
1.1 misho 644:
645: /* Remove all old members. */
1.1.1.2 ! misho 646: if (op == false || op == true)
1.1 misho 647: list_op(NULL, 0, def, freeall);
648:
649: /* Split str into multiple space-separated words and act on each one. */
1.1.1.2 ! misho 650: if (op != false) {
1.1 misho 651: end = str;
652: do {
653: /* Remove leading blanks, if nothing but blanks we are done. */
654: for (start = end; isblank((unsigned char)*start); start++)
655: ;
656: if (*start == '\0')
657: break;
658:
659: /* Find end position and perform operation. */
660: for (end = start; *end && !isblank((unsigned char)*end); end++)
661: ;
662: list_op(start, end - start, def, op == '-' ? delete : add);
663: } while (*end++ != '\0');
664: }
1.1.1.2 ! misho 665: debug_return_bool(true);
1.1 misho 666: }
667:
1.1.1.2 ! misho 668: static bool
1.1 misho 669: store_syslogfac(char *val, struct sudo_defs_types *def, int op)
670: {
671: struct strmap *fac;
1.1.1.2 ! misho 672: debug_decl(store_syslogfac, SUDO_DEBUG_DEFAULTS)
1.1 misho 673:
1.1.1.2 ! misho 674: if (op == false) {
! 675: def->sd_un.ival = false;
! 676: debug_return_bool(true);
1.1 misho 677: }
678: #ifdef LOG_NFACILITIES
679: if (!val)
1.1.1.2 ! misho 680: debug_return_bool(false);
1.1 misho 681: for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
682: ;
683: if (fac->name == NULL)
1.1.1.2 ! misho 684: debug_return_bool(false); /* not found */
1.1 misho 685:
686: def->sd_un.ival = fac->num;
687: #else
688: def->sd_un.ival = -1;
689: #endif /* LOG_NFACILITIES */
1.1.1.2 ! misho 690: debug_return_bool(true);
1.1 misho 691: }
692:
693: static const char *
694: logfac2str(int n)
695: {
696: #ifdef LOG_NFACILITIES
697: struct strmap *fac;
1.1.1.2 ! misho 698: debug_decl(logfac2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 699:
700: for (fac = facilities; fac->name && fac->num != n; fac++)
701: ;
1.1.1.2 ! misho 702: debug_return_str(fac->name);
1.1 misho 703: #else
704: return "default";
705: #endif /* LOG_NFACILITIES */
706: }
707:
1.1.1.2 ! misho 708: static bool
1.1 misho 709: store_syslogpri(char *val, struct sudo_defs_types *def, int op)
710: {
711: struct strmap *pri;
1.1.1.2 ! misho 712: debug_decl(store_syslogpri, SUDO_DEBUG_DEFAULTS)
1.1 misho 713:
1.1.1.2 ! misho 714: if (op == false || !val)
! 715: debug_return_bool(false);
1.1 misho 716:
717: for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
718: ;
719: if (pri->name == NULL)
1.1.1.2 ! misho 720: debug_return_bool(false); /* not found */
1.1 misho 721:
722: def->sd_un.ival = pri->num;
1.1.1.2 ! misho 723: debug_return_bool(true);
1.1 misho 724: }
725:
726: static const char *
727: logpri2str(int n)
728: {
729: struct strmap *pri;
1.1.1.2 ! misho 730: debug_decl(logpri2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 731:
732: for (pri = priorities; pri->name && pri->num != n; pri++)
733: ;
1.1.1.2 ! misho 734: debug_return_str(pri->name);
1.1 misho 735: }
736:
1.1.1.2 ! misho 737: static bool
1.1 misho 738: store_mode(char *val, struct sudo_defs_types *def, int op)
739: {
740: char *endp;
741: long l;
1.1.1.2 ! misho 742: debug_decl(store_mode, SUDO_DEBUG_DEFAULTS)
1.1 misho 743:
1.1.1.2 ! misho 744: if (op == false) {
1.1 misho 745: def->sd_un.mode = (mode_t)0777;
746: } else {
747: l = strtol(val, &endp, 8);
748: if (*endp != '\0' || l < 0 || l > 0777)
1.1.1.2 ! misho 749: debug_return_bool(false);
1.1 misho 750: def->sd_un.mode = (mode_t)l;
751: }
752: if (def->callback)
1.1.1.2 ! misho 753: debug_return_bool(def->callback(val));
! 754: debug_return_bool(true);
1.1 misho 755: }
756:
757: static void
758: list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
759: {
760: struct list_member *cur, *prev, *tmp;
1.1.1.2 ! misho 761: debug_decl(list_op, SUDO_DEBUG_DEFAULTS)
1.1 misho 762:
763: if (op == freeall) {
764: for (cur = def->sd_un.list; cur; ) {
765: tmp = cur;
766: cur = tmp->next;
767: efree(tmp->value);
768: efree(tmp);
769: }
770: def->sd_un.list = NULL;
1.1.1.2 ! misho 771: debug_return;
1.1 misho 772: }
773:
774: for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
775: if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
776:
777: if (op == add)
1.1.1.2 ! misho 778: debug_return; /* already exists */
1.1 misho 779:
780: /* Delete node */
781: if (prev != NULL)
782: prev->next = cur->next;
783: else
784: def->sd_un.list = cur->next;
785: efree(cur->value);
786: efree(cur);
787: break;
788: }
789: }
790:
791: /* Add new node to the head of the list. */
792: if (op == add) {
1.1.1.2 ! misho 793: cur = ecalloc(1, sizeof(struct list_member));
! 794: cur->value = estrndup(val, len);
1.1 misho 795: cur->next = def->sd_un.list;
796: def->sd_un.list = cur;
797: }
1.1.1.2 ! misho 798: debug_return;
1.1 misho 799: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>