Imported Upstream version 1.8.5p2
[debian/sudo] / plugins / sudoers / sudoers.c
1 /*
2  * Copyright (c) 1993-1996, 1998-2011 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  * For a brief history of sudo, please see the HISTORY file included
21  * with this distribution.
22  */
23
24 #define _SUDO_MAIN
25
26 #ifdef __TANDEM
27 # include <floss.h>
28 #endif
29
30 #include <config.h>
31
32 #include <sys/types.h>
33 #include <sys/stat.h>
34 #include <sys/param.h>
35 #include <sys/socket.h>
36 #include <stdio.h>
37 #ifdef STDC_HEADERS
38 # include <stdlib.h>
39 # include <stddef.h>
40 #else
41 # ifdef HAVE_STDLIB_H
42 #  include <stdlib.h>
43 # endif
44 #endif /* STDC_HEADERS */
45 #ifdef HAVE_STRING_H
46 # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
47 #  include <memory.h>
48 # endif
49 # include <string.h>
50 #endif /* HAVE_STRING_H */
51 #ifdef HAVE_STRINGS_H
52 # include <strings.h>
53 #endif /* HAVE_STRINGS_H */
54 #ifdef HAVE_UNISTD_H
55 # include <unistd.h>
56 #endif /* HAVE_UNISTD_H */
57 #include <pwd.h>
58 #include <errno.h>
59 #include <fcntl.h>
60 #include <signal.h>
61 #include <grp.h>
62 #include <time.h>
63 #ifdef HAVE_SETLOCALE
64 # include <locale.h>
65 #endif
66 #include <netinet/in.h>
67 #include <netdb.h>
68 #ifdef HAVE_LOGIN_CAP_H
69 # include <login_cap.h>
70 # ifndef LOGIN_DEFROOTCLASS
71 #  define LOGIN_DEFROOTCLASS    "daemon"
72 # endif
73 # ifndef LOGIN_SETENV
74 #  define LOGIN_SETENV  0
75 # endif
76 #endif
77 #ifdef HAVE_SELINUX
78 # include <selinux/selinux.h>
79 #endif
80 #include <ctype.h>
81 #include <setjmp.h>
82 #ifndef HAVE_GETADDRINFO
83 # include "compat/getaddrinfo.h"
84 #endif
85
86 #include "sudoers.h"
87 #include "interfaces.h"
88 #include "sudoers_version.h"
89 #include "auth/sudo_auth.h"
90 #include "secure_path.h"
91
92 /*
93  * Prototypes
94  */
95 static void init_vars(char * const *);
96 static int set_cmnd(void);
97 static void set_loginclass(struct passwd *);
98 static void set_runaspw(const char *);
99 static void set_runasgr(const char *);
100 static int cb_runas_default(const char *);
101 static int sudoers_policy_version(int verbose);
102 static int deserialize_info(char * const args[], char * const settings[],
103     char * const user_info[]);
104 static char *find_editor(int nfiles, char **files, char ***argv_out);
105 static void create_admin_success_flag(void);
106
107 /*
108  * Globals
109  */
110 struct sudo_user sudo_user;
111 struct passwd *list_pw;
112 struct interface *interfaces;
113 int long_list;
114 uid_t timestamp_uid;
115 extern int errorlineno;
116 extern bool parse_error;
117 extern char *errorfile;
118 #ifdef HAVE_BSD_AUTH_H
119 char *login_style;
120 #endif /* HAVE_BSD_AUTH_H */
121 sudo_conv_t sudo_conv;
122 sudo_printf_t sudo_printf;
123 int sudo_mode;
124
125 static int sudo_version;
126 static char *prev_user;
127 static char *runas_user;
128 static char *runas_group;
129 static struct sudo_nss_list *snl;
130 static const char *interfaces_string;
131 static sigaction_t saved_sa_int, saved_sa_quit, saved_sa_tstp;
132
133 /* XXX - must be extern for audit bits of sudo_auth.c */
134 int NewArgc;
135 char **NewArgv;
136
137 /* Declared here instead of plugin_error.c for static sudo builds. */
138 sigjmp_buf error_jmp;
139
140 static int
141 sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
142     sudo_printf_t plugin_printf, char * const settings[],
143     char * const user_info[], char * const envp[], char * const args[])
144 {
145     volatile int sources = 0;
146     sigaction_t sa;
147     struct sudo_nss *nss;
148     debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
149
150     sudo_version = version;
151     if (!sudo_conv)
152         sudo_conv = conversation;
153     if (!sudo_printf)
154         sudo_printf = plugin_printf;
155
156     /* Plugin args are only specified for API version 1.2 and higher. */
157     if (sudo_version < SUDO_API_MKVERSION(1, 2))
158         args = NULL;
159
160     if (sigsetjmp(error_jmp, 1)) {
161         /* called via error(), errorx() or log_fatal() */
162         rewind_perms();
163         debug_return_bool(-1);
164     }
165
166     bindtextdomain("sudoers", LOCALEDIR);
167
168     /*
169      * Signal setup:
170      *  Ignore keyboard-generated signals so the user cannot interrupt
171      *  us at some point and avoid the logging.
172      *  Install handler to wait for children when they exit.
173      */
174     zero_bytes(&sa, sizeof(sa));
175     sigemptyset(&sa.sa_mask);
176     sa.sa_flags = SA_RESTART;
177     sa.sa_handler = SIG_IGN;
178     (void) sigaction(SIGINT, &sa, &saved_sa_int);
179     (void) sigaction(SIGQUIT, &sa, &saved_sa_quit);
180     (void) sigaction(SIGTSTP, &sa, &saved_sa_tstp);
181
182     sudo_setpwent();
183     sudo_setgrent();
184
185     /* Initialize environment functions (including replacements). */
186     env_init(envp);
187
188     /* Setup defaults data structures. */
189     init_defaults();
190
191     /* Parse args, settings and user_info */
192     sudo_mode = deserialize_info(args, settings, user_info);
193
194     init_vars(envp);            /* XXX - move this later? */
195
196     /* Parse nsswitch.conf for sudoers order. */
197     snl = sudo_read_nss();
198
199     /* LDAP or NSS may modify the euid so we need to be root for the open. */
200     set_perms(PERM_INITIAL);
201     set_perms(PERM_ROOT);
202
203     /* Open and parse sudoers, set global defaults */
204     tq_foreach_fwd(snl, nss) {
205         if (nss->open(nss) == 0 && nss->parse(nss) == 0) {
206             sources++;
207             if (nss->setdefs(nss) != 0)
208                 log_error(NO_STDERR, _("problem with defaults entries"));
209         }
210     }
211     if (sources == 0) {
212         warningx(_("no valid sudoers sources found, quitting"));
213         debug_return_bool(-1);
214     }
215
216     /* XXX - collect post-sudoers parse settings into a function */
217
218     /*
219      * Initialize external group plugin, if any.
220      */
221     if (def_group_plugin) {
222         if (group_plugin_load(def_group_plugin) != true)
223             def_group_plugin = NULL;
224     }
225
226     /*
227      * Set runas passwd/group entries based on command line or sudoers.
228      * Note that if runas_group was specified without runas_user we
229      * defer setting runas_pw so the match routines know to ignore it.
230      */
231     if (runas_group != NULL) {
232         set_runasgr(runas_group);
233         if (runas_user != NULL)
234             set_runaspw(runas_user);
235     } else
236         set_runaspw(runas_user ? runas_user : def_runas_default);
237
238     if (!update_defaults(SETDEF_RUNAS))
239         log_error(NO_STDERR, _("problem with defaults entries"));
240
241     if (def_fqdn)
242         set_fqdn();     /* deferred until after sudoers is parsed */
243
244     /* Set login class if applicable. */
245     set_loginclass(runas_pw ? runas_pw : sudo_user.pw);
246
247     restore_perms();
248
249     debug_return_bool(true);
250 }
251
252 static void
253 sudoers_policy_close(int exit_status, int error_code)
254 {
255     debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN)
256
257     if (sigsetjmp(error_jmp, 1)) {
258         /* called via error(), errorx() or log_fatal() */
259         debug_return;
260     }
261
262     /* We do not currently log the exit status. */
263     if (error_code)
264         warningx(_("unable to execute %s: %s"), safe_cmnd, strerror(error_code));
265
266     /* Close the session we opened in sudoers_policy_init_session(). */
267     if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT))
268         (void)sudo_auth_end_session(runas_pw);
269
270     /* Free remaining references to password and group entries. */
271     pw_delref(sudo_user.pw);
272     pw_delref(runas_pw);
273     if (runas_gr != NULL)
274         gr_delref(runas_gr);
275     if (user_group_list != NULL)
276         grlist_delref(user_group_list);
277
278     debug_return;
279 }
280
281 /*
282  * The init_session function is called before executing the command
283  * and before uid/gid changes occur.
284  */
285 static int
286 sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
287 {
288     debug_decl(sudoers_policy_init, SUDO_DEBUG_PLUGIN)
289
290     /* user_env is only specified for API version 1.2 and higher. */
291     if (sudo_version < SUDO_API_MKVERSION(1, 2))
292         user_env = NULL;
293
294     if (sigsetjmp(error_jmp, 1)) {
295         /* called via error(), errorx() or log_fatal() */
296         return -1;
297     }
298
299     debug_return_bool(sudo_auth_begin_session(pwd, user_env));
300 }
301
302 static int
303 sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[],
304     char **command_infop[], char **argv_out[], char **user_env_out[])
305 {
306     static char *command_info[32]; /* XXX */
307     char **edit_argv = NULL;
308     struct sudo_nss *nss;
309     int cmnd_status = -1, validated;
310     volatile int info_len = 0;
311     volatile int rval = true;
312     debug_decl(sudoers_policy_main, SUDO_DEBUG_PLUGIN)
313
314     if (sigsetjmp(error_jmp, 1)) {
315         /* error recovery via error(), errorx() or log_fatal() */
316         rval = -1;
317         goto done;
318     }
319
320     /* Is root even allowed to run sudo? */
321     if (user_uid == 0 && !def_root_sudo) {
322         warningx(_("sudoers specifies that root is not allowed to sudo"));
323         goto bad;
324     }    
325
326     /* Check for -C overriding def_closefrom. */
327     if (user_closefrom >= 0 && user_closefrom != def_closefrom) {
328         if (!def_closefrom_override) {
329             warningx(_("you are not permitted to use the -C option"));
330             goto bad;
331         }
332         def_closefrom = user_closefrom;
333     }
334
335     set_perms(PERM_INITIAL);
336
337     /* Environment variables specified on the command line. */
338     if (env_add != NULL && env_add[0] != NULL)
339         sudo_user.env_vars = env_add;
340
341     /*
342      * Make a local copy of argc/argv, with special handling
343      * for pseudo-commands and the '-i' option.
344      */
345     if (argc == 0) {
346         NewArgc = 1;
347         NewArgv = emalloc2(NewArgc + 1, sizeof(char *));
348         NewArgv[0] = user_cmnd;
349         NewArgv[1] = NULL;
350     } else {
351         /* Must leave an extra slot before NewArgv for bash's --login */
352         NewArgc = argc;
353         NewArgv = emalloc2(NewArgc + 2, sizeof(char *));
354         memcpy(++NewArgv, argv, argc * sizeof(char *));
355         NewArgv[NewArgc] = NULL;
356         if (ISSET(sudo_mode, MODE_LOGIN_SHELL) && runas_pw != NULL)
357             NewArgv[0] = estrdup(runas_pw->pw_shell);
358     }
359
360     /* If given the -P option, set the "preserve_groups" flag. */
361     if (ISSET(sudo_mode, MODE_PRESERVE_GROUPS))
362         def_preserve_groups = true;
363
364     /* Find command in path */
365     cmnd_status = set_cmnd();
366     if (cmnd_status == -1) {
367         rval = -1;
368         goto done;
369     }
370
371 #ifdef HAVE_SETLOCALE
372     if (!setlocale(LC_ALL, def_sudoers_locale)) {
373         warningx(_("unable to set locale to \"%s\", using \"C\""),
374             def_sudoers_locale);
375         setlocale(LC_ALL, "C");
376     }
377 #endif
378
379     /*
380      * Check sudoers sources.
381      */
382     validated = FLAG_NO_USER | FLAG_NO_HOST;
383     tq_foreach_fwd(snl, nss) {
384         validated = nss->lookup(nss, validated, pwflag);
385
386         if (ISSET(validated, VALIDATE_OK)) {
387             /* Handle "= auth" in netsvc.conf */
388             if (nss->ret_if_found)
389                 break;
390         } else {
391             /* Handle [NOTFOUND=return] */
392             if (nss->ret_if_notfound)
393                 break;
394         }
395     }
396
397     if (safe_cmnd == NULL)
398         safe_cmnd = estrdup(user_cmnd);
399
400 #ifdef HAVE_SETLOCALE
401     setlocale(LC_ALL, "");
402 #endif
403
404     /* If only a group was specified, set runas_pw based on invoking user. */
405     if (runas_pw == NULL)
406         set_runaspw(user_name);
407
408     /*
409      * Look up the timestamp dir owner if one is specified.
410      */
411     if (def_timestampowner) {
412         struct passwd *pw;
413
414         if (*def_timestampowner == '#')
415             pw = sudo_getpwuid(atoi(def_timestampowner + 1));
416         else
417             pw = sudo_getpwnam(def_timestampowner);
418         if (pw != NULL) {
419             timestamp_uid = pw->pw_uid;
420             pw_delref(pw);
421         } else {
422             log_error(0, _("timestamp owner (%s): No such user"),
423                 def_timestampowner);
424             timestamp_uid = ROOT_UID;
425         }
426     }
427
428     /* If no command line args and "shell_noargs" is not set, error out. */
429     if (ISSET(sudo_mode, MODE_IMPLIED_SHELL) && !def_shell_noargs) {
430         rval = -2; /* usage error */
431         goto done;
432     }
433
434     /* Bail if a tty is required and we don't have one.  */
435     if (def_requiretty) {
436         int fd = open(_PATH_TTY, O_RDWR|O_NOCTTY);
437         if (fd == -1) {
438             audit_failure(NewArgv, _("no tty"));
439             warningx(_("sorry, you must have a tty to run sudo"));
440             goto bad;
441         } else
442             (void) close(fd);
443     }
444
445     /*
446      * We don't reset the environment for sudoedit or if the user
447      * specified the -E command line flag and they have setenv privs.
448      */
449     if (ISSET(sudo_mode, MODE_EDIT) ||
450         (ISSET(sudo_mode, MODE_PRESERVE_ENV) && def_setenv))
451         def_env_reset = false;
452
453     /* Build a new environment that avoids any nasty bits. */
454     rebuild_env();
455
456     /* Require a password if sudoers says so.  */
457     rval = check_user(validated, sudo_mode);
458     if (rval != true)
459         goto done;
460
461     /* If run as root with SUDO_USER set, set sudo_user.pw to that user. */
462     /* XXX - causes confusion when root is not listed in sudoers */
463     if (sudo_mode & (MODE_RUN | MODE_EDIT) && prev_user != NULL) {
464         if (user_uid == 0 && strcmp(prev_user, "root") != 0) {
465             struct passwd *pw;
466
467             if ((pw = sudo_getpwnam(prev_user)) != NULL) {
468                     if (sudo_user.pw != NULL)
469                         pw_delref(sudo_user.pw);
470                     sudo_user.pw = pw;
471             }
472         }
473     }
474
475     /* If the user was not allowed to run the command we are done. */
476     if (!ISSET(validated, VALIDATE_OK)) {
477         if (ISSET(validated, FLAG_NO_USER | FLAG_NO_HOST)) {
478             audit_failure(NewArgv, _("No user or host"));
479             log_denial(validated, 1);
480         } else {
481             if (def_path_info) {
482                 /*
483                  * We'd like to not leak path info at all here, but that can
484                  * *really* confuse the users.  To really close the leak we'd
485                  * have to say "not allowed to run foo" even when the problem
486                  * is just "no foo in path" since the user can trivially set
487                  * their path to just contain a single dir.
488                  */
489                 log_denial(validated,
490                     !(cmnd_status == NOT_FOUND_DOT || cmnd_status == NOT_FOUND));
491                 if (cmnd_status == NOT_FOUND)
492                     warningx(_("%s: command not found"), user_cmnd);
493                 else if (cmnd_status == NOT_FOUND_DOT)
494                     warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd);
495             } else {
496                 /* Just tell the user they are not allowed to run foo. */
497                 log_denial(validated, 1);
498             }
499             audit_failure(NewArgv, _("validation failure"));
500         }
501         goto bad;
502     }
503
504     /* Create Ubuntu-style dot file to indicate sudo was successful. */
505     create_admin_success_flag();
506
507     /* Finally tell the user if the command did not exist. */
508     if (cmnd_status == NOT_FOUND_DOT) {
509         audit_failure(NewArgv, _("command in current directory"));
510         warningx(_("ignoring `%s' found in '.'\nUse `sudo ./%s' if this is the `%s' you wish to run."), user_cmnd, user_cmnd, user_cmnd);
511         goto bad;
512     } else if (cmnd_status == NOT_FOUND) {
513         audit_failure(NewArgv, _("%s: command not found"), user_cmnd);
514         warningx(_("%s: command not found"), user_cmnd);
515         goto bad;
516     }
517
518     /* If user specified env vars make sure sudoers allows it. */
519     if (ISSET(sudo_mode, MODE_RUN) && !def_setenv) {
520         if (ISSET(sudo_mode, MODE_PRESERVE_ENV)) {
521             warningx(_("sorry, you are not allowed to preserve the environment"));
522             goto bad;
523         } else
524             validate_env_vars(sudo_user.env_vars);
525     }
526
527     if (ISSET(sudo_mode, (MODE_RUN | MODE_EDIT)) && (def_log_input || def_log_output)) {
528         if (def_iolog_file && def_iolog_dir) {
529             command_info[info_len++] = expand_iolog_path("iolog_path=",
530                 def_iolog_dir, def_iolog_file, &sudo_user.iolog_file);
531             sudo_user.iolog_file++;
532         }
533         if (def_log_input) {
534             command_info[info_len++] = estrdup("iolog_stdin=true");
535             command_info[info_len++] = estrdup("iolog_ttyin=true");
536         }
537         if (def_log_output) {
538             command_info[info_len++] = estrdup("iolog_stdout=true");
539             command_info[info_len++] = estrdup("iolog_stderr=true");
540             command_info[info_len++] = estrdup("iolog_ttyout=true");
541         }
542         if (def_compress_io)
543             command_info[info_len++] = estrdup("iolog_compress=true");
544     }
545
546     log_allowed(validated);
547     if (ISSET(sudo_mode, MODE_CHECK))
548         rval = display_cmnd(snl, list_pw ? list_pw : sudo_user.pw);
549     else if (ISSET(sudo_mode, MODE_LIST))
550         display_privs(snl, list_pw ? list_pw : sudo_user.pw); /* XXX - return val */
551
552     /* Cleanup sudoers sources */
553     tq_foreach_fwd(snl, nss) {
554         nss->close(nss);
555     }
556     if (def_group_plugin)
557         group_plugin_unload();
558
559     if (ISSET(sudo_mode, (MODE_VALIDATE|MODE_CHECK|MODE_LIST))) {
560         /* rval already set appropriately */
561         goto done;
562     }
563
564     /*
565      * Set umask based on sudoers.
566      * If user's umask is more restrictive, OR in those bits too
567      * unless umask_override is set.
568      */
569     if (def_umask != 0777) {
570         mode_t mask = def_umask;
571         if (!def_umask_override) {
572             mode_t omask = umask(mask);
573             mask |= omask;
574             umask(omask);
575         }
576         easprintf(&command_info[info_len++], "umask=0%o", (unsigned int)mask);
577     }
578
579     if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
580         char *p;
581
582         /* Convert /bin/sh -> -sh so shell knows it is a login shell */
583         if ((p = strrchr(NewArgv[0], '/')) == NULL)
584             p = NewArgv[0];
585         *p = '-';
586         NewArgv[0] = p;
587
588         /* Set cwd to run user's homedir. */
589         command_info[info_len++] = fmt_string("cwd", runas_pw->pw_dir);
590
591         /*
592          * Newer versions of bash require the --login option to be used
593          * in conjunction with the -c option even if the shell name starts
594          * with a '-'.  Unfortunately, bash 1.x uses -login, not --login
595          * so this will cause an error for that.
596          */
597         if (NewArgc > 1 && strcmp(NewArgv[0], "-bash") == 0 &&
598             strcmp(NewArgv[1], "-c") == 0) {
599             /* Use the extra slot before NewArgv so we can store --login. */
600             NewArgv--;
601             NewArgc++;
602             NewArgv[0] = NewArgv[1];
603             NewArgv[1] = "--login";
604         }
605
606 #if defined(_AIX) || (defined(__linux__) && !defined(HAVE_PAM))
607         /* Insert system-wide environment variables. */
608         read_env_file(_PATH_ENVIRONMENT, true);
609 #endif
610 #ifdef HAVE_LOGIN_CAP_H
611         /* Set environment based on login class. */
612         if (login_class) {
613             login_cap_t *lc = login_getclass(login_class);
614             if (lc != NULL) {
615                 setusercontext(lc, runas_pw, runas_pw->pw_uid, LOGIN_SETPATH|LOGIN_SETENV);
616                 login_close(lc);
617             }
618         }
619 #endif /* HAVE_LOGIN_CAP_H */
620     }
621
622     /* Insert system-wide environment variables. */
623     if (def_env_file)
624         read_env_file(def_env_file, false);
625
626     /* Insert user-specified environment variables. */
627     insert_env_vars(sudo_user.env_vars);
628
629     /* Restore signal handlers before we exec. */
630     (void) sigaction(SIGINT, &saved_sa_int, NULL);
631     (void) sigaction(SIGQUIT, &saved_sa_quit, NULL);
632     (void) sigaction(SIGTSTP, &saved_sa_tstp, NULL);
633
634     if (ISSET(sudo_mode, MODE_EDIT)) {
635         char *editor = find_editor(NewArgc - 1, NewArgv + 1, &edit_argv);
636         if (editor == NULL)
637             goto bad;
638         command_info[info_len++] = fmt_string("command", editor);
639         command_info[info_len++] = estrdup("sudoedit=true");
640     } else {
641         command_info[info_len++] = fmt_string("command", safe_cmnd);
642     }
643     if (def_stay_setuid) {
644         easprintf(&command_info[info_len++], "runas_uid=%u",
645             (unsigned int)user_uid);
646         easprintf(&command_info[info_len++], "runas_gid=%u",
647             (unsigned int)user_gid);
648         easprintf(&command_info[info_len++], "runas_euid=%u",
649             (unsigned int)runas_pw->pw_uid);
650         easprintf(&command_info[info_len++], "runas_egid=%u",
651             runas_gr ? (unsigned int)runas_gr->gr_gid :
652             (unsigned int)runas_pw->pw_gid);
653     } else {
654         easprintf(&command_info[info_len++], "runas_uid=%u",
655             (unsigned int)runas_pw->pw_uid);
656         easprintf(&command_info[info_len++], "runas_gid=%u",
657             runas_gr ? (unsigned int)runas_gr->gr_gid :
658             (unsigned int)runas_pw->pw_gid);
659     }
660     if (def_preserve_groups) {
661         command_info[info_len++] = "preserve_groups=true";
662     } else {
663         int i, len;
664         gid_t egid;
665         size_t glsize;
666         char *cp, *gid_list;
667         struct group_list *grlist = get_group_list(runas_pw);
668
669         /* We reserve an extra spot in the list for the effective gid. */
670         glsize = sizeof("runas_groups=") - 1 +
671             ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
672         gid_list = emalloc(glsize);
673         memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1);
674         cp = gid_list + sizeof("runas_groups=") - 1;
675
676         /* On BSD systems the effective gid is the first group in the list. */
677         egid = runas_gr ? (unsigned int)runas_gr->gr_gid :
678             (unsigned int)runas_pw->pw_gid;
679         len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);
680         if (len < 0 || len >= glsize - (cp - gid_list))
681             errorx(1, _("internal error, runas_groups overflow"));
682         cp += len;
683         for (i = 0; i < grlist->ngids; i++) {
684             if (grlist->gids[i] != egid) {
685                 len = snprintf(cp, glsize - (cp - gid_list), ",%u",
686                      (unsigned int) grlist->gids[i]);
687                 if (len < 0 || len >= glsize - (cp - gid_list))
688                     errorx(1, _("internal error, runas_groups overflow"));
689                 cp += len;
690             }
691         }
692         command_info[info_len++] = gid_list;
693         grlist_delref(grlist);
694     }
695     if (def_closefrom >= 0)
696         easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
697     if (def_noexec)
698         command_info[info_len++] = estrdup("noexec=true");
699     if (def_set_utmp)
700         command_info[info_len++] = estrdup("set_utmp=true");
701     if (def_use_pty)
702         command_info[info_len++] = estrdup("use_pty=true");
703     if (def_utmp_runas)
704         command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name);
705 #ifdef HAVE_LOGIN_CAP_H
706     if (def_use_loginclass)
707         command_info[info_len++] = fmt_string("login_class", login_class);
708 #endif /* HAVE_LOGIN_CAP_H */
709 #ifdef HAVE_SELINUX
710     if (user_role != NULL)
711         command_info[info_len++] = fmt_string("selinux_role", user_role);
712     if (user_type != NULL)
713         command_info[info_len++] = fmt_string("selinux_type", user_type);
714 #endif /* HAVE_SELINUX */
715
716     /* Must audit before uid change. */
717     audit_success(NewArgv);
718
719     *command_infop = command_info;
720
721     *argv_out = edit_argv ? edit_argv : NewArgv;
722
723     /* Get private version of the environment and zero out stashed copy. */
724     *user_env_out = env_get();
725     env_init(NULL);
726
727     goto done;
728
729 bad:
730     rval = false;
731
732 done:
733     rewind_perms();
734
735     /* Close the password and group files and free up memory. */
736     sudo_endpwent();
737     sudo_endgrent();
738
739     debug_return_bool(rval);
740 }
741
742 static int
743 sudoers_policy_check(int argc, char * const argv[], char *env_add[],
744     char **command_infop[], char **argv_out[], char **user_env_out[])
745 {
746     debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN)
747
748     if (!ISSET(sudo_mode, MODE_EDIT))
749         SET(sudo_mode, MODE_RUN);
750
751     debug_return_bool(sudoers_policy_main(argc, argv, 0, env_add, command_infop,
752         argv_out, user_env_out));
753 }
754
755 static int
756 sudoers_policy_validate(void)
757 {
758     debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN)
759
760     user_cmnd = "validate";
761     SET(sudo_mode, MODE_VALIDATE);
762
763     debug_return_bool(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL, NULL, NULL));
764 }
765
766 static void
767 sudoers_policy_invalidate(int remove)
768 {
769     debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN)
770
771     user_cmnd = "kill";
772     if (sigsetjmp(error_jmp, 1) == 0) {
773         remove_timestamp(remove);
774         plugin_cleanup(0);
775     }
776
777     debug_return;
778 }
779
780 static int
781 sudoers_policy_list(int argc, char * const argv[], int verbose,
782     const char *list_user)
783 {
784     int rval;
785     debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN)
786
787     user_cmnd = "list";
788     if (argc)
789         SET(sudo_mode, MODE_CHECK);
790     else
791         SET(sudo_mode, MODE_LIST);
792     if (verbose)
793         long_list = 1;
794     if (list_user) {
795         list_pw = sudo_getpwnam(list_user);
796         if (list_pw == NULL) {
797             warningx(_("unknown user: %s"), list_user);
798             debug_return_bool(-1);
799         }
800     }
801     rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL, NULL, NULL);
802     if (list_user) {
803         pw_delref(list_pw);
804         list_pw = NULL;
805     }
806
807     debug_return_bool(rval);
808 }
809
810 /*
811  * Initialize timezone, set umask, fill in ``sudo_user'' struct and
812  * load the ``interfaces'' array.
813  */
814 static void
815 init_vars(char * const envp[])
816 {
817     char * const * ep;
818     debug_decl(init_vars, SUDO_DEBUG_PLUGIN)
819
820 #ifdef HAVE_TZSET
821     (void) tzset();             /* set the timezone if applicable */
822 #endif /* HAVE_TZSET */
823
824     for (ep = envp; *ep; ep++) {
825         /* XXX - don't fill in if empty string */
826         switch (**ep) {
827             case 'K':
828                 if (strncmp("KRB5CCNAME=", *ep, 11) == 0)
829                     user_ccname = *ep + 11;
830                 break;
831             case 'P':
832                 if (strncmp("PATH=", *ep, 5) == 0)
833                     user_path = *ep + 5;
834                 break;
835             case 'S':
836                 if (!user_prompt && strncmp("SUDO_PROMPT=", *ep, 12) == 0)
837                     user_prompt = *ep + 12;
838                 else if (strncmp("SUDO_USER=", *ep, 10) == 0)
839                     prev_user = *ep + 10;
840                 break;
841             }
842     }
843
844     /*
845      * Get a local copy of the user's struct passwd with the shadow password
846      * if necessary.  It is assumed that euid is 0 at this point so we
847      * can read the shadow passwd file if necessary.
848      */
849     if ((sudo_user.pw = sudo_getpwuid(user_uid)) == NULL) {
850         /*
851          * It is not unusual for users to place "sudo -k" in a .logout
852          * file which can cause sudo to be run during reboot after the
853          * YP/NIS/NIS+/LDAP/etc daemon has died.
854          */
855         if (sudo_mode == MODE_KILL || sudo_mode == MODE_INVALIDATE)
856             errorx(1, _("unknown uid: %u"), (unsigned int) user_uid);
857
858         /* Need to make a fake struct passwd for the call to log_fatal(). */
859         sudo_user.pw = sudo_fakepwnamid(user_name, user_uid, user_gid);
860         log_fatal(0, _("unknown uid: %u"), (unsigned int) user_uid);
861         /* NOTREACHED */
862     }
863
864     /*
865      * Get group list.
866      */
867     if (user_group_list == NULL)
868         user_group_list = get_group_list(sudo_user.pw);
869
870     /* Set runas callback. */
871     sudo_defs_table[I_RUNAS_DEFAULT].callback = cb_runas_default;
872
873     /* It is now safe to use log_fatal() and set_perms() */
874     debug_return;
875 }
876
877 /*
878  * Fill in user_cmnd, user_args, user_base and user_stat variables
879  * and apply any command-specific defaults entries.
880  */
881 static int
882 set_cmnd(void)
883 {
884     int rval;
885     char *path = user_path;
886     debug_decl(set_cmnd, SUDO_DEBUG_PLUGIN)
887
888     /* Resolve the path and return. */
889     rval = FOUND;
890     user_stat = ecalloc(1, sizeof(struct stat));
891
892     /* Default value for cmnd, overridden below. */
893     if (user_cmnd == NULL)
894         user_cmnd = NewArgv[0];
895
896     if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) {
897         if (ISSET(sudo_mode, MODE_RUN | MODE_CHECK)) {
898             if (def_secure_path && !user_is_exempt())
899                 path = def_secure_path;
900             set_perms(PERM_RUNAS);
901             rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
902                 def_ignore_dot);
903             restore_perms();
904             if (rval != FOUND) {
905                 /* Failed as root, try as invoking user. */
906                 set_perms(PERM_USER);
907                 rval = find_path(NewArgv[0], &user_cmnd, user_stat, path,
908                     def_ignore_dot);
909                 restore_perms();
910             }
911         }
912
913         /* set user_args */
914         if (NewArgc > 1) {
915             char *to, *from, **av;
916             size_t size, n;
917
918             /* Alloc and build up user_args. */
919             for (size = 0, av = NewArgv + 1; *av; av++)
920                 size += strlen(*av) + 1;
921             user_args = emalloc(size);
922             if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
923                 /*
924                  * When running a command via a shell, the sudo front-end
925                  * escapes potential meta chars.  We unescape non-spaces
926                  * for sudoers matching and logging purposes.
927                  */
928                 for (to = user_args, av = NewArgv + 1; (from = *av); av++) {
929                     while (*from) {
930                         if (from[0] == '\\' && !isspace((unsigned char)from[1]))
931                             from++;
932                         *to++ = *from++;
933                     }
934                     *to++ = ' ';
935                 }
936                 *--to = '\0';
937             } else {
938                 for (to = user_args, av = NewArgv + 1; *av; av++) {
939                     n = strlcpy(to, *av, size - (to - user_args));
940                     if (n >= size - (to - user_args))
941                         errorx(1, _("internal error, set_cmnd() overflow"));
942                     to += n;
943                     *to++ = ' ';
944                 }
945                 *--to = '\0';
946             }
947         }
948     }
949     if (strlen(user_cmnd) >= PATH_MAX)
950         errorx(1, _("%s: %s"), user_cmnd, strerror(ENAMETOOLONG));
951
952     if ((user_base = strrchr(user_cmnd, '/')) != NULL)
953         user_base++;
954     else
955         user_base = user_cmnd;
956
957     if (!update_defaults(SETDEF_CMND))
958         log_error(NO_STDERR, _("problem with defaults entries"));
959
960     debug_return_int(rval);
961 }
962
963 /*
964  * Open sudoers and sanity check mode/owner/type.
965  * Returns a handle to the sudoers file or NULL on error.
966  */
967 FILE *
968 open_sudoers(const char *sudoers, bool doedit, bool *keepopen)
969 {
970     struct stat sb;
971     FILE *fp = NULL;
972     debug_decl(open_sudoers, SUDO_DEBUG_PLUGIN)
973
974     set_perms(PERM_SUDOERS);
975
976     switch (sudo_secure_file(sudoers, sudoers_uid, sudoers_gid, &sb)) {
977         case SUDO_PATH_SECURE:
978             /*
979              * If we are expecting sudoers to be group readable but
980              * it is not, we must open the file as root, not uid 1.
981              */
982             if (sudoers_uid == ROOT_UID && (sudoers_mode & S_IRGRP)) {
983                 if ((sb.st_mode & S_IRGRP) == 0) {
984                     restore_perms();
985                     set_perms(PERM_ROOT);
986                 }
987             }
988             /*
989              * Open sudoers and make sure we can read it so we can present
990              * the user with a reasonable error message (unlike the lexer).
991              */
992             if ((fp = fopen(sudoers, "r")) == NULL) {
993                 log_error(USE_ERRNO, _("unable to open %s"), sudoers);
994             } else {
995                 if (sb.st_size != 0 && fgetc(fp) == EOF) {
996                     log_error(USE_ERRNO, _("unable to read %s"),
997                         sudoers);
998                     fclose(fp);
999                     fp = NULL;
1000                 } else {
1001                     /* Rewind fp and set close on exec flag. */
1002                     rewind(fp);
1003                     (void) fcntl(fileno(fp), F_SETFD, 1);
1004                 }
1005             }
1006             break;
1007         case SUDO_PATH_MISSING:
1008             log_error(USE_ERRNO, _("unable to stat %s"), sudoers);
1009             break;
1010         case SUDO_PATH_BAD_TYPE:
1011             log_error(0, _("%s is not a regular file"), sudoers);
1012             break;
1013         case SUDO_PATH_WRONG_OWNER:
1014             log_error(0, _("%s is owned by uid %u, should be %u"),
1015                 sudoers, (unsigned int) sb.st_uid, (unsigned int) sudoers_uid);
1016             break;
1017         case SUDO_PATH_WORLD_WRITABLE:
1018             log_error(0, _("%s is world writable"), sudoers);
1019             break;
1020         case SUDO_PATH_GROUP_WRITABLE:
1021             log_error(0, _("%s is owned by gid %u, should be %u"),
1022                 sudoers, (unsigned int) sb.st_gid, (unsigned int) sudoers_gid);
1023             break;
1024         default:
1025             /* NOTREACHED */
1026             break;
1027     }
1028
1029     restore_perms();            /* change back to root */
1030
1031     debug_return_ptr(fp);
1032 }
1033
1034 #ifdef HAVE_LOGIN_CAP_H
1035 static void
1036 set_loginclass(struct passwd *pw)
1037 {
1038     const int errflags = NO_MAIL|MSG_ONLY;
1039     login_cap_t *lc;
1040     debug_decl(set_loginclass, SUDO_DEBUG_PLUGIN)
1041
1042     if (!def_use_loginclass)
1043         debug_return;
1044
1045     if (login_class && strcmp(login_class, "-") != 0) {
1046         if (user_uid != 0 &&
1047             strcmp(runas_user ? runas_user : def_runas_default, "root") != 0)
1048             errorx(1, _("only root can use `-c %s'"), login_class);
1049     } else {
1050         login_class = pw->pw_class;
1051         if (!login_class || !*login_class)
1052             login_class =
1053                 (pw->pw_uid == 0) ? LOGIN_DEFROOTCLASS : LOGIN_DEFCLASS;
1054     }
1055
1056     /* Make sure specified login class is valid. */
1057     lc = login_getclass(login_class);
1058     if (!lc || !lc->lc_class || strcmp(lc->lc_class, login_class) != 0) {
1059         /*
1060          * Don't make it a fatal error if the user didn't specify the login
1061          * class themselves.  We do this because if login.conf gets
1062          * corrupted we want the admin to be able to use sudo to fix it.
1063          */
1064         if (login_class)
1065             log_fatal(errflags, _("unknown login class: %s"), login_class);
1066         else
1067             log_error(errflags, _("unknown login class: %s"), login_class);
1068         def_use_loginclass = false;
1069     }
1070     login_close(lc);
1071     debug_return;
1072 }
1073 #else
1074 static void
1075 set_loginclass(struct passwd *pw)
1076 {
1077 }
1078 #endif /* HAVE_LOGIN_CAP_H */
1079
1080 /*
1081  * Look up the fully qualified domain name and set user_host and user_shost.
1082  */
1083 void
1084 set_fqdn(void)
1085 {
1086     struct addrinfo *res0, hint;
1087     char *p;
1088     debug_decl(set_fqdn, SUDO_DEBUG_PLUGIN)
1089
1090     zero_bytes(&hint, sizeof(hint));
1091     hint.ai_family = PF_UNSPEC;
1092     hint.ai_flags = AI_CANONNAME;
1093     if (getaddrinfo(user_host, NULL, &hint, &res0) != 0) {
1094         log_error(MSG_ONLY, _("unable to resolve host %s"), user_host);
1095     } else {
1096         if (user_shost != user_host)
1097             efree(user_shost);
1098         efree(user_host);
1099         user_host = estrdup(res0->ai_canonname);
1100         freeaddrinfo(res0);
1101     }
1102     if ((p = strchr(user_host, '.')) != NULL)
1103         user_shost = estrndup(user_host, (size_t)(p - user_host));
1104     else
1105         user_shost = user_host;
1106     debug_return;
1107 }
1108
1109 /*
1110  * Get passwd entry for the user we are going to run commands as
1111  * and store it in runas_pw.  By default, commands run as "root".
1112  */
1113 static void
1114 set_runaspw(const char *user)
1115 {
1116     debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
1117
1118     if (runas_pw != NULL)
1119         pw_delref(runas_pw);
1120     if (*user == '#') {
1121         if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL)
1122             runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0);
1123     } else {
1124         if ((runas_pw = sudo_getpwnam(user)) == NULL)
1125             log_fatal(NO_MAIL|MSG_ONLY, _("unknown user: %s"), user);
1126     }
1127     debug_return;
1128 }
1129
1130 /*
1131  * Get group entry for the group we are going to run commands as
1132  * and store it in runas_gr.
1133  */
1134 static void
1135 set_runasgr(const char *group)
1136 {
1137     debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
1138
1139     if (runas_gr != NULL)
1140         gr_delref(runas_gr);
1141     if (*group == '#') {
1142         if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL)
1143             runas_gr = sudo_fakegrnam(group);
1144     } else {
1145         if ((runas_gr = sudo_getgrnam(group)) == NULL)
1146             log_fatal(NO_MAIL|MSG_ONLY, _("unknown group: %s"), group);
1147     }
1148     debug_return;
1149 }
1150
1151 /*
1152  * Callback for runas_default sudoers setting.
1153  */
1154 static int
1155 cb_runas_default(const char *user)
1156 {
1157     /* Only reset runaspw if user didn't specify one. */
1158     if (!runas_user && !runas_group)
1159         set_runaspw(user);
1160     return true;
1161 }
1162
1163 /*
1164  * Cleanup hook for error()/errorx()
1165  */
1166 void
1167 plugin_cleanup(int gotsignal)
1168 {
1169     struct sudo_nss *nss;
1170
1171     if (!gotsignal) {
1172         debug_decl(plugin_cleanup, SUDO_DEBUG_PLUGIN)
1173         if (snl != NULL) {
1174             tq_foreach_fwd(snl, nss)
1175                 nss->close(nss);
1176         }
1177         if (def_group_plugin)
1178             group_plugin_unload();
1179         sudo_endpwent();
1180         sudo_endgrent();
1181         debug_return;
1182     }
1183 }
1184
1185 static int
1186 sudoers_policy_version(int verbose)
1187 {
1188     debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN)
1189
1190     if (sigsetjmp(error_jmp, 1)) {
1191         /* error recovery via error(), errorx() or log_fatal() */
1192         debug_return_bool(-1);
1193     }
1194
1195     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
1196         PACKAGE_VERSION);
1197     sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers file grammar version %d\n"),
1198         SUDOERS_GRAMMAR_VERSION);
1199
1200     if (verbose) {
1201         sudo_printf(SUDO_CONV_INFO_MSG, _("\nSudoers path: %s\n"), sudoers_file);
1202 #ifdef HAVE_LDAP
1203 # ifdef _PATH_NSSWITCH_CONF
1204         sudo_printf(SUDO_CONV_INFO_MSG, _("nsswitch path: %s\n"), _PATH_NSSWITCH_CONF);
1205 # endif
1206         sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.conf path: %s\n"), _PATH_LDAP_CONF);
1207         sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.secret path: %s\n"), _PATH_LDAP_SECRET);
1208 #endif
1209         dump_auth_methods();
1210         dump_defaults();
1211         sudo_printf(SUDO_CONV_INFO_MSG, "\n");
1212         if (interfaces_string != NULL) {
1213             dump_interfaces(interfaces_string);
1214             sudo_printf(SUDO_CONV_INFO_MSG, "\n");
1215         }
1216     }
1217     debug_return_bool(true);
1218 }
1219
1220 static int
1221 deserialize_info(char * const args[], char * const settings[], char * const user_info[])
1222 {
1223     char * const *cur;
1224     const char *p, *groups = NULL;
1225     const char *debug_flags = NULL;
1226     int flags = 0;
1227     debug_decl(deserialize_info, SUDO_DEBUG_PLUGIN)
1228
1229 #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
1230
1231     /* Parse sudo.conf plugin args. */
1232     if (args != NULL) {
1233         for (cur = args; *cur != NULL; cur++) {
1234             if (MATCHES(*cur, "sudoers_file=")) {
1235                 sudoers_file = *cur + sizeof("sudoers_file=") - 1;
1236                 continue;
1237             }
1238             if (MATCHES(*cur, "sudoers_uid=")) {
1239                 sudoers_uid = (uid_t) atoi(*cur + sizeof("sudoers_uid=") - 1);
1240                 continue;
1241             }
1242             if (MATCHES(*cur, "sudoers_gid=")) {
1243                 sudoers_gid = (gid_t) atoi(*cur + sizeof("sudoers_gid=") - 1);
1244                 continue;
1245             }
1246             if (MATCHES(*cur, "sudoers_mode=")) {
1247                 sudoers_mode = (mode_t) strtol(*cur + sizeof("sudoers_mode=") - 1,
1248                     NULL, 8);
1249                 continue;
1250             }
1251         }
1252     }
1253
1254     /* Parse command line settings. */
1255     user_closefrom = -1;
1256     for (cur = settings; *cur != NULL; cur++) {
1257         if (MATCHES(*cur, "closefrom=")) {
1258             user_closefrom = atoi(*cur + sizeof("closefrom=") - 1);
1259             continue;
1260         }
1261         if (MATCHES(*cur, "debug_flags=")) {
1262             debug_flags = *cur + sizeof("debug_flags=") - 1;
1263             continue;
1264         }
1265         if (MATCHES(*cur, "runas_user=")) {
1266             runas_user = *cur + sizeof("runas_user=") - 1;
1267             continue;
1268         }
1269         if (MATCHES(*cur, "runas_group=")) {
1270             runas_group = *cur + sizeof("runas_group=") - 1;
1271             continue;
1272         }
1273         if (MATCHES(*cur, "prompt=")) {
1274             user_prompt = *cur + sizeof("prompt=") - 1;
1275             def_passprompt_override = true;
1276             continue;
1277         }
1278         if (MATCHES(*cur, "set_home=")) {
1279             if (atobool(*cur + sizeof("set_home=") - 1) == true)
1280                 SET(flags, MODE_RESET_HOME);
1281             continue;
1282         }
1283         if (MATCHES(*cur, "preserve_environment=")) {
1284             if (atobool(*cur + sizeof("preserve_environment=") - 1) == true)
1285                 SET(flags, MODE_PRESERVE_ENV);
1286             continue;
1287         }
1288         if (MATCHES(*cur, "run_shell=")) {
1289             if (atobool(*cur + sizeof("run_shell=") - 1) == true)
1290                 SET(flags, MODE_SHELL);
1291             continue;
1292         }
1293         if (MATCHES(*cur, "login_shell=")) {
1294             if (atobool(*cur + sizeof("login_shell=") - 1) == true) {
1295                 SET(flags, MODE_LOGIN_SHELL);
1296                 def_env_reset = true;
1297             }
1298             continue;
1299         }
1300         if (MATCHES(*cur, "implied_shell=")) {
1301             if (atobool(*cur + sizeof("implied_shell=") - 1) == true)
1302                 SET(flags, MODE_IMPLIED_SHELL);
1303             continue;
1304         }
1305         if (MATCHES(*cur, "preserve_groups=")) {
1306             if (atobool(*cur + sizeof("preserve_groups=") - 1) == true)
1307                 SET(flags, MODE_PRESERVE_GROUPS);
1308             continue;
1309         }
1310         if (MATCHES(*cur, "ignore_ticket=")) {
1311             if (atobool(*cur + sizeof("ignore_ticket=") - 1) == true)
1312                 SET(flags, MODE_IGNORE_TICKET);
1313             continue;
1314         }
1315         if (MATCHES(*cur, "noninteractive=")) {
1316             if (atobool(*cur + sizeof("noninteractive=") - 1) == true)
1317                 SET(flags, MODE_NONINTERACTIVE);
1318             continue;
1319         }
1320         if (MATCHES(*cur, "sudoedit=")) {
1321             if (atobool(*cur + sizeof("sudoedit=") - 1) == true)
1322                 SET(flags, MODE_EDIT);
1323             continue;
1324         }
1325         if (MATCHES(*cur, "login_class=")) {
1326             login_class = *cur + sizeof("login_class=") - 1;
1327             def_use_loginclass = true;
1328             continue;
1329         }
1330 #ifdef HAVE_SELINUX
1331         if (MATCHES(*cur, "selinux_role=")) {
1332             user_role = *cur + sizeof("selinux_role=") - 1;
1333             continue;
1334         }
1335         if (MATCHES(*cur, "selinux_type=")) {
1336             user_type = *cur + sizeof("selinux_type=") - 1;
1337             continue;
1338         }
1339 #endif /* HAVE_SELINUX */
1340 #ifdef HAVE_BSD_AUTH_H
1341         if (MATCHES(*cur, "bsdauth_type=")) {
1342             login_style = *cur + sizeof("bsdauth_type=") - 1;
1343             continue;
1344         }
1345 #endif /* HAVE_BSD_AUTH_H */
1346 #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
1347         if (MATCHES(*cur, "progname=")) {
1348             setprogname(*cur + sizeof("progname=") - 1);
1349             continue;
1350         }
1351 #endif
1352         if (MATCHES(*cur, "network_addrs=")) {
1353             interfaces_string = *cur + sizeof("network_addrs=") - 1;
1354             set_interfaces(interfaces_string);
1355             continue;
1356         }
1357     }
1358
1359     for (cur = user_info; *cur != NULL; cur++) {
1360         if (MATCHES(*cur, "user=")) {
1361             user_name = estrdup(*cur + sizeof("user=") - 1);
1362             continue;
1363         }
1364         if (MATCHES(*cur, "uid=")) {
1365             user_uid = (uid_t) atoi(*cur + sizeof("uid=") - 1);
1366             continue;
1367         }
1368         if (MATCHES(*cur, "gid=")) {
1369             p = *cur + sizeof("gid=") - 1;
1370             user_gid = (gid_t) atoi(p);
1371             continue;
1372         }
1373         if (MATCHES(*cur, "groups=")) {
1374             groups = *cur + sizeof("groups=") - 1;
1375             continue;
1376         }
1377         if (MATCHES(*cur, "cwd=")) {
1378             user_cwd = estrdup(*cur + sizeof("cwd=") - 1);
1379             continue;
1380         }
1381         if (MATCHES(*cur, "tty=")) {
1382             user_tty = user_ttypath = estrdup(*cur + sizeof("tty=") - 1);
1383             if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
1384                 user_tty += sizeof(_PATH_DEV) - 1;
1385             continue;
1386         }
1387         if (MATCHES(*cur, "host=")) {
1388             user_host = user_shost = estrdup(*cur + sizeof("host=") - 1);
1389             if ((p = strchr(user_host, '.')))
1390                 user_shost = estrndup(user_host, (size_t)(p - user_host));
1391             continue;
1392         }
1393         if (MATCHES(*cur, "lines=")) {
1394             sudo_user.lines = atoi(*cur + sizeof("lines=") - 1);
1395             continue;
1396         }
1397         if (MATCHES(*cur, "cols=")) {
1398             sudo_user.cols = atoi(*cur + sizeof("cols=") - 1);
1399             continue;
1400         }
1401     }
1402     if (user_cwd == NULL)
1403         user_cwd = "unknown";
1404     if (user_tty == NULL)
1405         user_tty = "unknown"; /* user_ttypath remains NULL */
1406
1407     if (groups != NULL && groups[0] != '\0') {
1408         const char *cp;
1409         GETGROUPS_T *gids;
1410         int ngids;
1411
1412         /* Count number of groups, including passwd gid. */
1413         ngids = 2;
1414         for (cp = groups; *cp != '\0'; cp++) {
1415             if (*cp == ',')
1416                 ngids++;
1417         }
1418
1419         /* The first gid in the list is the passwd group gid. */
1420         gids = emalloc2(ngids, sizeof(GETGROUPS_T));
1421         gids[0] = user_gid;
1422         ngids = 1;
1423         cp = groups;
1424         for (;;) {
1425             gids[ngids] = atoi(cp);
1426             if (gids[0] != gids[ngids])
1427                 ngids++;
1428             cp = strchr(cp, ',');
1429             if (cp == NULL)
1430                 break;
1431             cp++; /* skip over comma */
1432         }
1433         set_group_list(user_name, gids, ngids);
1434         efree(gids);
1435     }
1436
1437     /* Setup debugging if indicated. */
1438     if (debug_flags != NULL) {
1439         sudo_debug_init(NULL, debug_flags);
1440         for (cur = settings; *cur != NULL; cur++)
1441             sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
1442         for (cur = user_info; *cur != NULL; cur++)
1443             sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);
1444     }
1445
1446 #undef MATCHES
1447     debug_return_int(flags);
1448 }
1449
1450 static char *
1451 resolve_editor(char *editor, int nfiles, char **files, char ***argv_out)
1452 {
1453     char *cp, **nargv, *editor_path = NULL;
1454     int ac, i, nargc;
1455     bool wasblank;
1456     debug_decl(resolve_editor, SUDO_DEBUG_PLUGIN)
1457
1458     editor = estrdup(editor); /* becomes part of argv_out */
1459
1460     /*
1461      * Split editor into an argument vector; editor is reused (do not free).
1462      * The EDITOR and VISUAL environment variables may contain command
1463      * line args so look for those and alloc space for them too.
1464      */
1465     nargc = 1;
1466     for (wasblank = false, cp = editor; *cp != '\0'; cp++) {
1467         if (isblank((unsigned char) *cp))
1468             wasblank = true;
1469         else if (wasblank) {
1470             wasblank = false;
1471             nargc++;
1472         }
1473     }
1474     /* If we can't find the editor in the user's PATH, give up. */
1475     cp = strtok(editor, " \t");
1476     if (cp == NULL ||
1477         find_path(cp, &editor_path, NULL, getenv("PATH"), 0) != FOUND) {
1478         efree(editor);
1479         debug_return_str(NULL);
1480     }
1481     nargv = (char **) emalloc2(nargc + 1 + nfiles + 1, sizeof(char *));
1482     for (ac = 0; cp != NULL && ac < nargc; ac++) {
1483         nargv[ac] = cp;
1484         cp = strtok(NULL, " \t");
1485     }
1486     nargv[ac++] = "--";
1487     for (i = 0; i < nfiles; )
1488         nargv[ac++] = files[i++];
1489     nargv[ac] = NULL;
1490
1491     *argv_out = nargv;
1492     debug_return_str(editor_path);
1493 }
1494
1495 /*
1496  * Determine which editor to use.  We don't need to worry about restricting
1497  * this to a "safe" editor since it runs with the uid of the invoking user,
1498  * not the runas (privileged) user.
1499  */
1500 static char *
1501 find_editor(int nfiles, char **files, char ***argv_out)
1502 {
1503     char *cp, *editor, *editor_path = NULL, **ev, *ev0[4];
1504     debug_decl(find_editor, SUDO_DEBUG_PLUGIN)
1505
1506     /*
1507      * If any of SUDO_EDITOR, VISUAL or EDITOR are set, choose the first one.
1508      */
1509     ev0[0] = "SUDO_EDITOR";
1510     ev0[1] = "VISUAL";
1511     ev0[2] = "EDITOR";
1512     ev0[3] = NULL;
1513     for (ev = ev0; *ev != NULL; ev++) {
1514         if ((editor = getenv(*ev)) != NULL && *editor != '\0') {
1515             editor_path = resolve_editor(editor, nfiles, files, argv_out);
1516             if (editor_path != NULL)
1517                 break;
1518         }
1519     }
1520     if (editor_path == NULL) {
1521         /* def_editor could be a path, split it up */
1522         editor = estrdup(def_editor);
1523         cp = strtok(editor, ":");
1524         while (cp != NULL && editor_path == NULL) {
1525             editor_path = resolve_editor(cp, nfiles, files, argv_out);
1526             cp = strtok(NULL, ":");
1527         }
1528         if (editor_path)
1529             efree(editor);
1530     }
1531     if (!editor_path) {
1532         audit_failure(NewArgv, _("%s: command not found"), editor);
1533         warningx(_("%s: command not found"), editor);
1534     }
1535     debug_return_str(editor_path);
1536 }
1537
1538 #ifdef USE_ADMIN_FLAG
1539 static void
1540 create_admin_success_flag(void)
1541 {
1542     struct stat statbuf;
1543     char flagfile[PATH_MAX];
1544     int fd, n;
1545     debug_decl(create_admin_success_flag, SUDO_DEBUG_PLUGIN)
1546
1547     /* Check whether the user is in the admin group. */
1548     if (!user_in_group(sudo_user.pw, "admin"))
1549         debug_return;
1550
1551     /* Build path to flag file. */
1552     n = snprintf(flagfile, sizeof(flagfile), "%s/.sudo_as_admin_successful",
1553         user_dir);
1554     if (n <= 0 || n >= sizeof(flagfile))
1555         debug_return;
1556
1557     /* Create admin flag file if it doesn't already exist. */
1558     set_perms(PERM_USER);
1559     if (stat(flagfile, &statbuf) != 0) {
1560         fd = open(flagfile, O_CREAT|O_WRONLY|O_EXCL, 0644);
1561         close(fd);
1562     }
1563     restore_perms();
1564     debug_return;
1565 }
1566 #else /* !USE_ADMIN_FLAG */
1567 static void
1568 create_admin_success_flag(void)
1569 {
1570     /* STUB */
1571 }
1572 #endif /* USE_ADMIN_FLAG */
1573
1574 static void
1575 sudoers_policy_register_hooks(int version, int (*register_hook)(struct sudo_hook *hook))
1576 {
1577     struct sudo_hook hook;
1578
1579     memset(&hook, 0, sizeof(hook));
1580     hook.hook_version = SUDO_HOOK_VERSION;
1581
1582     hook.hook_type = SUDO_HOOK_SETENV;
1583     hook.hook_fn = sudoers_hook_setenv;
1584     register_hook(&hook);
1585
1586     hook.hook_type = SUDO_HOOK_UNSETENV;
1587     hook.hook_fn = sudoers_hook_unsetenv;
1588     register_hook(&hook);
1589
1590     hook.hook_type = SUDO_HOOK_GETENV;
1591     hook.hook_fn = sudoers_hook_getenv;
1592     register_hook(&hook);
1593
1594     hook.hook_type = SUDO_HOOK_PUTENV;
1595     hook.hook_fn = sudoers_hook_putenv;
1596     register_hook(&hook);
1597 }
1598
1599 struct policy_plugin sudoers_policy = {
1600     SUDO_POLICY_PLUGIN,
1601     SUDO_API_VERSION,
1602     sudoers_policy_open,
1603     sudoers_policy_close,
1604     sudoers_policy_version,
1605     sudoers_policy_check,
1606     sudoers_policy_list,
1607     sudoers_policy_validate,
1608     sudoers_policy_invalidate,
1609     sudoers_policy_init_session,
1610     sudoers_policy_register_hooks
1611 };