From 02ed7daa25442fbe33b7be8743c4fb0e10d8492d Mon Sep 17 00:00:00 2001 From: Derrick Brashear Date: Wed, 17 Mar 2004 06:43:34 +0000 Subject: [PATCH] support-nfs-translator-sysname-lists-20040317 support sysname lists in nfs translator --- src/afs/VNOPS/afs_vnop_lookup.c | 113 ++++++++++++++++++++------------ src/afs/afs_nfsclnt.c | 31 ++++++--- src/afs/afs_pioctl.c | 28 ++++---- src/afs/afs_prototypes.h | 4 +- src/afs/exporter.h | 4 +- src/afs/nfsclient.h | 3 +- 6 files changed, 115 insertions(+), 68 deletions(-) diff --git a/src/afs/VNOPS/afs_vnop_lookup.c b/src/afs/VNOPS/afs_vnop_lookup.c index f377ea650..f1581ca1c 100644 --- a/src/afs/VNOPS/afs_vnop_lookup.c +++ b/src/afs/VNOPS/afs_vnop_lookup.c @@ -400,40 +400,49 @@ afs_ENameOK(register char *aname) return 1; } -int +static int afs_getsysname(register struct vrequest *areq, register struct vcache *adp, - register char *bufp) + register char *bufp, int *num, char **sysnamelist[]) { register struct unixuser *au; register afs_int32 error; - if (!afs_nfsexporter) { - strcpy(bufp, afs_sysname); - return 0; - } AFS_STATCNT(getsysname); - au = afs_GetUser(areq->uid, adp->fid.Cell, 0); - afs_PutUser(au, 0); - if (au->exporter) { - error = EXP_SYSNAME(au->exporter, NULL, bufp); - if (error) - strcpy(bufp, "@sys"); - return -1; - } else { - strcpy(bufp, afs_sysname); - return 0; + + *sysnamelist = afs_sysnamelist; + + if (!afs_nfsexporter) + strcpy(bufp, (*sysnamelist)[0]); + else { + au = afs_GetUser(areq->uid, adp->fid.Cell, 0); + if (au->exporter) { + error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num); + if (error) { + strcpy(bufp, "@sys"); + afs_PutUser(au, 0); + return -1; + } else { + strcpy(bufp, (*sysnamelist)[0]); + } + } else + strcpy(bufp, afs_sysname); + afs_PutUser(au, 0); } + return 0; } void -Check_AtSys(register struct vcache *avc, const char *aname, - struct sysname_info *state, struct vrequest *areq) +Check_AtSys(register struct vcache *avc, char *aname, + struct sysname_info *state, struct vrequest *areq) { + int num = 0; + char **sysnamelist[MAXSYSNAME]; + if (AFS_EQ_ATSYS(aname)) { state->offset = 0; state->name = (char *)osi_AllocLargeSpace(AFS_SMALLOCSIZ); state->allocked = 1; - state->index = afs_getsysname(areq, avc, state->name); + state->index = afs_getsysname(areq, avc, state->name, &num, sysnamelist); } else { state->offset = -1; state->allocked = 0; @@ -444,32 +453,54 @@ Check_AtSys(register struct vcache *avc, const char *aname, int Next_AtSys(register struct vcache *avc, struct vrequest *areq, - struct sysname_info *state) + struct sysname_info *state) { + int num = afs_sysnamecount; + char **sysnamelist[MAXSYSNAME]; + if (state->index == -1) - return 0; /* No list */ + return 0; /* No list */ - /* Check for the initial state of aname != "@sys" in Check_AtSys */ + /* Check for the initial state of aname != "@sys" in Check_AtSys*/ if (state->offset == -1 && state->allocked == 0) { - register char *tname; - /* Check for .*@sys */ - for (tname = state->name; *tname; tname++) - /*Move to the end of the string */ ; - if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname - 4))) { - state->offset = (tname - 4) - state->name; - tname = (char *)osi_AllocLargeSpace(AFS_LRALLOCSIZ); - strncpy(tname, state->name, state->offset); - state->name = tname; - state->allocked = 1; - state->index = - afs_getsysname(areq, avc, state->name + state->offset); - return 1; - } else - return 0; /* .*@sys doesn't match either */ - } else if (++(state->index) >= afs_sysnamecount - || !afs_sysnamelist[(int)state->index]) - return 0; /* end of list */ - strcpy(state->name + state->offset, afs_sysnamelist[(int)state->index]); + register char *tname; + + /* Check for .*@sys */ + for (tname=state->name; *tname; tname++) + /*Move to the end of the string*/; + + if ((tname > state->name + 4) && (AFS_EQ_ATSYS(tname-4))) { + state->offset = (tname - 4) - state->name; + tname = (char *) osi_AllocLargeSpace(AFS_LRALLOCSIZ); + strncpy(tname, state->name, state->offset); + state->name = tname; + state->allocked = 1; + num = 0; + state->index = afs_getsysname(areq, avc, state->name+state->offset, + &num, sysnamelist); + return 1; + } else + return 0; /* .*@sys doesn't match either */ + } else { + register struct unixuser *au; + register afs_int32 error; + + *sysnamelist = afs_sysnamelist; + + if (afs_nfsexporter) { + au = afs_GetUser(areq->uid, avc->fid.Cell, 0); + if (au->exporter) { + error = EXP_SYSNAME(au->exporter, (char *)0, sysnamelist, num); + if (error) { + return 0; + } + } + afs_PutUser(au, 0); + } + if (++(state->index) >= num || !(*sysnamelist)[state->index]) + return 0; /* end of list */ + } + strcpy(state->name+state->offset, (*sysnamelist)[state->index]); return 1; } diff --git a/src/afs/afs_nfsclnt.c b/src/afs/afs_nfsclnt.c index c970f0ff3..b433dd241 100644 --- a/src/afs/afs_nfsclnt.c +++ b/src/afs/afs_nfsclnt.c @@ -298,24 +298,37 @@ afs_nfsclient_hold(np) /* if inname is non-null, a new system name value is set for the remote user (inname contains the new sysname). In all cases, outname returns the current sysname value for this remote user */ -int -afs_nfsclient_sysname(np, inname, outname) - register struct nfsclientpag *np; - char *inname, *outname; +int +afs_nfsclient_sysname(register struct nfsclientpag *np, char *inname, + char **outname[], int *num) { + char *cp; + int count, t; #if defined(AFS_SGIMP_ENV) osi_Assert(ISAFS_GLOCK()); #endif AFS_STATCNT(afs_nfsclient_sysname); if (inname) { - if (!np->sysname) { - np->sysname = afs_osi_Alloc(MAXSYSNAME); + if (np->sysname) { + for(count=0; count < np->sysnamecount;++count) { + afs_osi_Free(np->sysname[count], MAXSYSNAME); + } + } + for(count=0; count < *num;++count) { + np->sysname[count]= afs_osi_Alloc(MAXSYSNAME); + } + cp = inname; + for(count=0; count < *num;++count) { + t = strlen(cp); + memcpy(np->sysname[count], cp, t+1); /* include null */ + cp += t+1; } - strcpy(np->sysname, inname); + np->sysnamecount = *num; } else if (!np->sysname) { - return ENODEV; /* XXX */ + return ENODEV; /* XXX */ } - strcpy(outname, np->sysname); + *outname = np->sysname; + *num = np->sysnamecount; return 0; } diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index 05f5100a4..f4e77c0a9 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -2643,13 +2643,13 @@ DECL_PIOCTL(PGetVnodeXStatus) /* for the reader. */ DECL_PIOCTL(PSetSysName) { - char *cp, inname[MAXSYSNAME], outname[MAXSYSNAME]; + char *cp, *cp2, inname[MAXSYSNAME], outname[MAXSYSNAME]; int setsysname, foundname = 0; register struct afs_exporter *exporter; register struct unixuser *au; register afs_int32 pag, error; - int t, count; - + int t, count, num = 0; + char **sysnamelist[MAXSYSNAME]; AFS_STATCNT(PSetSysName); if (!afs_globalVFS) { @@ -2668,6 +2668,7 @@ DECL_PIOCTL(PSetSysName) /* Check my args */ if (setsysname < 0 || setsysname > MAXNUMSYSNAMES) return EINVAL; + cp2 = ain; for (cp = ain, count = 0; count < setsysname; count++) { /* won't go past end of ain since maxsysname*num < ain length */ t = strlen(cp); @@ -2680,10 +2681,11 @@ DECL_PIOCTL(PSetSysName) } /* args ok */ - /* inname gets first entry in case we're being a translater */ + /* inname gets first entry in case we're being a translator */ t = strlen(ain); memcpy(inname, ain, t + 1); /* include terminating null */ ain += t + 1; + num = count; } if ((*acred)->cr_gid == RMTUSER_REQ) { /* Handles all exporters */ pag = PagInCred(*acred); @@ -2697,7 +2699,8 @@ DECL_PIOCTL(PSetSysName) afs_PutUser(au, READ_LOCK); return EINVAL; /* Better than panicing */ } - error = EXP_SYSNAME(exporter, (setsysname ? inname : NULL), outname); + error = EXP_SYSNAME(exporter, (setsysname ? cp2 : NULL), sysnamelist, + &num); if (error) { if (error == ENODEV) foundname = 0; /* sysname not set yet! */ @@ -2705,17 +2708,19 @@ DECL_PIOCTL(PSetSysName) afs_PutUser(au, READ_LOCK); return error; } - } else - foundname = 1; + } else { + foundname = num; + strcpy(outname, (*sysnamelist)[0]); + } afs_PutUser(au, READ_LOCK); } else { - /* Not xlating, so local case */ if (!afs_sysname) osi_Panic("PSetSysName: !afs_sysname\n"); if (!setsysname) { /* user just wants the info */ strcpy(outname, afs_sysname); foundname = afs_sysnamecount; + *sysnamelist = afs_sysnamelist; } else { /* Local guy; only root can change sysname */ if (!afs_osi_suser(*acred)) return EACCES; @@ -2746,14 +2751,13 @@ DECL_PIOCTL(PSetSysName) strcpy(cp, outname); /* ... the entry, ... */ cp += strlen(outname) + 1; for (count = 1; count < foundname; ++count) { /* ... or list. */ - /* Note: we don't support @sys lists for exporters */ - if (!afs_sysnamelist[count]) + if (!(*sysnamelist)[count]) osi_Panic ("PSetSysName: no afs_sysnamelist entry to read\n"); - t = strlen(afs_sysnamelist[count]); + t = strlen((*sysnamelist)[count]); if (t >= MAXSYSNAME) osi_Panic("PSetSysName: sysname entry garbled\n"); - strcpy(cp, afs_sysnamelist[count]); + strcpy(cp, (*sysnamelist)[count]); cp += t + 1; } } diff --git a/src/afs/afs_prototypes.h b/src/afs/afs_prototypes.h index 07ae65aee..adaf96f02 100644 --- a/src/afs/afs_prototypes.h +++ b/src/afs/afs_prototypes.h @@ -950,9 +950,7 @@ extern int afs_TryEvalFakeStat(struct vcache **avcp, struct vrequest *areq); extern void afs_PutFakeStat(struct afs_fakestat_state *state); extern int afs_ENameOK(register char *aname); -extern int afs_getsysname(register struct vrequest *areq, - register struct vcache *adp, register char *bufp); -extern void Check_AtSys(register struct vcache *avc, const char *aname, +extern void Check_AtSys(register struct vcache *avc, char *aname, struct sysname_info *state, struct vrequest *areq); extern int Next_AtSys(register struct vcache *avc, struct vrequest *areq, struct sysname_info *state); diff --git a/src/afs/exporter.h b/src/afs/exporter.h index 79409c894..61371b46a 100644 --- a/src/afs/exporter.h +++ b/src/afs/exporter.h @@ -93,8 +93,8 @@ struct afs_exporter { (*(EXP)->exp_op->export_hold)(EXP) #define EXP_RELE(EXP) \ (*(EXP)->exp_op->export_rele)(EXP) -#define EXP_SYSNAME(EXP, INNAME, OUTNAME) \ - (*(EXP)->exp_op->export_sysname)(EXP, INNAME, OUTNAME) +#define EXP_SYSNAME(EXP, INNAME, OUTNAME, NUM) \ + (*(EXP)->exp_op->export_sysname)(EXP, INNAME, OUTNAME, NUM) #define EXP_GC(EXP, param) \ (*(EXP)->exp_op->export_garbagecollect)(EXP, param) #define EXP_STATISTICS(EXP) \ diff --git a/src/afs/nfsclient.h b/src/afs/nfsclient.h index 9d7df833b..0db9d3cda 100644 --- a/src/afs/nfsclient.h +++ b/src/afs/nfsclient.h @@ -28,7 +28,8 @@ struct nfsclientpag { afs_int32 uid; /* search based on uid and ... */ afs_int32 host; /* ... nfs client's host ip address */ afs_int32 pag; /* active pag for all (uid, host) "unpaged" conns */ - char *sysname; /* user's "@sys" value; also kept in unixuser */ + char *sysname[MAXNUMSYSNAMES];/* user's "@sys" value; also kept in unixuser */ + int sysnamecount; /* number of sysnames */ afs_int32 lastcall; /* Used for timing out nfsclientpag structs */ }; -- 2.39.5