added delegation.c and .h
nfs41_client stores a list of nfs41_delegation_state
new function nfs41_delegate_open() to look for a compatible delegation before calling nfs41_open()
if nfs41_open() is granted a delegation, call nfs41_delegation_granted() to register it with the client
client calls nfs41_client_delegation_free() on unmount to free list of delegations
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>
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?
struct idmap_context contains configuration data (struct idmap_config), a cache for users, and a cache for groups. idmap_context is declared in idmap.c, and only available as an opaque pointer (nfs41_idmapper) elsewhere. similarly, Winldap.h is only included by idmap.c, and not needed elsewhere
nfs41_idmap_create() allocates the idmap_context, loads the configuration from file, and calls ldap_init(). it does not call ldap_connect(); we'll still be able to start the daemon if ldap isn't configured, or the ldap server is down. calling ldap_connect() is optional, as any ldap operation that requires a connection will establish it internally. this behavior, along with the LDAP_OPT_AUTO_RECONNECT option (defaults to on), means that we shouldn't have to maintain a separate connection for each thread
nfs41_idmap_*() functions return windows errors codes. LDAP_RETCODEs are mapped to windows errors with LdapMapErrorToWin32()
the user and group caches share a common generic interface in struct idmap_cache, which uses a linked list for storage, and protects access with a SRWLOCK. expiration of cache entries can be adjusted by the config option 'cache_ttl'
struct config_option g_options[] is a table of available config options and their default values. this patch adds a 'ms-nfs41-idmap.conf' file with all possible options set to default values, and commented out. the daemon expects to find this file under c:\etc\, and won't start if it can't be opened or parsed
Signed-off-by: Casey Bodley <cbodley@citi.umich.edu>