static int xlator_option_validate_bool (xlator_t *xl, const char *key, const char *value, volume_option_t *opt, char **op_errstr) { int ret = -1; char errstr[256]; gf_boolean_t is_valid; /* Check if the value is one of '0|1|on|off|no|yes|true|false|enable|disable' */ if (gf_string2boolean (value, &is_valid) != 0) { snprintf (errstr, 256, "option %s %s: '%s' is not a valid boolean value", key, value, value); gf_msg (xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr); goto out; } ret = 0; out: if (ret && op_errstr) *op_errstr = gf_strdup (errstr); return ret; }
auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; int ret = 0; char *name = NULL; char *searchstr = NULL; peer_info_t *peer_info = NULL; data_t *peer_info_data = NULL; data_t *allow_addr = NULL; data_t *reject_addr = NULL; char *addr_str = NULL; char *tmp = NULL; char *addr_cpy = NULL; char *service = NULL; uint16_t peer_port = 0; char is_inet_sdp = 0; char negate = 0; char match = 0; char peer_addr[UNIX_PATH_MAX]; char *type = NULL; gf_boolean_t allow_insecure = _gf_false; name = data_to_str (dict_get (input_params, "remote-subvolume")); if (!name) { gf_log ("authenticate/addr", GF_LOG_DEBUG, "remote-subvolume not specified"); goto out; } ret = gf_asprintf (&searchstr, "auth.addr.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_DEBUG, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); ret = gf_asprintf (&searchstr, "auth.addr.%s.reject", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } reject_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); if (!allow_addr) { /* TODO: backword compatibility */ ret = gf_asprintf (&searchstr, "auth.ip.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); } if (!(allow_addr || reject_addr)) { gf_log ("auth/addr", GF_LOG_DEBUG, "none of the options auth.addr.%s.allow or " "auth.addr.%s.reject specified, returning auth_dont_care", name, name); goto out; } peer_info_data = dict_get (input_params, "peer-info"); if (!peer_info_data) { gf_log ("auth/addr", GF_LOG_ERROR, "peer-info not present"); goto out; } peer_info = data_to_ptr (peer_info_data); switch (((struct sockaddr *) &peer_info->sockaddr)->sa_family) { case AF_INET_SDP: is_inet_sdp = 1; ((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET; case AF_INET: case AF_INET6: { strcpy (peer_addr, peer_info->identifier); service = strrchr (peer_addr, ':'); *service = '\0'; service ++; if (is_inet_sdp) { ((struct sockaddr *) &peer_info->sockaddr)->sa_family = AF_INET_SDP; } ret = dict_get_str (config_params, "rpc-auth-allow-insecure", &type); if (ret == 0) { ret = gf_string2boolean (type, &allow_insecure); if (ret < 0) { gf_log ("auth/addr", GF_LOG_WARNING, "rpc-auth-allow-insecure option %s " "is not a valid bool option", type); goto out; } } peer_port = atoi (service); if (peer_port >= PRIVILEGED_PORT_CEILING && !allow_insecure) { gf_log ("auth/addr", GF_LOG_ERROR, "client is bound to port %d which is not privileged", peer_port); goto out; } break; case AF_UNIX: strcpy (peer_addr, peer_info->identifier); break; default: gf_log ("authenticate/addr", GF_LOG_ERROR, "unknown address family %d", ((struct sockaddr *) &peer_info->sockaddr)->sa_family); goto out; } } if (reject_addr) { addr_cpy = gf_strdup (reject_addr->data); if (!addr_cpy) goto out; addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp); while (addr_str) { gf_log (name, GF_LOG_DEBUG, "rejected = \"%s\", received addr = \"%s\"", addr_str, peer_addr); if (addr_str[0] == '!') { negate = 1; addr_str++; } match = fnmatch (addr_str, peer_addr, 0); if (negate ? match : !match) { result = AUTH_REJECT; goto out; } addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp); } GF_FREE (addr_cpy); } if (allow_addr) { addr_cpy = gf_strdup (allow_addr->data); if (!addr_cpy) goto out; addr_str = strtok_r (addr_cpy, ADDR_DELIMITER, &tmp); while (addr_str) { gf_log (name, GF_LOG_DEBUG, "allowed = \"%s\", received addr = \"%s\"", addr_str, peer_addr); if (addr_str[0] == '!') { negate = 1; addr_str++; } match = fnmatch (addr_str, peer_addr, 0); if (negate ? match : !match) { result = AUTH_ACCEPT; goto out; } addr_str = strtok_r (NULL, ADDR_DELIMITER, &tmp); } } out: if (addr_cpy) GF_FREE (addr_cpy); return result; }
auth_result_t gf_auth (dict_t *input_params, dict_t *config_params) { auth_result_t result = AUTH_DONT_CARE; int ret = 0; char *name = NULL; char *searchstr = NULL; peer_info_t *peer_info = NULL; data_t *peer_info_data = NULL; data_t *allow_addr = NULL; data_t *reject_addr = NULL; char *service = NULL; uint16_t peer_port = 0; char peer_addr[UNIX_PATH_MAX] = {0,}; char *type = NULL; gf_boolean_t allow_insecure = _gf_false; char *subdir = NULL; name = data_to_str (dict_get (input_params, "remote-subvolume")); if (!name) { gf_log ("authenticate/addr", GF_LOG_DEBUG, "remote-subvolume not specified"); goto out; } ret = gf_asprintf (&searchstr, "auth.addr.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_DEBUG, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); ret = gf_asprintf (&searchstr, "auth.addr.%s.reject", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } reject_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); if (!allow_addr) { /* TODO: backward compatibility */ ret = gf_asprintf (&searchstr, "auth.ip.%s.allow", name); if (-1 == ret) { gf_log ("auth/addr", GF_LOG_ERROR, "asprintf failed while setting search string"); goto out; } allow_addr = dict_get (config_params, searchstr); GF_FREE (searchstr); } if (!(allow_addr || reject_addr)) { gf_log ("auth/addr", GF_LOG_DEBUG, "none of the options auth.addr.%s.allow or " "auth.addr.%s.reject specified, returning auth_dont_care", name, name); goto out; } peer_info_data = dict_get (input_params, "peer-info"); if (!peer_info_data) { gf_log ("auth/addr", GF_LOG_ERROR, "peer-info not present"); goto out; } ret = dict_get_str (input_params, "subdir-mount", &subdir); if (ret) { subdir = "/"; } peer_info = data_to_ptr (peer_info_data); switch (((struct sockaddr *) &peer_info->sockaddr)->sa_family) { case AF_INET_SDP: case AF_INET: case AF_INET6: strcpy (peer_addr, peer_info->identifier); service = strrchr (peer_addr, ':'); *service = '\0'; service++; ret = dict_get_str (config_params, "rpc-auth-allow-insecure", &type); if (ret == 0) { ret = gf_string2boolean (type, &allow_insecure); if (ret < 0) { gf_log ("auth/addr", GF_LOG_WARNING, "rpc-auth-allow-insecure option %s " "is not a valid bool option", type); goto out; } } peer_port = atoi (service); if (peer_port >= PRIVILEGED_PORT_CEILING && !allow_insecure) { gf_log ("auth/addr", GF_LOG_ERROR, "client is bound to port %d which is not privileged", peer_port); result = AUTH_REJECT; goto out; } break; case AF_UNIX: strcpy (peer_addr, peer_info->identifier); break; default: gf_log ("authenticate/addr", GF_LOG_ERROR, "unknown address family %d", ((struct sockaddr *) &peer_info->sockaddr)->sa_family); goto out; } if (reject_addr) { parse_entries_and_compare (reject_addr->data, peer_addr, name, subdir, &result, AUTH_REJECT); if (result == AUTH_REJECT) goto out; } if (allow_addr) { parse_entries_and_compare (allow_addr->data, peer_addr, name, subdir, &result, AUTH_ACCEPT); } out: return result; }
static error_t parse_opts (int key, char *arg, struct argp_state *state) { cmd_args_t *cmd_args = NULL; uint32_t n = 0; double d = 0.0; gf_boolean_t b = _gf_false; char *pwd = NULL; char tmp_buf[2048] = {0,}; cmd_args = state->input; switch (key) { case ARGP_VOLFILE_SERVER_KEY: cmd_args->volfile_server = gf_strdup (arg); break; case ARGP_VOLFILE_MAX_FETCH_ATTEMPTS: n = 0; if (gf_string2uint_base10 (arg, &n) == 0) { cmd_args->max_connect_attempts = n; break; } argp_failure (state, -1, 0, "Invalid limit on connect attempts %s", arg); break; case ARGP_READ_ONLY_KEY: cmd_args->read_only = 1; break; case ARGP_MAC_COMPAT_KEY: if (!arg) arg = "on"; if (gf_string2boolean (arg, &b) == 0) { cmd_args->mac_compat = b; break; } argp_failure (state, -1, 0, "invalid value \"%s\" for mac-compat", arg); break; case ARGP_VOLUME_FILE_KEY: if (cmd_args->volfile) GF_FREE (cmd_args->volfile); if (arg[0] != '/') { pwd = getcwd (NULL, PATH_MAX); if (!pwd) { argp_failure (state, -1, errno, "getcwd failed with error no %d", errno); break; } snprintf (tmp_buf, 1024, "%s/%s", pwd, arg); cmd_args->volfile = gf_strdup (tmp_buf); free (pwd); } else { cmd_args->volfile = gf_strdup (arg); } break; case ARGP_LOG_SERVER_KEY: if (cmd_args->log_server) GF_FREE (cmd_args->log_server); cmd_args->log_server = gf_strdup (arg); break; case ARGP_LOG_LEVEL_KEY: if (strcasecmp (arg, ARGP_LOG_LEVEL_NONE_OPTION) == 0) { cmd_args->log_level = GF_LOG_NONE; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_CRITICAL_OPTION) == 0) { cmd_args->log_level = GF_LOG_CRITICAL; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_ERROR_OPTION) == 0) { cmd_args->log_level = GF_LOG_ERROR; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_WARNING_OPTION) == 0) { cmd_args->log_level = GF_LOG_WARNING; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_NORMAL_OPTION) == 0) { cmd_args->log_level = GF_LOG_NORMAL; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_DEBUG_OPTION) == 0) { cmd_args->log_level = GF_LOG_DEBUG; break; } if (strcasecmp (arg, ARGP_LOG_LEVEL_TRACE_OPTION) == 0) { cmd_args->log_level = GF_LOG_TRACE; break; } argp_failure (state, -1, 0, "unknown log level %s", arg); break; case ARGP_LOG_FILE_KEY: cmd_args->log_file = gf_strdup (arg); break; case ARGP_VOLFILE_SERVER_PORT_KEY: n = 0; if (gf_string2uint_base10 (arg, &n) == 0) { cmd_args->volfile_server_port = n; break; } argp_failure (state, -1, 0, "unknown volfile server port %s", arg); break; case ARGP_LOG_SERVER_PORT_KEY: n = 0; if (gf_string2uint_base10 (arg, &n) == 0) { cmd_args->log_server_port = n; break; } argp_failure (state, -1, 0, "unknown log server port %s", arg); break; case ARGP_VOLFILE_SERVER_TRANSPORT_KEY: cmd_args->volfile_server_transport = gf_strdup (arg); break; case ARGP_VOLFILE_ID_KEY: cmd_args->volfile_id = gf_strdup (arg); break; case ARGP_PID_FILE_KEY: cmd_args->pid_file = gf_strdup (arg); break; case ARGP_NO_DAEMON_KEY: cmd_args->no_daemon_mode = ENABLE_NO_DAEMON_MODE; break; case ARGP_RUN_ID_KEY: cmd_args->run_id = gf_strdup (arg); break; case ARGP_DEBUG_KEY: cmd_args->debug_mode = ENABLE_DEBUG_MODE; break; case ARGP_DIRECT_IO_MODE_KEY: if (!arg) arg = "on"; if (gf_string2boolean (arg, &b) == 0) { cmd_args->fuse_direct_io_mode = b; break; } argp_failure (state, -1, 0, "unknown direct I/O mode setting \"%s\"", arg); break; case ARGP_ENTRY_TIMEOUT_KEY: d = 0.0; gf_string2double (arg, &d); if (!(d < 0.0)) { cmd_args->fuse_entry_timeout = d; break; } argp_failure (state, -1, 0, "unknown entry timeout %s", arg); break; case ARGP_ATTRIBUTE_TIMEOUT_KEY: d = 0.0; gf_string2double (arg, &d); if (!(d < 0.0)) { cmd_args->fuse_attribute_timeout = d; break; } argp_failure (state, -1, 0, "unknown attribute timeout %s", arg); break; case ARGP_CLIENT_PID_KEY: if (gf_string2int (arg, &cmd_args->client_pid) == 0) { cmd_args->client_pid_set = 1; break; } argp_failure (state, -1, 0, "unknown client pid %s", arg); break; case ARGP_VOLFILE_CHECK_KEY: cmd_args->volfile_check = 1; break; case ARGP_VOLUME_NAME_KEY: cmd_args->volume_name = gf_strdup (arg); break; case ARGP_XLATOR_OPTION_KEY: gf_remember_xlator_option (&cmd_args->xlator_options, arg); break; case ARGP_KEY_NO_ARGS: break; case ARGP_KEY_ARG: if (state->arg_num >= 1) argp_usage (state); cmd_args->mount_point = gf_strdup (arg); break; case ARGP_DUMP_FUSE_KEY: cmd_args->dump_fuse = gf_strdup (arg); break; case ARGP_BRICK_NAME_KEY: cmd_args->brick_name = gf_strdup (arg); break; case ARGP_BRICK_PORT_KEY: n = 0; if (gf_string2uint_base10 (arg, &n) == 0) { cmd_args->brick_port = n; break; } argp_failure (state, -1, 0, "unknown brick (listen) port %s", arg); break; } return 0; }