static int glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req) { gd1_mgmt_v3_unlock_req lock_req = {{0},}; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; glusterd_peerinfo_t *peerinfo = NULL; xlator_t *this = NULL; gf_boolean_t is_synctasked = _gf_false; gf_boolean_t free_ctx = _gf_false; this = THIS; GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req); if (ret < 0) { gf_log (this->name, GF_LOG_ERROR, "Failed to decode unlock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_log (this->name, GF_LOG_DEBUG, "Received volume unlock req " "from uuid: %s", uuid_utoa (lock_req.uuid)); if (glusterd_friend_find_by_uuid (lock_req.uuid, &peerinfo)) { gf_log (this->name, GF_LOG_WARNING, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (lock_req.uuid)); ret = -1; goto out; } ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t); if (!ctx) { ret = -1; goto out; } uuid_copy (ctx->uuid, lock_req.uuid); ctx->req = req; ctx->dict = dict_new (); if (!ctx->dict) { ret = -1; goto out; } ret = dict_unserialize (lock_req.dict.dict_val, lock_req.dict.dict_len, &ctx->dict); if (ret) { gf_log (this->name, GF_LOG_WARNING, "failed to unserialize the dictionary"); goto out; } is_synctasked = dict_get_str_boolean (ctx->dict, "is_synctasked", _gf_false); if (is_synctasked) { ret = glusterd_syctasked_mgmt_v3_unlock (req, &lock_req, ctx); /* The above function does not take ownership of ctx. * Therefore we need to free the ctx explicitly. */ free_ctx = _gf_true; } else { ret = glusterd_op_state_machine_mgmt_v3_unlock (req, &lock_req, ctx); } out: if (ret || free_ctx) { if (ctx->dict) dict_unref (ctx->dict); if (ctx) GF_FREE (ctx); } free (lock_req.dict.dict_val); gf_log (this->name, GF_LOG_TRACE, "Returning %d", ret); 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; data_t *allow_user = NULL; data_t *username_data = NULL; data_t *passwd_data = NULL; data_t *password_data = NULL; char *username = NULL; char *password = NULL; char *brick_name = NULL; char *searchstr = NULL; char *username_str = NULL; char *tmp = NULL; char *username_cpy = NULL; gf_boolean_t using_ssl = _gf_false; gf_boolean_t strict_auth = _gf_false; username_data = dict_get(input_params, "ssl-name"); if (username_data) { gf_log("auth/login", GF_LOG_INFO, "connecting user name: %s", username_data->data); using_ssl = _gf_true; } else { ret = dict_get_str_boolean(config_params, "strict-auth-accept", _gf_false); if (ret == -1) strict_auth = _gf_false; else strict_auth = ret; username_data = dict_get(input_params, "username"); if (!username_data) { if (strict_auth) { gf_log("auth/login", GF_LOG_DEBUG, "username not found, strict auth" " configured returning REJECT"); result = AUTH_REJECT; } else { gf_log("auth/login", GF_LOG_DEBUG, "username not found, returning" " DONT-CARE"); } goto out; } password_data = dict_get(input_params, "password"); if (!password_data) { if (strict_auth) { gf_log("auth/login", GF_LOG_DEBUG, "password not found, strict auth" " configured returning REJECT"); result = AUTH_REJECT; } else { gf_log("auth/login", GF_LOG_WARNING, "password not found, returning" " DONT-CARE"); } goto out; } password = data_to_str(password_data); } username = data_to_str(username_data); brick_name = data_to_str(dict_get(input_params, "remote-subvolume")); if (!brick_name) { gf_log("auth/login", GF_LOG_ERROR, "remote-subvolume not specified"); result = AUTH_REJECT; goto out; } ret = gf_asprintf(&searchstr, "auth.login.%s.%s", brick_name, using_ssl ? "ssl-allow" : "allow"); if (-1 == ret) { gf_log("auth/login", GF_LOG_ERROR, "asprintf failed while setting search string, " "returning REJECT"); result = AUTH_REJECT; goto out; } allow_user = dict_get(config_params, searchstr); GF_FREE(searchstr); if (allow_user) { gf_log("auth/login", GF_LOG_INFO, "allowed user names: %s", allow_user->data); /* * There's a subtle difference between SSL and non-SSL behavior * if we can't match anything in the "while" loop below. * Intuitively, we should AUTH_REJECT if there's no match. * However, existing code depends on allowing untrusted users * to connect with *no credentials at all* by falling through * the loop. They're still distinguished from trusted users * who do provide a valid username and password (in fact that's * pretty much the only thing we use non-SSL login auth for), * but they are allowed to connect. It's wrong, but it's not * worth changing elsewhere. Therefore, we do the sane thing * only for SSL here. * * For SSL, if there's a list *you must be on it*. Note that * if there's no list we don't care. In that case (and the * ssl-allow=* case as well) authorization is effectively * disabled, though authentication and encryption are still * active. * * Read NOTE on strict_auth above. */ if (using_ssl || strict_auth) { result = AUTH_REJECT; } username_cpy = gf_strdup(allow_user->data); if (!username_cpy) goto out; username_str = strtok_r(username_cpy, " ,", &tmp); /* * We have to match a user's *authenticated* name to one in the * list. If we're using SSL, they're already authenticated. * Otherwise, they need a matching password to complete the * process. */ while (username_str) { if (!fnmatch(username_str, username, 0)) { if (using_ssl) { result = AUTH_ACCEPT; break; } ret = gf_asprintf(&searchstr, "auth.login.%s.password", username); if (-1 == ret) { gf_log("auth/login", GF_LOG_WARNING, "asprintf failed while setting search string"); goto out; } passwd_data = dict_get(config_params, searchstr); GF_FREE(searchstr); if (!passwd_data) { gf_log("auth/login", GF_LOG_ERROR, "wrong username/password combination"); result = AUTH_REJECT; goto out; } result = !((strcmp(data_to_str(passwd_data), password)) ? AUTH_ACCEPT : AUTH_REJECT); if (result == AUTH_REJECT) gf_log("auth/login", GF_LOG_ERROR, "wrong password for user %s", username); break; } username_str = strtok_r(NULL, " ,", &tmp); } } out: GF_FREE(username_cpy); return result; }
static int glusterd_handle_mgmt_v3_unlock_fn (rpcsvc_request_t *req) { gd1_mgmt_v3_unlock_req lock_req = {{0},}; int32_t ret = -1; glusterd_op_lock_ctx_t *ctx = NULL; xlator_t *this = NULL; gf_boolean_t is_synctasked = _gf_false; gf_boolean_t free_ctx = _gf_false; this = THIS; GF_ASSERT (this); GF_ASSERT (req); ret = xdr_to_generic (req->msg[0], &lock_req, (xdrproc_t)xdr_gd1_mgmt_v3_unlock_req); if (ret < 0) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_REQ_DECODE_FAIL, "Failed to decode unlock " "request received from peer"); req->rpc_err = GARBAGE_ARGS; goto out; } gf_msg_debug (this->name, 0, "Received volume unlock req " "from uuid: %s", uuid_utoa (lock_req.uuid)); if (glusterd_peerinfo_find_by_uuid (lock_req.uuid) == NULL) { gf_msg (this->name, GF_LOG_WARNING, 0, GD_MSG_PEER_NOT_FOUND, "%s doesn't " "belong to the cluster. Ignoring request.", uuid_utoa (lock_req.uuid)); ret = -1; goto out; } ctx = GF_CALLOC (1, sizeof (*ctx), gf_gld_mt_op_lock_ctx_t); if (!ctx) { ret = -1; goto out; } gf_uuid_copy (ctx->uuid, lock_req.uuid); ctx->req = req; ctx->dict = dict_new (); if (!ctx->dict) { ret = -1; goto out; } ret = dict_unserialize (lock_req.dict.dict_val, lock_req.dict.dict_len, &ctx->dict); if (ret) { gf_msg (this->name, GF_LOG_WARNING, 0, GD_MSG_DICT_UNSERIALIZE_FAIL, "failed to unserialize the dictionary"); goto out; } is_synctasked = dict_get_str_boolean (ctx->dict, "is_synctasked", _gf_false); if (is_synctasked) { ret = glusterd_syctasked_mgmt_v3_unlock (req, &lock_req, ctx); if (ret) { gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3_locks"); /* Ignore the return code, as it shouldn't be propagated * from the handler function so as to avoid double * deletion of the req */ ret = 0; } /* The above function does not take ownership of ctx. * Therefore we need to free the ctx explicitly. */ free_ctx = _gf_true; } else { /* Shouldn't ignore the return code here, and it should * be propagated from the handler function as in failure * case it doesn't delete the req object */ ret = glusterd_op_state_machine_mgmt_v3_unlock (req, &lock_req, ctx); if (ret) gf_msg (this->name, GF_LOG_ERROR, 0, GD_MSG_MGMTV3_UNLOCK_FAIL, "Failed to release mgmt_v3_locks"); } out: if (ctx && (ret || free_ctx)) { if (ctx->dict) dict_unref (ctx->dict); GF_FREE (ctx); } free (lock_req.dict.dict_val); gf_msg_trace (this->name, 0, "Returning %d", ret); return ret; }