Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}