X-Git-Url: https://git.openafs.org/?p=openafs.git;a=blobdiff_plain;f=src%2Fafs%2Fafs_pioctl.c;h=2044147c559cca0969f3ce07187ef2b01fffeff5;hp=b48eca12beaf71a2455737a6efaa75f7f6d01030;hb=54b7292a4499106f956a4449c620466f64303498;hpb=a35279d3146688498bfabec9957a5fd47d6246de diff --git a/src/afs/afs_pioctl.c b/src/afs/afs_pioctl.c index b48eca1..2044147 100644 --- a/src/afs/afs_pioctl.c +++ b/src/afs/afs_pioctl.c @@ -44,6 +44,7 @@ extern afs_rwlock_t afs_xcbhash; extern afs_int32 afs_mariner, afs_marinerHost; extern struct srvAddr *afs_srvAddrs[NSERVERS]; extern int afs_resourceinit_flag; +extern afs_int32 cryptall; static int PBogus(), PSetAcl(), PGetAcl(), PSetTokens(), PGetVolumeStatus(); static int PSetVolumeStatus(), PFlush(), PNewStatMount(), PGetTokens(), PUnlog(); @@ -59,6 +60,8 @@ static int PSetSPrefs(), PGetSPrefs(), PGag(), PTwiddleRx(); static int PSetSPrefs33(), PStoreBehind(), PGCPAGs(); static int PGetCPrefs(), PSetCPrefs(); /* client network addresses */ static int PGetInitParams(), PFlushMount(), PRxStatProc(), PRxStatPeer(); +static int PGetRxkcrypt(), PSetRxkcrypt(); +static int PPrefetchFromTape(), PResidencyCmd(); int PExportAfs(); static int HandleClientContext(struct afs_ioctl *ablob, int *com, struct AFS_UCRED **acred, struct AFS_UCRED *credp); @@ -121,6 +124,19 @@ static int (*(pioctlSw[]))() = { PFlushMount, /* 52 - flush mount symlink data */ PRxStatProc, /* 53 - control process RX statistics */ PRxStatPeer, /* 54 - control peer RX statistics */ + PGetRxkcrypt, /* 55 -- Get rxkad encryption flag */ + PSetRxkcrypt, /* 56 -- Set rxkad encryption flag */ + PNoop, /* 57 -- arla: set file prio */ + PNoop, /* 58 -- arla: fallback getfh */ + PNoop, /* 59 -- arla: fallback fhopen */ + PNoop, /* 60 -- arla: controls xfsdebug */ + PNoop, /* 61 -- arla: controls arla debug */ + PNoop, /* 62 -- arla: debug interface */ + PNoop, /* 63 -- arla: print xfs status */ + PNoop, /* 64 -- arla: force cache check */ + PNoop, /* 65 -- arla: break callback */ + PPrefetchFromTape, /* 66 -- MR-AFS: prefetch file from tape */ + PResidencyCmd, /* 67 -- MR-AFS: generic commnd interface */ }; #define PSetClientContext 99 /* Special pioctl to setup caller's creds */ @@ -180,6 +196,21 @@ copyin_afs_ioctl(caddr_t cmarg, struct afs_ioctl *dst) } #endif /* defined(AFS_SGI_ENV) && (_MIPS_SZLONG==64) */ +#if defined(AFS_LINUX_64BIT_KERNEL) + struct afs_ioctl32 dst32; + +#ifdef AFS_SPARC64_LINUX20_ENV + if (current->tss.flags & SPARC_FLAG_32BIT) { +#else +#error Not done for this linux type +#endif + AFS_COPYIN(cmarg, (caddr_t) &dst32, sizeof dst32, code); + if (!code) + afs_ioctl32_to_afs_ioctl(&dst32, dst); + return code; + } +#endif /* defined(AFS_LINUX_64BIT_KERNEL) */ + AFS_COPYIN(cmarg, (caddr_t) dst, sizeof *dst, code); return code; } @@ -1471,10 +1502,16 @@ static PSetVolumeStatus(avc, afun, areq, ain, aout, ainSize, aoutSize) cp = ain; bcopy(cp, (char *)&volstat, sizeof(AFSFetchVolumeStatus)); cp += sizeof(AFSFetchVolumeStatus); + if (strlen(cp) >= sizeof(volName)) + return E2BIG; strcpy(volName, cp); cp += strlen(volName)+1; + if (strlen(cp) >= sizeof(offLineMsg)) + return E2BIG; strcpy(offLineMsg, cp); cp += strlen(offLineMsg)+1; + if (strlen(cp) >= sizeof(motd)) + return E2BIG; strcpy(motd, cp); storeStat.Mask = 0; if (volstat.MinQuota != -1) { @@ -3106,6 +3143,46 @@ static cred_t *crget(void) return cr; } #endif + +static int +PGetRxkcrypt(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) +struct vcache *avc; +int afun; +struct vrequest *areq; +char *ain, *aout; +afs_int32 ainSize; +afs_int32 *aoutSize; +struct AFS_UCRED *acred; +{ + bcopy((char *)&cryptall, aout, sizeof(afs_int32)); + *aoutSize=sizeof(afs_int32); + return 0; +} + +static int +PSetRxkcrypt(avc, afun, areq, ain, aout, ainSize, aoutSize, acred) +struct vcache *avc; +int afun; +struct vrequest *areq; +char *ain, *aout; +afs_int32 ainSize; +afs_int32 *aoutSize; +struct AFS_UCRED *acred; +{ + afs_int32 tmpval; + + if (!afs_osi_suser(acred)) + return EPERM; + if (ainSize != sizeof(afs_int32) || ain == NULL) + return EINVAL; + bcopy(ain, (char *)&tmpval, sizeof(afs_int32)); + /* if new mappings added later this will need to be changed */ + if (tmpval != 0 && tmpval != 1) + return EINVAL; + cryptall = tmpval; + return 0; +} + /* * Create new credentials to correspond to a remote user with given * . This allows a server running as root to @@ -3318,8 +3395,10 @@ afs_int32 *aoutSize; if ( ainSize < sizeof(struct setspref) ) return EINVAL; +#if 0 /* num_servers is unsigned */ if ( sin->num_servers < 0 ) return EINVAL; +#endif if ( sin->num_servers > AFS_MAX_INTERFACE_ADDR) return ENOMEM; @@ -3485,3 +3564,163 @@ out: return code; } +static PPrefetchFromTape(avc, afun, areq, ain, aout, ainSize, aoutSize) + struct vcache *avc; + int afun; + struct vrequest *areq; + char *ain, *aout; + afs_int32 ainSize; + afs_int32 *aoutSize; /* set this */ +{ + register afs_int32 code, code1; + afs_int32 bytes; + struct conn *tc; + struct rx_call *tcall; + struct AFSVolSync tsync; + struct AFSFetchStatus OutStatus; + struct AFSCallBack CallBack; + struct VenusFid tfid; + struct AFSFid *Fid; + struct vcache *tvc; + XSTATS_DECLS; + + AFS_STATCNT(PSetAcl); + if (!avc) + return EINVAL; + + if (ain && (ainSize == 3 * sizeof(afs_int32))) + Fid = (struct AFSFid *) ain; + else + Fid = &avc->fid.Fid; + tfid.Cell = avc->fid.Cell; + tfid.Fid.Volume = Fid->Volume; + tfid.Fid.Vnode = Fid->Vnode; + tfid.Fid.Unique = Fid->Unique; + + tvc = afs_GetVCache(&tfid, areq, (afs_int32 *)0, (struct vcache *)0, + WRITE_LOCK); + if (!tvc) { + afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD, + ICL_TYPE_POINTER, tvc, + ICL_TYPE_FID, &tfid, + ICL_TYPE_FID, &avc->fid); + return ENOENT; + } + afs_Trace3(afs_iclSetp, CM_TRACE_PREFETCHCMD, + ICL_TYPE_POINTER, tvc, + ICL_TYPE_FID, &tfid, + ICL_TYPE_FID, &tvc->fid); + + do { + tc = afs_Conn(&tvc->fid, areq, SHARED_LOCK); + if (tc) { + +#ifdef RX_ENABLE_LOCKS + AFS_GUNLOCK(); +#endif /* RX_ENABLE_LOCKS */ + tcall = rx_NewCall(tc->id); + code = StartRXAFS_FetchData(tcall, + (struct AFSFid *) &tvc->fid.Fid, 0, 0); + if (!code) { + bytes = rx_Read(tcall, (char *) aout, sizeof(afs_int32)); + code = EndRXAFS_FetchData(tcall, &OutStatus, &CallBack, &tsync); + } + code1 = rx_EndCall(tcall, code); +#ifdef RX_ENABLE_LOCKS + AFS_GLOCK(); +#endif /* RX_ENABLE_LOCKS */ + } else + code = -1; + } while + (afs_Analyze(tc, code, &tvc->fid, areq, + AFS_STATS_FS_RPCIDX_RESIDENCYRPCS, SHARED_LOCK, + (struct cell *)0)); + /* This call is done only to have the callback things handled correctly */ + afs_FetchStatus(tvc, &tfid, areq, &OutStatus); + afs_PutVCache(tvc, WRITE_LOCK); + + if (!code) { + *aoutSize = sizeof(afs_int32); + } + return code; +} + +static PResidencyCmd(avc, afun, areq, ain, aout, ainSize, aoutSize) +struct vcache *avc; +int afun; +struct vrequest *areq; +char *ain, *aout; +afs_int32 ainSize; +afs_int32 *aoutSize; /* set this */ +{ + register afs_int32 code; + struct conn *tc; + struct vcache *tvc; + struct ResidencyCmdInputs *Inputs; + struct ResidencyCmdOutputs *Outputs; + struct VenusFid tfid; + struct AFSFid *Fid; + + Inputs = (struct ResidencyCmdInputs *) ain; + Outputs = (struct ResidencyCmdOutputs *) aout; + if (!avc) return EINVAL; + if (!ain || ainSize != sizeof(struct ResidencyCmdInputs)) return EINVAL; + + Fid = &Inputs->fid; + if (!Fid->Volume) + Fid = &avc->fid.Fid; + + tfid.Cell = avc->fid.Cell; + tfid.Fid.Volume = Fid->Volume; + tfid.Fid.Vnode = Fid->Vnode; + tfid.Fid.Unique = Fid->Unique; + + tvc = afs_GetVCache(&tfid, areq, (afs_int32 *)0, (struct vcache *)0, + WRITE_LOCK); + afs_Trace3(afs_iclSetp, CM_TRACE_RESIDCMD, + ICL_TYPE_POINTER, tvc, + ICL_TYPE_INT32, Inputs->command, + ICL_TYPE_FID, &tfid); + if (!tvc) + return ENOENT; + + if (Inputs->command) { + do { + tc = afs_Conn(&tvc->fid, areq, SHARED_LOCK); + if (tc) { +#ifdef RX_ENABLE_LOCKS + AFS_GUNLOCK(); +#endif /* RX_ENABLE_LOCKS */ + code = RXAFS_ResidencyCmd(tc->id, Fid, + Inputs, + (struct ResidencyCmdOutputs *) aout); +#ifdef RX_ENABLE_LOCKS + AFS_GLOCK(); +#endif /* RX_ENABLE_LOCKS */ + } else + code = -1; + } while + (afs_Analyze(tc, code, &tvc->fid, areq, + AFS_STATS_FS_RPCIDX_RESIDENCYRPCS, SHARED_LOCK, + (struct cell *)0)); + /* This call is done to have the callback things handled correctly */ + afs_FetchStatus(tvc, &tfid, areq, &Outputs->status); + } else { /* just a status request, return also link data */ + code = 0; + Outputs->code = afs_FetchStatus(tvc, &tfid, areq, &Outputs->status); + Outputs->chars[0] = 0; + if (vType(tvc) == VLNK) { + ObtainWriteLock(&tvc->lock,555); + if (afs_HandleLink(tvc, areq) == 0) + strncpy((char *) &Outputs->chars, tvc->linkData, MAXCMDCHARS); + ReleaseWriteLock(&tvc->lock); + } + } + + afs_PutVCache(tvc, WRITE_LOCK); + + if (!code) { + *aoutSize = sizeof(struct ResidencyCmdOutputs); + } + return code; +}