sfsusrv
is an SFS file server implemented in
terms of the standard POSIX open/close/read/write calls.
sfsusrv
runs as a particular user, and lets that
particular user connect to it and access files. However, the
semantics of access control are wrong in sfsusrv
. For
example, if you don't have read permission on a file, you can still
open the file (even though a subsequent read will fail). Unix
semantics dictate that the open should fail.
% cd % tar xzvf ~class/src/sfsusrv.tar.gz % cd sfsusrv % sh ./setup + aclocal ... + set +x % setenv DEBUG -g % mkdir /home/c5/yourname % pushd /home/c5/yourname /home/c5/yourname ~/sfsusrv % =1/configure --with-sfs=/usr/local/fs/debug creating cache ./config.cache checking for a BSD compatible install... /usr/bin/install -c checking whether build environment is sane... yes ... creating Makefile creating config.h % gmake ...
% sfskey gen -P sfs_host_key Creating new key for sfs_host_key. Key Name: yourname@class5.scs.cs.nyu.edu Press returnYou must also create a configuration file for the server, called
sfsusrv_config
. Pick some directory to export (for
example /home/c1/scratch/yourname
, and create an
sfsusrv_config
file with the following contents:
KeyFile sfs_host_key Export /home/c1/scratch/yournameNext run
sfsusrv
. You must supply two arguments:
sfsusrv
as follows:
class1% mkdir /home/c1/scratch/export-$USER class1% echo hello > /home/c1/scratch/export-$USER/test.file class1% echo export /home/c1/scratch/export-$USER > sfsusrv_config class1% echo keyfile sfs_host_key >> sfsusrv_config class1% ./sfsusrv -p 4444 -f sfsusrv_config sfsusrv: version 0.0, pid 6273 sfsusrv: No sfssd detected, running in standalone mode. sfsusrv: Now exporting directory: /var/tmp sfsusrv: serving /sfs/4444@class1.scs.cs.nyu.edu:zm7g3qj632ymm8pvxsvyzf4a7upvqs7sThe last line that
sfsusrv
prints is the path name under
which your exported directory (/home/c1/scratch/export-$USER) will
appear on SFS client machines. Your path will be different from the
one printed above. The 4444 is the port number that
sfsusrv
is listening to. You can log into into a
different machine an access the files under
/sfs/4444@class1...
--pasting in whatever your actual
pathname is. Note you cannot access and SFS file
server running on the same machine as the client--you will get
Resource Deadlock Avoided errors.
class2% sfsagent Passphrase for /home/c/dm/.sfs/identity: class2% cd /sfs/4444@class1.scs.cs.nyu.edu:zm7g3qj632ymm8pvxsvyzf4a7upvqs7s sfsagent: sfsrwcd_1: class1.scs.cs.nyu.edu:zm7g3qj632ymm8pvxsvyzf4a7upvqs7s (1) class2% cat test.file hello class2%
class2% cd /sfs/4444@class1.scs.cs.nyu.edu:zm7g3qj632ymm8pvxsvyzf4a7upvqs7s class2% chmod 0 test.file class2% ls -l test.file ---------- 1 dm wheel 0 Nov 3 02:16 test.file class2% echo < test.file class2%Redirecting standard input to the echo command opens
test.file
for reading. However, the user does not have
read permission to test.file
. Thus, the open should
fail. Unfortunately, it doesn't. The reason is that
sfsusrv
does not implement NFSPROC3_ACCESS properly. If
you re-run sfsusrv with env ASRV_TRACE=10 ./sfsusrv -p 4444 -f
sfsusrv_config
(or ``set asrvtrace=10
'' inside
gdb), you will see something like the following:
sfsusrv: ASRV_TRACE: serve ex_nfs_program_3:ex_NFSPROC3_ACCESS x=3a5 i=1 access3args ARGS = { nfs_fh3 object = { opaque data%lt;64> = [10] { 85, d8, 01, 00, 00, 00, 00, 00, 00, 00 }; }; u_int32_t access = 0x1; }; sfsusrv: ASRV_TRACE: reply ex_nfs_program_3:ex_NFSPROC3_ACCESS x=3a5 ex_access3res REPLY = { nfsstat3 status = NFS3_OK; ex_access3resok resok = { ex_post_op_attr obj_attributes = { bool present = true; ex_fattr3 attributes = { ftype3 type = NF3REG; u_int32_t mode = 0x0; u_int32_t nlink = 0x1; u_int32_t uid = 0x42b; u_int32_t gid = 0x0; u_int64_t size = 0x0; u_int64_t used = 0x0; specdata3 rdev = { u_int32_t major = 0x0; u_int32_t minor = 0x0; }; u_int64_t fsid = 0x0; u_int64_t fileid = 0x1d885; nfstime3 atime = { u_int32_t seconds = 0x3be399bb; u_int32_t nseconds = 0x0; }; nfstime3 mtime = { u_int32_t seconds = 0x3be399bb; u_int32_t nseconds = 0x0; }; nfstime3 ctime = { u_int32_t seconds = 0x3be399c0; u_int32_t nseconds = 0x0; }; u_int32_t expire = 0x0; }; }; u_int32_t access = 0x1; }; };(Recall from the NFSPROC3_ACCESS section of RFC 1813 that 0x1 is ACCESS3_READ.)
The problem here is that the function
client::access_check
(in cliend.C) has not been
implemented yet, and always returns what has been requested. Your
task will be to implement this function.
myuid
, mygid
,
mygroups
, and myngroups
respectively.
(myngroups
is the number of groups pointed to by
mygroups
--it might be zero if the gid is the process's
only group.) You will want to compare these values to the uid and gid
in the file's attribute structure.
drwxrwxrwt
--you can treat them like
drwxrwxrwx
).
access_req
argument to
client::access_check
, any value X you return must
have no bits set that are not set in access_req
(i.e.,
X==(access_req&
X)
must hold).
gmake
distcheck
. Copy sfsusrv-0.0.tar.gz
and a
typescript
file of your testing (on the client side) to
~class/handin/lab4/username
.
~class/src/sfs1/svc/nfs3_prot.x
--
NFS3 protocol spec in XDR format. (Note that this file is slightly
simplified from the RFC 1813 syntax, but generates the same wire
protocol.)
man 2 intro
]. See especially the
paragraphs on ``File Access Permissions''.
getuid
manual page [man 2 getuid
]
getgid
manual page [man 2 getgid
]
getgroups
manual page [man 2 getgroups
]