Annotation of embedaddon/sudo/plugins/sudoers/defaults.c, revision 1.1.1.5
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: }
1.1.1.5 ! misho 359: memset(&def->sd_un, 0, sizeof(def->sd_un));
1.1 misho 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.5 ! misho 424: def_pam_service = estrdup("sudo");
! 425: #ifdef HAVE_PAM_LOGIN
! 426: def_pam_login_service = estrdup("sudo-i");
! 427: #else
! 428: def_pam_login_service = estrdup("sudo");
! 429: #endif
1.1.1.4 misho 430: #ifdef NO_PAM_SESSION
431: def_pam_session = false;
432: #else
433: def_pam_session = true;
434: #endif
1.1 misho 435:
436: /* Syslog options need special care since they both strings and ints */
437: #if (LOGGING & SLOG_SYSLOG)
1.1.1.2 misho 438: (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], true);
1.1 misho 439: (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI],
1.1.1.2 misho 440: true);
1.1 misho 441: (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI],
1.1.1.2 misho 442: true);
1.1 misho 443: #endif
444:
445: /* Password flags also have a string and integer component. */
1.1.1.2 misho 446: (void) store_tuple("any", &sudo_defs_table[I_LISTPW], true);
447: (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], true);
1.1 misho 448:
449: /* Then initialize the int-like things. */
450: #ifdef SUDO_UMASK
451: def_umask = SUDO_UMASK;
452: #else
453: def_umask = 0777;
454: #endif
455: def_loglinelen = MAXLOGFILELEN;
456: def_timestamp_timeout = TIMEOUT;
457: def_passwd_timeout = PASSWORD_TIMEOUT;
458: def_passwd_tries = TRIES_FOR_PASSWORD;
459: #ifdef HAVE_ZLIB_H
1.1.1.2 misho 460: def_compress_io = true;
1.1 misho 461: #endif
462:
463: /* Now do the strings */
464: def_mailto = estrdup(MAILTO);
1.1.1.4 misho 465: def_mailsub = estrdup(N_(MAILSUBJECT));
1.1 misho 466: def_badpass_message = estrdup(_(INCORRECT_PASSWORD));
467: def_timestampdir = estrdup(_PATH_SUDO_TIMEDIR);
468: def_passprompt = estrdup(_(PASSPROMPT));
469: def_runas_default = estrdup(RUNAS_DEFAULT);
470: #ifdef _PATH_SUDO_SENDMAIL
471: def_mailerpath = estrdup(_PATH_SUDO_SENDMAIL);
472: def_mailerflags = estrdup("-t");
473: #endif
474: #if (LOGGING & SLOG_FILE)
475: def_logfile = estrdup(_PATH_SUDO_LOGFILE);
476: #endif
477: #ifdef EXEMPTGROUP
478: def_exempt_group = estrdup(EXEMPTGROUP);
479: #endif
480: #ifdef SECURE_PATH
481: def_secure_path = estrdup(SECURE_PATH);
482: #endif
483: def_editor = estrdup(EDITOR);
1.1.1.2 misho 484: def_set_utmp = true;
1.1 misho 485:
486: /* Finally do the lists (currently just environment tables). */
487: init_envtables();
488:
489: firsttime = 0;
1.1.1.2 misho 490:
491: debug_return;
1.1 misho 492: }
493:
494: /*
495: * Update the defaults based on what was set by sudoers.
496: * Pass in an OR'd list of which default types to update.
497: */
1.1.1.3 misho 498: bool
1.1 misho 499: update_defaults(int what)
500: {
501: struct defaults *def;
1.1.1.2 misho 502: bool rc = true;
503: debug_decl(update_defaults, SUDO_DEBUG_DEFAULTS)
1.1 misho 504:
505: tq_foreach_fwd(&defaults, def) {
506: switch (def->type) {
507: case DEFAULTS:
508: if (ISSET(what, SETDEF_GENERIC) &&
509: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 510: rc = false;
1.1 misho 511: break;
512: case DEFAULTS_USER:
1.1.1.4 misho 513: #if 1
514: if (ISSET(what, SETDEF_USER)) {
515: int m;
516: m = userlist_matches(sudo_user.pw, &def->binding);
517: if (m == ALLOW) {
518: if (!set_default(def->var, def->val, def->op))
519: rc = false;
520: }
521: }
522: #else
1.1 misho 523: if (ISSET(what, SETDEF_USER) &&
524: userlist_matches(sudo_user.pw, &def->binding) == ALLOW &&
525: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 526: rc = false;
1.1.1.4 misho 527: #endif
1.1 misho 528: break;
529: case DEFAULTS_RUNAS:
530: if (ISSET(what, SETDEF_RUNAS) &&
1.1.1.3 misho 531: runaslist_matches(&def->binding, NULL, NULL, NULL) == ALLOW &&
1.1 misho 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_HOST:
536: if (ISSET(what, SETDEF_HOST) &&
537: hostlist_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: case DEFAULTS_CMND:
542: if (ISSET(what, SETDEF_CMND) &&
543: cmndlist_matches(&def->binding) == ALLOW &&
544: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 545: rc = false;
1.1 misho 546: break;
547: }
548: }
1.1.1.2 misho 549: debug_return_bool(rc);
1.1 misho 550: }
551:
1.1.1.3 misho 552: /*
553: * Check the defaults entries without actually setting them.
554: * Pass in an OR'd list of which default types to check.
555: */
556: bool
557: check_defaults(int what, bool quiet)
558: {
559: struct sudo_defs_types *cur;
560: struct defaults *def;
561: bool rc = true;
562: debug_decl(check_defaults, SUDO_DEBUG_DEFAULTS)
563:
564: tq_foreach_fwd(&defaults, def) {
565: switch (def->type) {
566: case DEFAULTS:
567: if (!ISSET(what, SETDEF_GENERIC))
568: continue;
569: break;
570: case DEFAULTS_USER:
571: if (!ISSET(what, SETDEF_USER))
572: continue;
573: break;
574: case DEFAULTS_RUNAS:
575: if (!ISSET(what, SETDEF_RUNAS))
576: continue;
577: break;
578: case DEFAULTS_HOST:
579: if (!ISSET(what, SETDEF_HOST))
580: continue;
581: break;
582: case DEFAULTS_CMND:
583: if (!ISSET(what, SETDEF_CMND))
584: continue;
585: break;
586: }
587: for (cur = sudo_defs_table; cur->name != NULL; cur++) {
588: if (strcmp(def->var, cur->name) == 0)
589: break;
590: }
591: if (cur->name == NULL) {
592: if (!quiet)
593: warningx(_("unknown defaults entry `%s'"), def->var);
594: rc = false;
595: }
596: }
597: debug_return_bool(rc);
598: }
599:
1.1.1.2 misho 600: static bool
1.1 misho 601: store_int(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_int, 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')
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 = (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_uint(char *val, struct sudo_defs_types *def, int op)
623: {
624: char *endp;
625: long l;
1.1.1.2 misho 626: debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
1.1 misho 627:
1.1.1.2 misho 628: if (op == false) {
1.1 misho 629: def->sd_un.ival = 0;
630: } else {
631: l = strtol(val, &endp, 10);
632: if (*endp != '\0' || l < 0)
1.1.1.2 misho 633: debug_return_bool(false);
1.1 misho 634: /* XXX - should check against INT_MAX */
635: def->sd_un.ival = (unsigned int)l;
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_float(char *val, struct sudo_defs_types *def, int op)
644: {
645: char *endp;
646: double d;
1.1.1.2 misho 647: debug_decl(store_float, SUDO_DEBUG_DEFAULTS)
1.1 misho 648:
1.1.1.2 misho 649: if (op == false) {
1.1 misho 650: def->sd_un.fval = 0.0;
651: } else {
652: d = strtod(val, &endp);
653: if (*endp != '\0')
1.1.1.2 misho 654: debug_return_bool(false);
1.1 misho 655: /* XXX - should check against HUGE_VAL */
656: def->sd_un.fval = d;
657: }
658: if (def->callback)
1.1.1.2 misho 659: debug_return_bool(def->callback(val));
660: debug_return_bool(true);
1.1 misho 661: }
662:
1.1.1.2 misho 663: static bool
1.1 misho 664: store_tuple(char *val, struct sudo_defs_types *def, int op)
665: {
666: struct def_values *v;
1.1.1.2 misho 667: debug_decl(store_tuple, SUDO_DEBUG_DEFAULTS)
1.1 misho 668:
669: /*
670: * Since enums are really just ints we store the value as an ival.
671: * In the future, there may be multiple enums for different tuple
672: * types we want to avoid and special knowledge of the tuple type.
673: * This does assume that the first entry in the tuple enum will
674: * be the equivalent to a boolean "false".
675: */
676: if (!val) {
1.1.1.2 misho 677: def->sd_un.ival = (op == false) ? 0 : 1;
1.1 misho 678: } else {
679: for (v = def->values; v->sval != NULL; v++) {
680: if (strcmp(v->sval, val) == 0) {
681: def->sd_un.ival = v->ival;
682: break;
683: }
684: }
685: if (v->sval == NULL)
1.1.1.2 misho 686: debug_return_bool(false);
1.1 misho 687: }
688: if (def->callback)
1.1.1.2 misho 689: debug_return_bool(def->callback(val));
690: debug_return_bool(true);
1.1 misho 691: }
692:
1.1.1.2 misho 693: static bool
1.1 misho 694: store_str(char *val, struct sudo_defs_types *def, int op)
695: {
1.1.1.2 misho 696: debug_decl(store_str, SUDO_DEBUG_DEFAULTS)
1.1 misho 697:
698: efree(def->sd_un.str);
1.1.1.2 misho 699: if (op == false)
1.1 misho 700: def->sd_un.str = NULL;
701: else
702: def->sd_un.str = estrdup(val);
703: if (def->callback)
1.1.1.2 misho 704: debug_return_bool(def->callback(val));
705: debug_return_bool(true);
1.1 misho 706: }
707:
1.1.1.2 misho 708: static bool
1.1 misho 709: store_list(char *str, struct sudo_defs_types *def, int op)
710: {
711: char *start, *end;
1.1.1.2 misho 712: debug_decl(store_list, SUDO_DEBUG_DEFAULTS)
1.1 misho 713:
714: /* Remove all old members. */
1.1.1.2 misho 715: if (op == false || op == true)
1.1 misho 716: list_op(NULL, 0, def, freeall);
717:
718: /* Split str into multiple space-separated words and act on each one. */
1.1.1.2 misho 719: if (op != false) {
1.1 misho 720: end = str;
721: do {
722: /* Remove leading blanks, if nothing but blanks we are done. */
723: for (start = end; isblank((unsigned char)*start); start++)
724: ;
725: if (*start == '\0')
726: break;
727:
728: /* Find end position and perform operation. */
729: for (end = start; *end && !isblank((unsigned char)*end); end++)
730: ;
731: list_op(start, end - start, def, op == '-' ? delete : add);
732: } while (*end++ != '\0');
733: }
1.1.1.2 misho 734: debug_return_bool(true);
1.1 misho 735: }
736:
1.1.1.2 misho 737: static bool
1.1 misho 738: store_syslogfac(char *val, struct sudo_defs_types *def, int op)
739: {
740: struct strmap *fac;
1.1.1.2 misho 741: debug_decl(store_syslogfac, SUDO_DEBUG_DEFAULTS)
1.1 misho 742:
1.1.1.2 misho 743: if (op == false) {
744: def->sd_un.ival = false;
745: debug_return_bool(true);
1.1 misho 746: }
747: #ifdef LOG_NFACILITIES
748: if (!val)
1.1.1.2 misho 749: debug_return_bool(false);
1.1 misho 750: for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
751: ;
752: if (fac->name == NULL)
1.1.1.2 misho 753: debug_return_bool(false); /* not found */
1.1 misho 754:
755: def->sd_un.ival = fac->num;
756: #else
757: def->sd_un.ival = -1;
758: #endif /* LOG_NFACILITIES */
1.1.1.2 misho 759: debug_return_bool(true);
1.1 misho 760: }
761:
762: static const char *
763: logfac2str(int n)
764: {
765: #ifdef LOG_NFACILITIES
766: struct strmap *fac;
1.1.1.2 misho 767: debug_decl(logfac2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 768:
769: for (fac = facilities; fac->name && fac->num != n; fac++)
770: ;
1.1.1.2 misho 771: debug_return_str(fac->name);
1.1 misho 772: #else
773: return "default";
774: #endif /* LOG_NFACILITIES */
775: }
776:
1.1.1.2 misho 777: static bool
1.1 misho 778: store_syslogpri(char *val, struct sudo_defs_types *def, int op)
779: {
780: struct strmap *pri;
1.1.1.2 misho 781: debug_decl(store_syslogpri, SUDO_DEBUG_DEFAULTS)
1.1 misho 782:
1.1.1.2 misho 783: if (op == false || !val)
784: debug_return_bool(false);
1.1 misho 785:
786: for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
787: ;
788: if (pri->name == NULL)
1.1.1.2 misho 789: debug_return_bool(false); /* not found */
1.1 misho 790:
791: def->sd_un.ival = pri->num;
1.1.1.2 misho 792: debug_return_bool(true);
1.1 misho 793: }
794:
795: static const char *
796: logpri2str(int n)
797: {
798: struct strmap *pri;
1.1.1.2 misho 799: debug_decl(logpri2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 800:
801: for (pri = priorities; pri->name && pri->num != n; pri++)
802: ;
1.1.1.2 misho 803: debug_return_str(pri->name);
1.1 misho 804: }
805:
1.1.1.2 misho 806: static bool
1.1 misho 807: store_mode(char *val, struct sudo_defs_types *def, int op)
808: {
809: char *endp;
810: long l;
1.1.1.2 misho 811: debug_decl(store_mode, SUDO_DEBUG_DEFAULTS)
1.1 misho 812:
1.1.1.2 misho 813: if (op == false) {
1.1 misho 814: def->sd_un.mode = (mode_t)0777;
815: } else {
816: l = strtol(val, &endp, 8);
817: if (*endp != '\0' || l < 0 || l > 0777)
1.1.1.2 misho 818: debug_return_bool(false);
1.1 misho 819: def->sd_un.mode = (mode_t)l;
820: }
821: if (def->callback)
1.1.1.2 misho 822: debug_return_bool(def->callback(val));
823: debug_return_bool(true);
1.1 misho 824: }
825:
826: static void
827: list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
828: {
829: struct list_member *cur, *prev, *tmp;
1.1.1.2 misho 830: debug_decl(list_op, SUDO_DEBUG_DEFAULTS)
1.1 misho 831:
832: if (op == freeall) {
833: for (cur = def->sd_un.list; cur; ) {
834: tmp = cur;
835: cur = tmp->next;
836: efree(tmp->value);
837: efree(tmp);
838: }
839: def->sd_un.list = NULL;
1.1.1.2 misho 840: debug_return;
1.1 misho 841: }
842:
843: for (cur = def->sd_un.list, prev = NULL; cur; prev = cur, cur = cur->next) {
844: if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
845:
846: if (op == add)
1.1.1.2 misho 847: debug_return; /* already exists */
1.1 misho 848:
849: /* Delete node */
850: if (prev != NULL)
851: prev->next = cur->next;
852: else
853: def->sd_un.list = cur->next;
854: efree(cur->value);
855: efree(cur);
856: break;
857: }
858: }
859:
860: /* Add new node to the head of the list. */
861: if (op == add) {
1.1.1.2 misho 862: cur = ecalloc(1, sizeof(struct list_member));
863: cur->value = estrndup(val, len);
1.1 misho 864: cur->next = def->sd_un.list;
865: def->sd_un.list = cur;
866: }
1.1.1.2 misho 867: debug_return;
1.1 misho 868: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>