.pg_nvers = NLM_NRVERS, /* number of entries in nlmsvc_version */
.pg_vers = nlmsvc_version, /* version table */
.pg_name = "lockd", /* service name */
+ .pg_class = "nfsd", /* share authentication with nfsd */
.pg_stats = &nlmsvc_stats, /* stats table */
};
fh.fh_export = NULL;
exp_readlock();
- rqstp->rq_client = exp_getclient(&rqstp->rq_addr);
- if (rqstp->rq_client == NULL)
- nfserr = nfserr_stale;
- else
- nfserr = nfsd_open(rqstp, &fh, S_IFREG, MAY_LOCK, filp);
+ nfserr = nfsd_open(rqstp, &fh, S_IFREG, MAY_LOCK, filp);
if (!nfserr) {
dget(filp->f_dentry);
mntget(filp->f_vfsmnt);
}
fh_put(&fh);
- if (rqstp->rq_client)
- auth_domain_put(rqstp->rq_client);
rqstp->rq_client = NULL;
exp_readunlock();
/* nlm and nfsd don't share error codes.
int data_left = fh->fh_size/4;
error = nfserr_stale;
+ if (rqstp->rq_client == NULL)
+ goto out;
if (rqstp->rq_vers > 2)
error = nfserr_badhandle;
if (rqstp->rq_vers == 4 && fh->fh_size == 0)
/* Lock the export hash tables for reading. */
exp_readlock();
- /* Validate the client's address. This will also defeat
- * port probes on port 2049 by unauthorized clients.
- */
- rqstp->rq_client = exp_getclient(&rqstp->rq_addr);
/* Process request with signals blocked. */
spin_lock_irq(¤t->sig->siglock);
siginitsetinv(¤t->blocked, ALLOWED_SIGS);
svc_process(serv, rqstp);
/* Unlock export hash tables */
- if (rqstp->rq_client) {
- auth_domain_put(rqstp->rq_client);
- rqstp->rq_client = NULL;
- }
exp_readunlock();
update_thread_usage(atomic_read(&nfsd_busy));
atomic_dec(&nfsd_busy);
.pg_nvers = NFSD_NRVERS, /* nr of entries in nfsd_version */
.pg_vers = nfsd_version, /* version table */
.pg_name = "nfsd", /* program name */
+ .pg_class = "nfsd", /* authentication class */
.pg_stats = &nfsd_svcstats, /* version table */
};
struct dentry *mounts = dget(dentry);
while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
;
- exp2 = exp_get_by_name(rqstp->rq_client, mnt, mounts);
+ exp2 = exp_get_by_name(exp->ex_client, mnt, mounts);
if (exp2 && EX_CROSSMNT(exp2)) {
/* successfully crossed mount point */
exp = exp2;
unsigned int pg_nvers; /* number of versions */
struct svc_version ** pg_vers; /* version array */
char * pg_name; /* service name */
+ char * pg_class; /* class name: services sharing authentication */
struct svc_stat * pg_stats; /* rpc statistics */
};
{
struct svc_buf *argp = &rqstp->rq_argbuf;
struct svc_buf *resp = &rqstp->rq_resbuf;
+ int rv=0;
+ struct ip_map key, *ipm;
if ((argp->len -= 3) < 0) {
return SVC_GARBAGE;
/* Put NULL verifier */
svc_putu32(resp, RPC_AUTH_NULL);
svc_putu32(resp, 0);
- return SVC_OK;
+
+ key.m_class = rqstp->rq_server->sv_program->pg_class;
+ key.m_addr = rqstp->rq_addr.sin_addr;
+
+ ipm = ip_map_lookup(&key, 0);
+
+ rqstp->rq_client = NULL;
+
+ if (ipm)
+ switch (cache_check(&ip_map_cache, &ipm->h)) {
+ case -EAGAIN:
+ rv = SVC_DROP;
+ break;
+ case -ENOENT:
+ rv = SVC_OK; /* rq_client is NULL */
+ break;
+ case 0:
+ rqstp->rq_client = &ipm->m_client->h;
+ cache_get(&rqstp->rq_client->h);
+ ip_map_put(&ipm->h, &ip_map_cache);
+ rv = SVC_OK;
+ break;
+ default: BUG();
+ }
+ else rv = SVC_DROP;
+
+ if (rqstp->rq_client == NULL && proc != 0)
+ *authp = rpc_autherr_badcred;
+
+ return rv;
}
static int
svcauth_null_release(struct svc_rqst *rqstp)
{
+ if (rqstp->rq_client)
+ auth_domain_put(rqstp->rq_client);
+ rqstp->rq_client = NULL;
+
return 0; /* don't drop */
}
struct svc_cred *cred = &rqstp->rq_cred;
u32 *bufp = argp->buf, slen, i;
int len = argp->len;
+ int rv=0;
+ struct ip_map key, *ipm;
if ((len -= 3) < 0)
return SVC_GARBAGE;
svc_putu32(resp, RPC_AUTH_NULL);
svc_putu32(resp, 0);
- return SVC_OK;
+ key.m_class = rqstp->rq_server->sv_program->pg_class;
+ key.m_addr = rqstp->rq_addr.sin_addr;
+
+ ipm = ip_map_lookup(&key, 0);
+
+ rqstp->rq_client = NULL;
+
+ if (ipm)
+ switch (cache_check(&ip_map_cache, &ipm->h)) {
+ case -EAGAIN:
+ rv = SVC_DROP;
+ break;
+ case -ENOENT:
+ rv = SVC_OK; /* rq_client is NULL */
+ break;
+ case 0:
+ rqstp->rq_client = &ipm->m_client->h;
+ cache_get(&rqstp->rq_client->h);
+ ip_map_put(&ipm->h, &ip_map_cache);
+ rv = SVC_OK;
+ break;
+ default: BUG();
+ }
+ else rv = SVC_DROP;
+
+ if (rqstp->rq_client == NULL && proc != 0)
+ goto badcred;
+ return rv;
badcred:
*authp = rpc_autherr_badcred;
{
/* Verifier (such as it is) is already in place.
*/
+ if (rqstp->rq_client)
+ auth_domain_put(rqstp->rq_client);
+ rqstp->rq_client = NULL;
+
return 0;
}