static int test_strtomode(int *ntests) { struct strtomode_data *d; const char *errstr; int errors = 0; mode_t mode; for (d = strtomode_data; d->mode_str != NULL; d++) { (*ntests)++; errstr = "some error"; mode = sudo_strtomode(d->mode_str, &errstr); if (errstr != NULL) { if (d->mode != (mode_t)-1) { sudo_warnx_nodebug("FAIL: %s: %s", d->mode_str, errstr); errors++; } } else if (mode != d->mode) { sudo_warnx_nodebug("FAIL: %s != 0%o", d->mode_str, (unsigned int) d->mode); errors++; } } return errors; }
/* * Deserialize args, settings and user_info arrays. * Fills in struct sudo_user and other common sudoers state. */ int sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group) { struct sudoers_policy_open_info *info = v; char * const *cur; const char *p, *errstr, *groups = NULL; const char *remhost = NULL; int flags = 0; debug_decl(sudoers_policy_deserialize_info, SUDOERS_DEBUG_PLUGIN) #define MATCHES(s, v) (strncmp(s, v, sizeof(v) - 1) == 0) /* Parse sudo.conf plugin args. */ if (info->plugin_args != NULL) { for (cur = info->plugin_args; *cur != NULL; cur++) { if (MATCHES(*cur, "sudoers_file=")) { sudoers_file = *cur + sizeof("sudoers_file=") - 1; continue; } if (MATCHES(*cur, "sudoers_uid=")) { p = *cur + sizeof("sudoers_uid=") - 1; sudoers_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "sudoers_gid=")) { p = *cur + sizeof("sudoers_gid=") - 1; sudoers_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "sudoers_mode=")) { p = *cur + sizeof("sudoers_mode=") - 1; sudoers_mode = sudo_strtomode(p, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "ldap_conf=")) { path_ldap_conf = *cur + sizeof("ldap_conf=") - 1; continue; } if (MATCHES(*cur, "ldap_secret=")) { path_ldap_secret = *cur + sizeof("ldap_secret=") - 1; continue; } } } /* Parse command line settings. */ user_closefrom = -1; for (cur = info->settings; *cur != NULL; cur++) { if (MATCHES(*cur, "closefrom=")) { errno = 0; p = *cur + sizeof("closefrom=") - 1; user_closefrom = strtonum(p, 4, INT_MAX, &errstr); if (user_closefrom == 0) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "runas_user="******"runas_user="******"runas_group=")) { *runas_group = *cur + sizeof("runas_group=") - 1; sudo_user.flags |= RUNAS_GROUP_SPECIFIED; continue; } if (MATCHES(*cur, "prompt=")) { user_prompt = *cur + sizeof("prompt=") - 1; def_passprompt_override = true; continue; } if (MATCHES(*cur, "set_home=")) { if (sudo_strtobool(*cur + sizeof("set_home=") - 1) == true) SET(flags, MODE_RESET_HOME); continue; } if (MATCHES(*cur, "preserve_environment=")) { if (sudo_strtobool(*cur + sizeof("preserve_environment=") - 1) == true) SET(flags, MODE_PRESERVE_ENV); continue; } if (MATCHES(*cur, "run_shell=")) { if (sudo_strtobool(*cur + sizeof("run_shell=") - 1) == true) SET(flags, MODE_SHELL); continue; } if (MATCHES(*cur, "login_shell=")) { if (sudo_strtobool(*cur + sizeof("login_shell=") - 1) == true) { SET(flags, MODE_LOGIN_SHELL); def_env_reset = true; } continue; } if (MATCHES(*cur, "implied_shell=")) { if (sudo_strtobool(*cur + sizeof("implied_shell=") - 1) == true) SET(flags, MODE_IMPLIED_SHELL); continue; } if (MATCHES(*cur, "preserve_groups=")) { if (sudo_strtobool(*cur + sizeof("preserve_groups=") - 1) == true) SET(flags, MODE_PRESERVE_GROUPS); continue; } if (MATCHES(*cur, "ignore_ticket=")) { if (sudo_strtobool(*cur + sizeof("ignore_ticket=") - 1) == true) SET(flags, MODE_IGNORE_TICKET); continue; } if (MATCHES(*cur, "noninteractive=")) { if (sudo_strtobool(*cur + sizeof("noninteractive=") - 1) == true) SET(flags, MODE_NONINTERACTIVE); continue; } if (MATCHES(*cur, "sudoedit=")) { if (sudo_strtobool(*cur + sizeof("sudoedit=") - 1) == true) SET(flags, MODE_EDIT); continue; } if (MATCHES(*cur, "login_class=")) { login_class = *cur + sizeof("login_class=") - 1; def_use_loginclass = true; continue; } #ifdef HAVE_PRIV_SET if (MATCHES(*cur, "runas_privs=")) { def_privs = *cur + sizeof("runas_privs=") - 1; continue; } if (MATCHES(*cur, "runas_limitprivs=")) { def_limitprivs = *cur + sizeof("runas_limitprivs=") - 1; continue; } #endif /* HAVE_PRIV_SET */ #ifdef HAVE_SELINUX if (MATCHES(*cur, "selinux_role=")) { user_role = *cur + sizeof("selinux_role=") - 1; continue; } if (MATCHES(*cur, "selinux_type=")) { user_type = *cur + sizeof("selinux_type=") - 1; continue; } #endif /* HAVE_SELINUX */ #ifdef HAVE_BSD_AUTH_H if (MATCHES(*cur, "bsdauth_type=")) { login_style = *cur + sizeof("bsdauth_type=") - 1; continue; } #endif /* HAVE_BSD_AUTH_H */ if (MATCHES(*cur, "network_addrs=")) { interfaces_string = *cur + sizeof("network_addrs=") - 1; set_interfaces(interfaces_string); continue; } if (MATCHES(*cur, "max_groups=")) { errno = 0; p = *cur + sizeof("max_groups=") - 1; sudo_user.max_groups = strtonum(p, 1, INT_MAX, &errstr); if (sudo_user.max_groups == 0) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "remote_host=")) { remhost = *cur + sizeof("remote_host=") - 1; continue; } } for (cur = info->user_info; *cur != NULL; cur++) { if (MATCHES(*cur, "user="******"user="******"uid=")) { p = *cur + sizeof("uid=") - 1; user_uid = (uid_t) sudo_strtoid(p, NULL, NULL, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "gid=")) { p = *cur + sizeof("gid=") - 1; user_gid = (gid_t) sudo_strtoid(p, NULL, NULL, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "groups=")) { groups = *cur + sizeof("groups=") - 1; continue; } if (MATCHES(*cur, "cwd=")) { user_cwd = sudo_estrdup(*cur + sizeof("cwd=") - 1); continue; } if (MATCHES(*cur, "tty=")) { user_tty = user_ttypath = sudo_estrdup(*cur + sizeof("tty=") - 1); if (strncmp(user_tty, _PATH_DEV, sizeof(_PATH_DEV) - 1) == 0) user_tty += sizeof(_PATH_DEV) - 1; continue; } if (MATCHES(*cur, "host=")) { user_host = user_shost = sudo_estrdup(*cur + sizeof("host=") - 1); if ((p = strchr(user_host, '.'))) user_shost = sudo_estrndup(user_host, (size_t)(p - user_host)); continue; } if (MATCHES(*cur, "lines=")) { errno = 0; p = *cur + sizeof("lines=") - 1; sudo_user.lines = strtonum(p, 1, INT_MAX, &errstr); if (sudo_user.lines == 0) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "cols=")) { errno = 0; p = *cur + sizeof("cols=") - 1; sudo_user.cols = strtonum(p, 1, INT_MAX, &errstr); if (sudo_user.lines == 0) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } if (MATCHES(*cur, "sid=")) { p = *cur + sizeof("sid=") - 1; sudo_user.sid = (pid_t) sudo_strtoid(p, NULL, NULL, &errstr); if (errstr != NULL) { sudo_warnx(U_("%s: %s"), *cur, U_(errstr)); goto bad; } continue; } } user_runhost = user_srunhost = sudo_estrdup(remhost ? remhost : user_host); if ((p = strchr(user_runhost, '.'))) user_srunhost = sudo_estrndup(user_runhost, (size_t)(p - user_runhost)); if (user_cwd == NULL) user_cwd = sudo_estrdup("unknown"); if (user_tty == NULL) user_tty = sudo_estrdup("unknown"); /* user_ttypath remains NULL */ if (groups != NULL && groups[0] != '\0') { /* sudo_parse_gids() will print a warning on error. */ user_ngids = sudo_parse_gids(groups, &user_gid, &user_gids); if (user_ngids == -1) goto bad; } /* Stash initial umask for later use. */ user_umask = umask(SUDO_UMASK); umask(user_umask); /* Dump settings and user info (XXX - plugin args) */ for (cur = info->settings; *cur != NULL; cur++) sudo_debug_printf(SUDO_DEBUG_INFO, "settings: %s", *cur); for (cur = info->user_info; *cur != NULL; cur++) sudo_debug_printf(SUDO_DEBUG_INFO, "user_info: %s", *cur); #undef MATCHES debug_return_int(flags); bad: debug_return_int(MODE_ERROR); }