Annotation of embedaddon/sudo/plugins/sudoers/policy.c, revision 1.1.1.2
1.1 misho 1: /*
2: * Copyright (c) 2010-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:
17: #include <config.h>
18:
19: #include <sys/types.h>
20: #include <sys/stat.h>
21: #include <netinet/in.h>
22: #include <stdio.h>
23: #ifdef STDC_HEADERS
24: # include <stdlib.h>
25: # include <stddef.h>
26: #else
27: # ifdef HAVE_STDLIB_H
28: # include <stdlib.h>
29: # endif
30: #endif /* STDC_HEADERS */
31: #ifdef HAVE_STRING_H
32: # if defined(HAVE_MEMORY_H) && !defined(STDC_HEADERS)
33: # include <memory.h>
34: # endif
35: # include <string.h>
36: #endif /* HAVE_STRING_H */
37: #ifdef HAVE_STRINGS_H
38: # include <strings.h>
39: #endif /* HAVE_STRINGS_H */
40: #ifdef HAVE_UNISTD_H
41: # include <unistd.h>
42: #endif /* HAVE_UNISTD_H */
43: #include <errno.h>
44: #include <grp.h>
45: #include <pwd.h>
46:
47: #include "sudoers.h"
48: #include "sudoers_version.h"
49: #include "interfaces.h"
50:
51: /*
52: * Info passed in from the sudo front-end.
53: */
54: struct sudoers_policy_open_info {
55: char * const *settings;
56: char * const *user_info;
57: char * const *plugin_args;
58: };
59:
60: /*
61: * Command execution args to be filled in: argv, envp and command info.
62: */
63: struct sudoers_exec_args {
64: char ***argv;
65: char ***envp;
66: char ***info;
67: };
68:
69: static int sudo_version;
70: static const char *interfaces_string;
71: sudo_conv_t sudo_conv;
72: const char *path_ldap_conf = _PATH_LDAP_CONF;
73: const char *path_ldap_secret = _PATH_LDAP_SECRET;
74:
75: extern __dso_public struct policy_plugin sudoers_policy;
76:
77: #ifdef HAVE_BSD_AUTH_H
78: extern char *login_style;
79: #endif /* HAVE_BSD_AUTH_H */
80:
81: /*
82: * Deserialize args, settings and user_info arrays.
83: * Fills in struct sudo_user and other common sudoers state.
84: */
85: int
86: sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
87: {
88: struct sudoers_policy_open_info *info = v;
89: char * const *cur;
1.1.1.2 ! misho 90: const char *p, *errstr, *groups = NULL;
1.1 misho 91: const char *debug_flags = NULL;
1.1.1.2 ! misho 92: const char *remhost = NULL;
1.1 misho 93: int flags = 0;
1.1.1.2 ! misho 94: long lval;
! 95: char *ep;
1.1 misho 96: debug_decl(sudoers_policy_deserialize_info, SUDO_DEBUG_PLUGIN)
97:
98: #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0)
99:
100: /* Parse sudo.conf plugin args. */
101: if (info->plugin_args != NULL) {
102: for (cur = info->plugin_args; *cur != NULL; cur++) {
103: if (MATCHES(*cur, "sudoers_file=")) {
104: sudoers_file = *cur + sizeof("sudoers_file=") - 1;
105: continue;
106: }
107: if (MATCHES(*cur, "sudoers_uid=")) {
1.1.1.2 ! misho 108: p = *cur + sizeof("sudoers_uid=") - 1;
! 109: sudoers_uid = (uid_t) atoid(p, NULL, NULL, &errstr);
! 110: if (errstr != NULL)
! 111: fatalx(_("%s: %s"), *cur, _(errstr));
1.1 misho 112: continue;
113: }
114: if (MATCHES(*cur, "sudoers_gid=")) {
1.1.1.2 ! misho 115: p = *cur + sizeof("sudoers_gid=") - 1;
! 116: sudoers_gid = (gid_t) atoid(p, NULL, NULL, &errstr);
! 117: if (errstr != NULL)
! 118: fatalx(_("%s: %s"), *cur, _(errstr));
1.1 misho 119: continue;
120: }
121: if (MATCHES(*cur, "sudoers_mode=")) {
1.1.1.2 ! misho 122: errno = 0;
! 123: p = *cur + sizeof("sudoers_mode=") - 1;
! 124: lval = strtol(p, &ep, 8);
! 125: if (*p == '\0' || *ep != '\0')
! 126: fatalx(_("%s: %s"), *cur, _("invalid value"));
! 127: if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
! 128: || (lval > 0777 || lval < 0))
! 129: fatalx(_("%s: %s"), *cur, _("value out of range"));
! 130: sudoers_mode = (mode_t) lval;
1.1 misho 131: continue;
132: }
133: if (MATCHES(*cur, "ldap_conf=")) {
134: path_ldap_conf = *cur + sizeof("ldap_conf=") - 1;
135: continue;
136: }
137: if (MATCHES(*cur, "ldap_secret=")) {
138: path_ldap_secret = *cur + sizeof("ldap_secret=") - 1;
139: continue;
140: }
141: }
142: }
143:
144: /* Parse command line settings. */
145: user_closefrom = -1;
146: for (cur = info->settings; *cur != NULL; cur++) {
147: if (MATCHES(*cur, "closefrom=")) {
1.1.1.2 ! misho 148: errno = 0;
! 149: p = *cur + sizeof("closefrom=") - 1;
! 150: lval = strtol(p, &ep, 10);
! 151: if (*p == '\0' || *ep != '\0')
! 152: fatalx(_("%s: %s"), *cur, _("invalid value"));
! 153: if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
! 154: || (lval > INT_MAX || lval < 3))
! 155: fatalx(_("%s: %s"), *cur, _("value out of range"));
! 156: user_closefrom = (int) lval;
1.1 misho 157: continue;
158: }
159: if (MATCHES(*cur, "debug_flags=")) {
160: debug_flags = *cur + sizeof("debug_flags=") - 1;
161: continue;
162: }
163: if (MATCHES(*cur, "runas_user=")) {
164: *runas_user = *cur + sizeof("runas_user=") - 1;
165: sudo_user.flags |= RUNAS_USER_SPECIFIED;
166: continue;
167: }
168: if (MATCHES(*cur, "runas_group=")) {
169: *runas_group = *cur + sizeof("runas_group=") - 1;
170: sudo_user.flags |= RUNAS_GROUP_SPECIFIED;
171: continue;
172: }
173: if (MATCHES(*cur, "prompt=")) {
174: user_prompt = *cur + sizeof("prompt=") - 1;
175: def_passprompt_override = true;
176: continue;
177: }
178: if (MATCHES(*cur, "set_home=")) {
179: if (atobool(*cur + sizeof("set_home=") - 1) == true)
180: SET(flags, MODE_RESET_HOME);
181: continue;
182: }
183: if (MATCHES(*cur, "preserve_environment=")) {
184: if (atobool(*cur + sizeof("preserve_environment=") - 1) == true)
185: SET(flags, MODE_PRESERVE_ENV);
186: continue;
187: }
188: if (MATCHES(*cur, "run_shell=")) {
189: if (atobool(*cur + sizeof("run_shell=") - 1) == true)
190: SET(flags, MODE_SHELL);
191: continue;
192: }
193: if (MATCHES(*cur, "login_shell=")) {
194: if (atobool(*cur + sizeof("login_shell=") - 1) == true) {
195: SET(flags, MODE_LOGIN_SHELL);
196: def_env_reset = true;
197: }
198: continue;
199: }
200: if (MATCHES(*cur, "implied_shell=")) {
201: if (atobool(*cur + sizeof("implied_shell=") - 1) == true)
202: SET(flags, MODE_IMPLIED_SHELL);
203: continue;
204: }
205: if (MATCHES(*cur, "preserve_groups=")) {
206: if (atobool(*cur + sizeof("preserve_groups=") - 1) == true)
207: SET(flags, MODE_PRESERVE_GROUPS);
208: continue;
209: }
210: if (MATCHES(*cur, "ignore_ticket=")) {
211: if (atobool(*cur + sizeof("ignore_ticket=") - 1) == true)
212: SET(flags, MODE_IGNORE_TICKET);
213: continue;
214: }
215: if (MATCHES(*cur, "noninteractive=")) {
216: if (atobool(*cur + sizeof("noninteractive=") - 1) == true)
217: SET(flags, MODE_NONINTERACTIVE);
218: continue;
219: }
220: if (MATCHES(*cur, "sudoedit=")) {
221: if (atobool(*cur + sizeof("sudoedit=") - 1) == true)
222: SET(flags, MODE_EDIT);
223: continue;
224: }
225: if (MATCHES(*cur, "login_class=")) {
226: login_class = *cur + sizeof("login_class=") - 1;
227: def_use_loginclass = true;
228: continue;
229: }
230: #ifdef HAVE_PRIV_SET
231: if (MATCHES(*cur, "runas_privs=")) {
232: def_privs = *cur + sizeof("runas_privs=") - 1;
233: continue;
234: }
235: if (MATCHES(*cur, "runas_limitprivs=")) {
236: def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1;
237: continue;
238: }
239: #endif /* HAVE_PRIV_SET */
240: #ifdef HAVE_SELINUX
241: if (MATCHES(*cur, "selinux_role=")) {
242: user_role = *cur + sizeof("selinux_role=") - 1;
243: continue;
244: }
245: if (MATCHES(*cur, "selinux_type=")) {
246: user_type = *cur + sizeof("selinux_type=") - 1;
247: continue;
248: }
249: #endif /* HAVE_SELINUX */
250: #ifdef HAVE_BSD_AUTH_H
251: if (MATCHES(*cur, "bsdauth_type=")) {
252: login_style = *cur + sizeof("bsdauth_type=") - 1;
253: continue;
254: }
255: #endif /* HAVE_BSD_AUTH_H */
256: #if !defined(HAVE_GETPROGNAME) && !defined(HAVE___PROGNAME)
257: if (MATCHES(*cur, "progname=")) {
258: setprogname(*cur + sizeof("progname=") - 1);
259: continue;
260: }
261: #endif
262: if (MATCHES(*cur, "network_addrs=")) {
263: interfaces_string = *cur + sizeof("network_addrs=") - 1;
264: set_interfaces(interfaces_string);
265: continue;
266: }
267: if (MATCHES(*cur, "max_groups=")) {
1.1.1.2 ! misho 268: errno = 0;
! 269: p = *cur + sizeof("max_groups=") - 1;
! 270: lval = strtol(p, &ep, 10);
! 271: if (*p == '\0' || *ep != '\0')
! 272: fatalx(_("%s: %s"), *cur, _("invalid value"));
! 273: if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
! 274: || (lval > INT_MAX || lval <= 0))
! 275: fatalx(_("%s: %s"), *cur, _("value out of range"));
! 276: sudo_user.max_groups = (int) lval;
! 277: continue;
! 278: }
! 279: if (MATCHES(*cur, "remote_host=")) {
! 280: remhost = *cur + sizeof("remote_host=") - 1;
1.1 misho 281: continue;
282: }
283: }
284:
285: for (cur = info->user_info; *cur != NULL; cur++) {
286: if (MATCHES(*cur, "user=")) {
287: user_name = estrdup(*cur + sizeof("user=") - 1);
288: continue;
289: }
290: if (MATCHES(*cur, "uid=")) {
1.1.1.2 ! misho 291: p = *cur + sizeof("uid=") - 1;
! 292: user_uid = (uid_t) atoid(p, NULL, NULL, &errstr);
! 293: if (errstr != NULL)
! 294: fatalx(_("%s: %s"), *cur, _(errstr));
1.1 misho 295: continue;
296: }
297: if (MATCHES(*cur, "gid=")) {
298: p = *cur + sizeof("gid=") - 1;
1.1.1.2 ! misho 299: user_gid = (gid_t) atoid(p, NULL, NULL, &errstr);
! 300: if (errstr != NULL)
! 301: fatalx(_("%s: %s"), *cur, _(errstr));
1.1 misho 302: continue;
303: }
304: if (MATCHES(*cur, "groups=")) {
305: groups = *cur + sizeof("groups=") - 1;
306: continue;
307: }
308: if (MATCHES(*cur, "cwd=")) {
309: user_cwd = estrdup(*cur + sizeof("cwd=") - 1);
310: continue;
311: }
312: if (MATCHES(*cur, "tty=")) {
313: user_tty = user_ttypath = estrdup(*cur + sizeof("tty=") - 1);
314: if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0)
315: user_tty += sizeof(_PATH_DEV) - 1;
316: continue;
317: }
318: if (MATCHES(*cur, "host=")) {
319: user_host = user_shost = estrdup(*cur + sizeof("host=") - 1);
320: if ((p = strchr(user_host, '.')))
321: user_shost = estrndup(user_host, (size_t)(p - user_host));
322: continue;
323: }
324: if (MATCHES(*cur, "lines=")) {
1.1.1.2 ! misho 325: errno = 0;
! 326: p = *cur + sizeof("lines=") - 1;
! 327: lval = strtol(p, &ep, 10);
! 328: if (*p == '\0' || *ep != '\0')
! 329: fatalx(_("%s: %s"), *cur, _("invalid value"));
! 330: if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
! 331: || (lval > INT_MAX || lval <= 0))
! 332: fatalx(_("%s: %s"), *cur, _("value out of range"));
! 333: sudo_user.lines = (int) lval;
1.1 misho 334: continue;
335: }
336: if (MATCHES(*cur, "cols=")) {
1.1.1.2 ! misho 337: errno = 0;
! 338: p = *cur + sizeof("cols=") - 1;
! 339: lval = strtol(p, &ep, 10);
! 340: if (*p == '\0' || *ep != '\0')
! 341: fatalx(_("%s: %s"), *cur, _("invalid value"));
! 342: if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
! 343: || (lval > INT_MAX || lval <= 0))
! 344: fatalx(_("%s: %s"), *cur, _("value out of range"));
! 345: sudo_user.cols = (int) lval;
1.1 misho 346: continue;
347: }
348: if (MATCHES(*cur, "sid=")) {
1.1.1.2 ! misho 349: p = *cur + sizeof("sid=") - 1;
! 350: sudo_user.sid = (pid_t) atoid(p, NULL, NULL, &errstr);
! 351: if (errstr != NULL)
! 352: fatalx(_("%s: %s"), *cur, _(errstr));
1.1 misho 353: continue;
354: }
355: }
1.1.1.2 ! misho 356: user_runhost = user_srunhost = estrdup(remhost ? remhost : user_host);
! 357: if ((p = strchr(user_runhost, '.')))
! 358: user_srunhost = estrndup(user_runhost, (size_t)(p - user_runhost));
1.1 misho 359: if (user_cwd == NULL)
360: user_cwd = "unknown";
361: if (user_tty == NULL)
362: user_tty = "unknown"; /* user_ttypath remains NULL */
363:
364: if (groups != NULL && groups[0] != '\0') {
1.1.1.2 ! misho 365: /* parse_gid_list() will call fatalx() on error. */
! 366: user_ngids = parse_gid_list(groups, &user_gid, &user_gids);
1.1 misho 367: }
368:
369: /* Stash initial umask for later use. */
370: user_umask = umask(SUDO_UMASK);
371: umask(user_umask);
372:
373: /* Setup debugging if indicated. */
374: if (debug_flags != NULL) {
375: sudo_debug_init(NULL, debug_flags);
376: for (cur = info->settings; *cur != NULL; cur++)
377: sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur);
378: for (cur = info->user_info; *cur != NULL; cur++)
379: sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur);
380: }
381:
382: #undef MATCHES
383: debug_return_int(flags);
384: }
385:
386: /*
387: * Setup the execution environment.
388: * Builds up the command_info list and sets argv and envp.
389: * Returns 1 on success and -1 on error.
390: */
391: int
392: sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
393: char *iolog_path, void *v)
394: {
395: struct sudoers_exec_args *exec_args = v;
396: char **command_info;
397: int info_len = 0;
398: debug_decl(sudoers_policy_exec_setup, SUDO_DEBUG_PLUGIN)
399:
400: /* Increase the length of command_info as needed, it is *not* checked. */
401: command_info = ecalloc(32, sizeof(char **));
402:
403: command_info[info_len++] = fmt_string("command", safe_cmnd);
404: if (def_log_input || def_log_output) {
405: if (iolog_path)
406: command_info[info_len++] = iolog_path;
407: if (def_log_input) {
408: command_info[info_len++] = estrdup("iolog_stdin=true");
409: command_info[info_len++] = estrdup("iolog_ttyin=true");
410: }
411: if (def_log_output) {
412: command_info[info_len++] = estrdup("iolog_stdout=true");
413: command_info[info_len++] = estrdup("iolog_stderr=true");
414: command_info[info_len++] = estrdup("iolog_ttyout=true");
415: }
416: if (def_compress_io) {
417: command_info[info_len++] = estrdup("iolog_compress=true");
418: }
419: if (def_maxseq) {
420: easprintf(&command_info[info_len++], "maxseq=%u", def_maxseq);
421: }
422: }
423: if (ISSET(sudo_mode, MODE_EDIT))
424: command_info[info_len++] = estrdup("sudoedit=true");
425: if (ISSET(sudo_mode, MODE_LOGIN_SHELL)) {
426: /* Set cwd to run user's homedir. */
427: command_info[info_len++] = fmt_string("cwd", runas_pw->pw_dir);
428: }
429: if (def_stay_setuid) {
430: easprintf(&command_info[info_len++], "runas_uid=%u",
431: (unsigned int)user_uid);
432: easprintf(&command_info[info_len++], "runas_gid=%u",
433: (unsigned int)user_gid);
434: easprintf(&command_info[info_len++], "runas_euid=%u",
435: (unsigned int)runas_pw->pw_uid);
436: easprintf(&command_info[info_len++], "runas_egid=%u",
437: runas_gr ? (unsigned int)runas_gr->gr_gid :
438: (unsigned int)runas_pw->pw_gid);
439: } else {
440: easprintf(&command_info[info_len++], "runas_uid=%u",
441: (unsigned int)runas_pw->pw_uid);
442: easprintf(&command_info[info_len++], "runas_gid=%u",
443: runas_gr ? (unsigned int)runas_gr->gr_gid :
444: (unsigned int)runas_pw->pw_gid);
445: }
446: if (def_preserve_groups) {
447: command_info[info_len++] = "preserve_groups=true";
448: } else {
449: int i, len;
450: gid_t egid;
451: size_t glsize;
452: char *cp, *gid_list;
453: struct group_list *grlist = sudo_get_grlist(runas_pw);
454:
455: /* We reserve an extra spot in the list for the effective gid. */
456: glsize = sizeof("runas_groups=") - 1 +
457: ((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
458: gid_list = emalloc(glsize);
459: memcpy(gid_list, "runas_groups=", sizeof("runas_groups=") - 1);
460: cp = gid_list + sizeof("runas_groups=") - 1;
461:
462: /* On BSD systems the effective gid is the first group in the list. */
463: egid = runas_gr ? (unsigned int)runas_gr->gr_gid :
464: (unsigned int)runas_pw->pw_gid;
465: len = snprintf(cp, glsize - (cp - gid_list), "%u", egid);
466: if (len < 0 || len >= glsize - (cp - gid_list))
467: fatalx(_("internal error, %s overflow"), "runas_groups");
468: cp += len;
469: for (i = 0; i < grlist->ngids; i++) {
470: if (grlist->gids[i] != egid) {
471: len = snprintf(cp, glsize - (cp - gid_list), ",%u",
472: (unsigned int) grlist->gids[i]);
473: if (len < 0 || len >= glsize - (cp - gid_list))
474: fatalx(_("internal error, %s overflow"), "runas_groups");
475: cp += len;
476: }
477: }
478: command_info[info_len++] = gid_list;
479: sudo_grlist_delref(grlist);
480: }
481: if (def_closefrom >= 0)
482: easprintf(&command_info[info_len++], "closefrom=%d", def_closefrom);
483: if (def_noexec)
484: command_info[info_len++] = estrdup("noexec=true");
485: if (def_exec_background)
486: command_info[info_len++] = estrdup("exec_background=true");
487: if (def_set_utmp)
488: command_info[info_len++] = estrdup("set_utmp=true");
489: if (def_use_pty)
490: command_info[info_len++] = estrdup("use_pty=true");
491: if (def_utmp_runas)
492: command_info[info_len++] = fmt_string("utmp_user", runas_pw->pw_name);
493: if (cmnd_umask != 0777)
494: easprintf(&command_info[info_len++], "umask=0%o", (unsigned int)cmnd_umask);
495: #ifdef HAVE_LOGIN_CAP_H
496: if (def_use_loginclass)
497: command_info[info_len++] = fmt_string("login_class", login_class);
498: #endif /* HAVE_LOGIN_CAP_H */
499: #ifdef HAVE_SELINUX
500: if (user_role != NULL)
501: command_info[info_len++] = fmt_string("selinux_role", user_role);
502: if (user_type != NULL)
503: command_info[info_len++] = fmt_string("selinux_type", user_type);
504: #endif /* HAVE_SELINUX */
505: #ifdef HAVE_PRIV_SET
506: if (runas_privs != NULL)
507: command_info[info_len++] = fmt_string("runas_privs", runas_privs);
508: if (runas_limitprivs != NULL)
509: command_info[info_len++] = fmt_string("runas_limitprivs", runas_limitprivs);
510: #endif /* HAVE_SELINUX */
511:
512: /* Fill in exec environment info */
513: *(exec_args->argv) = argv;
514: *(exec_args->envp) = envp;
515: *(exec_args->info) = command_info;
516:
517: debug_return_bool(true);
518: }
519:
520: static int
521: sudoers_policy_open(unsigned int version, sudo_conv_t conversation,
522: sudo_printf_t plugin_printf, char * const settings[],
523: char * const user_info[], char * const envp[], char * const args[])
524: {
525: struct sudoers_policy_open_info info;
526: debug_decl(sudoers_policy_open, SUDO_DEBUG_PLUGIN)
527:
528: sudo_version = version;
529: sudo_conv = conversation;
530: sudo_printf = plugin_printf;
531:
532: /* Plugin args are only specified for API version 1.2 and higher. */
533: if (sudo_version < SUDO_API_MKVERSION(1, 2))
534: args = NULL;
535:
536: if (fatal_setjmp() != 0) {
537: /* called via fatal(), fatalx() or log_fatal() */
538: rewind_perms();
539: fatal_disable_setjmp();
540: debug_return_bool(-1);
541: }
542:
543: /* Call the sudoers init function. */
544: info.settings = settings;
545: info.user_info = user_info;
546: info.plugin_args = args;
547: debug_return_bool(sudoers_policy_init(&info, envp));
548: }
549:
550: static void
551: sudoers_policy_close(int exit_status, int error_code)
552: {
553: debug_decl(sudoers_policy_close, SUDO_DEBUG_PLUGIN)
554:
555: if (fatal_setjmp() != 0) {
556: /* called via fatal(), fatalx() or log_fatal() */
557: fatal_disable_setjmp();
558: debug_return;
559: }
560:
561: /* We do not currently log the exit status. */
562: if (error_code) {
563: errno = error_code;
564: warning(_("unable to execute %s"), safe_cmnd);
565: }
566:
567: /* Close the session we opened in sudoers_policy_init_session(). */
568: if (ISSET(sudo_mode, MODE_RUN|MODE_EDIT))
569: (void)sudo_auth_end_session(runas_pw);
570:
571: /* Free remaining references to password and group entries. */
572: /* XXX - move cleanup to function in sudoers.c */
573: sudo_pw_delref(sudo_user.pw);
574: sudo_user.pw = NULL;
575: sudo_pw_delref(runas_pw);
576: runas_pw = NULL;
577: if (runas_gr != NULL) {
578: sudo_gr_delref(runas_gr);
579: runas_gr = NULL;
580: }
581: if (user_group_list != NULL) {
582: sudo_grlist_delref(user_group_list);
583: user_group_list = NULL;
584: }
585: efree(user_gids);
586: user_gids = NULL;
587:
588: debug_return;
589: }
590:
591: /*
592: * The init_session function is called before executing the command
593: * and before uid/gid changes occur.
594: * Returns 1 on success, 0 on failure and -1 on error.
595: */
596: static int
597: sudoers_policy_init_session(struct passwd *pwd, char **user_env[])
598: {
599: debug_decl(sudoers_policy_init_session, SUDO_DEBUG_PLUGIN)
600:
601: /* user_env is only specified for API version 1.2 and higher. */
602: if (sudo_version < SUDO_API_MKVERSION(1, 2))
603: user_env = NULL;
604:
605: if (fatal_setjmp() != 0) {
606: /* called via fatal(), fatalx() or log_fatal() */
607: fatal_disable_setjmp();
608: debug_return_bool(-1);
609: }
610:
611: debug_return_bool(sudo_auth_begin_session(pwd, user_env));
612: }
613:
614: static int
615: sudoers_policy_check(int argc, char * const argv[], char *env_add[],
616: char **command_infop[], char **argv_out[], char **user_env_out[])
617: {
618: struct sudoers_exec_args exec_args;
619: int rval;
620: debug_decl(sudoers_policy_check, SUDO_DEBUG_PLUGIN)
621:
622: if (!ISSET(sudo_mode, MODE_EDIT))
623: SET(sudo_mode, MODE_RUN);
624:
625: exec_args.argv = argv_out;
626: exec_args.envp = user_env_out;
627: exec_args.info = command_infop;
628:
629: rval = sudoers_policy_main(argc, argv, 0, env_add, &exec_args);
630: if (rval == true && sudo_version >= SUDO_API_MKVERSION(1, 3)) {
631: /* Unset close function if we don't need it to avoid extra process. */
632: if (!def_log_input && !def_log_output && !def_use_pty &&
633: !sudo_auth_needs_end_session())
634: sudoers_policy.close = NULL;
635: }
636: debug_return_bool(rval);
637: }
638:
639: static int
640: sudoers_policy_validate(void)
641: {
642: debug_decl(sudoers_policy_validate, SUDO_DEBUG_PLUGIN)
643:
644: user_cmnd = "validate";
645: SET(sudo_mode, MODE_VALIDATE);
646:
647: debug_return_bool(sudoers_policy_main(0, NULL, I_VERIFYPW, NULL, NULL));
648: }
649:
650: static void
651: sudoers_policy_invalidate(int remove)
652: {
653: debug_decl(sudoers_policy_invalidate, SUDO_DEBUG_PLUGIN)
654:
655: user_cmnd = "kill";
656: if (fatal_setjmp() == 0) {
657: remove_timestamp(remove);
658: sudoers_cleanup();
659: }
660: fatal_disable_setjmp();
661:
662: debug_return;
663: }
664:
665: static int
666: sudoers_policy_list(int argc, char * const argv[], int verbose,
667: const char *list_user)
668: {
669: int rval;
670: debug_decl(sudoers_policy_list, SUDO_DEBUG_PLUGIN)
671:
672: user_cmnd = "list";
673: if (argc)
674: SET(sudo_mode, MODE_CHECK);
675: else
676: SET(sudo_mode, MODE_LIST);
677: if (verbose)
678: long_list = 1;
679: if (list_user) {
680: list_pw = sudo_getpwnam(list_user);
681: if (list_pw == NULL) {
682: warningx(_("unknown user: %s"), list_user);
683: debug_return_bool(-1);
684: }
685: }
686: rval = sudoers_policy_main(argc, argv, I_LISTPW, NULL, NULL);
687: if (list_user) {
688: sudo_pw_delref(list_pw);
689: list_pw = NULL;
690: }
691:
692: debug_return_bool(rval);
693: }
694:
695: static int
696: sudoers_policy_version(int verbose)
697: {
698: debug_decl(sudoers_policy_version, SUDO_DEBUG_PLUGIN)
699:
700: if (fatal_setjmp() != 0) {
701: /* error recovery via fatal(), fatalx() or log_fatal() */
702: fatal_disable_setjmp();
703: debug_return_bool(-1);
704: }
705:
706: sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers policy plugin version %s\n"),
707: PACKAGE_VERSION);
708: sudo_printf(SUDO_CONV_INFO_MSG, _("Sudoers file grammar version %d\n"),
709: SUDOERS_GRAMMAR_VERSION);
710:
711: if (verbose) {
712: sudo_printf(SUDO_CONV_INFO_MSG, _("\nSudoers path: %s\n"), sudoers_file);
713: #ifdef HAVE_LDAP
714: # ifdef _PATH_NSSWITCH_CONF
715: sudo_printf(SUDO_CONV_INFO_MSG, _("nsswitch path: %s\n"), _PATH_NSSWITCH_CONF);
716: # endif
717: sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.conf path: %s\n"), path_ldap_conf);
718: sudo_printf(SUDO_CONV_INFO_MSG, _("ldap.secret path: %s\n"), path_ldap_secret);
719: #endif
720: dump_auth_methods();
721: dump_defaults();
722: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
723: if (interfaces_string != NULL) {
724: dump_interfaces(interfaces_string);
725: sudo_printf(SUDO_CONV_INFO_MSG, "\n");
726: }
727: }
728: debug_return_bool(true);
729: }
730:
731: static void
732: sudoers_policy_register_hooks(int version, int (*register_hook)(struct sudo_hook *hook))
733: {
734: struct sudo_hook hook;
735:
736: memset(&hook, 0, sizeof(hook));
737: hook.hook_version = SUDO_HOOK_VERSION;
738:
739: hook.hook_type = SUDO_HOOK_SETENV;
740: hook.hook_fn = sudoers_hook_setenv;
741: register_hook(&hook);
742:
743: hook.hook_type = SUDO_HOOK_UNSETENV;
744: hook.hook_fn = sudoers_hook_unsetenv;
745: register_hook(&hook);
746:
747: hook.hook_type = SUDO_HOOK_GETENV;
748: hook.hook_fn = sudoers_hook_getenv;
749: register_hook(&hook);
750:
751: hook.hook_type = SUDO_HOOK_PUTENV;
752: hook.hook_fn = sudoers_hook_putenv;
753: register_hook(&hook);
754: }
755:
756: __dso_public struct policy_plugin sudoers_policy = {
757: SUDO_POLICY_PLUGIN,
758: SUDO_API_VERSION,
759: sudoers_policy_open,
760: sudoers_policy_close,
761: sudoers_policy_version,
762: sudoers_policy_check,
763: sudoers_policy_list,
764: sudoers_policy_validate,
765: sudoers_policy_invalidate,
766: sudoers_policy_init_session,
767: sudoers_policy_register_hooks
768: };
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>