if we receive an rpc_autherr, just recreate a new rpc client as well
as the rpc auth structure. as it ties into the recovery and handles
that only one thread recovers and reestablishes the rpc auth context.
in theory, reestablishing rpc client does not necessitate new rpc auth
context. we really need to restablish one only if we get rpc autherr. however,
it simplifies the code not to introduce a different synchronization
mechanism for rpc auth in addition to the rpc one.
once libtirpc blocking recv was changed to a polling receive,
we no longer had a timeout mechanims on waiting for a reply.
solution: save a timestamp before the recv call, on each async recv return
check if the time lapsed does not exceed the timeout value. when timeout
is reach, return TIMEDOUT rpc error.
every upcall (except few) pass session and open_state pointer, so
add that to marshal_nfs41_header() in the driver. remove passing
of session and open_state elsewhere in marshal functions.
in the deamon, upcall.c now reads and stores pointers to session
and open_state in nfs41_upcall datastructure instead of having
each individual upcall store their own pointers. setattrl
and readdir args keeping pointer because the rest of the code
uses them a lot.
in upcall_parse() up refcounts on session and open_state if
valid handles were passed in. down refcounts upcall_cleanup() as
before. but need to be careful with count value for mount and open
upcalls. we need to take an extra ref because upcall_cleanup() now
will always decrement it.
reformated some of the old functions.
finalized mapping functions for windows to nfs4 access mask bits.
satisfying nfs41_acl_query for dacl.
when doing setacl and creating "who" field of the format user@nfs4domain,
use dns domain name of the windows client machine
instead of passing sids for the owner and group, create a security
descriptor and pass that back. this way we can add all the security
information that was queried in the daemon and pass a fully formed
security descriptor back to the kernel.
notice: irp_mj_query_security provides a pointer to the buffer that
suppose to hold the security descriptor. that memory is valid only
in the context of the process doing the security irp. we can't use
this pointer in then upcall entry and try to write the security
descriptor directly there as we process the downcall. that leads
to kernel oops.
thus we have to first allocate memory to hold the security descriptor
then copy bytes passed to us from the daemon. then do another copy
with the context of the security irp.
this commit does NOT have correct windows to nfs4 acl mappings but
rather has the wrapper functions defined for mapping them.
cthon tests still work with these mappings.
nfs41_cb_session stores the last cb_compound reply (whether or not cachethis was set) to handle retry attempts, along with the cb_compound arguments for improved NFS4ERR_SEQ_FALSE_RETRY detection
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
acls are lists of arbitrary length, so xdr_array() is used to allocate the array
during decode. because this memory is allocated by the tirpc library, it needs
to be freed there as well; added function nfsacl41_free() to do this with XDR_F
REE
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
Problem: say nfsd is not running but the redirector is active already
(ie. start deamon, stop deamon). problem doesn't exist if nfsd has never
been started. now a user process executes a mount command, the kernel
ends up creating a system thread to handle creation of the vnetroot.
that thread places a mount upcall and waits for the down call. now
kill the user process. now start the nfsd. it will pick up a queued up
upcall entry. however, in the arguments there are pointers to server name
and mount point values that are stored in the memory of the user process
that started the mount but now ended.
Solution: check that Mount.srv_name and Mount.root are still valid
addresses before dereferencing them.
MIT KDC don't issue tickets that are better than 1K.
Windows KDC carry authorization payloads with their service tickets
and thus much bigger than MIT's tickets.
Basic handling of owner and group security query (no dacl).
Added new upcall for NFS41_ACL_QUERY (driver and daemon code).
Daemon, upon getting NFS41_ACL_QUERY first places a getattr that has
owner, group attribute request. We currently don't cache them!!!
Then, we parse nfs4name format (ie user@domain or group@domain)
into user and domain. We currently ignore domain part!!!
Then, we assume that whatever we are mapping is "known" locally
(ie LookupAccountName() api which retrieves a SID for a given name).
Mapping from name to SID can only be done in the userland. We then
copy the bytes via the upcall pipe to the kernel. If the received
user or group cant be mapped via LookupAccoundName(), we create a
well known null SID as the reply.
Kernel creates a security descriptor in the absolute-format and adds
owner and group sids to it. Important: RtlSetOwner/Group functions only
work with absolute-format security descriptor, however the reply to the
user needs to be in the self-relative format.
The way security query works is that it passes us a buffer to be filled
with the security context. However the user doesn't know how big the
buffer should be so, the user is allowed to pass a null buffer and have
the kernel return how much memory is needed. This leads to 2 security
queries => 2 NFS41_ACL_QUERY upcalls => 2 getattr rpcs... It should be
improved.
TODO:
- need to add caching of owner/group attributes for a file?
- need to add calls to LDAP for more general mapping?
- need to cache reply of the ACL if supplied length is 0?