1 /*
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 1993-1996, 1998-2020 Todd C. Miller <Todd.Miller@sudo.ws>
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * Sponsored in part by the Defense Advanced Research Projects
19 * Agency (DARPA) and Air Force Research Laboratory, Air Force
20 * Materiel Command, USAF, under agreement number F39502-99-1-0512.
21 */
22
23 /*
24 * This is an open source non-commercial project. Dear PVS-Studio, please check it.
25 * PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
26 */
27
28 #ifdef __TANDEM
29 # include <floss.h>
30 #endif
31
32 #include <config.h>
33
34 #include <sys/types.h>
35 #include <sys/resource.h>
36 #include <sys/stat.h>
37 #include <sys/socket.h>
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <string.h>
41 #include <unistd.h>
42 #include <pwd.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <grp.h>
46 #include <netdb.h>
47 #ifdef HAVE_LOGIN_CAP_H
48 # include <login_cap.h>
49 # ifndef LOGIN_DEFROOTCLASS
50 # define LOGIN_DEFROOTCLASS "daemon"
51 # endif
52 # ifndef LOGIN_SETENV
53 # define LOGIN_SETENV 0
54 # endif
55 #endif
56 #ifdef HAVE_SELINUX
57 # include <selinux/selinux.h>
58 #endif
59 #include <ctype.h>
60 #ifndef HAVE_GETADDRINFO
61 # include "compat/getaddrinfo.h"
62 #endif
63
64 #include "sudoers.h"
65 #include "parse.h"
66 #include "check.h"
67 #include "auth/sudo_auth.h"
68 #include "sudo_iolog.h"
69
70 /*
71 * Prototypes
72 */
73 static int set_cmnd(void);
74 static bool init_vars(char * const *);
75 static bool set_loginclass(struct passwd *);
76 static bool set_runasgr(const char *, bool);
77 static bool set_runaspw(const char *, bool);
78 static bool tty_present(void);
79 static void set_callbacks(void);
80
81 /*
82 * Globals
83 */
84 struct sudo_user sudo_user;
85 struct passwd *list_pw;
86 uid_t timestamp_uid;
87 gid_t timestamp_gid;
88 bool force_umask;
89 int sudo_mode;
90
91 static char *prev_user;
92 static struct sudo_nss_list *snl;
93 static bool unknown_runas_uid;
94 static bool unknown_runas_gid;
95 static int cmnd_status = -1;
96 static struct defaults_list initial_defaults = TAILQ_HEAD_INITIALIZER(initial_defaults);
97
98 #ifdef __linux__
99 static struct rlimit nproclimit;
100 #endif
101
102 /* XXX - must be extern for audit bits of sudo_auth.c */
103 int NewArgc;
104 char **NewArgv;
105
106 #ifdef SUDOERS_LOG_CLIENT
107 # define remote_iologs (!SLIST_EMPTY(&def_log_servers))
108 #else
109 # define remote_iologs 0
110 #endif
111
112 /*
113 * Unlimit the number of processes since Linux's setuid() will
114 * apply resource limits when changing uid and return EAGAIN if
115 * nproc would be exceeded by the uid switch.
116 */
117 static void
unlimit_nproc(void)118 unlimit_nproc(void)
119 {
120 #ifdef __linux__
121 struct rlimit rl;
122 debug_decl(unlimit_nproc, SUDOERS_DEBUG_UTIL);
123
124 if (getrlimit(RLIMIT_NPROC, &nproclimit) != 0)
125 sudo_warn("getrlimit(RLIMIT_NPROC)");
126 rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
127 if (setrlimit(RLIMIT_NPROC, &rl) != 0) {
128 rl.rlim_cur = rl.rlim_max = nproclimit.rlim_max;
129 if (setrlimit(RLIMIT_NPROC, &rl) != 0)
130 sudo_warn("setrlimit(RLIMIT_NPROC)");
131 }
132 debug_return;
133 #endif /* __linux__ */
134 }
135
136 /*
137 * Restore saved value of RLIMIT_NPROC.
138 */
139 static void
restore_nproc(void)140 restore_nproc(void)
141 {
142 #ifdef __linux__
143 debug_decl(restore_nproc, SUDOERS_DEBUG_UTIL);
144
145 if (setrlimit(RLIMIT_NPROC, &nproclimit) != 0)
146 sudo_warn("setrlimit(RLIMIT_NPROC)");
147
148 debug_return;
149 #endif /* __linux__ */
150 }
151
152 static bool
sudoers_reinit_defaults(void)153 sudoers_reinit_defaults(void)
154 {
155 struct sudo_nss *nss, *nss_next;
156 debug_decl(sudoers_reinit_defaults, SUDOERS_DEBUG_PLUGIN);
157
158 if (!init_defaults()) {
159 sudo_warnx("%s", U_("unable to initialize sudoers default values"));
160 debug_return_bool(false);
161 }
162
163 if (!update_defaults(NULL, &initial_defaults,
164 SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
165 log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
166 N_("problem with defaults entries"));
167 debug_return_bool(false);
168 }
169
170 TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
171 if (nss->getdefs(nss) == -1 || !update_defaults(nss->parse_tree, NULL,
172 SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
173 log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
174 N_("problem with defaults entries"));
175 /* not a fatal error */
176 }
177 }
178
179 debug_return_int(true);
180 }
181
182 int
sudoers_init(void * info,char * const envp[])183 sudoers_init(void *info, char * const envp[])
184 {
185 struct sudo_nss *nss, *nss_next;
186 int oldlocale, sources = 0;
187 static int ret = -1;
188 debug_decl(sudoers_init, SUDOERS_DEBUG_PLUGIN);
189
190 /* Only initialize once. */
191 if (snl != NULL)
192 debug_return_int(ret);
193
194 bindtextdomain("sudoers", LOCALEDIR);
195
196 /* Register fatal/fatalx callback. */
197 sudo_fatal_callback_register(sudoers_cleanup);
198
199 /* Initialize environment functions (including replacements). */
200 if (!env_init(envp))
201 debug_return_int(-1);
202
203 /* Setup defaults data structures. */
204 if (!init_defaults()) {
205 sudo_warnx("%s", U_("unable to initialize sudoers default values"));
206 debug_return_int(-1);
207 }
208
209 /* Parse info from front-end. */
210 sudo_mode = sudoers_policy_deserialize_info(info, &initial_defaults);
211 if (ISSET(sudo_mode, MODE_ERROR))
212 debug_return_int(-1);
213
214 if (!init_vars(envp))
215 debug_return_int(-1);
216
217 /* Parse nsswitch.conf for sudoers order. */
218 snl = sudo_read_nss();
219
220 /* LDAP or NSS may modify the euid so we need to be root for the open. */
221 if (!set_perms(PERM_ROOT))
222 debug_return_int(-1);
223
224 /* Update defaults set by front-end. */
225 if (!update_defaults(NULL, &initial_defaults,
226 SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
227 log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
228 N_("problem with defaults entries"));
229 debug_return_int(-1);
230 }
231
232 /*
233 * Open and parse sudoers, set global defaults.
234 * Uses the C locale unless another is specified in sudoers.
235 */
236 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
237 sudo_warn_set_locale_func(sudoers_warn_setlocale);
238 init_parser(sudoers_file, false, false);
239 TAILQ_FOREACH_SAFE(nss, snl, entries, nss_next) {
240 if (nss->open(nss) == -1 || (nss->parse_tree = nss->parse(nss)) == NULL) {
241 TAILQ_REMOVE(snl, nss, entries);
242 continue;
243 }
244
245 sources++;
246 if (nss->getdefs(nss) == -1 || !update_defaults(nss->parse_tree, NULL,
247 SETDEF_GENERIC|SETDEF_HOST|SETDEF_USER|SETDEF_RUNAS, false)) {
248 log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
249 N_("problem with defaults entries"));
250 }
251 }
252 if (sources == 0) {
253 sudo_warnx("%s", U_("no valid sudoers sources found, quitting"));
254 goto cleanup;
255 }
256
257 /* Set login class if applicable (after sudoers is parsed). */
258 if (set_loginclass(runas_pw ? runas_pw : sudo_user.pw))
259 ret = true;
260
261 cleanup:
262 if (!restore_perms())
263 ret = -1;
264
265 /* Restore user's locale. */
266 sudo_warn_set_locale_func(NULL);
267 sudoers_setlocale(oldlocale, NULL);
268
269 debug_return_int(ret);
270 }
271
272 /*
273 * Expand I/O log dir and file into a full path.
274 * Returns the full I/O log path prefixed with "iolog_path=".
275 * Sets sudo_user.iolog_file as a side effect.
276 */
277 static char *
format_iolog_path(void)278 format_iolog_path(void)
279 {
280 char dir[PATH_MAX], file[PATH_MAX];
281 char *iolog_path = NULL;
282 int oldlocale;
283 bool ok;
284 debug_decl(format_iolog_path, SUDOERS_DEBUG_PLUGIN);
285
286 /* Use sudoers locale for strftime() */
287 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
288 ok = expand_iolog_path(def_iolog_dir, dir, sizeof(dir),
289 &sudoers_iolog_path_escapes[1], NULL);
290 if (ok) {
291 ok = expand_iolog_path(def_iolog_file, file, sizeof(file),
292 &sudoers_iolog_path_escapes[0], dir);
293 }
294 sudoers_setlocale(oldlocale, NULL);
295 if (!ok)
296 goto done;
297
298 if (asprintf(&iolog_path, "iolog_path=%s/%s", dir, file) == -1) {
299 iolog_path = NULL;
300 goto done;
301 }
302
303 /* Stash pointer to the I/O log for the event log. */
304 sudo_user.iolog_path = iolog_path + sizeof("iolog_path=") - 1;
305 sudo_user.iolog_file = sudo_user.iolog_path + 1 + strlen(dir);
306
307 done:
308 debug_return_str(iolog_path);
309 }
310
311 static int
check_user_runchroot(void)312 check_user_runchroot(void)
313 {
314 debug_decl(check_user_runchroot, SUDOERS_DEBUG_PLUGIN);
315
316 if (user_runchroot == NULL)
317 debug_return_bool(true);
318
319 sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
320 "def_runchroot %s, user_runchroot %s",
321 def_runchroot ? def_runchroot : "none",
322 user_runchroot ? user_runchroot : "none");
323
324 if (def_runchroot == NULL || (strcmp(def_runchroot, "*") != 0 &&
325 strcmp(def_runchroot, user_runchroot) != 0)) {
326 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
327 N_("user not allowed to change root directory to %s"),
328 user_runchroot);
329 sudo_warnx(U_("you are not permitted to use the -R option with %s"),
330 user_cmnd);
331 debug_return_bool(false);
332 }
333 free(def_runchroot);
334 if ((def_runchroot = strdup(user_runchroot)) == NULL) {
335 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
336 debug_return_int(-1);
337 }
338 debug_return_bool(true);
339 }
340
341 static int
check_user_runcwd(void)342 check_user_runcwd(void)
343 {
344 debug_decl(check_user_runcwd, SUDOERS_DEBUG_PLUGIN);
345
346 sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
347 "def_runcwd %s, user_runcwd %s, user_cwd %s",
348 def_runcwd ? def_runcwd : "none", user_runcwd ? user_runcwd : "none",
349 user_cwd ? user_cwd : "none");
350
351 if (strcmp(user_cwd, user_runcwd) != 0) {
352 if (def_runcwd == NULL || strcmp(def_runcwd, "*") != 0) {
353 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
354 N_("user not allowed to change directory to %s"), user_runcwd);
355 sudo_warnx(U_("you are not permitted to use the -D option with %s"),
356 user_cmnd);
357 debug_return_bool(false);
358 }
359 free(def_runcwd);
360 if ((def_runcwd = strdup(user_runcwd)) == NULL) {
361 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
362 debug_return_int(-1);
363 }
364 }
365 debug_return_bool(true);
366 }
367
368 static bool need_reinit;
369
370 int
sudoers_policy_main(int argc,char * const argv[],int pwflag,char * env_add[],bool verbose,void * closure)371 sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
372 bool verbose, void *closure)
373 {
374 char *iolog_path = NULL;
375 mode_t cmnd_umask = ACCESSPERMS;
376 int oldlocale, validated, ret = -1;
377 debug_decl(sudoers_policy_main, SUDOERS_DEBUG_PLUGIN);
378
379 sudo_warn_set_locale_func(sudoers_warn_setlocale);
380
381 if (argc == 0) {
382 sudo_warnx("%s", U_("no command specified"));
383 debug_return_int(-1);
384 }
385
386 /* Was previous command was intercepted? */
387 if (def_intercept)
388 SET(sudo_mode, MODE_POLICY_INTERCEPTED);
389
390 /* Only certain mode flags are legal for intercepted commands. */
391 if (ISSET(sudo_mode, MODE_POLICY_INTERCEPTED))
392 sudo_mode &= MODE_INTERCEPT_MASK;
393
394 /* Re-initialize defaults if we are called multiple times. */
395 if (need_reinit) {
396 if (!sudoers_reinit_defaults())
397 debug_return_int(-1);
398 }
399 need_reinit = true;
400
401 unlimit_nproc();
402
403 /* Is root even allowed to run sudo? */
404 if (user_uid == 0 && !def_root_sudo) {
405 /* Not an audit event (should it be?). */
406 sudo_warnx("%s",
407 U_("sudoers specifies that root is not allowed to sudo"));
408 goto bad;
409 }
410
411 if (!set_perms(PERM_INITIAL))
412 goto bad;
413
414 /* Environment variables specified on the command line. */
415 if (env_add != NULL && env_add[0] != NULL)
416 sudo_user.env_vars = env_add;
417
418 /*
419 * Make a local copy of argc/argv, with special handling for the
420 * '-i' option. We also allocate an extra slot for bash's --login.
421 */
422 if (NewArgv != NULL) {
423 sudoers_gc_remove(GC_PTR, NewArgv);
424 free(NewArgv);
425 }
426 NewArgc = argc;
427 NewArgv = reallocarray(NULL, NewArgc + 2, sizeof(char *));
428 if (NewArgv == NULL) {
429 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
430 goto done;
431 }
432 sudoers_gc_add(GC_PTR, NewArgv);
433 memcpy(NewArgv, argv, argc * sizeof(char *));
434 NewArgv[NewArgc] = NULL;
435 if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL) {
436 NewArgv[0] = strdup(runas_pw->pw_shell);
437 if (NewArgv[0] == NULL) {
438 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
439 goto done;
440 }
441 sudoers_gc_add(GC_PTR, NewArgv[0]);
442 }
443
444 /* If given the -P option, set the "preserve_groups" flag. */
445 if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
446 def_preserve_groups = true;
447
448 /* Find command in path and apply per-command Defaults. */
449 cmnd_status = set_cmnd();
450 if (cmnd_status == NOT_FOUND_ERROR)
451 goto done;
452
453 /* Check for -C overriding def_closefrom. */
454 if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
455 if (!def_closefrom_override) {
456 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
457 N_("user not allowed to override closefrom limit"));
458 sudo_warnx("%s", U_("you are not permitted to use the -C option"));
459 goto bad;
460 }
461 def_closefrom = user_closefrom;
462 }
463
464 /*
465 * Check sudoers sources, using the locale specified in sudoers.
466 */
467 sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
468 validated = sudoers_lookup(snl, sudo_user.pw, &cmnd_status, pwflag);
469 if (ISSET(validated, VALIDATE_ERROR)) {
470 /* The lookup function should have printed an error. */
471 goto done;
472 }
473
474 /* Restore user's locale. */
475 sudoers_setlocale(oldlocale, NULL);
476
477 if (safe_cmnd == NULL) {
478 if ((safe_cmnd = strdup(user_cmnd)) == NULL) {
479 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
480 goto done;
481 }
482 }
483
484 /* Defer uid/gid checks until after defaults have been updated. */
485 if (unknown_runas_uid && !def_runas_allow_unknown_id) {
486 log_warningx(SLOG_AUDIT, N_("unknown user %s"), runas_pw->pw_name);
487 goto done;
488 }
489 if (runas_gr != NULL) {
490 if (unknown_runas_gid && !def_runas_allow_unknown_id) {
491 log_warningx(SLOG_AUDIT, N_("unknown group %s"),
492 runas_gr->gr_name);
493 goto done;
494 }
495 }
496
497 /*
498 * Look up the timestamp dir owner if one is specified.
499 */
500 if (def_timestampowner) {
501 struct passwd *pw = NULL;
502
503 if (*def_timestampowner == '#') {
504 const char *errstr;
505 uid_t uid = sudo_strtoid(def_timestampowner + 1, &errstr);
506 if (errstr == NULL)
507 pw = sudo_getpwuid(uid);
508 }
509 if (pw == NULL)
510 pw = sudo_getpwnam(def_timestampowner);
511 if (pw != NULL) {
512 timestamp_uid = pw->pw_uid;
513 timestamp_gid = pw->pw_gid;
514 sudo_pw_delref(pw);
515 } else {
516 /* XXX - audit too? */
517 log_warningx(SLOG_SEND_MAIL,
518 N_("timestamp owner (%s): No such user"), def_timestampowner);
519 timestamp_uid = ROOT_UID;
520 timestamp_gid = ROOT_GID;
521 }
522 }
523
524 /* If no command line args and "shell_noargs" is not set, error out. */
525 if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
526 /* Not an audit event. */
527 ret = -2; /* usage error */
528 goto done;
529 }
530
531 /* Bail if a tty is required and we don't have one. */
532 if (def_requiretty && !tty_present()) {
533 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT, N_("no tty"));
534 sudo_warnx("%s", U_("sorry, you must have a tty to run sudo"));
535 goto bad;
536 }
537
538 /* Check runas user's shell. */
539 if (!check_user_shell(runas_pw)) {
540 log_warningx(SLOG_RAW_MSG|SLOG_AUDIT,
541 N_("invalid shell for user %s: %s"),
542 runas_pw->pw_name, runas_pw->pw_shell);
543 goto bad;
544 }
545
546 /*
547 * We don't reset the environment for sudoedit or if the user
548 * specified the -E command line flag and they have setenv privs.
549 */
550 if (ISSET(sudo_mode, MODE_EDIT) ||
551 (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv))
552 def_env_reset = false;
553
554 /* Build a new environment that avoids any nasty bits. */
555 if (!rebuild_env())
556 goto bad;
557
558 /* Require a password if sudoers says so. */
559 switch (check_user(validated, sudo_mode)) {
560 case true:
561 /* user authenticated successfully. */
562 break;
563 case false:
564 /* Note: log_denial() calls audit for us. */
565 if (!ISSET(validated, VALIDATE_SUCCESS)) {
566 /* Only display a denial message if no password was read. */
567 if (!log_denial(validated, def_passwd_tries <= 0))
568 goto done;
569 }
570 goto bad;
571 default:
572 /* some other error, ret is -1. */
573 goto done;
574 }
575
576 /* Check whether user_runchroot is permitted (if specified). */
577 switch (check_user_runchroot()) {
578 case true:
579 break;
580 case false:
581 goto bad;
582 default:
583 goto done;
584 }
585
586 /* Check whether user_runcwd is permitted (if specified). */
587 switch (check_user_runcwd()) {
588 case true:
589 break;
590 case false:
591 goto bad;
592 default:
593 goto done;
594 }
595
596 /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
597 /* XXX - causes confusion when root is not listed in sudoers */
598 if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT) && prev_user != NULL) {
599 if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
600 struct passwd *pw;
601
602 if ((pw = sudo_getpwnam(prev_user)) != NULL) {
603 if (sudo_user.pw != NULL)
604 sudo_pw_delref(sudo_user.pw);
605 sudo_user.pw = pw;
606 }
607 }
608 }
609
610 /* If the user was not allowed to run the command we are done. */
611 if (!ISSET(validated, VALIDATE_SUCCESS)) {
612 /* Note: log_failure() calls audit for us. */
613 if (!log_failure(validated, cmnd_status))
614 goto done;
615 goto bad;
616 }
617
618 /* Create Ubuntu-style dot file to indicate sudo was successful. */
619 if (create_admin_success_flag() == -1)
620 goto done;
621
622 /* Finally tell the user if the command did not exist. */
623 if (cmnd_status == NOT_FOUND_DOT) {
624 audit_failure(NewArgv, N_("command in current directory"));
625 sudo_warnx(U_("ignoring \"%s\" found in '.'\nUse \"sudo ./%s\" if this is the \"%s\" you wish to run."), user_cmnd, user_cmnd, user_cmnd);
626 goto bad;
627 } else if (cmnd_status == NOT_FOUND) {
628 if (ISSET(sudo_mode, MODE_CHECK)) {
629 audit_failure(NewArgv, N_("%s: command not found"),
630 NewArgv[0]);
631 sudo_warnx(U_("%s: command not found"), NewArgv[0]);
632 } else {
633 audit_failure(NewArgv, N_("%s: command not found"),
634 user_cmnd);
635 sudo_warnx(U_("%s: command not found"), user_cmnd);
636 }
637 goto bad;
638 }
639
640 /* If user specified a timeout make sure sudoers allows it. */
641 if (!def_user_command_timeouts && user_timeout > 0) {
642 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
643 N_("user not allowed to set a command timeout"));
644 sudo_warnx("%s",
645 U_("sorry, you are not allowed set a command timeout"));
646 goto bad;
647 }
648
649 /* If user specified env vars make sure sudoers allows it. */
650 if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
651 if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) {
652 log_warningx(SLOG_NO_STDERR|SLOG_AUDIT,
653 N_("user not allowed to preserve the environment"));
654 sudo_warnx("%s",
655 U_("sorry, you are not allowed to preserve the environment"));
656 goto bad;
657 } else {
658 if (!validate_env_vars(sudo_user.env_vars))
659 goto bad;
660 }
661 }
662
663 if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT)) && !remote_iologs) {
664 if ((def_log_input || def_log_output) && def_iolog_file && def_iolog_dir) {
665 if ((iolog_path = format_iolog_path()) == NULL) {
666 if (!def_ignore_iolog_errors)
667 goto done;
668 /* Unable to expand I/O log path, disable I/O logging. */
669 def_log_input = false;
670 def_log_output = false;
671 }
672 }
673 }
674
675 switch (sudo_mode & MODE_MASK) {
676 case MODE_CHECK:
677 ret = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
678 break;
679 case MODE_LIST:
680 ret = display_privs(snl, list_pw ? list_pw : sudo_user.pw, verbose);
681 break;
682 case MODE_VALIDATE:
683 case MODE_RUN:
684 case MODE_EDIT:
685 /* ret may be overridden by "goto bad" later */
686 ret = true;
687 break;
688 default:
689 /* Should not happen. */
690 sudo_warnx("internal error, unexpected sudo mode 0x%x", sudo_mode);
691 goto done;
692 }
693
694 if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST))) {
695 /* ret already set appropriately */
696 goto done;
697 }
698
699 /*
700 * Set umask based on sudoers.
701 * If user's umask is more restrictive, OR in those bits too
702 * unless umask_override is set.
703 */
704 if (def_umask != ACCESSPERMS) {
705 cmnd_umask = def_umask;
706 if (!def_umask_override)
707 cmnd_umask |= user_umask;
708 }
709
710 if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
711 char *p;
712
713 /* Convert /bin/sh -> -sh so shell knows it is a login shell */
714 if ((p = strrchr(NewArgv[0], '/')) == NULL)
715 p = NewArgv[0];
716 *p = '-';
717 NewArgv[0] = p;
718
719 /*
720 * Newer versions of bash require the --login option to be used
721 * in conjunction with the -c option even if the shell name starts
722 * with a '-'. Unfortunately, bash 1.x uses -login, not --login
723 * so this will cause an error for that.
724 */
725 if (NewArgc > 1 && strcmp(NewArgv[0], "-bash") == 0 &&
726 strcmp(NewArgv[1], "-c") == 0) {
727 /* We allocated extra space for the --login above. */
728 memmove(&NewArgv[2], &NewArgv[1], sizeof(char *) * NewArgc);
729 NewArgv[1] = "--login";
730 NewArgc++;
731 }
732
733 #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
734 /* Insert system-wide environment variables. */
735 if (!read_env_file(_PATH_ENVIRONMENT, true, false))
736 sudo_warn("%s", _PATH_ENVIRONMENT);
737 #endif
738 #ifdef HAVE_LOGIN_CAP_H
739 /* Set environment based on login class. */
740 if (login_class) {
741 login_cap_t *lc = login_getclass(login_class);
742 if (lc != NULL) {
743 setusercontext(lc, runas_pw, runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
744 login_close(lc);
745 }
746 }
747 #endif /* HAVE_LOGIN_CAP_H */
748 }
749
750 /* Insert system-wide environment variables. */
751 if (def_restricted_env_file) {
752 if (!read_env_file(def_restricted_env_file, false, true))
753 sudo_warn("%s", def_restricted_env_file);
754 }
755 if (def_env_file) {
756 if (!read_env_file(def_env_file, false, false))
757 sudo_warn("%s", def_env_file);
758 }
759
760 /* Insert user-specified environment variables. */
761 if (!insert_env_vars(sudo_user.env_vars))
762 goto done;
763
764 /* Note: must call audit before uid change. */
765 if (ISSET(sudo_mode, MODE_EDIT)) {
766 char **edit_argv;
767 int edit_argc;
768 const char *env_editor;
769
770 free(safe_cmnd);
771 safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argc,
772 &edit_argv, NULL, &env_editor, false);
773 if (safe_cmnd == NULL) {
774 if (errno != ENOENT)
775 goto done;
776 audit_failure(NewArgv, N_("%s: command not found"),
777 env_editor ? env_editor : def_editor);
778 sudo_warnx(U_("%s: command not found"),
779 env_editor ? env_editor : def_editor);
780 goto bad;
781 }
782 /* find_editor() already g/c'd edit_argv[] */
783 sudoers_gc_remove(GC_PTR, NewArgv);
784 free(NewArgv);
785 NewArgv = edit_argv;
786 NewArgc = edit_argc;
787
788 /* We want to run the editor with the unmodified environment. */
789 env_swap_old();
790 }
791
792 goto done;
793
794 bad:
795 ret = false;
796
797 done:
798 if (def_group_plugin)
799 group_plugin_unload();
800 init_parser(NULL, false, false);
801
802 if (ret == -1) {
803 /* Free stashed copy of the environment. */
804 (void)env_init(NULL);
805 } else {
806 /* Store settings to pass back to front-end. */
807 if (!sudoers_policy_store_result(ret, NewArgv, env_get(), cmnd_umask,
808 iolog_path, closure))
809 ret = -1;
810 }
811
812 if (!rewind_perms())
813 ret = -1;
814
815 restore_nproc();
816
817 sudo_warn_set_locale_func(NULL);
818
819 debug_return_int(ret);
820 }
821
822 /*
823 * Initialize timezone and fill in sudo_user struct.
824 */
825 static bool
init_vars(char * const envp[])826 init_vars(char * const envp[])
827 {
828 char * const * ep;
829 bool unknown_user = false;
830 debug_decl(init_vars, SUDOERS_DEBUG_PLUGIN);
831
832 if (!sudoers_initlocale(setlocale(LC_ALL, NULL), def_sudoers_locale)) {
833 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
834 debug_return_bool(false);
835 }
836
837 #define MATCHES(s, v) \
838 (strncmp((s), (v), sizeof(v) - 1) == 0 && (s)[sizeof(v) - 1] != '\0')
839
840 for (ep = envp; *ep; ep++) {
841 switch (**ep) {
842 case 'K':
843 if (MATCHES(*ep, "KRB5CCNAME="))
844 user_ccname = *ep + sizeof("KRB5CCNAME=") - 1;
845 break;
846 case 'P':
847 if (MATCHES(*ep, "PATH="))
848 user_path = *ep + sizeof("PATH=") - 1;
849 break;
850 case 'S':
851 if (MATCHES(*ep, "SUDO_PROMPT=")) {
852 /* Don't override "sudo -p prompt" */
853 if (user_prompt == NULL)
854 user_prompt = *ep + sizeof("SUDO_PROMPT=") - 1;
855 break;
856 }
857 if (MATCHES(*ep, "SUDO_USER="))
858 prev_user = *ep + sizeof("SUDO_USER=") - 1;
859 break;
860 }
861 }
862 #undef MATCHES
863
864 /*
865 * Get a local copy of the user's passwd struct and group list if we
866 * don't already have them.
867 */
868 if (sudo_user.pw == NULL) {
869 if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) {
870 /*
871 * It is not unusual for users to place "sudo -k" in a .logout
872 * file which can cause sudo to be run during reboot after the
873 * YP/NIS/NIS+/LDAP/etc daemon has died.
874 */
875 if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE) {
876 sudo_warnx(U_("unknown uid %u"), (unsigned int) user_uid);
877 debug_return_bool(false);
878 }
879
880 /* Need to make a fake struct passwd for the call to log_warningx(). */
881 sudo_user.pw = sudo_mkpwent(user_name, user_uid, user_gid, NULL, NULL);
882 unknown_user = true;
883 }
884 }
885 if (user_gid_list == NULL)
886 user_gid_list = sudo_get_gidlist(sudo_user.pw, ENTRY_TYPE_ANY);
887
888 /* Store initialize permissions so we can restore them later. */
889 if (!set_perms(PERM_INITIAL))
890 debug_return_bool(false);
891
892 /* Set parse callbacks */
893 set_callbacks();
894
895 /* It is now safe to use log_warningx() and set_perms() */
896 if (unknown_user) {
897 log_warningx(SLOG_SEND_MAIL, N_("unknown uid %u"),
898 (unsigned int) user_uid);
899 debug_return_bool(false);
900 }
901
902 /*
903 * Set runas passwd/group entries based on command line or sudoers.
904 * Note that if runas_group was specified without runas_user we
905 * run the command as the invoking user.
906 */
907 if (sudo_user.runas_group != NULL) {
908 if (!set_runasgr(sudo_user.runas_group, false))
909 debug_return_bool(false);
910 if (!set_runaspw(sudo_user.runas_user ?
911 sudo_user.runas_user : user_name, false))
912 debug_return_bool(false);
913 } else {
914 if (!set_runaspw(sudo_user.runas_user ?
915 sudo_user.runas_user : def_runas_default, false))
916 debug_return_bool(false);
917 }
918
919 debug_return_bool(true);
920 }
921
922 /*
923 * Fill in user_cmnd and user_stat variables.
924 * Does not fill in user_base.
925 */
926 int
set_cmnd_path(const char * runchroot)927 set_cmnd_path(const char *runchroot)
928 {
929 char *path = user_path;
930 int ret;
931 debug_decl(set_cmnd_path, SUDOERS_DEBUG_PLUGIN);
932
933 free(user_cmnd);
934 user_cmnd = NULL;
935 if (def_secure_path && !user_is_exempt())
936 path = def_secure_path;
937 if (!set_perms(PERM_RUNAS))
938 debug_return_int(NOT_FOUND_ERROR);
939 ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
940 runchroot, def_ignore_dot, NULL);
941 if (!restore_perms())
942 debug_return_int(NOT_FOUND_ERROR);
943 if (ret == NOT_FOUND) {
944 /* Failed as root, try as invoking user. */
945 if (!set_perms(PERM_USER))
946 debug_return_int(false);
947 ret = find_path(NewArgv[0], &user_cmnd, user_stat, path,
948 runchroot, def_ignore_dot, NULL);
949 if (!restore_perms())
950 debug_return_int(NOT_FOUND_ERROR);
951 }
952
953 debug_return_int(ret);
954 }
955
956 /*
957 * Fill in user_cmnd, user_args, user_base and user_stat variables
958 * and apply any command-specific defaults entries.
959 */
960 static int
set_cmnd(void)961 set_cmnd(void)
962 {
963 struct sudo_nss *nss;
964 int ret = FOUND;
965 debug_decl(set_cmnd, SUDOERS_DEBUG_PLUGIN);
966
967 /* Allocate user_stat for find_path() and match functions. */
968 free(user_stat);
969 user_stat = calloc(1, sizeof(struct stat));
970 if (user_stat == NULL) {
971 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
972 debug_return_int(NOT_FOUND_ERROR);
973 }
974
975 /* Re-initialize for when we are called multiple times. */
976 free(safe_cmnd);
977 safe_cmnd = NULL;
978
979 if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT|MODE_CHECK)) {
980 if (!ISSET(sudo_mode, MODE_EDIT)) {
981 const char *runchroot = user_runchroot;
982 if (runchroot == NULL && def_runchroot != NULL &&
983 strcmp(def_runchroot, "*") != 0)
984 runchroot = def_runchroot;
985
986 ret = set_cmnd_path(runchroot);
987 if (ret == NOT_FOUND_ERROR) {
988 if (errno == ENAMETOOLONG) {
989 audit_failure(NewArgv, N_("command too long"));
990 }
991 log_warning(0, "%s", NewArgv[0]);
992 debug_return_int(ret);
993 }
994 }
995
996 /* set user_args */
997 free(user_args);
998 user_args = NULL;
999 if (NewArgc > 1) {
1000 if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL) &&
1001 ISSET(sudo_mode, MODE_RUN)) {
1002 /*
1003 * When running a command via a shell, the sudo front-end
1004 * escapes potential meta chars. We unescape non-spaces
1005 * for sudoers matching and logging purposes.
1006 */
1007 user_args = strvec_join(NewArgv + 1, ' ', strlcpy_unescape);
1008 } else {
1009 user_args = strvec_join(NewArgv + 1, ' ', NULL);
1010 }
1011 if (user_args == NULL)
1012 debug_return_int(NOT_FOUND_ERROR);
1013 }
1014 }
1015 if (user_cmnd == NULL) {
1016 user_cmnd = strdup(NewArgv[0]);
1017 if (user_cmnd == NULL)
1018 debug_return_int(NOT_FOUND_ERROR);
1019 }
1020 user_base = sudo_basename(user_cmnd);
1021
1022 /* Convert "sudo sudoedit" -> "sudoedit" */
1023 if (ISSET(sudo_mode, MODE_RUN) && strcmp(user_base, "sudoedit") == 0) {
1024 char *new_cmnd;
1025
1026 CLR(sudo_mode, MODE_RUN);
1027 SET(sudo_mode, MODE_EDIT);
1028 sudo_warnx("%s", U_("sudoedit doesn't need to be run via sudo"));
1029 if ((new_cmnd = strdup("sudoedit")) == NULL) {
1030 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1031 debug_return_int(NOT_FOUND_ERROR);
1032 }
1033 free(user_cmnd);
1034 user_base = user_cmnd = new_cmnd;
1035 }
1036
1037 TAILQ_FOREACH(nss, snl, entries) {
1038 if (!update_defaults(nss->parse_tree, NULL, SETDEF_CMND, false)) {
1039 log_warningx(SLOG_SEND_MAIL|SLOG_NO_STDERR,
1040 N_("problem with defaults entries"));
1041 }
1042 }
1043
1044 debug_return_int(ret);
1045 }
1046
1047 /*
1048 * Open sudoers file and check mode/owner/type.
1049 * Returns a handle to the sudoers file or NULL on error.
1050 */
1051 FILE *
open_sudoers(const char * file,bool doedit,bool * keepopen)1052 open_sudoers(const char *file, bool doedit, bool *keepopen)
1053 {
1054 struct stat sb;
1055 FILE *fp = NULL;
1056 bool perm_root = false;
1057 debug_decl(open_sudoers, SUDOERS_DEBUG_PLUGIN);
1058
1059 if (!set_perms(PERM_SUDOERS))
1060 debug_return_ptr(NULL);
1061
1062 again:
1063 switch (sudo_secure_file(file, sudoers_uid, sudoers_gid, &sb)) {
1064 case SUDO_PATH_SECURE:
1065 /*
1066 * If we are expecting sudoers to be group readable by
1067 * SUDOERS_GID but it is not, we must open the file as root,
1068 * not uid 1.
1069 */
1070 if (sudoers_uid == ROOT_UID && ISSET(sudoers_mode, S_IRGRP)) {
1071 if (!ISSET(sb.st_mode, S_IRGRP) || sb.st_gid != SUDOERS_GID) {
1072 if (!perm_root) {
1073 if (!restore_perms() || !set_perms(PERM_ROOT))
1074 debug_return_ptr(NULL);
1075 }
1076 }
1077 }
1078 /*
1079 * Open file and make sure we can read it so we can present
1080 * the user with a reasonable error message (unlike the lexer).
1081 */
1082 if ((fp = fopen(file, "r")) == NULL) {
1083 log_warning(SLOG_SEND_MAIL, N_("unable to open %s"), file);
1084 } else {
1085 if (sb.st_size != 0 && fgetc(fp) == EOF) {
1086 log_warning(SLOG_SEND_MAIL,
1087 N_("unable to read %s"), file);
1088 fclose(fp);
1089 fp = NULL;
1090 } else {
1091 /* Rewind fp and set close on exec flag. */
1092 rewind(fp);
1093 (void) fcntl(fileno(fp), F_SETFD, 1);
1094 }
1095 }
1096 break;
1097 case SUDO_PATH_MISSING:
1098 /*
1099 * If we tried to stat() sudoers as non-root but got EACCES,
1100 * try again as root.
1101 */
1102 if (errno == EACCES && geteuid() != ROOT_UID) {
1103 int serrno = errno;
1104 if (restore_perms()) {
1105 if (!set_perms(PERM_ROOT))
1106 debug_return_ptr(NULL);
1107 perm_root = true;
1108 goto again;
1109 }
1110 errno = serrno;
1111 }
1112 log_warning(SLOG_SEND_MAIL, N_("unable to stat %s"), file);
1113 break;
1114 case SUDO_PATH_BAD_TYPE:
1115 log_warningx(SLOG_SEND_MAIL,
1116 N_("%s is not a regular file"), file);
1117 break;
1118 case SUDO_PATH_WRONG_OWNER:
1119 log_warningx(SLOG_SEND_MAIL,
1120 N_("%s is owned by uid %u, should be %u"), file,
1121 (unsigned int) sb.st_uid, (unsigned int) sudoers_uid);
1122 break;
1123 case SUDO_PATH_WORLD_WRITABLE:
1124 log_warningx(SLOG_SEND_MAIL, N_("%s is world writable"), file);
1125 break;
1126 case SUDO_PATH_GROUP_WRITABLE:
1127 log_warningx(SLOG_SEND_MAIL,
1128 N_("%s is owned by gid %u, should be %u"), file,
1129 (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
1130 break;
1131 default:
1132 /* NOTREACHED */
1133 break;
1134 }
1135
1136 if (!restore_perms()) {
1137 /* unable to change back to root */
1138 if (fp != NULL) {
1139 fclose(fp);
1140 fp = NULL;
1141 }
1142 }
1143
1144 debug_return_ptr(fp);
1145 }
1146
1147 #ifdef HAVE_LOGIN_CAP_H
1148 static bool
set_loginclass(struct passwd * pw)1149 set_loginclass(struct passwd *pw)
1150 {
1151 const int errflags = SLOG_RAW_MSG;
1152 login_cap_t *lc;
1153 bool ret = true;
1154 debug_decl(set_loginclass, SUDOERS_DEBUG_PLUGIN);
1155
1156 if (!def_use_loginclass)
1157 goto done;
1158
1159 if (login_class && strcmp(login_class, "-") != 0) {
1160 if (user_uid != 0 && pw->pw_uid != 0) {
1161 sudo_warnx(U_("only root can use \"-c %s\""), login_class);
1162 ret = false;
1163 goto done;
1164 }
1165 } else {
1166 login_class = pw->pw_class;
1167 if (!login_class || !*login_class)
1168 login_class =
1169 (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
1170 }
1171
1172 /* Make sure specified login class is valid. */
1173 lc = login_getclass(login_class);
1174 if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
1175 /*
1176 * Don't make it an error if the user didn't specify the login
1177 * class themselves. We do this because if login.conf gets
1178 * corrupted we want the admin to be able to use sudo to fix it.
1179 */
1180 log_warningx(errflags, N_("unknown login class %s"), login_class);
1181 def_use_loginclass = false;
1182 if (login_class)
1183 ret = false;
1184 }
1185 login_close(lc);
1186 done:
1187 debug_return_bool(ret);
1188 }
1189 #else
1190 static bool
set_loginclass(struct passwd * pw)1191 set_loginclass(struct passwd *pw)
1192 {
1193 return true;
1194 }
1195 #endif /* HAVE_LOGIN_CAP_H */
1196
1197 #ifndef AI_FQDN
1198 # define AI_FQDN AI_CANONNAME
1199 #endif
1200
1201 /*
1202 * Look up the fully qualified domain name of host.
1203 * Use AI_FQDN if available since "canonical" is not always the same as fqdn.
1204 * Returns 0 on success, setting longp and shortp.
1205 * Returns non-zero on failure, longp and shortp are unchanged.
1206 * See gai_strerror() for the list of error return codes.
1207 */
1208 static int
resolve_host(const char * host,char ** longp,char ** shortp)1209 resolve_host(const char *host, char **longp, char **shortp)
1210 {
1211 struct addrinfo *res0, hint;
1212 char *cp, *lname, *sname;
1213 int ret;
1214 debug_decl(resolve_host, SUDOERS_DEBUG_PLUGIN);
1215
1216 memset(&hint, 0, sizeof(hint));
1217 hint.ai_family = PF_UNSPEC;
1218 hint.ai_flags = AI_FQDN;
1219
1220 if ((ret = getaddrinfo(host, NULL, &hint, &res0)) != 0)
1221 debug_return_int(ret);
1222 if ((lname = strdup(res0->ai_canonname)) == NULL) {
1223 freeaddrinfo(res0);
1224 debug_return_int(EAI_MEMORY);
1225 }
1226 if ((cp = strchr(lname, '.')) != NULL) {
1227 sname = strndup(lname, (size_t)(cp - lname));
1228 if (sname == NULL) {
1229 free(lname);
1230 freeaddrinfo(res0);
1231 debug_return_int(EAI_MEMORY);
1232 }
1233 } else {
1234 sname = lname;
1235 }
1236 freeaddrinfo(res0);
1237 *longp = lname;
1238 *shortp = sname;
1239
1240 debug_return_int(0);
1241 }
1242
1243 /*
1244 * Look up the fully qualified domain name of user_host and user_runhost.
1245 * Sets user_host, user_shost, user_runhost and user_srunhost.
1246 */
1247 static bool
cb_fqdn(const union sudo_defs_val * sd_un)1248 cb_fqdn(const union sudo_defs_val *sd_un)
1249 {
1250 bool remote;
1251 int rc;
1252 char *lhost, *shost;
1253 debug_decl(cb_fqdn, SUDOERS_DEBUG_PLUGIN);
1254
1255 /* Nothing to do if fqdn flag is disabled. */
1256 if (sd_un != NULL && !sd_un->flag)
1257 debug_return_bool(true);
1258
1259 /* If the -h flag was given we need to resolve both host and runhost. */
1260 remote = strcmp(user_runhost, user_host) != 0;
1261
1262 /* First resolve user_host, setting user_host and user_shost. */
1263 if (resolve_host(user_host, &lhost, &shost) != 0) {
1264 if ((rc = resolve_host(user_runhost, &lhost, &shost)) != 0) {
1265 gai_log_warning(SLOG_SEND_MAIL|SLOG_RAW_MSG, rc,
1266 N_("unable to resolve host %s"), user_host);
1267 debug_return_bool(false);
1268 }
1269 }
1270 if (user_shost != user_host)
1271 free(user_shost);
1272 free(user_host);
1273 user_host = lhost;
1274 user_shost = shost;
1275
1276 /* Next resolve user_runhost, setting user_runhost and user_srunhost. */
1277 lhost = shost = NULL;
1278 if (remote) {
1279 if ((rc = resolve_host(user_runhost, &lhost, &shost)) != 0) {
1280 gai_log_warning(SLOG_NO_LOG|SLOG_RAW_MSG, rc,
1281 N_("unable to resolve host %s"), user_runhost);
1282 debug_return_bool(false);
1283 }
1284 } else {
1285 /* Not remote, just use user_host. */
1286 if ((lhost = strdup(user_host)) != NULL) {
1287 if (user_shost != user_host)
1288 shost = strdup(user_shost);
1289 else
1290 shost = lhost;
1291 }
1292 if (lhost == NULL || shost == NULL) {
1293 free(lhost);
1294 if (lhost != shost)
1295 free(shost);
1296 sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
1297 debug_return_bool(false);
1298 }
1299 }
1300 if (lhost != NULL && shost != NULL) {
1301 if (user_srunhost != user_runhost)
1302 free(user_srunhost);
1303 free(user_runhost);
1304 user_runhost = lhost;
1305 user_srunhost = shost;
1306 }
1307
1308 sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
1309 "host %s, shost %s, runhost %s, srunhost %s",
1310 user_host, user_shost, user_runhost, user_srunhost);
1311 debug_return_bool(true);
1312 }
1313
1314 /*
1315 * Get passwd entry for the user we are going to run commands as
1316 * and store it in runas_pw. By default, commands run as "root".
1317 */
1318 static bool
set_runaspw(const char * user,bool quiet)1319 set_runaspw(const char *user, bool quiet)
1320 {
1321 struct passwd *pw = NULL;
1322 debug_decl(set_runaspw, SUDOERS_DEBUG_PLUGIN);
1323
1324 unknown_runas_uid = false;
1325 if (*user == '#') {
1326 const char *errstr;
1327 uid_t uid = sudo_strtoid(user + 1, &errstr);
1328 if (errstr == NULL) {
1329 if ((pw = sudo_getpwuid(uid)) == NULL) {
1330 unknown_runas_uid = true;
1331 pw = sudo_fakepwnam(user, user_gid);
1332 }
1333 }
1334 }
1335 if (pw == NULL) {
1336 if ((pw = sudo_getpwnam(user)) == NULL) {
1337 if (!quiet)
1338 log_warningx(SLOG_AUDIT, N_("unknown user %s"), user);
1339 debug_return_bool(false);
1340 }
1341 }
1342 if (runas_pw != NULL)
1343 sudo_pw_delref(runas_pw);
1344 runas_pw = pw;
1345 debug_return_bool(true);
1346 }
1347
1348 /*
1349 * Get group entry for the group we are going to run commands as
1350 * and store it in runas_gr.
1351 */
1352 static bool
set_runasgr(const char * group,bool quiet)1353 set_runasgr(const char *group, bool quiet)
1354 {
1355 struct group *gr = NULL;
1356 debug_decl(set_runasgr, SUDOERS_DEBUG_PLUGIN);
1357
1358 unknown_runas_gid = false;
1359 if (*group == '#') {
1360 const char *errstr;
1361 gid_t gid = sudo_strtoid(group + 1, &errstr);
1362 if (errstr == NULL) {
1363 if ((gr = sudo_getgrgid(gid)) == NULL) {
1364 unknown_runas_gid = true;
1365 gr = sudo_fakegrnam(group);
1366 }
1367 }
1368 }
1369 if (gr == NULL) {
1370 if ((gr = sudo_getgrnam(group)) == NULL) {
1371 if (!quiet)
1372 log_warningx(SLOG_AUDIT, N_("unknown group %s"), group);
1373 debug_return_bool(false);
1374 }
1375 }
1376 if (runas_gr != NULL)
1377 sudo_gr_delref(runas_gr);
1378 runas_gr = gr;
1379 debug_return_bool(true);
1380 }
1381
1382 /*
1383 * Callback for runas_default sudoers setting.
1384 */
1385 static bool
cb_runas_default(const union sudo_defs_val * sd_un)1386 cb_runas_default(const union sudo_defs_val *sd_un)
1387 {
1388 debug_decl(cb_runas_default, SUDOERS_DEBUG_PLUGIN);
1389
1390 /* Only reset runaspw if user didn't specify one. */
1391 if (sudo_user.runas_user == NULL && sudo_user.runas_group == NULL)
1392 debug_return_bool(set_runaspw(sd_un->str, true));
1393 debug_return_bool(true);
1394 }
1395
1396 /*
1397 * Callback for tty_tickets sudoers setting.
1398 */
1399 static bool
cb_tty_tickets(const union sudo_defs_val * sd_un)1400 cb_tty_tickets(const union sudo_defs_val *sd_un)
1401 {
1402 debug_decl(cb_tty_tickets, SUDOERS_DEBUG_PLUGIN);
1403
1404 /* Convert tty_tickets -> timestamp_type */
1405 if (sd_un->flag)
1406 def_timestamp_type = tty;
1407 else
1408 def_timestamp_type = global;
1409 debug_return_bool(true);
1410 }
1411
1412 /*
1413 * Callback for umask sudoers setting.
1414 */
1415 static bool
cb_umask(const union sudo_defs_val * sd_un)1416 cb_umask(const union sudo_defs_val *sd_un)
1417 {
1418 debug_decl(cb_umask, SUDOERS_DEBUG_PLUGIN);
1419
1420 /* Force umask if explicitly set in sudoers. */
1421 force_umask = sd_un->mode != ACCESSPERMS;
1422
1423 debug_return_bool(true);
1424 }
1425
1426 /*
1427 * Callback for runchroot sudoers setting.
1428 */
1429 static bool
cb_runchroot(const union sudo_defs_val * sd_un)1430 cb_runchroot(const union sudo_defs_val *sd_un)
1431 {
1432 debug_decl(cb_runchroot, SUDOERS_DEBUG_PLUGIN);
1433
1434 sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
1435 "def_runchroot now %s", sd_un->str);
1436 if (user_cmnd != NULL) {
1437 /* Update user_cmnd based on the new chroot. */
1438 cmnd_status = set_cmnd_path(sd_un->str);
1439 sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
1440 "user_cmnd now %s", user_cmnd);
1441 }
1442
1443 debug_return_bool(true);
1444 }
1445
1446 static bool
cb_logfile(const union sudo_defs_val * sd_un)1447 cb_logfile(const union sudo_defs_val *sd_un)
1448 {
1449 int logtype = def_syslog ? EVLOG_SYSLOG : EVLOG_NONE;
1450 debug_decl(cb_logfile, SUDOERS_DEBUG_PLUGIN);
1451
1452 if (sd_un->str != NULL)
1453 SET(logtype, EVLOG_FILE);
1454 eventlog_set_type(logtype);
1455 eventlog_set_logpath(sd_un->str);
1456
1457 debug_return_bool(true);
1458 }
1459
1460 static bool
cb_log_format(const union sudo_defs_val * sd_un)1461 cb_log_format(const union sudo_defs_val *sd_un)
1462 {
1463 debug_decl(cb_log_format, SUDOERS_DEBUG_PLUGIN);
1464
1465 eventlog_set_format(sd_un->tuple == sudo ? EVLOG_SUDO : EVLOG_JSON);
1466
1467 debug_return_bool(true);
1468 }
1469
1470 static bool
cb_syslog(const union sudo_defs_val * sd_un)1471 cb_syslog(const union sudo_defs_val *sd_un)
1472 {
1473 int logtype = def_logfile ? EVLOG_FILE : EVLOG_NONE;
1474 debug_decl(cb_syslog, SUDOERS_DEBUG_PLUGIN);
1475
1476 if (sd_un->str != NULL)
1477 SET(logtype, EVLOG_SYSLOG);
1478 eventlog_set_type(logtype);
1479
1480 debug_return_bool(true);
1481 }
1482
1483 static bool
cb_syslog_goodpri(const union sudo_defs_val * sd_un)1484 cb_syslog_goodpri(const union sudo_defs_val *sd_un)
1485 {
1486 debug_decl(cb_syslog_goodpri, SUDOERS_DEBUG_PLUGIN);
1487
1488 eventlog_set_syslog_acceptpri(sd_un->ival);
1489
1490 debug_return_bool(true);
1491 }
1492
1493 static bool
cb_syslog_badpri(const union sudo_defs_val * sd_un)1494 cb_syslog_badpri(const union sudo_defs_val *sd_un)
1495 {
1496 debug_decl(cb_syslog_badpri, SUDOERS_DEBUG_PLUGIN);
1497
1498 eventlog_set_syslog_rejectpri(sd_un->ival);
1499 eventlog_set_syslog_alertpri(sd_un->ival);
1500
1501 debug_return_bool(true);
1502 }
1503
1504 static bool
cb_syslog_maxlen(const union sudo_defs_val * sd_un)1505 cb_syslog_maxlen(const union sudo_defs_val *sd_un)
1506 {
1507 debug_decl(cb_syslog_maxlen, SUDOERS_DEBUG_PLUGIN);
1508
1509 eventlog_set_syslog_maxlen(sd_un->ival);
1510
1511 debug_return_bool(true);
1512 }
1513
1514 static bool
cb_loglinelen(const union sudo_defs_val * sd_un)1515 cb_loglinelen(const union sudo_defs_val *sd_un)
1516 {
1517 debug_decl(cb_loglinelen, SUDOERS_DEBUG_PLUGIN);
1518
1519 eventlog_set_file_maxlen(sd_un->ival);
1520
1521 debug_return_bool(true);
1522 }
1523
1524 static bool
cb_log_year(const union sudo_defs_val * sd_un)1525 cb_log_year(const union sudo_defs_val *sd_un)
1526 {
1527 debug_decl(cb_syslog_maxlen, SUDOERS_DEBUG_PLUGIN);
1528
1529 eventlog_set_time_fmt(sd_un->flag ? "%h %e %T %Y" : "%h %e %T");
1530
1531 debug_return_bool(true);
1532 }
1533
1534 static bool
cb_log_host(const union sudo_defs_val * sd_un)1535 cb_log_host(const union sudo_defs_val *sd_un)
1536 {
1537 debug_decl(cb_syslog_maxlen, SUDOERS_DEBUG_PLUGIN);
1538
1539 eventlog_set_omit_hostname(!sd_un->flag);
1540
1541 debug_return_bool(true);
1542 }
1543
1544 static bool
cb_mailerpath(const union sudo_defs_val * sd_un)1545 cb_mailerpath(const union sudo_defs_val *sd_un)
1546 {
1547 debug_decl(cb_mailerpath, SUDOERS_DEBUG_PLUGIN);
1548
1549 eventlog_set_mailerpath(sd_un->str);
1550
1551 debug_return_bool(true);
1552 }
1553
1554 static bool
cb_mailerflags(const union sudo_defs_val * sd_un)1555 cb_mailerflags(const union sudo_defs_val *sd_un)
1556 {
1557 debug_decl(cb_mailerflags, SUDOERS_DEBUG_PLUGIN);
1558
1559 eventlog_set_mailerflags(sd_un->str);
1560
1561 debug_return_bool(true);
1562 }
1563
1564 static bool
cb_mailfrom(const union sudo_defs_val * sd_un)1565 cb_mailfrom(const union sudo_defs_val *sd_un)
1566 {
1567 debug_decl(cb_mailfrom, SUDOERS_DEBUG_PLUGIN);
1568
1569 eventlog_set_mailfrom(sd_un->str);
1570
1571 debug_return_bool(true);
1572 }
1573
1574 static bool
cb_mailto(const union sudo_defs_val * sd_un)1575 cb_mailto(const union sudo_defs_val *sd_un)
1576 {
1577 debug_decl(cb_mailto, SUDOERS_DEBUG_PLUGIN);
1578
1579 eventlog_set_mailto(sd_un->str);
1580
1581 debug_return_bool(true);
1582 }
1583
1584 static bool
cb_mailsub(const union sudo_defs_val * sd_un)1585 cb_mailsub(const union sudo_defs_val *sd_un)
1586 {
1587 debug_decl(cb_mailsub, SUDOERS_DEBUG_PLUGIN);
1588
1589 eventlog_set_mailsub(sd_un->str);
1590
1591 debug_return_bool(true);
1592 }
1593
1594 /*
1595 * Set parse Defaults callbacks.
1596 * We do this here instead in def_data.in so we don't have to
1597 * stub out the callbacks for visudo and testsudoers.
1598 */
1599 static void
set_callbacks(void)1600 set_callbacks(void)
1601 {
1602 debug_decl(set_callbacks, SUDOERS_DEBUG_PLUGIN);
1603
1604 /* Set fqdn callback. */
1605 sudo_defs_table[I_FQDN].callback = cb_fqdn;
1606
1607 /* Set group_plugin callback. */
1608 sudo_defs_table[I_GROUP_PLUGIN].callback = cb_group_plugin;
1609
1610 /* Set runas callback. */
1611 sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
1612
1613 /* Set locale callback. */
1614 sudo_defs_table[I_SUDOERS_LOCALE].callback = sudoers_locale_callback;
1615
1616 /* Set maxseq callback. */
1617 sudo_defs_table[I_MAXSEQ].callback = cb_maxseq;
1618
1619 /* Set iolog_user callback. */
1620 sudo_defs_table[I_IOLOG_USER].callback = cb_iolog_user;
1621
1622 /* Set iolog_group callback. */
1623 sudo_defs_table[I_IOLOG_GROUP].callback = cb_iolog_group;
1624
1625 /* Set iolog_mode callback. */
1626 sudo_defs_table[I_IOLOG_MODE].callback = cb_iolog_mode;
1627
1628 /* Set tty_tickets callback. */
1629 sudo_defs_table[I_TTY_TICKETS].callback = cb_tty_tickets;
1630
1631 /* Set umask callback. */
1632 sudo_defs_table[I_UMASK].callback = cb_umask;
1633
1634 /* Set runchroot callback. */
1635 sudo_defs_table[I_RUNCHROOT].callback = cb_runchroot;
1636
1637 /* eventlog callbacks */
1638 sudo_defs_table[I_SYSLOG].callback = cb_syslog;
1639 sudo_defs_table[I_SYSLOG_GOODPRI].callback = cb_syslog_goodpri;
1640 sudo_defs_table[I_SYSLOG_BADPRI].callback = cb_syslog_badpri;
1641 sudo_defs_table[I_SYSLOG_MAXLEN].callback = cb_syslog_maxlen;
1642 sudo_defs_table[I_LOGLINELEN].callback = cb_loglinelen;
1643 sudo_defs_table[I_LOG_HOST].callback = cb_log_host;
1644 sudo_defs_table[I_LOGFILE].callback = cb_logfile;
1645 sudo_defs_table[I_LOG_FORMAT].callback = cb_log_format;
1646 sudo_defs_table[I_LOG_YEAR].callback = cb_log_year;
1647 sudo_defs_table[I_MAILERPATH].callback = cb_mailerpath;
1648 sudo_defs_table[I_MAILERFLAGS].callback = cb_mailerflags;
1649 sudo_defs_table[I_MAILFROM].callback = cb_mailfrom;
1650 sudo_defs_table[I_MAILTO].callback = cb_mailto;
1651 sudo_defs_table[I_MAILSUB].callback = cb_mailsub;
1652
1653 debug_return;
1654 }
1655
1656 /*
1657 * Cleanup hook for sudo_fatal()/sudo_fatalx()
1658 * Also called at policy close time.
1659 */
1660 void
sudoers_cleanup(void)1661 sudoers_cleanup(void)
1662 {
1663 struct sudo_nss *nss;
1664 struct defaults *def;
1665 debug_decl(sudoers_cleanup, SUDOERS_DEBUG_PLUGIN);
1666
1667 if (snl != NULL) {
1668 TAILQ_FOREACH(nss, snl, entries) {
1669 nss->close(nss);
1670 }
1671 snl = NULL;
1672 init_parser(NULL, false, false);
1673 }
1674 while ((def = TAILQ_FIRST(&initial_defaults)) != NULL) {
1675 TAILQ_REMOVE(&initial_defaults, def, entries);
1676 free(def->var);
1677 free(def->val);
1678 free(def);
1679 }
1680 need_reinit = false;
1681 if (def_group_plugin)
1682 group_plugin_unload();
1683 sudo_user_free();
1684 sudo_freepwcache();
1685 sudo_freegrcache();
1686
1687 /* Clear globals */
1688 list_pw = NULL;
1689 NewArgv = NULL;
1690 NewArgc = 0;
1691 prev_user = NULL;
1692
1693 debug_return;
1694 }
1695
1696 static bool
tty_present(void)1697 tty_present(void)
1698 {
1699 debug_decl(tty_present, SUDOERS_DEBUG_PLUGIN);
1700
1701 if (user_ttypath == NULL) {
1702 int fd = open(_PATH_TTY, O_RDWR);
1703 if (fd == -1)
1704 debug_return_bool(false);
1705 close(fd);
1706 }
1707 debug_return_bool(true);
1708 }
1709
1710 /*
1711 * Free memory allocated for struct sudo_user.
1712 */
1713 void
sudo_user_free(void)1714 sudo_user_free(void)
1715 {
1716 debug_decl(sudo_user_free, SUDOERS_DEBUG_PLUGIN);
1717
1718 /* Free remaining references to password and group entries. */
1719 if (sudo_user.pw != NULL)
1720 sudo_pw_delref(sudo_user.pw);
1721 if (runas_pw != NULL)
1722 sudo_pw_delref(runas_pw);
1723 if (runas_gr != NULL)
1724 sudo_gr_delref(runas_gr);
1725 if (user_gid_list != NULL)
1726 sudo_gidlist_delref(user_gid_list);
1727
1728 /* Free dynamic contents of sudo_user. */
1729 free(user_cwd);
1730 free(user_name);
1731 free(user_gids);
1732 if (user_ttypath != NULL)
1733 free(user_ttypath);
1734 else
1735 free(user_tty);
1736 if (user_shost != user_host)
1737 free(user_shost);
1738 free(user_host);
1739 if (user_srunhost != user_runhost)
1740 free(user_srunhost);
1741 free(user_runhost);
1742 free(user_cmnd);
1743 free(user_args);
1744 free(safe_cmnd);
1745 free(user_stat);
1746 #ifdef HAVE_SELINUX
1747 free(user_role);
1748 free(user_type);
1749 #endif
1750 #ifdef HAVE_PRIV_SET
1751 free(runas_privs);
1752 free(runas_limitprivs);
1753 #endif
1754 memset(&sudo_user, 0, sizeof(sudo_user));
1755
1756 debug_return;
1757 }
1758