From dae0bfcfec35817e166ca0614560d23b8778ec17 Mon Sep 17 00:00:00 2001 From: Adam Marcionek Date: Wed, 2 Jan 2019 10:54:41 -0500 Subject: [PATCH] Added Subject to access method Access method should check against the caller's RPC credentials. Addresses #71. --- .../java/org/dcache/nfs/v3/NfsServerV3.java | 149 +++--------------- .../org/dcache/nfs/v4/OperationACCESS.java | 2 +- .../java/org/dcache/nfs/v4/OperationOPEN.java | 4 +- .../dcache/nfs/vfs/ForwardingFileSystem.java | 5 + .../org/dcache/nfs/vfs/VirtualFileSystem.java | 13 ++ 5 files changed, 43 insertions(+), 130 deletions(-) diff --git a/core/src/main/java/org/dcache/nfs/v3/NfsServerV3.java b/core/src/main/java/org/dcache/nfs/v3/NfsServerV3.java index 294f29af9..755d2ea0a 100644 --- a/core/src/main/java/org/dcache/nfs/v3/NfsServerV3.java +++ b/core/src/main/java/org/dcache/nfs/v3/NfsServerV3.java @@ -19,141 +19,36 @@ */ package org.dcache.nfs.v3; +import static org.dcache.nfs.v3.HimeraNfsUtils.defaultPostOpAttr; +import static org.dcache.nfs.v3.HimeraNfsUtils.defaultWccData; +import static org.dcache.nfs.v3.NameUtils.checkFilename; + +import java.util.Iterator; + +import javax.security.auth.Subject; + import org.dcache.auth.Subjects; +import org.dcache.nfs.ChimeraNFSException; import org.dcache.nfs.ExportFile; import org.dcache.nfs.nfsstat; -import org.dcache.nfs.ChimeraNFSException; -import org.dcache.nfs.v3.xdr.LOOKUP3res; -import org.dcache.nfs.v3.xdr.WRITE3resfail; -import org.dcache.nfs.v3.xdr.RMDIR3resok; -import org.dcache.nfs.v3.xdr.SYMLINK3resfail; -import org.dcache.nfs.v3.xdr.post_op_fh3; -import org.dcache.nfs.v3.xdr.READLINK3args; -import org.dcache.nfs.v3.xdr.uint64; -import org.dcache.nfs.v3.xdr.MKDIR3res; -import org.dcache.nfs.v3.xdr.WRITE3args; -import org.dcache.nfs.v3.xdr.createmode3; -import org.dcache.nfs.v3.xdr.post_op_attr; -import org.dcache.nfs.v3.xdr.LINK3resfail; -import org.dcache.nfs.v3.xdr.READ3resfail; -import org.dcache.nfs.v3.xdr.MKDIR3resok; -import org.dcache.nfs.v3.xdr.READDIR3args; -import org.dcache.nfs.v3.xdr.LOOKUP3resfail; -import org.dcache.nfs.v3.xdr.dirlistplus3; -import org.dcache.nfs.v3.xdr.SYMLINK3resok; -import org.dcache.nfs.v3.xdr.READDIR3resok; -import org.dcache.nfs.v3.xdr.entry3; -import org.dcache.nfs.v3.xdr.READ3args; -import org.dcache.nfs.v3.xdr.LOOKUP3args; -import org.dcache.nfs.v3.xdr.PATHCONF3res; -import org.dcache.nfs.v3.xdr.LINK3args; -import org.dcache.nfs.v3.xdr.REMOVE3res; -import org.dcache.nfs.v3.xdr.READ3resok; -import org.dcache.nfs.v3.xdr.sattr3; -import org.dcache.nfs.v3.xdr.count3; -import org.dcache.nfs.v3.xdr.MKNOD3args; -import org.dcache.nfs.v3.xdr.READ3res; -import org.dcache.nfs.v3.xdr.READLINK3resok; -import org.dcache.nfs.v3.xdr.cookie3; -import org.dcache.nfs.v3.xdr.LOOKUP3resok; -import org.dcache.nfs.v3.xdr.READDIR3resfail; -import org.dcache.nfs.v3.xdr.RMDIR3res; -import org.dcache.nfs.v3.xdr.RMDIR3resfail; -import org.dcache.nfs.v3.xdr.WRITE3resok; -import org.dcache.nfs.v3.xdr.REMOVE3resfail; -import org.dcache.nfs.v3.xdr.WRITE3res; -import org.dcache.nfs.v3.xdr.wcc_data; -import org.dcache.nfs.v3.xdr.nfs3_prot; -import org.dcache.nfs.v3.xdr.MKDIR3resfail; -import org.dcache.nfs.v3.xdr.RENAME3resok; -import org.dcache.nfs.v3.xdr.dirlist3; -import org.dcache.nfs.v3.xdr.READDIRPLUS3args; -import org.dcache.nfs.v3.xdr.MKDIR3args; -import org.dcache.nfs.v3.xdr.fattr3; -import org.dcache.nfs.v3.xdr.MKNOD3res; -import org.dcache.nfs.v3.xdr.fileid3; -import org.dcache.nfs.v3.xdr.SETATTR3resfail; -import org.dcache.nfs.v3.xdr.uint32; -import org.dcache.nfs.v3.xdr.entryplus3; -import org.dcache.nfs.v3.xdr.pre_op_attr; -import org.dcache.nfs.v3.xdr.SETATTR3args; -import org.dcache.nfs.v3.xdr.SYMLINK3res; -import org.dcache.nfs.v3.xdr.PATHCONF3args; -import org.dcache.nfs.v3.xdr.writeverf3; -import org.dcache.nfs.v3.xdr.RENAME3args; -import org.dcache.nfs.v3.xdr.SYMLINK3args; -import org.dcache.nfs.v3.xdr.READDIRPLUS3resfail; -import org.dcache.nfs.v3.xdr.nfs_fh3; -import org.dcache.nfs.v3.xdr.REMOVE3resok; -import org.dcache.nfs.v3.xdr.READLINK3res; -import org.dcache.nfs.v3.xdr.RENAME3res; -import org.dcache.nfs.v3.xdr.RMDIR3args; -import org.dcache.nfs.v3.xdr.READDIRPLUS3resok; -import org.dcache.nfs.v3.xdr.cookieverf3; -import org.dcache.nfs.v3.xdr.nfs3_protServerStub; -import org.dcache.nfs.v3.xdr.READDIRPLUS3res; -import org.dcache.nfs.v3.xdr.nfstime3; -import org.dcache.nfs.v3.xdr.LINK3resok; -import org.dcache.nfs.v3.xdr.size3; -import org.dcache.nfs.v3.xdr.REMOVE3args; -import org.dcache.nfs.v3.xdr.wcc_attr; -import org.dcache.nfs.v3.xdr.SETATTR3res; -import org.dcache.nfs.v3.xdr.LINK3res; -import org.dcache.nfs.v3.xdr.SETATTR3resok; -import org.dcache.nfs.v3.xdr.READDIR3res; -import org.dcache.nfs.v3.xdr.PATHCONF3resok; -import org.dcache.nfs.v3.xdr.nfspath3; -import org.dcache.nfs.v3.xdr.filename3; -import org.dcache.nfs.v3.xdr.FSINFO3res; -import org.dcache.nfs.v3.xdr.GETATTR3resok; -import org.dcache.nfs.v3.xdr.CREATE3args; -import org.dcache.nfs.v3.xdr.CREATE3resok; -import org.dcache.nfs.v3.xdr.FSSTAT3args; -import org.dcache.nfs.v3.xdr.FSSTAT3resok; -import org.dcache.nfs.v3.xdr.FSINFO3args; -import org.dcache.nfs.v3.xdr.CREATE3res; -import org.dcache.nfs.v3.xdr.GETATTR3args; -import org.dcache.nfs.v3.xdr.ACCESS3resfail; -import org.dcache.nfs.v3.xdr.GETATTR3res; -import org.dcache.nfs.v3.xdr.COMMIT3res; -import org.dcache.nfs.v3.xdr.FSINFO3resok; -import org.dcache.nfs.v3.xdr.ACCESS3resok; -import org.dcache.nfs.v3.xdr.FSSTAT3res; -import org.dcache.nfs.v3.xdr.COMMIT3args; -import org.dcache.nfs.v3.xdr.ACCESS3args; -import org.dcache.nfs.v3.xdr.CREATE3resfail; -import org.dcache.nfs.v3.xdr.FSINFO3resfail; -import org.dcache.nfs.v3.xdr.ACCESS3res; -import org.dcache.nfs.v3.xdr.COMMIT3resok; -import java.io.IOException; -import java.util.Iterator; - -import org.dcache.nfs.v3.xdr.COMMIT3resfail; -import org.dcache.nfs.v3.xdr.FSSTAT3resfail; -import org.dcache.nfs.v3.xdr.MKNOD3resfail; -import org.dcache.nfs.v3.xdr.READLINK3resfail; -import org.dcache.nfs.v3.xdr.RENAME3resfail; +import org.dcache.nfs.status.ExistException; +import org.dcache.nfs.status.NfsIoException; +import org.dcache.nfs.status.NoEntException; +import org.dcache.nfs.status.NotDirException; +import org.dcache.nfs.status.TooSmallException; +import org.dcache.nfs.v3.xdr.*; import org.dcache.nfs.vfs.DirectoryEntry; -import org.dcache.nfs.vfs.VirtualFileSystem; +import org.dcache.nfs.vfs.DirectoryStream; +import org.dcache.nfs.vfs.FsStat; +import org.dcache.nfs.vfs.Inode; +import org.dcache.nfs.vfs.PseudoFs; import org.dcache.nfs.vfs.Stat; -import org.dcache.nfs.status.*; -import org.dcache.oncrpc4j.util.Bytes; -import org.dcache.oncrpc4j.rpc.OncRpcException; +import org.dcache.nfs.vfs.VirtualFileSystem; import org.dcache.oncrpc4j.rpc.RpcCall; +import org.dcache.oncrpc4j.util.Bytes; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import static org.dcache.nfs.v3.HimeraNfsUtils.defaultPostOpAttr; -import static org.dcache.nfs.v3.HimeraNfsUtils.defaultWccData; -import static org.dcache.nfs.v3.NameUtils.checkFilename; - -import org.dcache.nfs.vfs.FsStat; -import org.dcache.nfs.vfs.Inode; -import org.dcache.nfs.vfs.PseudoFs; -import org.dcache.nfs.vfs.DirectoryStream; - -import javax.security.auth.Subject; - public class NfsServerV3 extends nfs3_protServerStub { // needed to calculate replay size for READDIR3 and READDIRPLUS3 @@ -201,7 +96,7 @@ public ACCESS3res NFSPROC3_ACCESS_3(RpcCall call$, ACCESS3args arg1) { HimeraNfsUtils.fill_attributes(objStat, res.resok.obj_attributes.attributes); - int realAccess = fs.access(inode, arg1.access.value); + int realAccess = fs.access(inode, arg1.access.value, call$.getCredential().getSubject()); res.resok.access = new uint32(realAccess); } catch (ChimeraNFSException hne) { diff --git a/core/src/main/java/org/dcache/nfs/v4/OperationACCESS.java b/core/src/main/java/org/dcache/nfs/v4/OperationACCESS.java index dba54c0eb..f3b19e30c 100644 --- a/core/src/main/java/org/dcache/nfs/v4/OperationACCESS.java +++ b/core/src/main/java/org/dcache/nfs/v4/OperationACCESS.java @@ -46,7 +46,7 @@ public void process(CompoundContext context, nfs_resop4 result) final ACCESS4res res = result.opaccess; int requestedAccess = _args.opaccess.access.value; - int realAccess = context.getFs().access(context.currentInode(), requestedAccess); + int realAccess = context.getFs().access(context.currentInode(), requestedAccess, context.getSubject()); _log.debug("NFS Request ACCESS uid: {} {} {}", context.getSubject(), requestedAccess, realAccess ); diff --git a/core/src/main/java/org/dcache/nfs/v4/OperationOPEN.java b/core/src/main/java/org/dcache/nfs/v4/OperationOPEN.java index 31a3ce90d..181d6da95 100644 --- a/core/src/main/java/org/dcache/nfs/v4/OperationOPEN.java +++ b/core/src/main/java/org/dcache/nfs/v4/OperationOPEN.java @@ -183,7 +183,7 @@ public void process(CompoundContext context, nfs_resop4 result) throws ChimeraNF Integer.toOctalString(fileStat.getMode() & 0777)); } - if (context.getFs().access(inode, nfs4_prot.ACCESS4_MODIFY) == 0) { + if (context.getFs().access(inode, nfs4_prot.ACCESS4_MODIFY, context.getSubject()) == 0) { throw new AccessException(); } @@ -296,7 +296,7 @@ private void checkCanAccess(CompoundContext context, Inode inode, uint32_t share throw new InvalException("Invalid share_access mode: " + share_access.value); } - if (context.getFs().access(inode, accessMode) != accessMode) { + if (context.getFs().access(inode, accessMode, context.getSubject()) != accessMode) { throw new AccessException(); } diff --git a/core/src/main/java/org/dcache/nfs/vfs/ForwardingFileSystem.java b/core/src/main/java/org/dcache/nfs/vfs/ForwardingFileSystem.java index 4f968e55b..d0a1a2447 100644 --- a/core/src/main/java/org/dcache/nfs/vfs/ForwardingFileSystem.java +++ b/core/src/main/java/org/dcache/nfs/vfs/ForwardingFileSystem.java @@ -45,6 +45,11 @@ public int access(Inode inode, int mode) throws IOException { return delegate().access(inode, mode); } + @Override + public int access(Inode inode, int mode, Subject subject) throws IOException { + return delegate().access(inode, mode, subject); + } + @Override public Inode create(Inode parent, Stat.Type type, String path, Subject subject, int mode) throws IOException { return delegate().create(parent, type, path, subject, mode); diff --git a/core/src/main/java/org/dcache/nfs/vfs/VirtualFileSystem.java b/core/src/main/java/org/dcache/nfs/vfs/VirtualFileSystem.java index b59d6d7e8..25a219b06 100644 --- a/core/src/main/java/org/dcache/nfs/vfs/VirtualFileSystem.java +++ b/core/src/main/java/org/dcache/nfs/vfs/VirtualFileSystem.java @@ -52,9 +52,22 @@ public interface VirtualFileSystem { * @param mode a mask of permission bits to check. * @return an allowed subset of permissions from the given mask. * @throws IOException + * @deprecated Replaced by {@link #access(Inode, int, Subject)} */ + @Deprecated int access(Inode inode, int mode) throws IOException; + /** + * Check access to file system object. + * + * @param inode inode of the object to check. + * @param mode a mask of permission bits to check. + * @param subject the user subject making the request. + * @return an allowed subset of permissions from the given mask. + * @throws IOException + */ + int access(Inode inode, int mode, Subject subject) throws IOException; + /** * Create a new object in a given directory with a specific name. *