Esempio n. 1
0
/**
 * cache_nfs_fh -- Places the nfs file handle in the underlying dict as we are
 *                 using as our cache. The key is "exportid:gfid:host_addr", the
 *                 value is an entry struct containing the export item that
 *                 was authorized for the operation and the file handle that was
 *                 authorized.
 *
 * @cache: The cache to place fh's in
 * @fh   : The fh to cache
 * @host_addr: The address of the host
 * @export_item: The export item that was authorized
 *
 */
int
cache_nfs_fh (struct auth_cache *cache, struct nfs3_fh *fh,
              const char *host_addr, struct export_item *export_item)
{
        int                      ret        = -EINVAL;
        char                    *hashkey    = NULL;
        data_t                  *entry_data = NULL;
        time_t                   timestamp  = 0;
        gf_boolean_t             can_write  = _gf_false;
        struct auth_cache_entry *entry      = NULL;

        GF_VALIDATE_OR_GOTO (GF_NFS, host_addr, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, cache, out);
        GF_VALIDATE_OR_GOTO (GF_NFS, fh, out);

        /* If we could already find it in the cache, just return */
        ret = auth_cache_lookup (cache, fh, host_addr, &timestamp, &can_write);
        if (ret == 0) {
                gf_msg_trace (GF_NFS, 0, "found cached auth/fh for host "
                              "%s", host_addr);
                goto out;
        }

        hashkey = make_hashkey (fh, host_addr);
        if (!hashkey) {
                ret = -ENOMEM;
                goto out;
        }

        entry = auth_cache_entry_init ();
        if (!entry) {
                ret = -ENOMEM;
                goto out;
        }

        entry->timestamp = time (NULL);
        entry->item = export_item;

        /* The cache entry will simply be the time that the entry
         * was cached.
         */
        entry_data = bin_to_data (entry, sizeof (*entry));
        if (!entry_data) {
                GF_FREE (entry);
                goto out;
        }

        ret = dict_set (cache->cache_dict, hashkey, entry_data);
        if (ret == -1) {
                GF_FREE (entry);
                goto out;
        }
        gf_msg_trace (GF_NFS, 0, "Caching file-handle (%s)", host_addr);
        ret = 0;
out:
        GF_FREE (hashkey);

        return ret;
}
Esempio n. 2
0
/**
 * is_nfs_fh_cached_and_writeable -- Checks if an NFS FH is cached for the given
 *                                   host and writable
 * @cache: The fh cache
 * @host_addr: Address to use in lookup
 * @fh: The fh to use in lookup
 *
 *
 * @return: TRUE if cached & writable, FALSE otherwise
 *
 */
gf_boolean_t
is_nfs_fh_cached_and_writeable (struct auth_cache *cache, struct nfs3_fh *fh,
                                const char *host_addr)
{
        int          ret       = 0;
        time_t       timestamp = 0;
        gf_boolean_t cached    = _gf_false;
        gf_boolean_t writable  = _gf_false;

        if (!fh)
                goto out;

        ret = auth_cache_lookup (cache, fh, host_addr, &timestamp, &writable);
        cached = ((ret == ENTRY_FOUND) && writable);

out:
        return cached;
}
Esempio n. 3
0
bool passdb_cache_lookup_credentials(struct auth_request *request,
				     const char *key, const char **password_r,
				     const char **scheme_r,
				     enum passdb_result *result_r,
				     bool use_expired)
{
	const char *value, *const *list;
	struct auth_cache_node *node;
	bool expired, neg_expired;

	if (passdb_cache == NULL)
		return FALSE;

	value = auth_cache_lookup(passdb_cache, request, key, &node,
				  &expired, &neg_expired);
	if (value == NULL || (expired && !use_expired)) {
		auth_request_log_debug(request, AUTH_SUBSYS_DB,
				       value == NULL ? "cache miss" :
				       "cache expired");
		return FALSE;
	}
	passdb_cache_log_hit(request, value);

	if (*value == '\0') {
		/* negative cache entry */
		*result_r = PASSDB_RESULT_USER_UNKNOWN;
		*password_r = NULL;
		*scheme_r = NULL;
		return TRUE;
	}

	list = t_strsplit_tab(value);
	auth_request_set_fields(request, list + 1, NULL);

	*result_r = PASSDB_RESULT_OK;
	*password_r = *list[0] == '\0' ? NULL : list[0];
	*scheme_r = password_get_scheme(password_r);
	i_assert(*scheme_r != NULL || *password_r == NULL);
	return TRUE;
}
Esempio n. 4
0
static bool
passdb_cache_lookup(struct auth_request *request, const char *key,
		    bool use_expired, struct auth_cache_node **node_r,
		    const char **value_r, bool *neg_expired_r)
{
	const char *value;
	bool expired;

	/* value = password \t ... */
	value = auth_cache_lookup(passdb_cache, request, key, node_r,
				  &expired, neg_expired_r);
	if (value == NULL || (expired && !use_expired)) {
		auth_request_log_debug(request, AUTH_SUBSYS_DB,
				       value == NULL ? "cache miss" :
				       "cache expired");
		return FALSE;
	}
	passdb_cache_log_hit(request, value);

	*value_r = value;
	return TRUE;
}
Esempio n. 5
0
bool passdb_cache_verify_plain(struct auth_request *request, const char *key,
			       const char *password,
			       enum passdb_result *result_r, int use_expired)
{
	const char *value, *cached_pw, *scheme, *const *list;
	struct auth_cache_node *node;
	int ret;
	bool expired, neg_expired;

	if (passdb_cache == NULL || key == NULL)
		return FALSE;

	/* value = password \t ... */
	value = auth_cache_lookup(passdb_cache, request, key, &node,
				  &expired, &neg_expired);
	if (value == NULL || (expired && !use_expired)) {
		auth_request_log_debug(request, AUTH_SUBSYS_DB,
				       value == NULL ? "cache miss" :
				       "cache expired");
		return FALSE;
	}
	passdb_cache_log_hit(request, value);

	if (*value == '\0') {
		/* negative cache entry */
		auth_request_log_unknown_user(request, AUTH_SUBSYS_DB);
		*result_r = PASSDB_RESULT_USER_UNKNOWN;
		return TRUE;
	}

	list = t_strsplit_tab(value);

	cached_pw = list[0];
	if (*cached_pw == '\0') {
		/* NULL password */
		auth_request_log_info(request, AUTH_SUBSYS_DB,
				      "Cached NULL password access");
		ret = 1;
	} else {
		scheme = password_get_scheme(&cached_pw);
		i_assert(scheme != NULL);

		ret = auth_request_password_verify(request, password, cached_pw,
						   scheme, AUTH_SUBSYS_DB);

		if (ret == 0 && (node->last_success || neg_expired)) {
			/* a) the last authentication was successful. assume
			   that the password was changed and cache is expired.
			   b) negative TTL reached, use it for password
			   mismatches too. */
			node->last_success = FALSE;
			return FALSE;
		}
	}
	node->last_success = ret > 0;

	/* save the extra_fields only after we know we're using the
	   cached data */
	auth_request_set_fields(request, list + 1, NULL);

	*result_r = ret > 0 ? PASSDB_RESULT_OK :
		PASSDB_RESULT_PASSWORD_MISMATCH;
	return TRUE;
}