}
static struct cache_detail rsi_cache = {
+ .owner = THIS_MODULE,
.hash_size = RSI_HASHMAX,
.hash_table = rsi_table,
.name = "auth.rpcsec.init",
gss_mech_put(gm);
goto out;
}
- if (gss_import_sec_context(buf, len, gm, &rsci.mechctx)) {
+ status = gss_import_sec_context(buf, len, gm, &rsci.mechctx);
+ if (status) {
gss_mech_put(gm);
goto out;
}
}
static struct cache_detail rsc_cache = {
+ .owner = THIS_MODULE,
.hash_size = RSC_HASHMAX,
.hash_table = rsc_table,
.name = "auth.rpcsec.context",
if (rqstp->rq_deferred) /* skip verification of revisited request */
return SVC_OK;
- if (gss_verify_mic(ctx_id, &rpchdr, &checksum, NULL)
- != GSS_S_COMPLETE) {
+ if (gss_verify_mic(ctx_id, &rpchdr, &checksum) != GSS_S_COMPLETE) {
*authp = rpcsec_gsserr_credproblem;
return SVC_DENIED;
}
return SVC_OK;
}
+static int
+gss_write_null_verf(struct svc_rqst *rqstp)
+{
+ u32 *p;
+
+ svc_putu32(rqstp->rq_res.head, htonl(RPC_AUTH_NULL));
+ p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
+ /* don't really need to check if head->iov_len > PAGE_SIZE ... */
+ *p++ = 0;
+ if (!xdr_ressize_check(rqstp, p))
+ return -1;
+ return 0;
+}
+
static int
gss_write_verf(struct svc_rqst *rqstp, struct gss_ctx *ctx_id, u32 seq)
{
xdr_buf_from_iov(&iov, &verf_data);
p = rqstp->rq_res.head->iov_base + rqstp->rq_res.head->iov_len;
mic.data = (u8 *)(p + 1);
- maj_stat = gss_get_mic(ctx_id, 0, &verf_data, &mic);
+ maj_stat = gss_get_mic(ctx_id, &verf_data, &mic);
if (maj_stat != GSS_S_COMPLETE)
return -1;
*p++ = htonl(mic.len);
goto out;
if (read_bytes_from_xdr_buf(buf, integ_len + 4, mic.data, mic.len))
goto out;
- maj_stat = gss_verify_mic(ctx, &integ_buf, &mic, NULL);
+ maj_stat = gss_verify_mic(ctx, &integ_buf, &mic);
if (maj_stat != GSS_S_COMPLETE)
goto out;
if (ntohl(svc_getu32(&buf->head[0])) != seq)
return SVC_OK;
}
+static inline int
+gss_write_init_verf(struct svc_rqst *rqstp, struct rsi *rsip)
+{
+ struct rsc *rsci;
+
+ if (rsip->major_status != GSS_S_COMPLETE)
+ return gss_write_null_verf(rqstp);
+ rsci = gss_svc_searchbyctx(&rsip->out_handle);
+ if (rsci == NULL) {
+ rsip->major_status = GSS_S_NO_CONTEXT;
+ return gss_write_null_verf(rqstp);
+ }
+ return gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN);
+}
+
/*
* Accept an rpcsec packet.
* If context establishment, punt to user space
case -ENOENT:
goto drop;
case 0:
- rsci = gss_svc_searchbyctx(&rsip->out_handle);
- if (!rsci) {
- goto drop;
- }
- if (gss_write_verf(rqstp, rsci->mechctx, GSS_SEQ_WIN))
+ if (gss_write_init_verf(rqstp, rsip))
goto drop;
if (resv->iov_len + 4 > PAGE_SIZE)
goto drop;
resv = &resbuf->tail[0];
}
mic.data = (u8 *)resv->iov_base + resv->iov_len + 4;
- if (gss_get_mic(gsd->rsci->mechctx, 0, &integ_buf, &mic))
+ if (gss_get_mic(gsd->rsci->mechctx, &integ_buf, &mic))
goto out_err;
svc_putu32(resv, htonl(mic.len));
memset(mic.data + mic.len, 0,
void
gss_svc_shutdown(void)
{
- cache_unregister(&rsc_cache);
- cache_unregister(&rsi_cache);
+ if (cache_unregister(&rsc_cache))
+ printk(KERN_ERR "auth_rpcgss: failed to unregister rsc cache\n");
+ if (cache_unregister(&rsi_cache))
+ printk(KERN_ERR "auth_rpcgss: failed to unregister rsi cache\n");
svc_auth_unregister(RPC_AUTH_GSS);
}