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