Return to policy.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / sudo / plugins / sudoers |
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: };