ms-nfs41-client/daemon/upcall.h

250 lines
6.9 KiB
C
Raw Normal View History

/* Copyright (c) 2010, 2011
* The Regents of the University of Michigan
* All Rights Reserved
*
* Olga Kornievskaia <aglo@umich.edu>
* Casey Bodley <cbodley@umich.edu>
*
* Permission is granted to use, copy and redistribute this software
* for noncommercial education and research purposes, so long as no
* fee is charged, and so long as the name of the University of Michigan
* is not used in any advertising or publicity pertaining to the use
* or distribution of this software without specific, written prior
* authorization. Permission to modify or otherwise create derivative
* works of this software is not granted.
*
* This software is provided as is, without representation or warranty
* of any kind either express or implied, including without limitation
* the implied warranties of merchantability, fitness for a particular
* purpose, or noninfringement. The Regents of the University of
* Michigan shall not be liable for any damages, including special,
* indirect, incidental, or consequential damages, with respect to any
* claim arising out of or in connection with the use of the software,
* even if it has been or is hereafter advised of the possibility of
* such damages.
*/
#ifndef __NFS41_DAEMON_UPCALL_H__
#define __NFS41_DAEMON_UPCALL_H__
#include "nfs41_ops.h"
#include "from_kernel.h"
#define NFSD_VERSION_MISMATCH 116
/* structures for upcall arguments */
typedef struct __mount_upcall_args {
const char *hostname;
const char *path;
2010-12-01 19:11:47 -05:00
DWORD sec_flavor;
DWORD rsize;
DWORD wsize;
DWORD lease_time;
} mount_upcall_args;
typedef struct __open_upcall_args {
nfs41_abs_path symlink;
FILE_BASIC_INFO basic_info;
FILE_STANDARD_INFO std_info;
const char *path;
ULONG access_mask;
ULONG access_mode;
ULONG file_attrs;
ULONG disposition;
ULONG create_opts;
LONG open_owner_id;
DWORD mode;
2012-02-08 11:11:09 -05:00
ULONGLONG changeattr;
HANDLE srv_open;
DWORD deleg_type;
BOOLEAN created;
BOOLEAN symlink_embedded;
} open_upcall_args;
typedef struct __close_upcall_args {
HANDLE srv_open;
const char *path;
BOOLEAN remove;
BOOLEAN renamed;
} close_upcall_args;
typedef struct __readwrite_upcall_args {
unsigned char *buffer;
2012-02-17 14:47:00 -05:00
ULONGLONG offset;
ULONG len;
ULONG out_len;
2012-02-08 16:29:25 -05:00
ULONGLONG ctime;
} readwrite_upcall_args;
typedef struct __lock_upcall_args {
uint64_t offset;
uint64_t length;
BOOLEAN exclusive;
BOOLEAN blocking;
BOOLEAN acquired;
} lock_upcall_args;
typedef struct __unlock_upcall_args {
uint32_t count;
unsigned char *buf;
uint32_t buf_len;
} unlock_upcall_args;
typedef struct __getattr_upcall_args {
FILE_BASIC_INFO basic_info;
FILE_STANDARD_INFO std_info;
FILE_ATTRIBUTE_TAG_INFO tag_info;
FILE_INTERNAL_INFORMATION intr_info;
int query_class;
int buf_len;
int query_reply_len;
ULONGLONG ctime;
} getattr_upcall_args;
typedef struct __setattr_upcall_args {
const char *path;
nfs41_root *root;
nfs41_open_state *state;
unsigned char *buf;
uint32_t buf_len;
int set_class;
ULONGLONG ctime;
} setattr_upcall_args;
2011-09-22 14:56:11 -04:00
typedef struct __getexattr_upcall_args {
const char *path;
unsigned char *buf;
uint32_t buf_len;
ULONG eaindex;
unsigned char *ealist;
uint32_t ealist_len;
BOOLEAN single;
BOOLEAN restart;
} getexattr_upcall_args;
typedef struct __setexattr_upcall_args {
2011-09-22 14:56:11 -04:00
const char *path;
unsigned char *buf;
uint32_t buf_len;
uint32_t mode;
ULONGLONG ctime;
} setexattr_upcall_args;
typedef struct __readdir_upcall_args {
const char *filter;
nfs41_root *root;
nfs41_open_state *state;
int buf_len;
int query_class;
int query_reply_len;
BOOLEAN initial;
BOOLEAN restart;
BOOLEAN single;
2011-09-27 12:21:26 -04:00
unsigned char *kbuf;
} readdir_upcall_args;
typedef struct __symlink_upcall_args {
nfs41_abs_path target_get;
char *target_set;
const char *path;
BOOLEAN set;
} symlink_upcall_args;
typedef struct __volume_upcall_args {
FS_INFORMATION_CLASS query;
int len;
union {
FILE_FS_SIZE_INFORMATION size;
FILE_FS_FULL_SIZE_INFORMATION fullsize;
FILE_FS_ATTRIBUTE_INFORMATION attribute;
} info;
} volume_upcall_args;
first stab at handling security irp 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?
2011-03-15 16:31:52 -04:00
typedef struct __getacl_upcall_args {
SECURITY_INFORMATION query;
PSECURITY_DESCRIPTOR sec_desc;
DWORD sec_desc_len;
first stab at handling security irp 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?
2011-03-15 16:31:52 -04:00
} getacl_upcall_args;
typedef struct __setacl_upcall_args {
SECURITY_INFORMATION query;
PSECURITY_DESCRIPTOR sec_desc;
ULONGLONG ctime;
} setacl_upcall_args;
typedef union __upcall_args {
mount_upcall_args mount;
open_upcall_args open;
close_upcall_args close;
readwrite_upcall_args rw;
lock_upcall_args lock;
unlock_upcall_args unlock;
getattr_upcall_args getattr;
2011-09-22 14:56:11 -04:00
getexattr_upcall_args getexattr;
setattr_upcall_args setattr;
setexattr_upcall_args setexattr;
readdir_upcall_args readdir;
symlink_upcall_args symlink;
volume_upcall_args volume;
first stab at handling security irp 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?
2011-03-15 16:31:52 -04:00
getacl_upcall_args getacl;
setacl_upcall_args setacl;
} upcall_args;
typedef struct __nfs41_upcall {
uint64_t xid;
uint32_t opcode;
uint32_t status;
uint32_t last_error;
upcall_args args;
2010-10-27 16:18:12 -04:00
uid_t uid;
gid_t gid;
2010-10-27 16:18:12 -04:00
/* store referenced pointers with the upcall for
* automatic dereferencing on upcall_cleanup();
* see upcall_root_ref() and upcall_open_state_ref() */
nfs41_root *root_ref;
2010-10-27 16:18:12 -04:00
nfs41_open_state *state_ref;
} nfs41_upcall;
/* upcall operation interface */
typedef int (*upcall_parse_proc)(unsigned char*, uint32_t, nfs41_upcall*);
typedef int (*upcall_handle_proc)(nfs41_upcall*);
typedef int (*upcall_marshall_proc)(unsigned char*, uint32_t*, nfs41_upcall*);
typedef void (*upcall_cancel_proc)(nfs41_upcall*);
typedef void (*upcall_cleanup_proc)(nfs41_upcall*);
typedef struct __nfs41_upcall_op {
upcall_parse_proc parse;
upcall_handle_proc handle;
upcall_marshall_proc marshall;
upcall_cancel_proc cancel;
upcall_cleanup_proc cleanup;
} nfs41_upcall_op;
/* upcall.c */
int upcall_parse(
IN unsigned char *buffer,
IN uint32_t length,
OUT nfs41_upcall *upcall);
int upcall_handle(
IN nfs41_upcall *upcall);
2010-11-02 14:40:52 -04:00
void upcall_marshall(
IN nfs41_upcall *upcall,
OUT unsigned char *buffer,
IN uint32_t length,
OUT uint32_t *length_out);
void upcall_cancel(
IN nfs41_upcall *upcall);
void upcall_cleanup(
IN nfs41_upcall *upcall);
#endif /* !__NFS41_DAEMON_UPCALL_H__ */