예제 #1
0
 def handle_1(self, data, cred):
     # STUB
     log_cb.info("*" * 20)
     log_cb.info("Handling CB_COMPOUND")
     p = nfs4lib.FancyNFS4Packer()
     res = CB_COMPOUND4res(NFS4ERR_BACK_CHAN_BUSY, "STUB CB_REPLY", [])
     p.pack_CB_COMPOUND4res(res)
     return rpc.SUCCESS, p.get_buffer()
예제 #2
0
파일: nfs4server.py 프로젝트: wzugang/pynfs
 def __init__(self, rootfh, host, port, pubfh = None):
     rpc.RPCServer.__init__(self, prog=NFS4_PROGRAM, vers=NFS_V4,
                            host=host, port=port)
     self.nfs4packer = nfs4lib.FancyNFS4Packer()
     self.nfs4unpacker = nfs4lib.FancyNFS4Unpacker('')
     self.state = nfs4state.NFSServerState(rootfh)
     self.fhcache = {}
     self.rootfh = rootfh
     self.pubfh = pubfh
     self.verfnum = 0
예제 #3
0
파일: nfs4server.py 프로젝트: wzugang/pynfs
 def check_replay(self, op, replay):
     """Pull appropriate info for a replay attempt"""
     fh, args, oldop = replay
     p = nfs4lib.FancyNFS4Packer()
     p.pack_nfs_argop4(op)
     newstr = p.get_buffer()
     p.reset()
     p.pack_nfs_argop4(oldop)
     oldstr = p.get_buffer()
     if oldstr == newstr: # Sadly, op == oldop won't work
         return (fh, args)
     else:
         return (None, (NFS4ERR_BAD_SEQID,))
예제 #4
0
 def set_ssv(self, ssv=None, *args, **kwargs):
     protect = self.client.protect
     if ssv is None:
         ssv = nfs4lib.random_string(protect.context.ssv_len)
     if "credinfo" not in kwargs:
         kwargs["credinfo"] = self.cred
     seq_op = self.seq_op(kwargs.pop("slot", None))
     p = nfs4lib.FancyNFS4Packer()
     p.pack_SEQUENCE4args(seq_op.opsequence)
     digest =  protect.context.hmac(p.get_buffer(), SSV4_SUBKEY_MIC_I2T)
     ssv_op = op4.set_ssv(ssv, digest)
     res = self.c.compound([seq_op, ssv_op], *args, **kwargs)
     # STUB - do some checking
     protect.context.set_ssv(ssv)
     return res
예제 #5
0
 def handle_1(self, data, cred):
     log_cb.info("*" * 20)
     log_cb.info("Handling COMPOUND")
     # data is an XDR packed string.  Unpack it.
     unpacker = nfs4lib.FancyNFS4Unpacker(data)
     try:
         args = unpacker.unpack_CB_COMPOUND4args()
         unpacker.done()
     except:
         log_cb.warn("returning GARBAGE_ARGS")
         log_cb.debug("unpacking raised the following error", exc_info=True)
         return rpc.GARBAGE_ARGS, None
     log_cb.debug(repr(args))
     try:
         # SEQUENCE needs to know size of request
         args.req_size = len(data)
         # Handle the request
         env = self.op_cb_compound(args, cred)
         log_cb.info(repr(env.results.reply.results))
         # Pack the results back into an XDR string
         p = nfs4lib.FancyNFS4Packer()
         p.pack_CB_COMPOUND4res(
             CB_COMPOUND4res(env.results.reply.status,
                             env.results.reply.tag,
                             env.results.reply.results))
         data = p.get_buffer()
         # Stuff the replay cache
         if env.cache is not None:
             p.reset()
             p.pack_CB_COMPOUND4res(
                 CB_COMPOUND4res(env.results.cache.status,
                                 env.results.cache.tag,
                                 env.results.cache.results))
             env.cache.data = p.get_buffer()
             env.cache.valid.set()
     except NFS4Replay as e:
         log_cb.info("Replay...waiting for valid data")
         e.cache.valid.wait()
         log_cb.info("Replay...sending data")
         data = e.cache.data
     return rpc.SUCCESS, data, getattr(env, "notify", None)
예제 #6
0
 def handle_1(self, data, cred, callback=False):
     """COMPOUND procedure"""
     log.debug("*" * 40)
     if callback:
         log.debug("** CALLBACK **")
     log.debug("Handling COMPOUND")
     # stage 1: data in XDR as received from the client
     unpacker = nfs4lib.FancyNFS4Unpacker(data)
     if callback:
         args = unpacker.unpack_CB_COMPOUNDargs()
     else:
         args = unpacker.unpack_COMPOUND4args()
     log.debug("Client sent:")
     log.debug(repr(args))
     unpacker.done()
     # stage 2: pre-processing - data in COMPOUND4args
     # XXX: check operation, alter stuff, delay etc. etc.
     args.req_size = len(data)  # BUG, need to use cred.payload_size
     if callback:
         env = CBCompoundState(args, cred)
     else:
         env = CompoundState(args, cred)
     for arg in args.argarray:
         env.index += 1
         opname = nfs_opnum4.get(arg.argop, 'op_illegal')
         log.info("*** %s (%d) ***" % (opname, arg.argop))
         # look for functions implemented by the proxy
         # that override communication
         funct = getattr(self, opname.lower(), None)
         if funct is not None and callable(funct):
             try:
                 result = funct(arg, cred, direction=0)
             except Exception:
                 log.error("Function override %s failed" % opname.lower())
         # handle error condition if specified
         error = None
         if self.errorhandler is not None:
             error = self.errorhandler.get_error(opname.lower()[3:], arg,
                                                 env)
         if error is not None:
             result = encode_status_by_name(opname.lower()[3:],
                                            int(error),
                                            msg="Proxy Rewrite Error")
             env.results.append(result)
             p = nfs4lib.FancyNFS4Packer()
             if callback:
                 res = CB_COMPOUND4res(env.results.reply.status,
                                       env.results.reply.tag,
                                       env.results.reply.results)
                 p.pack_CB_COMPOUND4res(res)
             else:
                 res = COMPOUND4res(env.results.reply.status,
                                    env.results.reply.tag,
                                    env.results.reply.results)
                 p.pack_COMPOUND4res(res)
             log.info(repr(res))
             reply = p.get_buffer()
             return rpc.SUCCESS, reply
     #stage 3: repack the data and forward to server
     packer = nfs4lib.FancyNFS4Packer()
     if callback:
         packer.pack_CB_COMPOUND4args(args)
     else:
         packer.pack_COMPOUND4args(args)
     log.debug("Proxy sent:")
     log.debug(repr(args))
     calldata = packer.get_buffer()
     try:
         ret_data = self.forward_call(calldata, callback)
     except rpc.RPCTimeout:
         log.critical("Error: cannot connect to destination server")
         return rpc.GARBAGE_ARGS, None
     # stage 4: data in XDR as returned by the server
     unpacker = nfs4lib.FancyNFS4Unpacker(ret_data)
     if callback:
         res = unpacker.unpack_CB_COMPOUND4res()
     else:
         res = unpacker.unpack_COMPOUND4res()
     log.debug("Server returned:")
     log.debug(repr(res))
     unpacker.done()
     # stage 5: post-processing - data in COMPOUND4res
     # XXX: check operation etc.
     for arg in res.resarray:
         opname = nfs_opnum4.get(arg.resop, 'op_illegal')
         log.info("*** %s (%d) ***" % (opname, arg.resop))
         # look for functions implemented by the proxy
         # that override communication
         funct = getattr(self, opname.lower(), None)
         if funct is not None and callable(funct):
             try:
                 result = funct(arg, cred, direction=1)
             except Exception:
                 log.error("Function override %s failed" % opname.lower())
     # state 6: repack and return XDR data to client
     packer = nfs4lib.FancyNFS4Packer()
     if callback:
         packer.pack_CB_COMPOUND4res(res)
     else:
         packer.pack_COMPOUND4res(res)
     log.debug("Proxy returned:")
     log.debug(repr(res))
     reply = packer.get_buffer()
     return rpc.SUCCESS, reply
예제 #7
0
파일: nfs4server.py 프로젝트: wzugang/pynfs
 def op_readdir(self, op):
     # We ignore dircount hint
     print("  CURRENT FILEHANDLE %s" % repr(self.curr_fh))
     print("  COOKIEVERF: %s, %s" % ( repr(op.opreaddir.cookieverf), repr(op.opreaddir.cookie)))
     print("  DIRCOUNT: %d MAXCOUNT: %d" % ( op.opreaddir.dircount, op.opreaddir.maxcount))
     print("  ATTRMASK: %s" % [nfs4lib.get_attr_name(bit) for bit in nfs4lib.bitmap2list(op.opreaddir.attr_request)])
     if not self.curr_fh:
         return simple_error(NFS4ERR_NOFILEHANDLE)
     if self.curr_fh.get_type() != NF4DIR:
         return simple_error(NFS4ERR_NOTDIR)
     if op.opreaddir.cookie in [1,2]:
         return simple_error(NFS4ERR_BAD_COOKIE)
     if op.opreaddir.maxcount == 0:
         return simple_error(NFS4ERR_TOOSMALL)
     zeroverf = '\x00\x00\x00\x00\x00\x00\x00\x00'
     if op.opreaddir.cookie == 0 and op.opreaddir.cookieverf != zeroverf:
         return simple_error(NFS4ERR_BAD_COOKIE)
     try:
         verifier = self.curr_fh.getdirverf()
         if op.opreaddir.cookie != 0:
             if op.opreaddir.cookieverf != verifier:
                 return simple_error(NFS4ERR_NOT_SAME)
         try:
             dirlist = self.curr_fh.read_dir(op.opreaddir.cookie)
         except IndexError:
             return simple_error(NFS4ERR_BAD_COOKIE)
         attrs = nfs4lib.bitmap2list(op.opreaddir.attr_request)
         entries = []
         bytecnt = 0
         packer = nfs4lib.FancyNFS4Packer()
         for entry in dirlist:
             # Get file attributes
             try:
                 attrvals = entry.fh.get_attributes(attrs)
             except NFS4Error:
                 if FATTR4_RDATTR_ERROR not in attrs: raise
                 attrvals = entry.fh.get_attributes([FATTR4_RDATTR_ERROR])
             entry.attr = attrvals
             # Compute size of XDR encoding
             e4 = entry4(entry.cookie, entry.name, entry.attr, [])
             packer.reset()
             packer.pack_entry4(e4)
             # Make sure returned value not too big
             bytecnt += len(packer.get_buffer())
             if bytecnt > op.opreaddir.maxcount - 16:
                 break
             # Add file to returned entries
             entries.insert(0,entry)
         if (not entries) and dirlist:
             return simple_error(NFS4ERR_TOOSMALL)
         # Encode entries as linked list
         e4 = []
         for entry in entries:
             e4 = [entry4(entry.cookie, entry.name, entry.attr, nextentry=e4)]
         if len(entries) < len(dirlist):
             d4 = dirlist4(e4, eof=0)
         else:
             d4 = dirlist4(e4, eof=1)
     except NFS4Error as e:
         return simple_error(e.code)
     rdresok = READDIR4resok(cookieverf=verifier, reply=d4)
     return simple_error(NFS4_OK, rdresok)