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