Imported Upstream version 1.8.7
[debian/sudo] / plugins / sudoers / sudoers.c
1 /*
2  * Copyright (c) 1993-1996, 1998-2013 Todd C. Miller <Todd.Miller@courtesan.com>
3  *
4  * Permission to use, copy, modify, and distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  *
16  * Sponsored in part by the Defense Advanced Research Projects
17  * Agency (DARPA) and Air Force Research Laboratory, Air Force
18  * Materiel Command, USAF, under agreement number F39502-99-1-0512.
19  */
20
21 #define _SUDO_MAIN
22
23 #ifdef __TANDEM
24 # include <floss.h>
25 #endif
26
27 #include <config.h>
28
29 #include <sys/types.h>
30 #include <sys/stat.h>
31 #include <sys/socket.h>
32 #include <stdio.h>
33 #ifdef STDC_HEADERS
34 # include <stdlib.h>
35 # include <stddef.h>
36 #else
37 # ifdef HAVE_STDLIB_H
38 #  include <stdlib.h>
39 # endif
40 #endif /* STDC_HEADERS */
41 #ifdef HAVE_STRING_H
42 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
43 #  include <memory.h>
44 # endif
45 # include <string.h>
46 #endif /* HAVE_STRING_H */
47 #ifdef HAVE_STRINGS_H
48 # include <strings.h>
49 #endif /* HAVE_STRINGS_H */
50 #ifdef HAVE_UNISTD_H
51 # include <unistd.h>
52 #endif /* HAVE_UNISTD_H */
53 #include <pwd.h>
54 #include <errno.h>
55 #include <fcntl.h>
56 #include <signal.h>
57 #include <grp.h>
58 #include <time.h>
59 #include <netdb.h>
60 #ifdef HAVE_LOGIN_CAP_H
61 # include <login_cap.h>
62 # ifndef LOGIN_DEFROOTCLASS
63 #  define LOGIN_DEFROOTCLASS    "daemon"
64 # endif
65 # ifndef LOGIN_SETENV
66 #  define LOGIN_SETENV  0
67 # endif
68 #endif
69 #ifdef HAVE_SELINUX
70 # include <selinux/selinux.h>
71 #endif
72 #include <ctype.h>
73 #ifndef HAVE_GETADDRINFO
74 # include "compat/getaddrinfo.h"
75 #endif
76
77 #include "sudoers.h"
78 #include "auth/sudo_auth.h"
79 #include "secure_path.h"
80
81 /*
82  * Prototypes
83  */
84 static char *find_editor(int nfiles, char **files, char ***argv_out);
85 static int cb_runas_default(const char *);
86 static int cb_sudoers_locale(const char *);
87 static int set_cmnd(void);
88 static void create_admin_success_flag(void);
89 static void init_vars(char * const *);
90 static void set_fqdn(void);
91 static void set_loginclass(struct passwd *);
92 static void set_runasgr(const char *);
93 static void set_runaspw(const char *);
94 static bool tty_present(void);
95
96 /*
97  * Globals
98  */
99 struct sudo_user sudo_user;
100 struct passwd *list_pw;
101 int long_list;
102 uid_t timestamp_uid;
103 extern int errorlineno;
104 extern bool parse_error;
105 extern char *errorfile;
106 #ifdef HAVE_BSD_AUTH_H
107 char *login_style;
108 #endif /* HAVE_BSD_AUTH_H */
109 int sudo_mode;
110
111 static char *prev_user;
112 static char *runas_user;
113 static char *runas_group;
114 static struct sudo_nss_list *snl;
115
116 /* XXX - must be extern for audit bits of sudo_auth.c */
117 int NewArgc;
118 char **NewArgv;
119
120 int
121 sudoers_policy_init(void *info, char * const envp[])
122 {
123     volatile int sources = 0;
124     struct sudo_nss *nss, *nss_next;
125     debug_decl(sudoers_policy_init, SUDO_DEBUG_PLUGIN)
126
127     bindtextdomain("sudoers", LOCALEDIR);
128
129     sudo_setpwent();
130     sudo_setgrent();
131
132     /* Register fatal/fatalx callback. */
133     fatal_callback_register(sudoers_cleanup);
134
135     /* Initialize environment functions (including replacements). */
136     env_init(envp);
137
138     /* Setup defaults data structures. */
139     init_defaults();
140
141     /* Parse info from front-end. */
142     sudo_mode = sudoers_policy_deserialize_info(info, &runas_user, &runas_group);
143
144     init_vars(envp);            /* XXX - move this later? */
145
146     /* Parse nsswitch.conf for sudoers order. */
147     snl = sudo_read_nss();
148
149     /* LDAP or NSS may modify the euid so we need to be root for the open. */
150     set_perms(PERM_INITIAL);
151     set_perms(PERM_ROOT);
152
153     /* Open and parse sudoers, set global defaults */
154     for (nss = snl->first; nss != NULL; nss = nss_next) {
155         nss_next = nss->next;
156         if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
157             sources++;
158             if (nss->setdefs(nss) != 0)
159                 log_warning(NO_STDERR, N_("problem with defaults entries"));
160         } else {
161             tq_remove(snl, nss);
162         }
163     }
164     if (sources == 0) {
165         warningx(_("no valid sudoers sources found, quitting"));
166         debug_return_bool(-1);
167     }
168
169     /* XXX - collect post-sudoers parse settings into a function */
170
171     /*
172      * Initialize external group plugin, if any.
173      */
174     if (def_group_plugin) {
175         if (group_plugin_load(def_group_plugin) != true)
176             def_group_plugin = NULL;
177     }
178
179     /*
180      * Set runas passwd/group entries based on command line or sudoers.
181      * Note that if runas_group was specified without runas_user we
182      * defer setting runas_pw so the match routines know to ignore it.
183      */
184     /* XXX - qpm4u does more here as it may have already set runas_pw */
185     if (runas_group != NULL) {
186         set_runasgr(runas_group);
187         if (runas_user != NULL)
188             set_runaspw(runas_user);
189     } else
190         set_runaspw(runas_user ? runas_user : def_runas_default);
191
192     if (!update_defaults(SETDEF_RUNAS))
193         log_warning(NO_STDERR, N_("problem with defaults entries"));
194
195     if (def_fqdn)
196         set_fqdn();     /* deferred until after sudoers is parsed */
197
198     /* Set login class if applicable. */
199     set_loginclass(runas_pw ? runas_pw : sudo_user.pw);
200
201     restore_perms();
202
203     debug_return_bool(true);
204 }
205
206 int
207 sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
208     void *closure)
209 {
210     char **edit_argv = NULL;
211     char *iolog_path = NULL;
212     mode_t cmnd_umask = 0777;
213     struct sudo_nss *nss;
214     int cmnd_status = -1, oldlocale, validated;
215     volatile int rval = true;
216     debug_decl(sudoers_policy_main, SUDO_DEBUG_PLUGIN)
217
218     /* XXX - would like to move this to policy.c but need the cleanup. */
219     if (fatal_setjmp() != 0) {
220         /* error recovery via fatal(), fatalx() or log_fatal() */
221         rval = -1;
222         goto done;
223     }
224
225     /* Is root even allowed to run sudo? */
226     if (user_uid == 0 && !def_root_sudo) {
227         warningx(_("sudoers specifies that root is not allowed to sudo"));
228         goto bad;
229     }    
230
231     /* Check for -C overriding def_closefrom. */
232     if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
233         if (!def_closefrom_override) {
234             warningx(_("you are not permitted to use the -C option"));
235             goto bad;
236         }
237         def_closefrom = user_closefrom;
238     }
239
240     set_perms(PERM_INITIAL);
241
242     /* Environment variables specified on the command line. */
243     if (env_add != NULL && env_add[0] != NULL)
244         sudo_user.env_vars = env_add;
245
246     /*
247      * Make a local copy of argc/argv, with special handling
248      * for pseudo-commands and the '-i' option.
249      */
250     if (argc == 0) {
251         NewArgc = 1;
252         NewArgv = emalloc2(NewArgc + 1, sizeof(char *));
253         NewArgv[0] = user_cmnd;
254         NewArgv[1] = NULL;
255     } else {
256         /* Must leave an extra slot before NewArgv for bash's --login */
257         NewArgc = argc;
258         NewArgv = emalloc2(NewArgc + 2, sizeof(char *));
259         memcpy(++NewArgv, argv, argc * sizeof(char *));
260         NewArgv[NewArgc] = NULL;
261         if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL)
262             NewArgv[0] = estrdup(runas_pw->pw_shell);
263     }
264
265     /* If given the -P option, set the "preserve_groups" flag. */
266     if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
267         def_preserve_groups = true;
268
269     /* Find command in path */
270     cmnd_status = set_cmnd();
271
272     /*
273      * Check sudoers sources, using the locale specified in sudoers.
274      */
275     sudoers_setlocale(SUDOERS_LOCALE_SUDOERS, &oldlocale);
276     validated = FLAG_NO_USER | FLAG_NO_HOST;
277     tq_foreach_fwd(snl, nss) {
278         validated = nss->lookup(nss, validated, pwflag);
279
280         if (ISSET(validated, VALIDATE_OK)) {
281             /* Handle [SUCCESS=return] */
282             if (nss->ret_if_found)
283                 break;
284         } else {
285             /* Handle [NOTFOUND=return] */
286             if (nss->ret_if_notfound)
287                 break;
288         }
289     }
290
291     /* Restore user's locale. */
292     sudoers_setlocale(oldlocale, NULL);
293
294     if (safe_cmnd == NULL)
295         safe_cmnd = estrdup(user_cmnd);
296
297     /* If only a group was specified, set runas_pw based on invoking user. */
298     if (runas_pw == NULL)
299         set_runaspw(user_name);
300
301     /*
302      * Look up the timestamp dir owner if one is specified.
303      */
304     if (def_timestampowner) {
305         struct passwd *pw;
306
307         if (*def_timestampowner == '#')
308             pw = sudo_getpwuid(atoi(def_timestampowner + 1));
309         else
310             pw = sudo_getpwnam(def_timestampowner);
311         if (pw != NULL) {
312             timestamp_uid = pw->pw_uid;
313             sudo_pw_delref(pw);
314         } else {
315             log_warning(0, N_("timestamp owner (%s): No such user"),
316                 def_timestampowner);
317             timestamp_uid = ROOT_UID;
318         }
319     }
320
321     /* If no command line args and "shell_noargs" is not set, error out. */
322     if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
323         rval = -2; /* usage error */
324         goto done;
325     }
326
327     /* Bail if a tty is required and we don't have one.  */
328     if (def_requiretty && !tty_present()) {
329         audit_failure(NewArgv, N_("no tty"));
330         warningx(_("sorry, you must have a tty to run sudo"));
331         goto bad;
332     }
333
334     /*
335      * We don't reset the environment for sudoedit or if the user
336      * specified the -E command line flag and they have setenv privs.
337      */
338     if (ISSET(sudo_mode, MODE_EDIT) ||
339         (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv))
340         def_env_reset = false;
341
342     /* Build a new environment that avoids any nasty bits. */
343     rebuild_env();
344
345     /* Require a password if sudoers says so.  */
346     rval = check_user(validated, sudo_mode);
347     if (rval != true) {
348         if (!ISSET(validated, VALIDATE_OK))
349             log_denial(validated, false);
350         goto done;
351     }
352
353     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
354     /* XXX - causes confusion when root is not listed in sudoers */
355     if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) {
356         if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
357             struct passwd *pw;
358
359             if ((pw = sudo_getpwnam(prev_user)) != NULL) {
360                     if (sudo_user.pw != NULL)
361                         sudo_pw_delref(sudo_user.pw);
362                     sudo_user.pw = pw;
363             }
364         }
365     }
366
367     /* If the user was not allowed to run the command we are done. */
368     if (!ISSET(validated, VALIDATE_OK)) {
369         log_failure(validated, cmnd_status);
370         goto bad;
371     }
372
373     /* Create Ubuntu-style dot file to indicate sudo was successful. */
374     create_admin_success_flag();
375
376     /* Finally tell the user if the command did not exist. */
377     if (cmnd_status == NOT_FOUND_DOT) {
378         audit_failure(NewArgv, N_("command in current directory"));
379         warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd);
380         goto bad;
381     } else if (cmnd_status == NOT_FOUND) {
382         if (ISSET(sudo_mode, MODE_CHECK)) {
383             audit_failure(NewArgv, N_("%s: command not found"), NewArgv[0]);
384             warningx(_("%s: command not found"), NewArgv[0]);
385         } else {
386             audit_failure(NewArgv, N_("%s: command not found"), user_cmnd);
387             warningx(_("%s: command not found"), user_cmnd);
388         }
389         goto bad;
390     }
391
392     /* If user specified env vars make sure sudoers allows it. */
393     if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
394         if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) {
395             warningx(_("sorry, you are not allowed to preserve the environment"));
396             goto bad;
397         } else
398             validate_env_vars(sudo_user.env_vars);
399     }
400
401     if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT))) {
402         if ((def_log_input || def_log_output) && def_iolog_file && def_iolog_dir) {
403             const char prefix[] = "iolog_path=";
404             iolog_path = expand_iolog_path(prefix, def_iolog_dir,
405                 def_iolog_file, &sudo_user.iolog_file);
406             sudo_user.iolog_file++;
407         }
408     }
409
410     log_allowed(validated);
411     if (ISSET(sudo_mode, MODE_CHECK))
412         rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
413     else if (ISSET(sudo_mode, MODE_LIST))
414         display_privs(snl, list_pw ? list_pw : sudo_user.pw); /* XXX - return val */
415
416     /* Cleanup sudoers sources */
417     tq_foreach_fwd(snl, nss) {
418         nss->close(nss);
419     }
420     if (def_group_plugin)
421         group_plugin_unload();
422
423     if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST))) {
424         /* rval already set appropriately */
425         goto done;
426     }
427
428     /*
429      * Set umask based on sudoers.
430      * If user's umask is more restrictive, OR in those bits too
431      * unless umask_override is set.
432      */
433     if (def_umask != 0777) {
434         cmnd_umask = def_umask;
435         if (!def_umask_override)
436             cmnd_umask |= user_umask;
437     }
438
439     if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
440         char *p;
441
442         /* Convert /bin/sh -> -sh so shell knows it is a login shell */
443         if ((p = strrchr(NewArgv[0], '/')) == NULL)
444             p = NewArgv[0];
445         *p = '-';
446         NewArgv[0] = p;
447
448         /*
449          * Newer versions of bash require the --login option to be used
450          * in conjunction with the -c option even if the shell name starts
451          * with a '-'.  Unfortunately, bash 1.x uses -login, not --login
452          * so this will cause an error for that.
453          */
454         if (NewArgc > 1 && strcmp(NewArgv[0], "-bash") == 0 &&
455             strcmp(NewArgv[1], "-c") == 0) {
456             /* Use the extra slot before NewArgv so we can store --login. */
457             NewArgv--;
458             NewArgc++;
459             NewArgv[0] = NewArgv[1];
460             NewArgv[1] = "--login";
461         }
462
463 #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
464         /* Insert system-wide environment variables. */
465         read_env_file(_PATH_ENVIRONMENT, true);
466 #endif
467 #ifdef HAVE_LOGIN_CAP_H
468         /* Set environment based on login class. */
469         if (login_class) {
470             login_cap_t *lc = login_getclass(login_class);
471             if (lc != NULL) {
472                 setusercontext(lc, runas_pw, runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
473                 login_close(lc);
474             }
475         }
476 #endif /* HAVE_LOGIN_CAP_H */
477     }
478
479     /* Insert system-wide environment variables. */
480     if (def_env_file)
481         read_env_file(def_env_file, false);
482
483     /* Insert user-specified environment variables. */
484     insert_env_vars(sudo_user.env_vars);
485
486     if (ISSET(sudo_mode, MODE_EDIT)) {
487         efree(safe_cmnd);
488         safe_cmnd = find_editor(NewArgc - 1, NewArgv + 1, &edit_argv);
489         if (safe_cmnd == NULL)
490             goto bad;
491     }
492
493     /* Must audit before uid change. */
494     audit_success(NewArgv);
495
496     /* Setup execution environment to pass back to front-end. */
497     rval = sudoers_policy_exec_setup(edit_argv ? edit_argv : NewArgv,
498         env_get(), cmnd_umask, iolog_path, closure);
499
500     /* Zero out stashed copy of environment, it is owned by the front-end. */
501     env_init(NULL);
502
503     goto done;
504
505 bad:
506     rval = false;
507
508 done:
509     fatal_disable_setjmp();
510     rewind_perms();
511
512     /* Close the password and group files and free up memory. */
513     sudo_endpwent();
514     sudo_endgrent();
515
516     debug_return_bool(rval);
517 }
518
519 /*
520  * Initialize timezone and fill in ``sudo_user'' struct.
521  */
522 static void
523 init_vars(char * const envp[])
524 {
525     char * const * ep;
526     debug_decl(init_vars, SUDO_DEBUG_PLUGIN)
527
528     sudoers_initlocale(setlocale(LC_ALL, NULL), def_sudoers_locale);
529
530     for (ep = envp; *ep; ep++) {
531         /* XXX - don't fill in if empty string */
532         switch (**ep) {
533             case 'K':
534                 if (strncmp("KRB5CCNAME=", *ep, 11) == 0)
535                     user_ccname = *ep + 11;
536                 break;
537             case 'P':
538                 if (strncmp("PATH=", *ep, 5) == 0)
539                     user_path = *ep + 5;
540                 break;
541             case 'S':
542                 if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0)
543                     user_prompt = *ep + 12;
544                 else if (strncmp("SUDO_USER=", *ep, 10) == 0)
545                     prev_user = *ep + 10;
546                 break;
547             }
548     }
549
550     /*
551      * Get a local copy of the user's struct passwd if we don't already
552      * have one.
553      */
554     if (sudo_user.pw == NULL) {
555         if ((sudo_user.pw = sudo_getpwnam(user_name)) == NULL) {
556             /*
557              * It is not unusual for users to place "sudo -k" in a .logout
558              * file which can cause sudo to be run during reboot after the
559              * YP/NIS/NIS+/LDAP/etc daemon has died.
560              */
561             if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE)
562                 fatalx(_("unknown uid: %u"), (unsigned int) user_uid);
563
564             /* Need to make a fake struct passwd for the call to log_fatal(). */
565             sudo_user.pw = sudo_mkpwent(user_name, user_uid, user_gid, NULL, NULL);
566             log_fatal(0, N_("unknown uid: %u"), (unsigned int) user_uid);
567             /* NOTREACHED */
568         }
569     }
570
571     /*
572      * Get group list.
573      */
574     if (user_group_list == NULL)
575         user_group_list = sudo_get_grlist(sudo_user.pw);
576
577     /* Set runas callback. */
578     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
579
580     /* Set locale callback. */
581     sudo_defs_table[I_SUDOERS_LOCALE].callback = cb_sudoers_locale;
582
583     /* Set maxseq callback. */
584     sudo_defs_table[I_MAXSEQ].callback = io_set_max_sessid;
585
586     /* It is now safe to use log_fatal() and set_perms() */
587     debug_return;
588 }
589
590 /*
591  * Fill in user_cmnd, user_args, user_base and user_stat variables
592  * and apply any command-specific defaults entries.
593  */
594 static int
595 set_cmnd(void)
596 {
597     int rval;
598     char *path = user_path;
599     debug_decl(set_cmnd, SUDO_DEBUG_PLUGIN)
600
601     /* Resolve the path and return. */
602     rval = FOUND;
603     user_stat = ecalloc(1, sizeof(struct stat));
604
605     /* Default value for cmnd, overridden below. */
606     if (user_cmnd == NULL)
607         user_cmnd = NewArgv[0];
608
609     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
610         if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
611             if (def_secure_path && !user_is_exempt())
612                 path = def_secure_path;
613             set_perms(PERM_RUNAS);
614             rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
615                 def_ignore_dot);
616             restore_perms();
617             if (rval != FOUND) {
618                 /* Failed as root, try as invoking user. */
619                 set_perms(PERM_USER);
620                 rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
621                     def_ignore_dot);
622                 restore_perms();
623             }
624         }
625
626         /* set user_args */
627         if (NewArgc > 1) {
628             char *to, *from, **av;
629             size_t size, n;
630
631             /* Alloc and build up user_args. */
632             for (size = 0, av = NewArgv + 1; *av; av++)
633                 size += strlen(*av) + 1;
634             user_args = emalloc(size);
635             if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
636                 /*
637                  * When running a command via a shell, the sudo front-end
638                  * escapes potential meta chars.  We unescape non-spaces
639                  * for sudoers matching and logging purposes.
640                  */
641                 for (to = user_args, av = NewArgv + 1; (from = *av); av++) {
642                     while (*from) {
643                         if (from[0] == '\\' && !isspace((unsigned char)from[1]))
644                             from++;
645                         *to++ = *from++;
646                     }
647                     *to++ = ' ';
648                 }
649                 *--to = '\0';
650             } else {
651                 for (to = user_args, av = NewArgv + 1; *av; av++) {
652                     n = strlcpy(to, *av, size - (to - user_args));
653                     if (n >= size - (to - user_args))
654                         fatalx(_("internal error, %s overflow"), "set_cmnd()");
655                     to += n;
656                     *to++ = ' ';
657                 }
658                 *--to = '\0';
659             }
660         }
661     }
662     if (strlen(user_cmnd) >= PATH_MAX) {
663         errno = ENAMETOOLONG;
664         fatal("%s", user_cmnd);
665     }
666
667     if ((user_base = strrchr(user_cmnd, '/')) != NULL)
668         user_base++;
669     else
670         user_base = user_cmnd;
671
672     if (!update_defaults(SETDEF_CMND))
673         log_warning(NO_STDERR, N_("problem with defaults entries"));
674
675     debug_return_int(rval);
676 }
677
678 /*
679  * Open sudoers and sanity check mode/owner/type.
680  * Returns a handle to the sudoers file or NULL on error.
681  */
682 FILE *
683 open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
684 {
685     struct stat sb;
686     FILE *fp = NULL;
687     debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN)
688
689     set_perms(PERM_SUDOERS);
690
691     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
692         case SUDO_PATH_SECURE:
693             /*
694              * If we are expecting sudoers to be group readable but
695              * it is not, we must open the file as root, not uid 1.
696              */
697             if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) {
698                 if ((sb.st_mode & S_IRGRP) == 0) {
699                     restore_perms();
700                     set_perms(PERM_ROOT);
701                 }
702             }
703             /*
704              * Open sudoers and make sure we can read it so we can present
705              * the user with a reasonable error message (unlike the lexer).
706              */
707             if ((fp = fopen(sudoers, "r")) == NULL) {
708                 log_warning(USE_ERRNO, N_("unable to open %s"), sudoers);
709             } else {
710                 if (sb.st_size != 0 && fgetc(fp) == EOF) {
711                     log_warning(USE_ERRNO, N_("unable to read %s"),
712                         sudoers);
713                     fclose(fp);
714                     fp = NULL;
715                 } else {
716                     /* Rewind fp and set close on exec flag. */
717                     rewind(fp);
718                     (void) fcntl(fileno(fp), F_SETFD, 1);
719                 }
720             }
721             break;
722         case SUDO_PATH_MISSING:
723             log_warning(USE_ERRNO, N_("unable to stat %s"), sudoers);
724             break;
725         case SUDO_PATH_BAD_TYPE:
726             log_warning(0, N_("%s is not a regular file"), sudoers);
727             break;
728         case SUDO_PATH_WRONG_OWNER:
729             log_warning(0, N_("%s is owned by uid %u, should be %u"),
730                 sudoers, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid);
731             break;
732         case SUDO_PATH_WORLD_WRITABLE:
733             log_warning(0, N_("%s is world writable"), sudoers);
734             break;
735         case SUDO_PATH_GROUP_WRITABLE:
736             log_warning(0, N_("%s is owned by gid %u, should be %u"),
737                 sudoers, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
738             break;
739         default:
740             /* NOTREACHED */
741             break;
742     }
743
744     restore_perms();            /* change back to root */
745
746     debug_return_ptr(fp);
747 }
748
749 #ifdef HAVE_LOGIN_CAP_H
750 static void
751 set_loginclass(struct passwd *pw)
752 {
753     const int errflags = NO_MAIL|MSG_ONLY;
754     login_cap_t *lc;
755     debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
756
757     if (!def_use_loginclass)
758         debug_return;
759
760     if (login_class && strcmp(login_class, "-") != 0) {
761         if (user_uid != 0 &&
762             strcmp(runas_user ? runas_user : def_runas_default, "root") != 0)
763             fatalx(_("only root can use `-c %s'"), login_class);
764     } else {
765         login_class = pw->pw_class;
766         if (!login_class || !*login_class)
767             login_class =
768                 (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
769     }
770
771     /* Make sure specified login class is valid. */
772     lc = login_getclass(login_class);
773     if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
774         /*
775          * Don't make it a fatal error if the user didn't specify the login
776          * class themselves.  We do this because if login.conf gets
777          * corrupted we want the admin to be able to use sudo to fix it.
778          */
779         if (login_class)
780             log_fatal(errflags, N_("unknown login class: %s"), login_class);
781         else
782             log_warning(errflags, N_("unknown login class: %s"), login_class);
783         def_use_loginclass = false;
784     }
785     login_close(lc);
786     debug_return;
787 }
788 #else
789 static void
790 set_loginclass(struct passwd *pw)
791 {
792 }
793 #endif /* HAVE_LOGIN_CAP_H */
794
795 #ifndef AI_FQDN
796 # define AI_FQDN AI_CANONNAME
797 #endif
798
799 /*
800  * Look up the fully qualified domain name and set user_host and user_shost.
801  * Use AI_FQDN if available since "canonical" is not always the same as fqdn.
802  */
803 static void
804 set_fqdn(void)
805 {
806     struct addrinfo *res0, hint;
807     char *p;
808     debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN)
809
810     zero_bytes(&hint, sizeof(hint));
811     hint.ai_family = PF_UNSPEC;
812     hint.ai_flags = AI_FQDN;
813     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
814         log_warning(MSG_ONLY, N_("unable to resolve host %s"), user_host);
815     } else {
816         if (user_shost != user_host)
817             efree(user_shost);
818         efree(user_host);
819         user_host = estrdup(res0->ai_canonname);
820         freeaddrinfo(res0);
821         if ((p = strchr(user_host, '.')) != NULL)
822             user_shost = estrndup(user_host, (size_t)(p - user_host));
823         else
824             user_shost = user_host;
825     }
826     debug_return;
827 }
828
829 /*
830  * Get passwd entry for the user we are going to run commands as
831  * and store it in runas_pw.  By default, commands run as "root".
832  */
833 static void
834 set_runaspw(const char *user)
835 {
836     debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
837
838     if (runas_pw != NULL)
839         sudo_pw_delref(runas_pw);
840     if (*user == '#') {
841         if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
842             runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
843     } else {
844         if ((runas_pw = sudo_getpwnam(user)) == NULL)
845             log_fatal(NO_MAIL|MSG_ONLY, N_("unknown user: %s"), user);
846     }
847     debug_return;
848 }
849
850 /*
851  * Get group entry for the group we are going to run commands as
852  * and store it in runas_gr.
853  */
854 static void
855 set_runasgr(const char *group)
856 {
857     debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
858
859     if (runas_gr != NULL)
860         sudo_gr_delref(runas_gr);
861     if (*group == '#') {
862         if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
863             runas_gr = sudo_fakegrnam(group);
864     } else {
865         if ((runas_gr = sudo_getgrnam(group)) == NULL)
866             log_fatal(NO_MAIL|MSG_ONLY, N_("unknown group: %s"), group);
867     }
868     debug_return;
869 }
870
871 /*
872  * Callback for runas_default sudoers setting.
873  */
874 static int
875 cb_runas_default(const char *user)
876 {
877     /* Only reset runaspw if user didn't specify one. */
878     if (!runas_user && !runas_group)
879         set_runaspw(user);
880     return true;
881 }
882
883 /*
884  * Callback for sudoers_locale sudoers setting.
885  */
886 static int
887 cb_sudoers_locale(const char *locale)
888 {
889     sudoers_initlocale(NULL, locale);
890     return true;
891 }
892
893 /*
894  * Cleanup hook for fatal()/fatalx()
895  */
896 void
897 sudoers_cleanup(void)
898 {
899     struct sudo_nss *nss;
900     debug_decl(sudoers_cleanup, SUDO_DEBUG_PLUGIN)
901
902     if (snl != NULL) {
903         tq_foreach_fwd(snl, nss)
904             nss->close(nss);
905     }
906     if (def_group_plugin)
907         group_plugin_unload();
908     sudo_endpwent();
909     sudo_endgrent();
910
911     debug_return;
912 }
913
914 static char *
915 resolve_editor(const char *ed, size_t edlen, int nfiles, char **files, char ***argv_out)
916 {
917     char *cp, **nargv, *editor, *editor_path = NULL;
918     int ac, i, nargc;
919     bool wasblank;
920     debug_decl(resolve_editor, SUDO_DEBUG_PLUGIN)
921
922     /* Note: editor becomes part of argv_out and is not freed. */
923     editor = emalloc(edlen + 1);
924     memcpy(editor, ed, edlen);
925     editor[edlen] = '\0';
926
927     /*
928      * Split editor into an argument vector; editor is reused (do not free).
929      * The EDITOR and VISUAL environment variables may contain command
930      * line args so look for those and alloc space for them too.
931      */
932     nargc = 1;
933     for (wasblank = false, cp = editor; *cp != '\0'; cp++) {
934         if (isblank((unsigned char) *cp))
935             wasblank = true;
936         else if (wasblank) {
937             wasblank = false;
938             nargc++;
939         }
940     }
941     /* If we can't find the editor in the user's PATH, give up. */
942     cp = strtok(editor, " \t");
943     if (cp == NULL ||
944         find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) {
945         efree(editor);
946         debug_return_str(NULL);
947     }
948     nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *));
949     for (ac = 0; cp != NULL && ac < nargc; ac++) {
950         nargv[ac] = cp;
951         cp = strtok(NULL, " \t");
952     }
953     nargv[ac++] = "--";
954     for (i = 0; i < nfiles; )
955         nargv[ac++] = files[i++];
956     nargv[ac] = NULL;
957
958     *argv_out = nargv;
959     debug_return_str(editor_path);
960 }
961
962 /*
963  * Determine which editor to use.  We don't need to worry about restricting
964  * this to a "safe" editor since it runs with the uid of the invoking user,
965  * not the runas (privileged) user.
966  */
967 static char *
968 find_editor(int nfiles, char **files, char ***argv_out)
969 {
970     const char *cp, *ep, *editor;
971     char *editor_path = NULL, **ev, *ev0[4];
972     size_t len;
973     debug_decl(find_editor, SUDO_DEBUG_PLUGIN)
974
975     /*
976      * If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
977      */
978     ev0[0] = "SUDO_EDITOR";
979     ev0[1] = "VISUAL";
980     ev0[2] = "EDITOR";
981     ev0[3] = NULL;
982     for (ev = ev0; editor_path == NULL && *ev != NULL; ev++) {
983         if ((editor = getenv(*ev)) != NULL && *editor != '\0') {
984             editor_path = resolve_editor(editor, strlen(editor), nfiles,
985                 files, argv_out);
986         }
987     }
988     if (editor_path == NULL) {
989         /* def_editor could be a path, split it up, avoiding strtok() */
990         cp = editor = def_editor;
991         do {
992             if ((ep = strchr(cp, ':')) != NULL)
993                 len = ep - cp;
994             else
995                 len = strlen(cp);
996             editor_path = resolve_editor(cp, len, nfiles, files, argv_out);
997             cp = ep + 1;
998         } while (ep != NULL && editor_path == NULL);
999     }
1000     if (!editor_path) {
1001         audit_failure(NewArgv, N_("%s: command not found"), editor);
1002         warningx(_("%s: command not found"), editor);
1003     }
1004     debug_return_str(editor_path);
1005 }
1006
1007 #ifdef USE_ADMIN_FLAG
1008 static void
1009 create_admin_success_flag(void)
1010 {
1011     struct stat statbuf;
1012     char flagfile[PATH_MAX];
1013     int fd, n;
1014     debug_decl(create_admin_success_flag, SUDO_DEBUG_PLUGIN)
1015
1016     /* Check whether the user is in the admin group. */
1017     if (!user_in_group(sudo_user.pw, "admin"))
1018         debug_return;
1019
1020     /* Build path to flag file. */
1021     n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful",
1022         user_dir);
1023     if (n <= 0 || n >= sizeof(flagfile))
1024         debug_return;
1025
1026     /* Create admin flag file if it doesn't already exist. */
1027     set_perms(PERM_USER);
1028     if (stat(flagfile, &statbuf) != 0) {
1029         fd = open(flagfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
1030         close(fd);
1031     }
1032     restore_perms();
1033     debug_return;
1034 }
1035 #else /* !USE_ADMIN_FLAG */
1036 static void
1037 create_admin_success_flag(void)
1038 {
1039     /* STUB */
1040 }
1041 #endif /* USE_ADMIN_FLAG */
1042
1043 static bool
1044 tty_present(void)
1045 {
1046 #if defined(HAVE_STRUCT_KINFO_PROC2_P_TDEV) || defined(HAVE_STRUCT_KINFO_PROC_P_TDEV) || defined(HAVE_STRUCT_KINFO_PROC_KI_TDEV) || defined(HAVE_STRUCT_KINFO_PROC_KP_EPROC_E_TDEV) || defined(HAVE_STRUCT_PSINFO_PR_TTYDEV) || defined(HAVE_PSTAT_GETPROC) || defined(__linux__)
1047     return user_ttypath != NULL;
1048 #else
1049     int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
1050     if (fd != -1)
1051         close(fd);
1052     return fd != -1;
1053 #endif
1054 }