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