static int sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[]) { void *handle; sudo_log = sudo_printf; if (SUDO_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) { sudo_log(SUDO_CONV_ERROR_MSG, "sysgroup_group: incompatible major version %d, expected %d\n", SUDO_API_VERSION_GET_MAJOR(version), GROUP_API_VERSION_MAJOR); return -1; } /* Share group cache with sudo if possible. */ handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrnam"); if (handle != NULL) { sysgroup_getgrnam = (sysgroup_getgrnam_t)handle; } else { sysgroup_getgrnam = (sysgroup_getgrnam_t)getgrnam; need_setent = true; } handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_getgrgid"); if (handle != NULL) { sysgroup_getgrgid = (sysgroup_getgrgid_t)handle; } else { sysgroup_getgrgid = (sysgroup_getgrgid_t)getgrgid; need_setent = true; } handle = sudo_dso_findsym(SUDO_DSO_DEFAULT, "sudo_gr_delref"); if (handle != NULL) sysgroup_gr_delref = (sysgroup_gr_delref_t)handle; if (need_setent) setgrent(); return true; }
static int sample_init(int version, sudo_printf_t sudo_printf, char *const argv[]) { struct stat sb; sudo_log = sudo_printf; if (SUDO_API_VERSION_GET_MAJOR(version) != GROUP_API_VERSION_MAJOR) { sudo_log(SUDO_CONV_ERROR_MSG, "group_file: incompatible major version %d, expected %d\n", SUDO_API_VERSION_GET_MAJOR(version), GROUP_API_VERSION_MAJOR); return -1; } /* Sanity check the specified group file. */ if (argv == NULL || argv[0] == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "group_file: path to group file not specified\n"); return -1; } if (stat(argv[0], &sb) != 0) { sudo_log(SUDO_CONV_ERROR_MSG, "group_file: %s: %s\n", argv[0], strerror(errno)); return -1; } if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) { sudo_log(SUDO_CONV_ERROR_MSG, "%s must be only be writable by owner\n", argv[0]); return -1; } mysetgrfile(argv[0]); mysetgrent(); return true; }
/* * Plugin policy open function. This is called at opening the * plugin by sudo utility. * */ int policy_open(unsigned int version, sudo_conv_t conversation, sudo_printf_t sudo_printf, char * const settings[], char * const user_info[], char * const user_env[]) { char * const *ui; const char *runas_user = NULL; const char *runas_group = NULL; if (sudo_conv == NULL) sudo_conv = conversation; if (sudo_log == NULL) sudo_log = sudo_printf; /* Check the version of sudo plugin api */ if (SUDO_API_VERSION_GET_MAJOR(version) != SUDO_API_VERSION_MAJOR) { sudo_log(SUDO_CONV_ERROR_MSG, "The sss sudo plugin requires API version %d.x\n", SUDO_API_VERSION_MAJOR); return ERROR; } init_size_of_msg_contents(); for (ui = settings; *ui != NULL; ui++) { /* get the debug level */ if (strncmp(*ui, "debug_level=", sizeof("debug_level=") - 1) == 0) { debug_level = atoi(*ui + sizeof("debug_level=") - 1); msg.debug_level = debug_level; } /* *check if the user specified the -E flag, indicating that *the user wishes to preserve the environment. * */ else if (strncmp(*ui, "preserve_environment=", sizeof("preserve_environment=") - 1) == 0) { if (strcasecmp(*ui + sizeof("preserve_environment=") - 1, "true") == 0) msg.use_preserve_environment = TRUE; } /* * check if the user specified the -H flag. If true, set the * HOME environment variable to the target user's home directory. */ else if (strncmp(*ui, "set_home=", sizeof("set_home=") - 1) == 0) { if (strcasecmp(*ui + sizeof("set_home=") - 1, "true") == 0) msg.use_set_home = TRUE; } /* * check if the user specified the -s flag, indicating that the * user wishes to run a shell. */ else if (strncmp(*ui, "run_shell=", sizeof("run_shell=") - 1) == 0) { if (strcasecmp(*ui + sizeof("run_shell=") - 1, "true") == 0) msg.use_run_shell = TRUE; } /* * Check if the user specified the -i flag, indicating that the * user wishes to run a login shell. */ else if (strncmp(*ui, "login_shell=", sizeof("login_shell=") - 1) == 0) { if (strcasecmp(*ui + sizeof("login_shell=") - 1, "true") == 0) msg.use_login_shell = TRUE; } /* * check to see whether user specified the -k flag along with a * command, indicating that the user wishes to ignore any cached * authentication credentials. */ else if (strncmp(*ui, "ignore_ticket=", sizeof("ignore_ticket=") - 1) == 0) { if (strcasecmp(*ui + sizeof("ignore_ticket=") - 1, "true") == 0) msg.use_ignore_ticket = TRUE; } /* * The prompt to use when requesting a password, if specified * via the -p flag. */ else if (strncmp(*ui, "prompt=", sizeof("prompt=") - 1) == 0) { msg.prompt = strdup(*ui + sizeof("prompt=") - 1); } /* Find the user to be run as */ else if (strncmp(*ui, "runas_user="******"runas_user="******"runas_user="******"runas_group=", sizeof("runas_group=") - 1) == 0) { msg.runas_group = strdup(*ui + sizeof("runas_group=") - 1); runas_group = msg.runas_group; } /* * To get thhe command name that sudo was run as, typically * "sudo" or "sudoedit". setprogname() is only supported in BSD * No need to include it now. * * else if (strncmp(*ui, "progname=", sizeof("progname=") - 1) == 0) { * setprogname(*ui + sizeof("progname=") - 1); * } * */ /* Check to see if sudo was called as sudoedit or with -e flag. */ else if (strncmp(*ui, "sudoedit=", sizeof("sudoedit=") - 1) == 0) { if (strcasecmp(*ui + sizeof("sudoedit=") - 1, "true") == 0) use_sudoedit = TRUE; msg.use_sudoedit = use_sudoedit; } /* This plugin doesn't support running sudo with no arguments. */ else if (strncmp(*ui, "implied_shell=", sizeof("implied_shell=") - 1) == 0) { if (strcasecmp(*ui + sizeof("implied_shell=") - 1, "true") == 0) return -2; /* usage error */ } /* *check to see whether user specified the -P flag, indicating *that the user wishes to preserve the group vector instead of *setting it based on the runas user. */ else if (strncmp(*ui, "preserve_groups=", sizeof("preserve_groups=") - 1) == 0) { if (strcasecmp(*ui + sizeof("preserve_groups=") - 1, "true") == 0) msg.use_preserve_groups = TRUE; } /* * check to see whether user specified the -n flag, indicating that * sudo should operate in non-interactive mode. The plugin may reject * a command run in non-interactive mode if user interaction is required. */ else if (strncmp(*ui, "noninteractive=", sizeof("noninteractive=") - 1) == 0) { if (strcasecmp(*ui + sizeof("noninteractive=") - 1, "true") == 0) msg.use_noninteractive = TRUE; } /* to get network_addrs */ else if (strncmp(*ui, "network_addrs=", sizeof("network_addrs=") - 1) == 0) { msg.network_addrs = strdup(*ui + sizeof("network_addrs=") - 1); } /* settings are over */ } /* Build the user info */ for (ui = user_info; *ui != NULL; ui++) { /* get user name */ if (strncmp(*ui, "user="******"user="******"user="******"uid=", sizeof("uid=") - 1) == 0) { msg.userid = atoi(*ui + sizeof("uid=") - 1); } /* get cwd */ else if (strncmp(*ui, "cwd=", sizeof("cwd=") - 1) == 0) { msg.cwd = strdup(*ui + sizeof("cwd=") - 1); } /* get tty */ else if (strncmp(*ui, "tty=", sizeof("tty=") - 1) == 0) { msg.tty = strdup( *ui + sizeof("tty=") - 1); } /* get lines - to be removed at final code if no use */ else if (strncmp(*ui, "lines=", sizeof("lines=") - 1) == 0) { user_information.lines = atoi(*ui + sizeof("lines=") - 1); } /* get cols - to be removed at final code if no use */ else if (strncmp(*ui, "cols=", sizeof("cols=") - 1) == 0) { user_information.cols = atoi(*ui + sizeof("cols=") - 1); } } /* * No need to check the user or group status here. * TODO: Sgallagh, Pls conform this. :) * * * if (runas_user != NULL) { if(runas_user[0] == '#'){ if ((pw = getpwuid(atoi(runas_user+1))) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user); return 0; } } else if ((pw = getpwnam(runas_user)) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown user %s\n", runas_user); return 0; } runas_uid = pw->pw_uid; } if (runas_group != NULL) { if(runas_group[0] == '#'){ if ((gr = getgrgid(atoi(runas_group+1))) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_user); return 0; } } else if ((gr = getgrnam(runas_group)) == NULL) { sudo_log(SUDO_CONV_ERROR_MSG, "unknown group %s\n", runas_group); return 0; } runas_gid = gr->gr_gid; }*/ /* fill Plugin state. */ plugin_state.envp = user_env; msg.user_env = user_env; /* FIXME: Set a mechanism to handle environment */ plugin_state.settings = settings; plugin_state.user_info = user_info; return 1; }
/* * Load the plugins listed in conf_file. */ void sudo_load_plugins(const char *conf_file, struct plugin_container *policy_plugin, struct plugin_container_list *io_plugins) { struct generic_plugin *plugin; struct plugin_container *container; struct plugin_info *info; struct plugin_info_list *plugin_list; struct stat sb; void *handle; char path[PATH_MAX]; /* Parse sudo.conf */ plugin_list = sudo_read_conf(conf_file); tq_foreach_fwd(plugin_list, info) { if (info->path[0] == '/') { if (strlcpy(path, info->path, sizeof(path)) >= sizeof(path)) errorx(1, "%s: %s", info->path, strerror(ENAMETOOLONG)); } else { if (snprintf(path, sizeof(path), "%s%s", _PATH_SUDO_PLUGIN_DIR, info->path) >= sizeof(path)) { errorx(1, "%s%s: %s", _PATH_SUDO_PLUGIN_DIR, info->path, strerror(ENAMETOOLONG)); } } if (stat(path, &sb) != 0) error(1, "%s", path); if (sb.st_uid != ROOT_UID) errorx(1, "%s must be owned by uid %d", path, ROOT_UID); if ((sb.st_mode & (S_IWGRP|S_IWOTH)) != 0) errorx(1, "%s must be only be writable by owner", path); /* Open plugin and map in symbol */ handle = dlopen(path, RTLD_LAZY|RTLD_LOCAL); if (!handle) errorx(1, "unable to dlopen %s: %s", path, dlerror()); plugin = dlsym(handle, info->symbol_name); if (!plugin) errorx(1, "unable to find symbol %s in %s", info->symbol_name, path); if (plugin->type != SUDO_POLICY_PLUGIN && plugin->type != SUDO_IO_PLUGIN) { errorx(1, "%s: unknown policy type %d", path, plugin->type); } if (SUDO_API_VERSION_GET_MAJOR(plugin->version) != SUDO_API_VERSION_MAJOR) { errorx(1, "%s: incompatible policy major version %d, expected %d", path, SUDO_API_VERSION_GET_MAJOR(plugin->version), SUDO_API_VERSION_MAJOR); } if (plugin->type == SUDO_POLICY_PLUGIN) { if (policy_plugin->handle) errorx(1, "only a single policy plugin may be loaded"); policy_plugin->handle = handle; policy_plugin->name = info->symbol_name; policy_plugin->u.generic = plugin; } else if (plugin->type == SUDO_IO_PLUGIN) { container = emalloc(sizeof(*container)); container->prev = container; container->next = NULL; container->handle = handle; container->name = info->symbol_name; container->u.generic = plugin; tq_append(io_plugins, container); } } if (policy_plugin->handle == NULL) errorx(1, "%s: at least one policy plugin must be specified", conf_file); if (policy_plugin->u.policy->check_policy == NULL) errorx(1, "policy plugin %s does not include a check_policy method"); }