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