Merge pull request #14 from linuxbox2/duplex-13

real merge of gss fixes to nfs-ganesha/ntirpc
diff --git a/src/authgss_hash.c b/src/authgss_hash.c
index 9bd3576..4ca53b5 100644
--- a/src/authgss_hash.c
+++ b/src/authgss_hash.c
@@ -126,7 +126,7 @@
 
 	authgss_hash_st.size = 0;
 	authgss_hash_st.max_part =
-	    __svc_params->gss.max_gc / authgss_hash_st.xt.npart;
+	    __svc_params->gss.max_ctx / authgss_hash_st.xt.npart;
 	authgss_hash_st.initialized = true;
 
  unlock:
@@ -251,23 +251,23 @@
 
 	cond_init_authgss_hash();
 
-	for (ix = 0, part = IDLE_NEXT(); ix < authgss_hash_st.xt.npart;
+	for (ix = 0, cnt = 0, part = IDLE_NEXT();
+	     ((ix < authgss_hash_st.xt.npart) &&
+		     (cnt < __svc_params->gss.max_gc));
 	     ++ix, part = IDLE_NEXT()) {
 		xp = &(authgss_hash_st.xt.tree[part]);
 		axp = (struct authgss_x_part *)xp->u1;
-		cnt = 0;
 		mutex_lock(&xp->mtx);
  again:
 		gd = TAILQ_FIRST(&axp->lru_q);
 		if (!gd)
 			goto next_t;
 
-		if (unlikely((authgss_hash_st.size > __svc_params->gss.max_gc)
-			     ||
-			     ((((axp->gen > gd->gen) ? 
-                                axp->gen - gd->gen : gd->gen - axp->gen) >
-			       __svc_params->gss.max_idle_gen))
-			     || (authgss_ctx_expired(gd)))) {
+		/* Remove the least-recently-used entry in this hash
+		 * partition iff it is expired, or the partition size
+		 * limit is exceeded */
+		if (unlikely((authgss_hash_st.size > authgss_hash_st.max_part)
+				|| (authgss_ctx_expired(gd)))) {
 
 			/* remove entry */
 			rbtree_x_cached_remove(&authgss_hash_st.xt, xp,
@@ -278,7 +278,7 @@
 			/* drop sentinel ref (may free gd) */
 			unref_svc_rpc_gss_data(gd, SVC_RPC_GSS_FLAG_NONE);
 
-			if (++cnt < authgss_hash_st.max_part)
+			if (++cnt < __svc_params->gss.max_gc)
 				goto again;
 		}
  next_t:
diff --git a/src/svc.c b/src/svc.c
index f053c05..666152f 100644
--- a/src/svc.c
+++ b/src/svc.c
@@ -202,8 +202,9 @@
 	if (params->gss_max_ctx)
 		__svc_params->gss.max_ctx = params->gss_max_ctx;
 	else
-		__svc_params->gss.max_ctx = 1024;
+		__svc_params->gss.max_ctx = 16384; /* 16K clients */
 
+	/* XXX deprecating */
 	if (params->gss_max_idle_gen)
 		__svc_params->gss.max_idle_gen = params->gss_max_idle_gen;
 	else
diff --git a/src/svc_auth_gss.c b/src/svc_auth_gss.c
index 953dd80..3322ab5 100644
--- a/src/svc_auth_gss.c
+++ b/src/svc_auth_gss.c
@@ -451,10 +451,14 @@
 	if ((gc->gc_proc == RPCSEC_GSS_DATA)
 	    || (gc->gc_proc == RPCSEC_GSS_DESTROY)) {
 
-		/* XXX fix prototype, toss junk args */
+		/* Per RFC 2203 5.3.3.3, if a valid security context
+		 * cannot be found to authorize a request, the
+		 * implementation returns RPCSEC_GSS_CREDPROBLEM.
+		 * N.B., we are explicitly allowed to discard contexts
+		 * for any reason (e.g., to save space). */
 		gd = authgss_ctx_hash_get(gc);
 		if (!gd)
-			svcauth_gss_return(AUTH_REJECTEDCRED);
+			svcauth_gss_return(RPCSEC_GSS_CREDPROBLEM);
 		gd_hashed = true;
 		if (gc->gc_svc != gd->sec.svc)
 			gd->sec.svc = gc->gc_svc;