#include "gss_err.h"
#include "gss_internal.h"
#include "gss_api.h"
+#include "gss_crypto.h"
#define GSS_SVC_UPCALL_TIMEOUT (20)
static DEFINE_SPINLOCK(__ctx_index_lock);
static __u64 __ctx_index;
+unsigned int krb5_allow_old_client_csum;
+
__u64 gss_get_next_ctx_index(void)
{
__u64 idx;
return hash >> (BITS_PER_LONG - bits);
}
-/* This compatibility can be removed once kernel 3.3 is used,
- * since cache_register_net/cache_unregister_net are exported.
- * Note that since kernel 3.4 cache_register and cache_unregister
- * are removed.
-*/
-static inline int _cache_register_net(struct cache_detail *cd, struct net *net)
-{
-#ifdef HAVE_CACHE_REGISTER
- return cache_register(cd);
-#else
- return cache_register_net(cd, net);
-#endif
-}
-static inline void _cache_unregister_net(struct cache_detail *cd,
- struct net *net)
-{
-#ifdef HAVE_CACHE_REGISTER
- cache_unregister(cd);
-#else
- cache_unregister_net(cd, net);
-#endif
-}
/****************************************
* rpc sec init (rsi) cache *
****************************************/
static struct rsi *rsi_update(struct rsi *new, struct rsi *old);
static struct rsi *rsi_lookup(struct rsi *item);
+#ifdef HAVE_CACHE_DETAIL_WRITERS
+static inline int channel_users(struct cache_detail *cd)
+{
+ return atomic_read(&cd->writers);
+}
+#else
+static inline int channel_users(struct cache_detail *cd)
+{
+ return atomic_read(&cd->readers);
+}
+#endif
+
static inline int rsi_hash(struct rsi *item)
{
return hash_mem((char *)item->in_handle.data, item->in_handle.len,
(*bpp)[-1] = '\n';
}
-#ifdef HAVE_SUNRPC_UPCALL_HAS_3ARGS
-static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
-{
- return sunrpc_cache_pipe_upcall(cd, h, rsi_request);
-}
-#else
-
-static int rsi_upcall(struct cache_detail *cd, struct cache_head *h)
-{
- return sunrpc_cache_pipe_upcall(cd, h);
-}
-#endif
-
static inline void __rsi_init(struct rsi *new, struct rsi *item)
{
new->out_handle = RAWOBJ_EMPTY;
static void rsi_put(struct kref *ref)
{
- struct rsi *rsi = container_of(ref, struct rsi, h.ref);
+ struct rsi *rsi = container_of(ref, struct rsi, h.ref);
#ifdef HAVE_CACHE_HEAD_HLIST
- LASSERT(rsi->h.cache_list.next == NULL);
+ LASSERT(hlist_unhashed(&rsi->h.cache_list));
#else
LASSERT(rsi->h.next == NULL);
#endif
- rsi_free(rsi);
- OBD_FREE_PTR(rsi);
+ rsi_free(rsi);
+ OBD_FREE_PTR(rsi);
}
static int rsi_match(struct cache_head *a, struct cache_head *b)
char *buf = mesg;
int len;
struct rsi rsii, *rsip = NULL;
- time_t expiry;
+ time64_t expiry;
int status = -EINVAL;
ENTRY;
.hash_table = rsi_table,
.name = "auth.sptlrpc.init",
.cache_put = rsi_put,
-#ifndef HAVE_SUNRPC_UPCALL_HAS_3ARGS
.cache_request = rsi_request,
-#endif
- .cache_upcall = rsi_upcall,
+ .cache_upcall = sunrpc_cache_pipe_upcall,
.cache_parse = rsi_parse,
.match = rsi_match,
.init = rsi_init,
static void rsc_put(struct kref *ref)
{
- struct rsc *rsci = container_of(ref, struct rsc, h.ref);
+ struct rsc *rsci = container_of(ref, struct rsc, h.ref);
#ifdef HAVE_CACHE_HEAD_HLIST
- LASSERT(rsci->h.cache_list.next == NULL);
+ LASSERT(hlist_unhashed(&rsci->h.cache_list));
#else
- LASSERT(rsci->h.next == NULL);
+ LASSERT(rsci->h.next == NULL);
#endif
- rsc_free(rsci);
- OBD_FREE_PTR(rsci);
+ rsc_free(rsci);
+ OBD_FREE_PTR(rsci);
}
static int rsc_match(struct cache_head *a, struct cache_head *b)
char *buf = mesg;
int len, rv, tmp_int;
struct rsc rsci, *rscp = NULL;
- time_t expiry;
+ time64_t expiry;
int status = -EINVAL;
struct gss_api_mech *gm = NULL;
CERROR("unable to get expire time, drop it\n");
GOTO(out, rc = -EINVAL);
}
- rsci.h.expiry_time = (time_t) ctx_expiry;
+ rsci.h.expiry_time = ctx_expiry;
switch (imp->imp_obd->u.cli.cl_sp_to) {
case LUSTRE_SP_MDT:
cache_get(&rsip->h); /* take an extra ref */
init_waitqueue_head(&rsip->waitq);
- init_waitqueue_entry(&wait, current);
+ init_wait(&wait);
add_wait_queue(&rsip->waitq, &wait);
cache_check:
if (first_check) {
first_check = 0;
- read_lock(&rsi_cache.hash_lock);
+ cache_read_lock(&rsi_cache);
valid = test_bit(CACHE_VALID, &rsip->h.flags);
if (valid == 0)
set_current_state(TASK_INTERRUPTIBLE);
- read_unlock(&rsi_cache.hash_lock);
+ cache_read_unlock(&rsi_cache);
if (valid == 0) {
- unsigned long jiffies;
- jiffies = msecs_to_jiffies(MSEC_PER_SEC *
- GSS_SVC_UPCALL_TIMEOUT);
- schedule_timeout(jiffies);
+ unsigned long timeout;
+
+ timeout = cfs_time_seconds(GSS_SVC_UPCALL_TIMEOUT);
+ schedule_timeout(timeout);
}
cache_get(&rsip->h);
goto cache_check;
grctx->src_ctx = &rsci->ctx;
}
+ if (gw->gw_flags & LUSTRE_GSS_PACK_KCSUM) {
+ grctx->src_ctx->gsc_mechctx->hash_func = gss_digest_hash;
+ } else if (!strcmp(grctx->src_ctx->gsc_mechctx->mech_type->gm_name,
+ "krb5") &&
+ !krb5_allow_old_client_csum) {
+ CWARN("%s: deny connection from '%s' due to missing 'krb_csum' feature, set 'sptlrpc.gss.krb5_allow_old_client_csum=1' to allow, but recommend client upgrade: rc = %d\n",
+ target->obd_name, libcfs_nid2str(req->rq_peer.nid),
+ -EPROTO);
+ GOTO(out, rc = SECSVC_DROP);
+ } else {
+ grctx->src_ctx->gsc_mechctx->hash_func =
+ gss_digest_hash_compat;
+ }
+
if (rawobj_dup(&rsci->ctx.gsc_rvs_hdl, rvs_hdl)) {
CERROR("failed duplicate reverse handle\n");
GOTO(out, rc);
*/
get_random_bytes(&__ctx_index, sizeof(__ctx_index));
- rc = _cache_register_net(&rsi_cache, &init_net);
+ rc = cache_register_net(&rsi_cache, &init_net);
if (rc != 0)
return rc;
- rc = _cache_register_net(&rsc_cache, &init_net);
+ rc = cache_register_net(&rsc_cache, &init_net);
if (rc != 0) {
- _cache_unregister_net(&rsi_cache, &init_net);
+ cache_unregister_net(&rsi_cache, &init_net);
return rc;
}
* Here we wait at minimum 1.5 seconds.
*/
for (i = 0; i < 6; i++) {
- if (atomic_read(&rsi_cache.readers) > 0)
+ if (channel_users(&rsi_cache) > 0)
break;
- set_current_state(TASK_UNINTERRUPTIBLE);
- LASSERT(msecs_to_jiffies(MSEC_PER_SEC / 4) > 0);
- schedule_timeout(msecs_to_jiffies(MSEC_PER_SEC / 4));
+ schedule_timeout_uninterruptible(cfs_time_seconds(1) / 4);
}
- if (atomic_read(&rsi_cache.readers) == 0)
+ if (channel_users(&rsi_cache) == 0)
CWARN("Init channel is not opened by lsvcgssd, following "
"request might be dropped until lsvcgssd is active\n");
void gss_exit_svc_upcall(void)
{
cache_purge(&rsi_cache);
- _cache_unregister_net(&rsi_cache, &init_net);
+ cache_unregister_net(&rsi_cache, &init_net);
cache_purge(&rsc_cache);
- _cache_unregister_net(&rsc_cache, &init_net);
+ cache_unregister_net(&rsc_cache, &init_net);
}