Annotation of embedaddon/sudo/plugins/sudoers/defaults.c, revision 1.1.1.6
1.1 misho 1: /*
1.1.1.6 ! misho 2: * Copyright (c) 1999-2005, 2007-2014
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_INT:
152: sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.ival);
153: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
154: break;
1.1.1.6 ! misho 155: case T_UINT:
! 156: sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.uival);
! 157: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
! 158: break;
1.1 misho 159: case T_FLOAT:
160: sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.fval);
161: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
162: break;
163: case T_MODE:
164: sudo_printf(SUDO_CONV_INFO_MSG, desc, cur->sd_un.mode);
165: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
166: break;
167: case T_LIST:
1.1.1.6 ! misho 168: if (!SLIST_EMPTY(&cur->sd_un.list)) {
1.1 misho 169: sudo_printf(SUDO_CONV_INFO_MSG, "%s\n", desc);
1.1.1.6 ! misho 170: SLIST_FOREACH(item, &cur->sd_un.list, entries) {
1.1 misho 171: sudo_printf(SUDO_CONV_INFO_MSG,
172: "\t%s\n", item->value);
173: }
174: }
175: break;
176: case T_TUPLE:
177: for (def = cur->values; def->sval; def++) {
1.1.1.6 ! misho 178: if (cur->sd_un.tuple == def->nval) {
1.1 misho 179: sudo_printf(SUDO_CONV_INFO_MSG, desc, def->sval);
180: break;
181: }
182: }
183: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
184: break;
185: }
186: }
187: }
1.1.1.2 misho 188: debug_return;
1.1 misho 189: }
190:
191: /*
192: * Sets/clears an entry in the defaults structure
193: * If a variable that takes a value is used in a boolean
194: * context with op == 0, disable that variable.
195: * Eg. you may want to turn off logging to a file for some hosts.
196: * This is only meaningful for variables that are *optional*.
197: */
1.1.1.2 misho 198: bool
1.1 misho 199: set_default(char *var, char *val, int op)
200: {
201: struct sudo_defs_types *cur;
202: int num;
1.1.1.2 misho 203: debug_decl(set_default, SUDO_DEBUG_DEFAULTS)
1.1 misho 204:
205: for (cur = sudo_defs_table, num = 0; cur->name; cur++, num++) {
206: if (strcmp(var, cur->name) == 0)
207: break;
208: }
209: if (!cur->name) {
1.1.1.6 ! misho 210: warningx(U_("unknown defaults entry `%s'"), var);
1.1.1.2 misho 211: debug_return_bool(false);
1.1 misho 212: }
213:
214: switch (cur->type & T_MASK) {
215: case T_LOGFAC:
216: if (!store_syslogfac(val, cur, op)) {
217: if (val)
1.1.1.6 ! misho 218: warningx(U_("value `%s' is invalid for option `%s'"),
1.1 misho 219: val, var);
220: else
1.1.1.6 ! misho 221: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 222: debug_return_bool(false);
1.1 misho 223: }
224: break;
225: case T_LOGPRI:
226: if (!store_syslogpri(val, cur, op)) {
227: if (val)
1.1.1.6 ! misho 228: warningx(U_("value `%s' is invalid for option `%s'"),
1.1 misho 229: val, var);
230: else
1.1.1.6 ! misho 231: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 232: debug_return_bool(false);
1.1 misho 233: }
234: break;
235: case T_STR:
236: if (!val) {
237: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 238: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 239: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 240: debug_return_bool(false);
1.1 misho 241: }
242: }
243: if (ISSET(cur->type, T_PATH) && val && *val != '/') {
1.1.1.6 ! misho 244: warningx(U_("values for `%s' must start with a '/'"), var);
1.1.1.2 misho 245: debug_return_bool(false);
1.1 misho 246: }
247: if (!store_str(val, cur, op)) {
1.1.1.6 ! misho 248: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 249: debug_return_bool(false);
1.1 misho 250: }
251: break;
252: case T_INT:
253: if (!val) {
254: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 255: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 256: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 257: debug_return_bool(false);
1.1 misho 258: }
259: }
260: if (!store_int(val, cur, op)) {
1.1.1.6 ! misho 261: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 262: debug_return_bool(false);
1.1 misho 263: }
264: break;
265: case T_UINT:
266: if (!val) {
267: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 268: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 269: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 270: debug_return_bool(false);
1.1 misho 271: }
272: }
273: if (!store_uint(val, cur, op)) {
1.1.1.6 ! misho 274: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 275: debug_return_bool(false);
1.1 misho 276: }
277: break;
278: case T_FLOAT:
279: if (!val) {
280: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 281: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 282: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 283: debug_return_bool(false);
1.1 misho 284: }
285: }
286: if (!store_float(val, cur, op)) {
1.1.1.6 ! misho 287: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 288: debug_return_bool(false);
1.1 misho 289: }
290: break;
291: case T_MODE:
292: if (!val) {
293: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 294: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 295: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 296: debug_return_bool(false);
1.1 misho 297: }
298: }
299: if (!store_mode(val, cur, op)) {
1.1.1.6 ! misho 300: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 301: debug_return_bool(false);
1.1 misho 302: }
303: break;
304: case T_FLAG:
305: if (val) {
1.1.1.6 ! misho 306: warningx(U_("option `%s' does not take a value"), var);
1.1.1.2 misho 307: debug_return_bool(false);
1.1 misho 308: }
309: cur->sd_un.flag = op;
310: break;
311: case T_LIST:
312: if (!val) {
313: /* Check for bogus boolean usage or lack of a value. */
1.1.1.2 misho 314: if (!ISSET(cur->type, T_BOOL) || op != false) {
1.1.1.6 ! misho 315: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 316: debug_return_bool(false);
1.1 misho 317: }
318: }
319: if (!store_list(val, cur, op)) {
1.1.1.6 ! misho 320: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 321: debug_return_bool(false);
1.1 misho 322: }
323: break;
324: case T_TUPLE:
325: if (!val && !ISSET(cur->type, T_BOOL)) {
1.1.1.6 ! misho 326: warningx(U_("no value specified for `%s'"), var);
1.1.1.2 misho 327: debug_return_bool(false);
1.1 misho 328: }
329: if (!store_tuple(val, cur, op)) {
1.1.1.6 ! misho 330: warningx(U_("value `%s' is invalid for option `%s'"), val, var);
1.1.1.2 misho 331: debug_return_bool(false);
1.1 misho 332: }
333: break;
334: }
335:
1.1.1.2 misho 336: debug_return_bool(true);
1.1 misho 337: }
338:
339: /*
340: * Set default options to compiled-in values.
341: * Any of these may be overridden at runtime by a "Defaults" file.
342: */
343: void
344: init_defaults(void)
345: {
346: static int firsttime = 1;
347: struct sudo_defs_types *def;
1.1.1.2 misho 348: debug_decl(init_defaults, SUDO_DEBUG_DEFAULTS)
1.1 misho 349:
350: /* Clear any old settings. */
351: if (!firsttime) {
352: for (def = sudo_defs_table; def->name; def++) {
353: switch (def->type & T_MASK) {
354: case T_STR:
355: efree(def->sd_un.str);
356: def->sd_un.str = NULL;
357: break;
358: case T_LIST:
359: list_op(NULL, 0, def, freeall);
360: break;
361: }
1.1.1.5 misho 362: memset(&def->sd_un, 0, sizeof(def->sd_un));
1.1 misho 363: }
364: }
365:
366: /* First initialize the flags. */
367: #ifdef LONG_OTP_PROMPT
1.1.1.2 misho 368: def_long_otp_prompt = true;
1.1 misho 369: #endif
370: #ifdef IGNORE_DOT_PATH
1.1.1.2 misho 371: def_ignore_dot = true;
1.1 misho 372: #endif
373: #ifdef ALWAYS_SEND_MAIL
1.1.1.2 misho 374: def_mail_always = true;
1.1 misho 375: #endif
376: #ifdef SEND_MAIL_WHEN_NO_USER
1.1.1.2 misho 377: def_mail_no_user = true;
1.1 misho 378: #endif
379: #ifdef SEND_MAIL_WHEN_NO_HOST
1.1.1.2 misho 380: def_mail_no_host = true;
1.1 misho 381: #endif
382: #ifdef SEND_MAIL_WHEN_NOT_OK
1.1.1.2 misho 383: def_mail_no_perms = true;
1.1 misho 384: #endif
385: #ifndef NO_TTY_TICKETS
1.1.1.2 misho 386: def_tty_tickets = true;
1.1 misho 387: #endif
388: #ifndef NO_LECTURE
389: def_lecture = once;
390: #endif
391: #ifndef NO_AUTHENTICATION
1.1.1.2 misho 392: def_authenticate = true;
1.1 misho 393: #endif
394: #ifndef NO_ROOT_SUDO
1.1.1.2 misho 395: def_root_sudo = true;
1.1 misho 396: #endif
397: #ifdef HOST_IN_LOG
1.1.1.2 misho 398: def_log_host = true;
1.1 misho 399: #endif
400: #ifdef SHELL_IF_NO_ARGS
1.1.1.2 misho 401: def_shell_noargs = true;
1.1 misho 402: #endif
403: #ifdef SHELL_SETS_HOME
1.1.1.2 misho 404: def_set_home = true;
1.1 misho 405: #endif
406: #ifndef DONT_LEAK_PATH_INFO
1.1.1.2 misho 407: def_path_info = true;
1.1 misho 408: #endif
409: #ifdef FQDN
1.1.1.2 misho 410: def_fqdn = true;
1.1 misho 411: #endif
412: #ifdef USE_INSULTS
1.1.1.2 misho 413: def_insults = true;
1.1 misho 414: #endif
415: #ifdef ENV_EDITOR
1.1.1.2 misho 416: def_env_editor = true;
1.1 misho 417: #endif
418: #ifdef UMASK_OVERRIDE
1.1.1.2 misho 419: def_umask_override = true;
1.1 misho 420: #endif
421: def_iolog_file = estrdup("%{seq}");
422: def_iolog_dir = estrdup(_PATH_SUDO_IO_LOGDIR);
423: def_sudoers_locale = estrdup("C");
424: def_env_reset = ENV_RESET;
1.1.1.2 misho 425: def_set_logname = true;
1.1 misho 426: def_closefrom = STDERR_FILENO + 1;
1.1.1.5 misho 427: def_pam_service = estrdup("sudo");
428: #ifdef HAVE_PAM_LOGIN
429: def_pam_login_service = estrdup("sudo-i");
430: #else
431: def_pam_login_service = estrdup("sudo");
432: #endif
1.1.1.4 misho 433: #ifdef NO_PAM_SESSION
434: def_pam_session = false;
435: #else
436: def_pam_session = true;
437: #endif
1.1.1.6 ! misho 438: #ifdef HAVE_INNETGR
! 439: def_use_netgroups = true;
! 440: #endif
1.1 misho 441:
442: /* Syslog options need special care since they both strings and ints */
443: #if (LOGGING & SLOG_SYSLOG)
1.1.1.2 misho 444: (void) store_syslogfac(LOGFAC, &sudo_defs_table[I_SYSLOG], true);
1.1 misho 445: (void) store_syslogpri(PRI_SUCCESS, &sudo_defs_table[I_SYSLOG_GOODPRI],
1.1.1.2 misho 446: true);
1.1 misho 447: (void) store_syslogpri(PRI_FAILURE, &sudo_defs_table[I_SYSLOG_BADPRI],
1.1.1.2 misho 448: true);
1.1 misho 449: #endif
450:
451: /* Password flags also have a string and integer component. */
1.1.1.2 misho 452: (void) store_tuple("any", &sudo_defs_table[I_LISTPW], true);
453: (void) store_tuple("all", &sudo_defs_table[I_VERIFYPW], true);
1.1 misho 454:
455: /* Then initialize the int-like things. */
456: #ifdef SUDO_UMASK
457: def_umask = SUDO_UMASK;
458: #else
459: def_umask = 0777;
460: #endif
461: def_loglinelen = MAXLOGFILELEN;
462: def_timestamp_timeout = TIMEOUT;
463: def_passwd_timeout = PASSWORD_TIMEOUT;
464: def_passwd_tries = TRIES_FOR_PASSWORD;
465: #ifdef HAVE_ZLIB_H
1.1.1.2 misho 466: def_compress_io = true;
1.1 misho 467: #endif
468:
469: /* Now do the strings */
470: def_mailto = estrdup(MAILTO);
1.1.1.4 misho 471: def_mailsub = estrdup(N_(MAILSUBJECT));
1.1 misho 472: def_badpass_message = estrdup(_(INCORRECT_PASSWORD));
1.1.1.6 ! misho 473: def_lecture_status_dir = estrdup(_PATH_SUDO_LECTURE_DIR);
1.1 misho 474: def_timestampdir = estrdup(_PATH_SUDO_TIMEDIR);
475: def_passprompt = estrdup(_(PASSPROMPT));
476: def_runas_default = estrdup(RUNAS_DEFAULT);
477: #ifdef _PATH_SUDO_SENDMAIL
478: def_mailerpath = estrdup(_PATH_SUDO_SENDMAIL);
479: def_mailerflags = estrdup("-t");
480: #endif
481: #if (LOGGING & SLOG_FILE)
482: def_logfile = estrdup(_PATH_SUDO_LOGFILE);
483: #endif
484: #ifdef EXEMPTGROUP
485: def_exempt_group = estrdup(EXEMPTGROUP);
486: #endif
487: #ifdef SECURE_PATH
488: def_secure_path = estrdup(SECURE_PATH);
489: #endif
490: def_editor = estrdup(EDITOR);
1.1.1.2 misho 491: def_set_utmp = true;
1.1.1.6 ! misho 492: def_pam_setcred = true;
1.1 misho 493:
494: /* Finally do the lists (currently just environment tables). */
495: init_envtables();
496:
497: firsttime = 0;
1.1.1.2 misho 498:
499: debug_return;
1.1 misho 500: }
501:
502: /*
503: * Update the defaults based on what was set by sudoers.
504: * Pass in an OR'd list of which default types to update.
505: */
1.1.1.3 misho 506: bool
1.1 misho 507: update_defaults(int what)
508: {
509: struct defaults *def;
1.1.1.2 misho 510: bool rc = true;
511: debug_decl(update_defaults, SUDO_DEBUG_DEFAULTS)
1.1 misho 512:
1.1.1.6 ! misho 513: TAILQ_FOREACH(def, &defaults, entries) {
1.1 misho 514: switch (def->type) {
515: case DEFAULTS:
516: if (ISSET(what, SETDEF_GENERIC) &&
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_USER:
1.1.1.4 misho 521: #if 1
522: if (ISSET(what, SETDEF_USER)) {
523: int m;
1.1.1.6 ! misho 524: m = userlist_matches(sudo_user.pw, def->binding);
1.1.1.4 misho 525: if (m == ALLOW) {
526: if (!set_default(def->var, def->val, def->op))
527: rc = false;
528: }
529: }
530: #else
1.1 misho 531: if (ISSET(what, SETDEF_USER) &&
1.1.1.6 ! misho 532: userlist_matches(sudo_user.pw, def->binding) == ALLOW &&
1.1 misho 533: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 534: rc = false;
1.1.1.4 misho 535: #endif
1.1 misho 536: break;
537: case DEFAULTS_RUNAS:
538: if (ISSET(what, SETDEF_RUNAS) &&
1.1.1.6 ! misho 539: runaslist_matches(def->binding, NULL, NULL, NULL) == ALLOW &&
1.1 misho 540: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 541: rc = false;
1.1 misho 542: break;
543: case DEFAULTS_HOST:
544: if (ISSET(what, SETDEF_HOST) &&
1.1.1.6 ! misho 545: hostlist_matches(def->binding) == ALLOW &&
1.1 misho 546: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 547: rc = false;
1.1 misho 548: break;
549: case DEFAULTS_CMND:
550: if (ISSET(what, SETDEF_CMND) &&
1.1.1.6 ! misho 551: cmndlist_matches(def->binding) == ALLOW &&
1.1 misho 552: !set_default(def->var, def->val, def->op))
1.1.1.2 misho 553: rc = false;
1.1 misho 554: break;
555: }
556: }
1.1.1.2 misho 557: debug_return_bool(rc);
1.1 misho 558: }
559:
1.1.1.3 misho 560: /*
561: * Check the defaults entries without actually setting them.
562: * Pass in an OR'd list of which default types to check.
563: */
564: bool
565: check_defaults(int what, bool quiet)
566: {
567: struct sudo_defs_types *cur;
568: struct defaults *def;
569: bool rc = true;
570: debug_decl(check_defaults, SUDO_DEBUG_DEFAULTS)
571:
1.1.1.6 ! misho 572: TAILQ_FOREACH(def, &defaults, entries) {
1.1.1.3 misho 573: switch (def->type) {
574: case DEFAULTS:
575: if (!ISSET(what, SETDEF_GENERIC))
576: continue;
577: break;
578: case DEFAULTS_USER:
579: if (!ISSET(what, SETDEF_USER))
580: continue;
581: break;
582: case DEFAULTS_RUNAS:
583: if (!ISSET(what, SETDEF_RUNAS))
584: continue;
585: break;
586: case DEFAULTS_HOST:
587: if (!ISSET(what, SETDEF_HOST))
588: continue;
589: break;
590: case DEFAULTS_CMND:
591: if (!ISSET(what, SETDEF_CMND))
592: continue;
593: break;
594: }
595: for (cur = sudo_defs_table; cur->name != NULL; cur++) {
596: if (strcmp(def->var, cur->name) == 0)
597: break;
598: }
599: if (cur->name == NULL) {
600: if (!quiet)
1.1.1.6 ! misho 601: warningx(U_("unknown defaults entry `%s'"), def->var);
1.1.1.3 misho 602: rc = false;
603: }
604: }
605: debug_return_bool(rc);
606: }
607:
1.1.1.2 misho 608: static bool
1.1 misho 609: store_int(char *val, struct sudo_defs_types *def, int op)
610: {
1.1.1.6 ! misho 611: const char *errstr;
! 612: int i;
1.1.1.2 misho 613: debug_decl(store_int, SUDO_DEBUG_DEFAULTS)
1.1 misho 614:
1.1.1.2 misho 615: if (op == false) {
1.1 misho 616: def->sd_un.ival = 0;
617: } else {
1.1.1.6 ! misho 618: i = strtonum(val, INT_MIN, INT_MAX, &errstr);
! 619: if (errstr != NULL) {
! 620: sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
! 621: "%s: %s", val, errstr);
1.1.1.2 misho 622: debug_return_bool(false);
1.1.1.6 ! misho 623: }
! 624: def->sd_un.ival = i;
1.1 misho 625: }
626: if (def->callback)
1.1.1.2 misho 627: debug_return_bool(def->callback(val));
628: debug_return_bool(true);
1.1 misho 629: }
630:
1.1.1.2 misho 631: static bool
1.1 misho 632: store_uint(char *val, struct sudo_defs_types *def, int op)
633: {
1.1.1.6 ! misho 634: const char *errstr;
! 635: unsigned int u;
1.1.1.2 misho 636: debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
1.1 misho 637:
1.1.1.2 misho 638: if (op == false) {
1.1.1.6 ! misho 639: def->sd_un.uival = 0;
1.1 misho 640: } else {
1.1.1.6 ! misho 641: u = strtonum(val, 0, UINT_MAX, &errstr);
! 642: if (errstr != NULL) {
! 643: sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
! 644: "%s: %s", val, errstr);
1.1.1.2 misho 645: debug_return_bool(false);
1.1.1.6 ! misho 646: }
! 647: def->sd_un.uival = u;
1.1 misho 648: }
649: if (def->callback)
1.1.1.2 misho 650: debug_return_bool(def->callback(val));
651: debug_return_bool(true);
1.1 misho 652: }
653:
1.1.1.2 misho 654: static bool
1.1 misho 655: store_float(char *val, struct sudo_defs_types *def, int op)
656: {
657: char *endp;
658: double d;
1.1.1.2 misho 659: debug_decl(store_float, SUDO_DEBUG_DEFAULTS)
1.1 misho 660:
1.1.1.2 misho 661: if (op == false) {
1.1 misho 662: def->sd_un.fval = 0.0;
663: } else {
664: d = strtod(val, &endp);
665: if (*endp != '\0')
1.1.1.2 misho 666: debug_return_bool(false);
1.1 misho 667: /* XXX - should check against HUGE_VAL */
668: def->sd_un.fval = d;
669: }
670: if (def->callback)
1.1.1.2 misho 671: debug_return_bool(def->callback(val));
672: debug_return_bool(true);
1.1 misho 673: }
674:
1.1.1.2 misho 675: static bool
1.1 misho 676: store_tuple(char *val, struct sudo_defs_types *def, int op)
677: {
678: struct def_values *v;
1.1.1.2 misho 679: debug_decl(store_tuple, SUDO_DEBUG_DEFAULTS)
1.1 misho 680:
681: /*
1.1.1.6 ! misho 682: * Look up tuple value by name to find enum def_tuple value.
! 683: * For negation to work the first element of enum def_tuple
! 684: * must be equivalent to boolean false.
1.1 misho 685: */
686: if (!val) {
1.1.1.2 misho 687: def->sd_un.ival = (op == false) ? 0 : 1;
1.1 misho 688: } else {
689: for (v = def->values; v->sval != NULL; v++) {
690: if (strcmp(v->sval, val) == 0) {
1.1.1.6 ! misho 691: def->sd_un.tuple = v->nval;
1.1 misho 692: break;
693: }
694: }
695: if (v->sval == NULL)
1.1.1.2 misho 696: debug_return_bool(false);
1.1 misho 697: }
698: if (def->callback)
1.1.1.2 misho 699: debug_return_bool(def->callback(val));
700: debug_return_bool(true);
1.1 misho 701: }
702:
1.1.1.2 misho 703: static bool
1.1 misho 704: store_str(char *val, struct sudo_defs_types *def, int op)
705: {
1.1.1.2 misho 706: debug_decl(store_str, SUDO_DEBUG_DEFAULTS)
1.1 misho 707:
708: efree(def->sd_un.str);
1.1.1.2 misho 709: if (op == false)
1.1 misho 710: def->sd_un.str = NULL;
711: else
712: def->sd_un.str = estrdup(val);
713: if (def->callback)
1.1.1.2 misho 714: debug_return_bool(def->callback(val));
715: debug_return_bool(true);
1.1 misho 716: }
717:
1.1.1.2 misho 718: static bool
1.1 misho 719: store_list(char *str, struct sudo_defs_types *def, int op)
720: {
721: char *start, *end;
1.1.1.2 misho 722: debug_decl(store_list, SUDO_DEBUG_DEFAULTS)
1.1 misho 723:
724: /* Remove all old members. */
1.1.1.2 misho 725: if (op == false || op == true)
1.1 misho 726: list_op(NULL, 0, def, freeall);
727:
728: /* Split str into multiple space-separated words and act on each one. */
1.1.1.2 misho 729: if (op != false) {
1.1 misho 730: end = str;
731: do {
732: /* Remove leading blanks, if nothing but blanks we are done. */
733: for (start = end; isblank((unsigned char)*start); start++)
734: ;
735: if (*start == '\0')
736: break;
737:
738: /* Find end position and perform operation. */
739: for (end = start; *end && !isblank((unsigned char)*end); end++)
740: ;
741: list_op(start, end - start, def, op == '-' ? delete : add);
742: } while (*end++ != '\0');
743: }
1.1.1.2 misho 744: debug_return_bool(true);
1.1 misho 745: }
746:
1.1.1.2 misho 747: static bool
1.1 misho 748: store_syslogfac(char *val, struct sudo_defs_types *def, int op)
749: {
750: struct strmap *fac;
1.1.1.2 misho 751: debug_decl(store_syslogfac, SUDO_DEBUG_DEFAULTS)
1.1 misho 752:
1.1.1.2 misho 753: if (op == false) {
754: def->sd_un.ival = false;
755: debug_return_bool(true);
1.1 misho 756: }
757: #ifdef LOG_NFACILITIES
758: if (!val)
1.1.1.2 misho 759: debug_return_bool(false);
1.1 misho 760: for (fac = facilities; fac->name && strcmp(val, fac->name); fac++)
761: ;
762: if (fac->name == NULL)
1.1.1.2 misho 763: debug_return_bool(false); /* not found */
1.1 misho 764:
765: def->sd_un.ival = fac->num;
766: #else
767: def->sd_un.ival = -1;
768: #endif /* LOG_NFACILITIES */
1.1.1.2 misho 769: debug_return_bool(true);
1.1 misho 770: }
771:
772: static const char *
773: logfac2str(int n)
774: {
775: #ifdef LOG_NFACILITIES
776: struct strmap *fac;
1.1.1.2 misho 777: debug_decl(logfac2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 778:
779: for (fac = facilities; fac->name && fac->num != n; fac++)
780: ;
1.1.1.6 ! misho 781: debug_return_const_str(fac->name);
1.1 misho 782: #else
783: return "default";
784: #endif /* LOG_NFACILITIES */
785: }
786:
1.1.1.2 misho 787: static bool
1.1 misho 788: store_syslogpri(char *val, struct sudo_defs_types *def, int op)
789: {
790: struct strmap *pri;
1.1.1.2 misho 791: debug_decl(store_syslogpri, SUDO_DEBUG_DEFAULTS)
1.1 misho 792:
1.1.1.2 misho 793: if (op == false || !val)
794: debug_return_bool(false);
1.1 misho 795:
796: for (pri = priorities; pri->name && strcmp(val, pri->name); pri++)
797: ;
798: if (pri->name == NULL)
1.1.1.2 misho 799: debug_return_bool(false); /* not found */
1.1 misho 800:
801: def->sd_un.ival = pri->num;
1.1.1.2 misho 802: debug_return_bool(true);
1.1 misho 803: }
804:
805: static const char *
806: logpri2str(int n)
807: {
808: struct strmap *pri;
1.1.1.2 misho 809: debug_decl(logpri2str, SUDO_DEBUG_DEFAULTS)
1.1 misho 810:
811: for (pri = priorities; pri->name && pri->num != n; pri++)
812: ;
1.1.1.6 ! misho 813: debug_return_const_str(pri->name);
1.1 misho 814: }
815:
1.1.1.2 misho 816: static bool
1.1 misho 817: store_mode(char *val, struct sudo_defs_types *def, int op)
818: {
1.1.1.6 ! misho 819: mode_t mode;
! 820: const char *errstr;
1.1.1.2 misho 821: debug_decl(store_mode, SUDO_DEBUG_DEFAULTS)
1.1 misho 822:
1.1.1.2 misho 823: if (op == false) {
1.1.1.6 ! misho 824: def->sd_un.mode = 0777;
1.1 misho 825: } else {
1.1.1.6 ! misho 826: mode = atomode(val, &errstr);
! 827: if (errstr != NULL) {
! 828: sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
! 829: "%s is %s", val, errstr);
1.1.1.2 misho 830: debug_return_bool(false);
1.1.1.6 ! misho 831: }
! 832: def->sd_un.mode = mode;
1.1 misho 833: }
834: if (def->callback)
1.1.1.2 misho 835: debug_return_bool(def->callback(val));
836: debug_return_bool(true);
1.1 misho 837: }
838:
839: static void
840: list_op(char *val, size_t len, struct sudo_defs_types *def, enum list_ops op)
841: {
1.1.1.6 ! misho 842: struct list_member *cur, *prev = NULL;
1.1.1.2 misho 843: debug_decl(list_op, SUDO_DEBUG_DEFAULTS)
1.1 misho 844:
845: if (op == freeall) {
1.1.1.6 ! misho 846: while ((cur = SLIST_FIRST(&def->sd_un.list)) != NULL) {
! 847: SLIST_REMOVE_HEAD(&def->sd_un.list, entries);
! 848: efree(cur->value);
! 849: efree(cur);
1.1 misho 850: }
1.1.1.2 misho 851: debug_return;
1.1 misho 852: }
853:
1.1.1.6 ! misho 854: SLIST_FOREACH(cur, &def->sd_un.list, entries) {
1.1 misho 855: if ((strncmp(cur->value, val, len) == 0 && cur->value[len] == '\0')) {
856:
857: if (op == add)
1.1.1.2 misho 858: debug_return; /* already exists */
1.1 misho 859:
860: /* Delete node */
1.1.1.6 ! misho 861: if (prev == NULL)
! 862: SLIST_REMOVE_HEAD(&def->sd_un.list, entries);
1.1 misho 863: else
1.1.1.6 ! misho 864: SLIST_REMOVE_AFTER(prev, entries);
1.1 misho 865: efree(cur->value);
866: efree(cur);
867: break;
868: }
1.1.1.6 ! misho 869: prev = cur;
1.1 misho 870: }
871:
872: /* Add new node to the head of the list. */
873: if (op == add) {
1.1.1.2 misho 874: cur = ecalloc(1, sizeof(struct list_member));
875: cur->value = estrndup(val, len);
1.1.1.6 ! misho 876: SLIST_INSERT_HEAD(&def->sd_un.list, cur, entries);
1.1 misho 877: }
1.1.1.2 misho 878: debug_return;
1.1 misho 879: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>