static int seq_dict_foreach (dict_t *dict, int (*fn)(char *str, void *data), void *data) { char index[] = "4294967296"; // 1<<32 int i = 0; char *val = NULL; int ret = 0; for (;;i++) { snprintf(index, sizeof(index), "%d", i); ret = dict_get_str (dict, index, &val); if (ret != 0) return ret == -ENOENT ? 0 : ret; ret = fn (val, data); if (ret != 0) 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; }
transport_t * transport_load (dict_t *options, xlator_t *xl) { struct transport *trans = NULL, *return_trans = NULL; char *name = NULL; void *handle = NULL; char *type = NULL; char str[] = "ERROR"; int32_t ret = -1; int8_t is_tcp = 0, is_unix = 0, is_ibsdp = 0; volume_opt_list_t *vol_opt = NULL; GF_VALIDATE_OR_GOTO("transport", options, fail); GF_VALIDATE_OR_GOTO("transport", xl, fail); trans = GF_CALLOC (1, sizeof (struct transport), gf_common_mt_transport); GF_VALIDATE_OR_GOTO("transport", trans, fail); trans->xl = xl; type = str; /* Backward compatibility */ ret = dict_get_str (options, "transport-type", &type); if (ret < 0) { ret = dict_set_str (options, "transport-type", "socket"); if (ret < 0) gf_log ("dict", GF_LOG_DEBUG, "setting transport-type failed"); gf_log ("transport", GF_LOG_WARNING, "missing 'option transport-type'. defaulting to " "\"socket\""); } else { { /* Backword compatibility to handle * /client, * * /server. */ char *tmp = strchr (type, '/'); if (tmp) *tmp = '\0'; } is_tcp = strcmp (type, "tcp"); is_unix = strcmp (type, "unix"); is_ibsdp = strcmp (type, "ib-sdp"); if ((is_tcp == 0) || (is_unix == 0) || (is_ibsdp == 0)) { if (is_unix == 0) ret = dict_set_str (options, "transport.address-family", "unix"); if (is_ibsdp == 0) ret = dict_set_str (options, "transport.address-family", "inet-sdp"); if (ret < 0) gf_log ("dict", GF_LOG_DEBUG, "setting address-family failed"); ret = dict_set_str (options, "transport-type", "socket"); if (ret < 0) gf_log ("dict", GF_LOG_DEBUG, "setting transport-type failed"); } } ret = dict_get_str (options, "transport-type", &type); if (ret < 0) { GF_FREE (trans); gf_log ("transport", GF_LOG_ERROR, "'option transport-type <xx>' missing in volume '%s'", xl->name); goto fail; } ret = gf_asprintf (&name, "%s/%s.so", TRANSPORTDIR, type); if (-1 == ret) { gf_log ("transport", GF_LOG_ERROR, "asprintf failed"); goto fail; } gf_log ("transport", GF_LOG_DEBUG, "attempt to load file %s", name); handle = dlopen (name, RTLD_NOW|RTLD_GLOBAL); if (handle == NULL) { gf_log ("transport", GF_LOG_ERROR, "%s", dlerror ()); gf_log ("transport", GF_LOG_ERROR, "volume '%s': transport-type '%s' is not valid or " "not found on this machine", xl->name, type); GF_FREE (name); GF_FREE (trans); goto fail; } GF_FREE (name); trans->ops = dlsym (handle, "tops"); if (trans->ops == NULL) { gf_log ("transport", GF_LOG_ERROR, "dlsym (transport_ops) on %s", dlerror ()); GF_FREE (trans); goto fail; } trans->init = dlsym (handle, "init"); if (trans->init == NULL) { gf_log ("transport", GF_LOG_ERROR, "dlsym (gf_transport_init) on %s", dlerror ()); GF_FREE (trans); goto fail; } trans->fini = dlsym (handle, "fini"); if (trans->fini == NULL) { gf_log ("transport", GF_LOG_ERROR, "dlsym (gf_transport_fini) on %s", dlerror ()); GF_FREE (trans); goto fail; } vol_opt = GF_CALLOC (1, sizeof (volume_opt_list_t), gf_common_mt_volume_opt_list_t); vol_opt->given_opt = dlsym (handle, "options"); if (vol_opt->given_opt == NULL) { gf_log ("transport", GF_LOG_DEBUG, "volume option validation not specified"); } else { list_add_tail (&vol_opt->list, &xl->volume_options); if (-1 == validate_xlator_volume_options (xl, vol_opt->given_opt)) { gf_log ("transport", GF_LOG_ERROR, "volume option validation failed"); GF_FREE (trans); goto fail; } } ret = trans->init (trans); if (ret != 0) { gf_log ("transport", GF_LOG_ERROR, "'%s' initialization failed", type); GF_FREE (trans); goto fail; } pthread_mutex_init (&trans->lock, NULL); return_trans = trans; fail: return return_trans; }
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; }
int quotad_aggregator_getlimit (rpcsvc_request_t *req) { call_frame_t *frame = NULL; gf_cli_req cli_req = {{0}, }; gf_cli_rsp cli_rsp = {0}; gfs3_lookup_req args = {{0,},}; gfs3_lookup_rsp rsp = {0,}; quotad_aggregator_state_t *state = NULL; xlator_t *this = NULL; dict_t *dict = NULL; int ret = -1, op_errno = 0; char *gfid_str = NULL; uuid_t gfid = {0}; GF_VALIDATE_OR_GOTO ("quotad-aggregator", req, err); this = THIS; ret = xdr_to_generic (req->msg[0], &cli_req, (xdrproc_t)xdr_gf_cli_req); if (ret < 0) { //failed to decode msg; gf_log ("", GF_LOG_ERROR, "xdr decoding error"); req->rpc_err = GARBAGE_ARGS; goto err; } if (cli_req.dict.dict_len) { dict = dict_new (); ret = dict_unserialize (cli_req.dict.dict_val, cli_req.dict.dict_len, &dict); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "Failed to " "unserialize req-buffer to dictionary"); goto err; } } ret = dict_get_str (dict, "gfid", &gfid_str); if (ret) { goto err; } uuid_parse ((const char*)gfid_str, gfid); frame = quotad_aggregator_get_frame_from_req (req); if (frame == NULL) { rsp.op_errno = ENOMEM; goto err; } state = frame->root->state; state->xdata = dict; ret = dict_set_int32 (state->xdata, QUOTA_LIMIT_KEY, 42); if (ret) goto err; ret = dict_set_int32 (state->xdata, QUOTA_SIZE_KEY, 42); if (ret) goto err; ret = dict_set_int32 (state->xdata, GET_ANCESTRY_PATH_KEY,42); if (ret) goto err; memcpy (&args.gfid, &gfid, 16); args.bname = alloca (req->msg[0].iov_len); args.xdata.xdata_val = alloca (req->msg[0].iov_len); ret = qd_nameless_lookup (this, frame, &args, state->xdata, quotad_aggregator_getlimit_cbk); if (ret) { rsp.op_errno = ret; goto err; } return ret; err: cli_rsp.op_ret = -1; cli_rsp.op_errno = op_errno; cli_rsp.op_errstr = ""; quotad_aggregator_getlimit_cbk (this, frame, &cli_rsp); dict_unref (dict); return ret; }