ReactOS  0.4.12-dev-18-gf469aca
open.c File Reference
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include "nfs41_ops.h"
#include "delegation.h"
#include "from_kernel.h"
#include "daemon_debug.h"
#include "upcall.h"
#include "util.h"
Include dependency graph for open.c:

Go to the source code of this file.

Macros

#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION
 

Functions

static int create_open_state (IN const char *path, IN uint32_t open_owner_id, OUT nfs41_open_state **state_out)
 
static void open_state_free (IN nfs41_open_state *state)
 
void nfs41_open_state_ref (IN nfs41_open_state *state)
 
void nfs41_open_state_deref (IN nfs41_open_state *state)
 
void nfs41_open_stateid_arg (IN nfs41_open_state *state, OUT stateid_arg *arg)
 
static void client_state_add (IN nfs41_open_state *state)
 
static void client_state_remove (IN nfs41_open_state *state)
 
static int do_open (IN OUT nfs41_open_state *state, IN uint32_t create, IN uint32_t createhow, IN nfs41_file_info *createattrs, IN bool_t try_recovery, OUT nfs41_file_info *info)
 
static int open_or_delegate (IN OUT nfs41_open_state *state, IN uint32_t create, IN uint32_t createhow, IN nfs41_file_info *createattrs, IN bool_t try_recovery, OUT nfs41_file_info *info)
 
static int parse_abs_path (unsigned char **buffer, uint32_t *length, nfs41_abs_path *path)
 
static int parse_open (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static BOOLEAN open_for_attributes (uint32_t type, ULONG access_mask, ULONG disposition, int status)
 
static int map_disposition_2_nfsopen (ULONG disposition, int in_status, bool_t persistent, uint32_t *create, uint32_t *createhowmode, uint32_t *last_error)
 
static void map_access_2_allowdeny (ULONG access_mask, ULONG access_mode, ULONG disposition, uint32_t *allow, uint32_t *deny)
 
static int check_execute_access (nfs41_open_state *state)
 
static int create_with_ea (IN uint32_t disposition, IN uint32_t lookup_status)
 
static int handle_open (nfs41_upcall *upcall)
 
static int marshall_open (unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
 
static void cancel_open (IN nfs41_upcall *upcall)
 
static int parse_close (unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
 
static int do_nfs41_close (nfs41_open_state *state)
 
static int handle_close (nfs41_upcall *upcall)
 
static void cleanup_close (nfs41_upcall *upcall)
 

Variables

const nfs41_upcall_op nfs41_op_open
 
const nfs41_upcall_op nfs41_op_close
 

Macro Definition Documentation

◆ FIX_ALLOW_DENY_WIN2NFS_CONVERSION

#define FIX_ALLOW_DENY_WIN2NFS_CONVERSION

Function Documentation

◆ cancel_open()

static void cancel_open ( IN nfs41_upcall upcall)
static

Definition at line 780 of file open.c.

781 {
782  int status = NFS4_OK;
783  open_upcall_args *args = &upcall->args.open;
784  nfs41_open_state *state = upcall->state_ref;
785 
786  dprintf(1, "--> cancel_open('%s')\n", args->path);
787 
788  if (upcall->state_ref == NULL ||
789  upcall->state_ref == INVALID_HANDLE_VALUE)
790  goto out; /* if handle_open() failed, the state was already freed */
791 
792  if (state->do_close) {
793  stateid_arg stateid;
794  stateid.open = state;
795  stateid.delegation = NULL;
796  stateid.type = STATEID_OPEN;
797  memcpy(&stateid.stateid, &state->stateid, sizeof(stateid4));
798 
799  status = nfs41_close(state->session, &state->file, &stateid);
800  if (status)
801  dprintf(1, "cancel_open: nfs41_close() failed with %s\n",
802  nfs_error_string(status));
803 
804  } else if (args->created) {
805  const nfs41_component *name = &state->file.name;
806  /* break any delegations and truncate before REMOVE */
807  nfs41_delegation_return(state->session, &state->file,
809  status = nfs41_remove(state->session, &state->parent,
810  name, state->file.fh.fileid);
811  if (status)
812  dprintf(1, "cancel_open: nfs41_remove() failed with %s\n",
813  nfs_error_string(status));
814  }
815 
816  /* remove from the client's list of state for recovery */
817  client_state_remove(state);
818  nfs41_open_state_deref(state);
819 out:
820  status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
821  dprintf(1, "<-- cancel_open() returning %d\n", status);
822 }
BOOLEAN created
Definition: upcall.h:57
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
int nfs41_remove(IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *target, IN uint64_t fileid)
Definition: nfs41_ops.c:1180
#define TRUE
Definition: types.h:120
uint64_t fileid
Definition: nfs41_types.h:55
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
void nfs41_open_state_deref(IN nfs41_open_state *state)
Definition: open.c:104
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
Definition: match.c:390
struct __nfs41_session * session
Definition: nfs41.h:132
bool_t do_close
Definition: nfs41.h:134
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
static void client_state_remove(IN nfs41_open_state *state)
Definition: open.c:179
enum stateid_type type
Definition: nfs41_ops.h:285
stateid4 stateid
Definition: nfs41.h:135
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
int nfs41_delegation_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
Definition: delegation.c:629
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
nfs41_open_state * open
Definition: nfs41_ops.h:286
static int state
Definition: maze.c:121
nfs41_path_fh parent
Definition: nfs41.h:129
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const char * path
Definition: upcall.h:45
nfs41_path_fh file
Definition: nfs41.h:130
nfs41_component name
Definition: nfs41_types.h:61
stateid4 stateid
Definition: nfs41_ops.h:284
int nfs41_close(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid)
Definition: nfs41_ops.c:627
nfs41_updowncall_list upcall
Definition: nfs41_driver.c:273
Definition: name.c:36
Definition: ps.c:97

◆ check_execute_access()

static int check_execute_access ( nfs41_open_state state)
static

Definition at line 444 of file open.c.

Referenced by handle_open().

445 {
446  uint32_t supported, access;
447  int status = nfs41_access(state->session, &state->file,
448  ACCESS4_EXECUTE | ACCESS4_READ, &supported, &access);
449  if (status) {
450  eprintf("nfs41_access() failed with %s for %s\n",
451  nfs_error_string(status), state->path.path);
452  status = ERROR_ACCESS_DENIED;
453  } else if ((supported & ACCESS4_EXECUTE) == 0) {
454  /* server can't verify execute access;
455  * for now, assume that read access is good enough */
456  if ((supported & ACCESS4_READ) == 0 || (access & ACCESS4_READ) == 0) {
457  eprintf("server can't verify execute access, and user does "
458  "not have read access to file %s\n", state->path.path);
459  status = ERROR_ACCESS_DENIED;
460  }
461  } else if ((access & ACCESS4_EXECUTE) == 0) {
462  dprintf(1, "user does not have execute access to file %s\n",
463  state->path.path);
464  status = ERROR_ACCESS_DENIED;
465  } else
466  dprintf(2, "user has execute access to file\n");
467  return status;
468 }
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
struct __nfs41_session * session
Definition: nfs41.h:132
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
#define dprintf
Definition: regdump.c:33
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
int nfs41_access(IN nfs41_session *session, IN nfs41_path_fh *file, IN uint32_t requested, OUT uint32_t *supported OPTIONAL, OUT uint32_t *access OPTIONAL)
Definition: nfs41_ops.c:1554
nfs41_path_fh file
Definition: nfs41.h:130
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
UINT32 uint32_t
Definition: types.h:75
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
nfs41_abs_path path
Definition: nfs41.h:128
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ cleanup_close()

static void cleanup_close ( nfs41_upcall upcall)
static

Definition at line 929 of file open.c.

930 {
931  /* release the initial reference from create_open_state() */
933 }
void nfs41_open_state_deref(IN nfs41_open_state *state)
Definition: open.c:104
nfs41_open_state * state_ref
Definition: upcall.h:207

◆ client_state_add()

static void client_state_add ( IN nfs41_open_state state)
static

Definition at line 169 of file open.c.

Referenced by open_or_delegate().

171 {
172  nfs41_client *client = state->session->client;
173 
174  EnterCriticalSection(&client->state.lock);
175  list_add_tail(&client->state.opens, &state->client_entry);
176  LeaveCriticalSection(&client->state.lock);
177 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
static FILE * client
Definition: client.c:41
struct client_state state
Definition: nfs41.h:215
static int state
Definition: maze.c:121
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ client_state_remove()

static void client_state_remove ( IN nfs41_open_state state)
static

Definition at line 179 of file open.c.

Referenced by cancel_open(), and handle_close().

181 {
182  nfs41_client *client = state->session->client;
183 
184  EnterCriticalSection(&client->state.lock);
185  list_remove(&state->client_entry);
186  LeaveCriticalSection(&client->state.lock);
187 }
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
static FILE * client
Definition: client.c:41
struct client_state state
Definition: nfs41.h:215
static int state
Definition: maze.c:121
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)

◆ create_open_state()

static int create_open_state ( IN const char path,
IN uint32_t  open_owner_id,
OUT nfs41_open_state **  state_out 
)
static

Definition at line 34 of file open.c.

Referenced by handle_open().

38 {
39  int status;
41 
42  state = calloc(1, sizeof(nfs41_open_state));
43  if (state == NULL) {
44  status = GetLastError();
45  goto out;
46  }
47 
48  InitializeSRWLock(&state->path.lock);
51  goto out_free;
52  }
53  state->path.len = (unsigned short)strlen(state->path.path);
54  path_fh_init(&state->file, &state->path);
55  path_fh_init(&state->parent, &state->path);
56  last_component(state->path.path, state->file.name.name, &state->parent.name);
57 
60  state->owner.owner_len = (uint32_t)strlen((const char*)state->owner.owner);
61  state->ref_count = 1;
62  list_init(&state->locks.list);
63  list_init(&state->client_entry);
64  InitializeCriticalSection(&state->locks.lock);
65 
66  state->ea.list = INVALID_HANDLE_VALUE;
67  InitializeCriticalSection(&state->ea.lock);
68 
69  *state_out = state;
70  status = NO_ERROR;
71 out:
72  return status;
73 
74 out_free:
75  free(state);
76  goto out;
77 }
struct __nfs41_open_state::@26 ea
struct __nfs41_open_state::@25 locks
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define free
Definition: debug_ros.c:5
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
char * LPSTR
Definition: xmlstorage.h:182
#define NO_ERROR
Definition: dderror.h:5
bool_t last_component(IN const char *path, IN const char *path_end, OUT nfs41_component *component)
Definition: util.c:317
unsigned char owner[NFS4_OPAQUE_LIMIT]
Definition: nfs41_types.h:119
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:91
STRSAFEAPI StringCchPrintfA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszFormat,...)
Definition: strsafe.h:520
#define NFS4_OPAQUE_LIMIT
Definition: nfs41_const.h:31
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:697
smooth NULL
Definition: ftsmooth.c:416
void path_fh_init(OUT nfs41_path_fh *file, IN nfs41_abs_path *path)
Definition: util.c:346
uint32_t owner_len
Definition: nfs41_types.h:118
const char * name
Definition: nfs41_types.h:48
unsigned short len
Definition: nfs41_types.h:43
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
nfs41_path_fh parent
Definition: nfs41.h:129
VOID WINAPI InitializeSRWLock(PSRWLOCK Lock)
Definition: sync.c:75
LONG open_owner_id
Definition: nfs41_driver.c:107
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
nfs41_path_fh file
Definition: nfs41.h:130
nfs41_component name
Definition: nfs41_types.h:61
Definition: services.c:325
state_owner4 owner
Definition: nfs41.h:136
#define calloc
Definition: rosglue.h:14
__WINE_SERVER_LIST_INLINE void list_init(struct list *list)
Definition: list.h:149
struct list_entry client_entry
Definition: nfs41.h:138
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
nfs41_abs_path path
Definition: nfs41.h:128
#define uint32_t
Definition: nsiface.idl:61
static SERVICE_STATUS status
Definition: service.c:31
#define ERROR_FILENAME_EXCED_RANGE
Definition: winerror.h:263

◆ create_with_ea()

static int create_with_ea ( IN uint32_t  disposition,
IN uint32_t  lookup_status 
)
static

Definition at line 470 of file open.c.

Referenced by handle_open().

473 {
474  /* only set EAs on file creation */
475  return disposition == FILE_SUPERSEDE || disposition == FILE_CREATE
476  || disposition == FILE_OVERWRITE || disposition == FILE_OVERWRITE_IF
477  || (disposition == FILE_OPEN_IF && lookup_status == NFS4ERR_NOENT);
478 }
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_SUPERSEDE
Definition: from_kernel.h:53

◆ do_nfs41_close()

static int do_nfs41_close ( nfs41_open_state state)
static

Definition at line 849 of file open.c.

Referenced by handle_close().

850 {
851  int status;
852  stateid_arg stateid;
853  stateid.open = state;
854  stateid.delegation = NULL;
855  stateid.type = STATEID_OPEN;
856  memcpy(&stateid.stateid, &state->stateid, sizeof(stateid4));
857 
858  status = nfs41_close(state->session, &state->file, &stateid);
859  if (status) {
860  dprintf(1, "nfs41_close() failed with error %s.\n",
861  nfs_error_string(status));
862  status = nfs_to_windows_error(status, ERROR_INTERNAL_ERROR);
863  }
864 
865  return status;
866 }
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
struct __nfs41_session * session
Definition: nfs41.h:132
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
enum stateid_type type
Definition: nfs41_ops.h:285
stateid4 stateid
Definition: nfs41.h:135
nfs41_delegation_state * delegation
Definition: nfs41_ops.h:287
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
nfs41_open_state * open
Definition: nfs41_ops.h:286
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
nfs41_path_fh file
Definition: nfs41.h:130
stateid4 stateid
Definition: nfs41_ops.h:284
int nfs41_close(IN nfs41_session *session, IN nfs41_path_fh *file, IN stateid_arg *stateid)
Definition: nfs41_ops.c:627
static SERVICE_STATUS status
Definition: service.c:31

◆ do_open()

static int do_open ( IN OUT nfs41_open_state state,
IN uint32_t  create,
IN uint32_t  createhow,
IN nfs41_file_info createattrs,
IN bool_t  try_recovery,
OUT nfs41_file_info info 
)
static

Definition at line 189 of file open.c.

Referenced by messages< char >::open(), messages< wchar_t >::open(), and open_or_delegate().

196 {
197  open_claim4 claim;
198  stateid4 open_stateid;
199  open_delegation4 delegation = { 0 };
200  nfs41_delegation_state *deleg_state = NULL;
201  int status;
202 
203  claim.claim = CLAIM_NULL;
204  claim.u.null.filename = &state->file.name;
205 
206  status = nfs41_open(state->session, &state->parent, &state->file,
207  &state->owner, &claim, state->share_access, state->share_deny,
208  create, createhow, createattrs, TRUE, &open_stateid,
209  &delegation, info);
210  if (status)
211  goto out;
212 
213  /* allocate delegation state and register it with the client */
214  nfs41_delegation_granted(state->session, &state->parent,
215  &state->file, &delegation, TRUE, &deleg_state);
216  if (deleg_state) {
217  deleg_state->srv_open = state->srv_open;
218  dprintf(1, "do_open: received delegation: saving srv_open = %x\n",
219  state->srv_open);
220  }
221 
223  /* update the stateid */
224  memcpy(&state->stateid, &open_stateid, sizeof(open_stateid));
225  state->do_close = 1;
226  state->delegation.state = deleg_state;
228 out:
229  return status;
230 }
VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:54
#define TRUE
Definition: types.h:120
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
static FILE * out
Definition: regtests2xml.c:44
union __open_claim4::@40 u
int nfs41_open(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN state_owner4 *owner, IN open_claim4 *claim, IN uint32_t allow, IN uint32_t deny, IN uint32_t create, IN uint32_t how_mode, IN OPTIONAL nfs41_file_info *createattrs, IN bool_t try_recovery, OUT stateid4 *stateid, OUT open_delegation4 *delegation, OUT OPTIONAL nfs41_file_info *info)
Definition: nfs41_ops.c:366
static int state
Definition: maze.c:121
VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK Lock)
Definition: sync.c:82
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
struct __open_claim4::@40::__open_claim_null null
uint32_t claim
Definition: nfs41_ops.h:615
int nfs41_delegation_granted(IN nfs41_session *session, IN nfs41_path_fh *parent, IN nfs41_path_fh *file, IN open_delegation4 *delegation, IN bool_t try_recovery, OUT nfs41_delegation_state **deleg_out)
Definition: delegation.c:330
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31

◆ handle_close()

static int handle_close ( nfs41_upcall upcall)
static

Definition at line 868 of file open.c.

869 {
870  int status = NFS4_OK, rm_status = NFS4_OK;
871  close_upcall_args *args = &upcall->args.close;
872  nfs41_open_state *state = upcall->state_ref;
873 
874  /* return associated file layouts if necessary */
875  if (state->type == NF4REG)
876  pnfs_layout_state_close(state->session, state, args->remove);
877 
878  if (state->srv_open == args->srv_open)
880 
881  if (args->remove) {
882  nfs41_component *name = &state->file.name;
883 
884  if (args->renamed) {
885  dprintf(1, "removing a renamed file %s\n", name->name);
886  create_silly_rename(&state->path, &state->file.fh, name);
887  status = do_nfs41_close(state);
888  if (status)
889  goto out;
890  else
891  state->do_close = 0;
892  }
893 
894  /* break any delegations and truncate before REMOVE */
895  nfs41_delegation_return(state->session, &state->file,
897 
898  dprintf(1, "calling nfs41_remove for %s\n", name->name);
899 retry_delete:
900  rm_status = nfs41_remove(state->session, &state->parent,
901  name, state->file.fh.fileid);
902  if (rm_status) {
903  if (rm_status == NFS4ERR_FILE_OPEN) {
904  status = do_nfs41_close(state);
905  if (!status) {
906  state->do_close = 0;
907  goto retry_delete;
908  } else goto out;
909  }
910  dprintf(1, "nfs41_remove() failed with error %s.\n",
911  nfs_error_string(rm_status));
912  rm_status = nfs_to_windows_error(rm_status, ERROR_INTERNAL_ERROR);
913  }
914  }
915 
916  if (state->do_close) {
917  status = do_nfs41_close(state);
918  }
919 out:
920  /* remove from the client's list of state for recovery */
921  client_state_remove(state);
922 
923  if (status || !rm_status)
924  return status;
925  else
926  return rm_status;
927 }
HANDLE srv_open
Definition: nfs41.h:164
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
int nfs41_remove(IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *target, IN uint64_t fileid)
Definition: nfs41_ops.c:1180
#define TRUE
Definition: types.h:120
uint64_t fileid
Definition: nfs41_types.h:55
#define ERROR_INTERNAL_ERROR
Definition: winerror.h:840
void pnfs_layout_state_close(IN struct __nfs41_session *session, IN struct __nfs41_open_state *state, IN bool_t remove)
BOOLEAN renamed
Definition: upcall.h:65
Definition: match.c:390
static int do_nfs41_close(nfs41_open_state *state)
Definition: open.c:849
struct __nfs41_session * session
Definition: nfs41.h:132
bool_t do_close
Definition: nfs41.h:134
close_upcall_args close
Definition: upcall.h:178
nfs41_open_state * state_ref
Definition: upcall.h:207
#define dprintf
Definition: regdump.c:33
HANDLE srv_open
Definition: upcall.h:62
uint32_t type
Definition: nfs41.h:133
static void client_state_remove(IN nfs41_open_state *state)
Definition: open.c:179
upcall_args args
Definition: upcall.h:198
const char * name
Definition: nfs41_types.h:48
int nfs41_delegation_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
Definition: delegation.c:629
BOOLEAN remove
Definition: upcall.h:64
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
int create_silly_rename(IN nfs41_abs_path *path, IN const nfs41_fh *fh, OUT nfs41_component *silly)
Definition: util.c:380
static int state
Definition: maze.c:121
nfs41_path_fh parent
Definition: nfs41.h:129
nfs41_path_fh file
Definition: nfs41.h:130
nfs41_component name
Definition: nfs41_types.h:61
Definition: name.c:36
void nfs41_delegation_remove_srvopen(IN nfs41_session *session, IN nfs41_path_fh *file)
Definition: delegation.c:610
nfs41_abs_path path
Definition: nfs41.h:128
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ handle_open()

static int handle_open ( nfs41_upcall upcall)
static

Definition at line 480 of file open.c.

481 {
482  int status = 0;
483  open_upcall_args *args = &upcall->args.open;
485  nfs41_file_info info = { 0 };
486 
487  status = create_open_state(args->path, args->open_owner_id, &state);
488  if (status) {
489  eprintf("create_open_state(%d) failed with %d\n",
490  args->open_owner_id, status);
491  goto out;
492  }
493  state->srv_open = args->srv_open;
494 
495  // first check if windows told us it's a directory
496  if (args->create_opts & FILE_DIRECTORY_FILE)
497  state->type = NF4DIR;
498  else
499  state->type = NF4REG;
500 
501  // always do a lookup
502  status = nfs41_lookup(upcall->root_ref, nfs41_root_session(upcall->root_ref),
503  &state->path, &state->parent, &state->file, &info, &state->session);
504 
505  if (status == ERROR_REPARSE) {
506  uint32_t depth = 0;
507  /* one of the parent components was a symlink */
508  do {
509  if (++depth > NFS41_MAX_SYMLINK_DEPTH) {
510  status = ERROR_TOO_MANY_LINKS;
511  goto out_free_state;
512  }
513 
514  /* replace the path with the symlink target's */
515  status = nfs41_symlink_target(state->session,
516  &state->parent, &state->path);
517  if (status) {
518  /* can't do the reparse if we can't get the target */
519  eprintf("nfs41_symlink_target() failed with %d\n", status);
520  goto out_free_state;
521  }
522 
523  /* redo the lookup until it doesn't return REPARSE */
524  status = nfs41_lookup(upcall->root_ref, state->session,
525  &state->path, &state->parent, NULL, NULL, &state->session);
526  } while (status == ERROR_REPARSE);
527 
528  if (status == NO_ERROR || status == ERROR_FILE_NOT_FOUND) {
529  abs_path_copy(&args->symlink, &state->path);
530  status = NO_ERROR;
531  upcall->last_error = ERROR_REPARSE;
532  args->symlink_embedded = TRUE;
533  }
534  goto out_free_state;
535  }
536 
537  // now if file/dir exists, use type returned by lookup
538  if (status == NO_ERROR) {
539  if (info.type == NF4DIR) {
540  dprintf(2, "handle_nfs41_open: DIRECTORY\n");
541  if (args->create_opts & FILE_NON_DIRECTORY_FILE) {
542  eprintf("trying to open directory %s as a file\n",
543  state->path.path);
544  status = ERROR_DIRECTORY;
545  goto out_free_state;
546  }
547  } else if (info.type == NF4REG) {
548  dprintf(2, "handle nfs41_open: FILE\n");
549  if (args->create_opts & FILE_DIRECTORY_FILE) {
550  eprintf("trying to open file %s as a directory\n",
551  state->path.path);
552  status = ERROR_BAD_FILE_TYPE;
553  goto out_free_state;
554  }
555  } else if (info.type == NF4LNK) {
556  dprintf(2, "handle nfs41_open: SYMLINK\n");
557  if (args->create_opts & FILE_OPEN_REPARSE_POINT) {
558  /* continue and open the symlink itself, but we need to
559  * know if the target is a regular file or directory */
561  int target_status = nfs41_symlink_follow(upcall->root_ref,
562  state->session, &state->file, &target_info);
563  if (target_status == NO_ERROR && target_info.type == NF4DIR)
564  info.symlink_dir = TRUE;
565  } else {
566  /* replace the path with the symlink target */
567  status = nfs41_symlink_target(state->session,
568  &state->file, &args->symlink);
569  if (status) {
570  eprintf("nfs41_symlink_target() for %s failed with %d\n",
571  args->path, status);
572  } else {
573  /* tell the driver to call RxPrepareToReparseSymbolicLink() */
574  upcall->last_error = ERROR_REPARSE;
575  args->symlink_embedded = FALSE;
576  }
577  goto out_free_state;
578  }
579  } else
580  dprintf(2, "handle_open(): unsupported type=%d\n", info.type);
581  state->type = info.type;
582  } else if (status != ERROR_FILE_NOT_FOUND)
583  goto out_free_state;
584 
585  /* XXX: this is a hard-coded check for the open arguments we see from
586  * the CreateSymbolicLink() system call. we respond to this by deferring
587  * the CREATE until we get the upcall to set the symlink. this approach
588  * is troublesome for two reasons:
589  * -an application might use these exact arguments to create a normal
590  * file, and we would return success without actually creating it
591  * -an application could create a symlink by sending the FSCTL to set
592  * the reparse point manually, and their open might be different. in
593  * this case we'd create the file on open, and need to remove it
594  * before creating the symlink */
595  if (args->disposition == FILE_CREATE &&
597  args->access_mode == 0 &&
599  /* fail if the file already exists */
600  if (status == NO_ERROR) {
601  status = ERROR_FILE_EXISTS;
602  goto out_free_state;
603  }
604 
605  /* defer the call to CREATE until we get the symlink set upcall */
606  dprintf(1, "trying to create a symlink, deferring create\n");
607 
608  /* because of WRITE_ATTR access, be prepared for a setattr upcall;
609  * will crash if the superblock is null, so use the parent's */
610  state->file.fh.superblock = state->parent.fh.superblock;
611 
612  status = NO_ERROR;
613  } else if (args->symlink.len) {
614  /* handle cygwin symlinks */
615  nfs41_file_info createattrs;
616  createattrs.attrmask.count = 2;
617  createattrs.attrmask.arr[0] = 0;
618  createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
619  createattrs.mode = 0777;
620 
621  dprintf(1, "creating cygwin symlink %s -> %s\n",
622  state->file.name.name, args->symlink.path);
623 
624  status = nfs41_create(state->session, NF4LNK, &createattrs,
625  args->symlink.path, &state->parent, &state->file, &info);
626  if (status) {
627  eprintf("nfs41_create() for symlink=%s failed with %s\n",
628  args->symlink.path, nfs_error_string(status));
629  status = map_symlink_errors(status);
630  goto out_free_state;
631  }
632  nfs_to_basic_info(&info, &args->basic_info);
633  nfs_to_standard_info(&info, &args->std_info);
634  args->mode = info.mode;
635  args->changeattr = info.change;
636  } else if (open_for_attributes(state->type, args->access_mask,
637  args->disposition, status)) {
638  if (status) {
639  dprintf(1, "nfs41_lookup failed with %d\n", status);
640  goto out_free_state;
641  }
642 
643  nfs_to_basic_info(&info, &args->basic_info);
644  nfs_to_standard_info(&info, &args->std_info);
645  args->mode = info.mode;
646  args->changeattr = info.change;
647  } else {
648  nfs41_file_info createattrs = { 0 };
649  uint32_t create = 0, createhowmode = 0, lookup_status = status;
650 
651  if (!lookup_status && (args->disposition == FILE_OVERWRITE ||
652  args->disposition == FILE_OVERWRITE_IF ||
653  args->disposition == FILE_SUPERSEDE)) {
654  if ((info.hidden && !(args->file_attrs & FILE_ATTRIBUTE_HIDDEN)) ||
655  (info.system && !(args->file_attrs & FILE_ATTRIBUTE_SYSTEM))) {
656  status = ERROR_ACCESS_DENIED;
657  goto out_free_state;
658  }
659  if (args->disposition != FILE_SUPERSEDE)
660  args->mode = info.mode;
661  }
662  createattrs.attrmask.count = 2;
665  createattrs.mode = args->mode;
666  createattrs.hidden = args->file_attrs & FILE_ATTRIBUTE_HIDDEN ? 1 : 0;
667  createattrs.system = args->file_attrs & FILE_ATTRIBUTE_SYSTEM ? 1 : 0;
668  createattrs.archive = args->file_attrs & FILE_ATTRIBUTE_ARCHIVE ? 1 : 0;
669 
671  args->disposition, &state->share_access, &state->share_deny);
672  status = map_disposition_2_nfsopen(args->disposition, status,
673  state->session->flags & CREATE_SESSION4_FLAG_PERSIST,
674  &create, &createhowmode, &upcall->last_error);
675  if (status)
676  goto out_free_state;
677 
678  if (args->access_mask & FILE_EXECUTE && state->file.fh.len) {
679  status = check_execute_access(state);
680  if (status)
681  goto out_free_state;
682  }
683 
684 supersede_retry:
685  // XXX file exists and we have to remove it first
686  if (args->disposition == FILE_SUPERSEDE && lookup_status == NO_ERROR) {
687  nfs41_component *name = &state->file.name;
688  if (!(args->create_opts & FILE_DIRECTORY_FILE))
689  nfs41_delegation_return(state->session, &state->file,
691 
692  dprintf(1, "open for FILE_SUPERSEDE removing %s first\n", name->name);
693  status = nfs41_remove(state->session, &state->parent,
694  name, state->file.fh.fileid);
695  if (status)
696  goto out_free_state;
697  }
698 
699  if (create == OPEN4_CREATE && (args->create_opts & FILE_DIRECTORY_FILE)) {
700  status = nfs41_create(state->session, NF4DIR, &createattrs, NULL,
701  &state->parent, &state->file, &info);
702  args->created = status == NFS4_OK ? TRUE : FALSE;
703  } else {
704  createattrs.attrmask.arr[0] |= FATTR4_WORD0_SIZE;
705  createattrs.size = 0;
706  dprintf(1, "creating with mod %o\n", args->mode);
707  status = open_or_delegate(state, create, createhowmode, &createattrs,
708  TRUE, &info);
709  if (status == NFS4_OK && state->delegation.state)
710  args->deleg_type = state->delegation.state->state.type;
711  }
712  if (status) {
713  dprintf(1, "%s failed with %s\n", (create == OPEN4_CREATE &&
714  (args->create_opts & FILE_DIRECTORY_FILE))?"nfs41_create":"nfs41_open",
715  nfs_error_string(status));
716  if (args->disposition == FILE_SUPERSEDE && status == NFS4ERR_EXIST)
717  goto supersede_retry;
718  status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
719  goto out_free_state;
720  } else {
721  nfs_to_basic_info(&info, &args->basic_info);
722  nfs_to_standard_info(&info, &args->std_info);
723  args->mode = info.mode;
724  args->changeattr = info.change;
725  }
726 
727  /* set extended attributes on file creation */
728  if (args->ea && create_with_ea(args->disposition, lookup_status)) {
729  status = nfs41_ea_set(state, args->ea);
730  status = nfs_to_windows_error(status, ERROR_FILE_NOT_FOUND);
731  }
732  }
733 
734  upcall->state_ref = state;
736 out:
737  return status;
738 out_free_state:
739  nfs41_open_state_deref(state);
740  goto out;
741 }
HANDLE srv_open
Definition: nfs41.h:164
int nfs41_symlink_follow(IN nfs41_root *root, IN nfs41_session *session, IN nfs41_path_fh *symlink, OUT nfs41_file_info *info)
Definition: symlink.c:146
BOOLEAN created
Definition: upcall.h:57
static int check_execute_access(nfs41_open_state *state)
Definition: open.c:444
nfs41_abs_path symlink
Definition: upcall.h:42
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
int nfs_to_windows_error(int status, int default_error)
Definition: util.c:235
int nfs41_symlink_target(IN nfs41_session *session, IN nfs41_path_fh *file, OUT nfs41_abs_path *target)
Definition: symlink.c:92
int nfs41_remove(IN nfs41_session *session, IN nfs41_path_fh *parent, IN const nfs41_component *target, IN uint64_t fileid)
Definition: nfs41_ops.c:1180
open_upcall_args open
Definition: upcall.h:177
#define TRUE
Definition: types.h:120
uint64_t fileid
Definition: nfs41_types.h:55
struct __nfs41_superblock * superblock
Definition: nfs41_types.h:56
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
void nfs41_open_state_deref(IN nfs41_open_state *state)
Definition: open.c:104
#define FILE_CREATE
Definition: from_kernel.h:55
int nfs41_lookup(IN nfs41_root *root, IN nfs41_session *session, IN OUT nfs41_abs_path *path_inout, OUT OPTIONAL nfs41_path_fh *parent_out, OUT OPTIONAL nfs41_path_fh *target_out, OUT OPTIONAL nfs41_file_info *info_out, OUT nfs41_session **session_out)
Definition: lookup.c:424
void eprintf(LPCSTR format,...)
Definition: daemon_debug.c:86
#define FILE_OVERWRITE
Definition: from_kernel.h:57
ULONG disposition
Definition: upcall.h:49
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_DIRECTORY
Definition: winerror.h:295
uint32_t arr[3]
Definition: nfs41_types.h:97
Definition: match.c:390
int map_symlink_errors(int status)
Definition: util.c:293
struct __nfs41_session * session
Definition: nfs41.h:132
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
int nfs41_create(IN nfs41_session *session, IN uint32_t type, IN nfs41_file_info *createattrs, IN OPTIONAL const char *symlink, IN nfs41_path_fh *parent, OUT nfs41_path_fh *file, OUT nfs41_file_info *info)
Definition: nfs41_ops.c:530
HANDLE srv_open
Definition: upcall.h:54
#define ERROR_BAD_FILE_TYPE
Definition: winerror.h:277
static int open_or_delegate(IN OUT nfs41_open_state *state, IN uint32_t create, IN uint32_t createhow, IN nfs41_file_info *createattrs, IN bool_t try_recovery, OUT nfs41_file_info *info)
Definition: open.c:232
void abs_path_copy(OUT nfs41_abs_path *dst, IN const nfs41_abs_path *src)
Definition: util.c:338
nfs41_root * root_ref
Definition: upcall.h:206
void nfs_to_basic_info(IN const nfs41_file_info *info, OUT PFILE_BASIC_INFO basic_out)
Definition: util.c:163
#define ERROR_ACCESS_DENIED
Definition: compat.h:87
nfs41_open_state * state_ref
Definition: upcall.h:207
#define dprintf
Definition: regdump.c:33
uint32_t count
Definition: nfs41_types.h:96
uint32_t type
Definition: nfs41.h:133
smooth NULL
Definition: ftsmooth.c:416
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
ULONG file_attrs
Definition: upcall.h:48
static int create_open_state(IN const char *path, IN uint32_t open_owner_id, OUT nfs41_open_state **state_out)
Definition: open.c:34
uint32_t len
Definition: nfs41_types.h:54
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
void nfs41_open_state_ref(IN nfs41_open_state *state)
Definition: open.c:96
ULONG access_mode
Definition: upcall.h:47
upcall_args args
Definition: upcall.h:198
const char * name
Definition: nfs41_types.h:48
BOOLEAN symlink_embedded
Definition: upcall.h:58
#define CREATE_SESSION4_FLAG_PERSIST
Definition: nfs41_const.h:307
unsigned short len
Definition: nfs41_types.h:43
struct __nfs41_open_state::@24 delegation
static BOOLEAN open_for_attributes(uint32_t type, ULONG access_mask, ULONG disposition, int status)
Definition: open.c:320
int nfs41_delegation_return(IN nfs41_session *session, IN nfs41_path_fh *file, IN enum open_delegation_type4 access, IN bool_t truncate)
Definition: delegation.c:629
static FILE * out
Definition: regtests2xml.c:44
const char * nfs_error_string(int status)
Definition: daemon_debug.c:370
static __inline nfs41_session * nfs41_root_session(IN nfs41_root *root)
Definition: nfs41.h:321
static int map_disposition_2_nfsopen(ULONG disposition, int in_status, bool_t persistent, uint32_t *create, uint32_t *createhowmode, uint32_t *last_error)
Definition: open.c:352
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
void nfs_to_standard_info(IN const nfs41_file_info *info, OUT PFILE_STANDARD_INFO std_out)
Definition: util.c:175
GLint GLint GLsizei GLsizei GLsizei depth
Definition: gl.h:1546
#define ERROR_TOO_MANY_LINKS
Definition: winerror.h:671
ULONG create_opts
Definition: upcall.h:50
static int state
Definition: maze.c:121
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
nfs41_path_fh parent
Definition: nfs41.h:129
#define SYNCHRONIZE
Definition: nt_native.h:61
#define ERROR_REPARSE
Definition: winerror.h:522
PFILE_FULL_EA_INFORMATION ea
Definition: upcall.h:56
const char * path
Definition: upcall.h:45
DWORD deleg_type
Definition: upcall.h:55
ULONGLONG changeattr
Definition: upcall.h:53
nfs41_path_fh file
Definition: nfs41.h:130
nfs41_component name
Definition: nfs41_types.h:61
uint32_t share_access
Definition: nfs41.h:141
uint32_t last_error
Definition: upcall.h:197
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
int nfs41_ea_set(IN nfs41_open_state *state, IN PFILE_FULL_EA_INFORMATION ea)
Definition: ea.c:116
UINT32 uint32_t
Definition: types.h:75
#define NFS41_MAX_SYMLINK_DEPTH
Definition: nfs41_const.h:60
LONG open_owner_id
Definition: upcall.h:51
static int create_with_ea(IN uint32_t disposition, IN uint32_t lookup_status)
Definition: open.c:470
static void map_access_2_allowdeny(ULONG access_mask, ULONG access_mode, ULONG disposition, uint32_t *allow, uint32_t *deny)
Definition: open.c:401
Definition: name.c:36
uint32_t share_deny
Definition: nfs41.h:142
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
nfs41_abs_path path
Definition: nfs41.h:128
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31
FILE_BASIC_INFO basic_info
Definition: upcall.h:43
#define FILE_OPEN_REPARSE_POINT
Definition: from_kernel.h:46
ULONG access_mask
Definition: upcall.h:46
#define DELETE
Definition: nt_native.h:57
FILE_STANDARD_INFO std_info
Definition: upcall.h:44
Definition: ps.c:97

◆ map_access_2_allowdeny()

static void map_access_2_allowdeny ( ULONG  access_mask,
ULONG  access_mode,
ULONG  disposition,
uint32_t allow,
uint32_t deny 
)
static

Definition at line 401 of file open.c.

Referenced by handle_open().

403 {
404  if ((access_mask &
406  (access_mask & (FILE_READ_DATA | FILE_EXECUTE)))
407  *allow = OPEN4_SHARE_ACCESS_BOTH;
408  else if (access_mask & (FILE_READ_DATA | FILE_EXECUTE))
409  *allow = OPEN4_SHARE_ACCESS_READ;
410  else if (access_mask &
412  *allow = OPEN4_SHARE_ACCESS_WRITE;
413  /* if we are creating a file and no data access is specified, then
414  * do an open and request no delegations. example open with share access 0
415  * and share deny 0 (ie deny_both).
416  */
417  if ((disposition == FILE_CREATE || disposition == FILE_OPEN_IF ||
418  disposition == FILE_OVERWRITE_IF || disposition == FILE_SUPERSEDE ||
419  disposition == FILE_OVERWRITE) &&
420  !(access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA |
423 
424 #define FIX_ALLOW_DENY_WIN2NFS_CONVERSION
425 #ifdef FIX_ALLOW_DENY_WIN2NFS_CONVERSION
426  if ((access_mode & FILE_SHARE_READ) &&
427  (access_mode & FILE_SHARE_WRITE))
428  *deny = OPEN4_SHARE_DENY_NONE;
429  else if (access_mode & FILE_SHARE_READ)
430  *deny = OPEN4_SHARE_DENY_WRITE;
431  else if (access_mode & FILE_SHARE_WRITE)
432  *deny = OPEN4_SHARE_DENY_READ;
433  else
434  *deny = OPEN4_SHARE_DENY_BOTH;
435 #else
436  // AGLO: 11/13/2009.
437  // readonly file that is being opened for reading with a
438  // share read mode given above logic translates into deny
439  // write and linux server does not allow it.
440  *deny = OPEN4_SHARE_DENY_NONE;
441 #endif
442 }
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
#define FILE_SHARE_READ
Definition: compat.h:125
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_SUPERSEDE
Definition: from_kernel.h:53

◆ map_disposition_2_nfsopen()

static int map_disposition_2_nfsopen ( ULONG  disposition,
int  in_status,
bool_t  persistent,
uint32_t create,
uint32_t createhowmode,
uint32_t last_error 
)
static

Definition at line 352 of file open.c.

Referenced by handle_open().

355 {
356  int status = NO_ERROR;
357  if (disposition == FILE_SUPERSEDE) {
358  if (in_status == NFS4ERR_NOENT)
359  *last_error = ERROR_FILE_NOT_FOUND;
360  //remove and recreate the file
361  *create = OPEN4_CREATE;
362  if (persistent) *createhowmode = GUARDED4;
363  else *createhowmode = EXCLUSIVE4_1;
364  } else if (disposition == FILE_CREATE) {
365  // if lookup succeeded which means the file exist, return an error
366  if (!in_status)
367  status = ERROR_FILE_EXISTS;
368  else {
369  *create = OPEN4_CREATE;
370  if (persistent) *createhowmode = GUARDED4;
371  else *createhowmode = EXCLUSIVE4_1;
372  }
373  } else if (disposition == FILE_OPEN) {
374  if (in_status == NFS4ERR_NOENT)
375  status = ERROR_FILE_NOT_FOUND;
376  else
378  } else if (disposition == FILE_OPEN_IF) {
379  if (in_status == NFS4ERR_NOENT) {
380  dprintf(1, "creating new file\n");
381  *create = OPEN4_CREATE;
382  *last_error = ERROR_FILE_NOT_FOUND;
383  } else {
384  dprintf(1, "opening existing file\n");
386  }
387  } else if (disposition == FILE_OVERWRITE) {
388  if (in_status == NFS4ERR_NOENT)
389  status = ERROR_FILE_NOT_FOUND;
390  //truncate file
391  *create = OPEN4_CREATE;
392  } else if (disposition == FILE_OVERWRITE_IF) {
393  if (in_status == NFS4ERR_NOENT)
394  *last_error = ERROR_FILE_NOT_FOUND;
395  //truncate file
396  *create = OPEN4_CREATE;
397  }
398  return status;
399 }
#define ERROR_FILE_EXISTS
Definition: winerror.h:165
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define NO_ERROR
Definition: dderror.h:5
#define dprintf
Definition: regdump.c:33
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ marshall_open()

static int marshall_open ( unsigned char buffer,
uint32_t length,
nfs41_upcall upcall 
)
static

Definition at line 743 of file open.c.

744 {
745  int status;
746  open_upcall_args *args = &upcall->args.open;
747 
748  status = safe_write(&buffer, length, &args->basic_info, sizeof(args->basic_info));
749  if (status) goto out;
750  status = safe_write(&buffer, length, &args->std_info, sizeof(args->std_info));
751  if (status) goto out;
752  status = safe_write(&buffer, length, &upcall->state_ref, sizeof(HANDLE));
753  if (status) goto out;
754  status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
755  if (status) goto out;
756  status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
757  if (status) goto out;
758  status = safe_write(&buffer, length, &args->deleg_type, sizeof(args->deleg_type));
759  if (status) goto out;
760  if (upcall->last_error == ERROR_REPARSE) {
761  unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR);
762  status = safe_write(&buffer, length, &args->symlink_embedded, sizeof(BOOLEAN));
763  if (status) goto out;
764  status = safe_write(&buffer, length, &len, sizeof(len));
765  if (status) goto out;
766  /* convert args->symlink to wchar */
767  if (*length <= len || !MultiByteToWideChar(CP_UTF8, 0,
768  args->symlink.path, args->symlink.len,
769  (LPWSTR)buffer, len / sizeof(WCHAR))) {
770  status = ERROR_BUFFER_OVERFLOW;
771  goto out;
772  }
773  }
774  dprintf(2, "NFS41_OPEN: downcall open_state=0x%p mode %o changeattr 0x%llu\n",
775  upcall->state_ref, args->mode, args->changeattr);
776 out:
777  return status;
778 }
nfs41_abs_path symlink
Definition: upcall.h:42
open_upcall_args open
Definition: upcall.h:177
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
#define CP_UTF8
Definition: nls.h:20
nfs41_open_state * state_ref
Definition: upcall.h:207
#define dprintf
Definition: regdump.c:33
unsigned char BOOLEAN
upcall_args args
Definition: upcall.h:198
BOOLEAN symlink_embedded
Definition: upcall.h:58
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned short len
Definition: nfs41_types.h:43
static FILE * out
Definition: regtests2xml.c:44
int safe_write(unsigned char **pos, uint32_t *remaining, void *src, uint32_t src_len)
Definition: util.c:44
GLenum GLsizei len
Definition: glext.h:6722
#define ERROR_REPARSE
Definition: winerror.h:522
DWORD deleg_type
Definition: upcall.h:55
ULONGLONG changeattr
Definition: upcall.h:53
uint32_t last_error
Definition: upcall.h:197
#define MultiByteToWideChar
Definition: compat.h:100
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
WCHAR * LPWSTR
Definition: xmlstorage.h:184
static SERVICE_STATUS status
Definition: service.c:31
FILE_BASIC_INFO basic_info
Definition: upcall.h:43
FILE_STANDARD_INFO std_info
Definition: upcall.h:44

◆ nfs41_open_state_deref()

void nfs41_open_state_deref ( IN nfs41_open_state state)

Definition at line 104 of file open.c.

Referenced by cancel_open(), cleanup_close(), delegation_return(), handle_open(), nfs41_rpc_netaddr(), and upcall_cleanup().

106 {
107  const LONG count = InterlockedDecrement(&state->ref_count);
108 
109  dprintf(2, "nfs41_open_state_deref(%s) count %d\n", state->path.path, count);
110  if (count == 0)
112 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
static void open_state_free(IN nfs41_open_state *state)
Definition: open.c:79
long LONG
Definition: pedump.c:60
#define dprintf
Definition: regdump.c:33
#define InterlockedDecrement
Definition: armddk.h:52
static int state
Definition: maze.c:121

◆ nfs41_open_state_ref()

void nfs41_open_state_ref ( IN nfs41_open_state state)

Definition at line 96 of file open.c.

Referenced by deleg_open_find(), handle_open(), nfs41_rpc_netaddr(), and upcall_parse().

98 {
99  const LONG count = InterlockedIncrement(&state->ref_count);
100 
101  dprintf(2, "nfs41_open_state_ref(%s) count %d\n", state->path.path, count);
102 }
GLuint GLuint GLsizei count
Definition: gl.h:1545
long LONG
Definition: pedump.c:60
#define dprintf
Definition: regdump.c:33
static int state
Definition: maze.c:121
#define InterlockedIncrement
Definition: armddk.h:53

◆ nfs41_open_stateid_arg()

void nfs41_open_stateid_arg ( IN nfs41_open_state state,
OUT stateid_arg arg 
)

Definition at line 125 of file open.c.

128 {
129  arg->open = state;
130  arg->delegation = NULL;
131 
132  AcquireSRWLockShared(&state->lock);
133 
134  if (state->delegation.state) {
135  nfs41_delegation_state *deleg = state->delegation.state;
136  AcquireSRWLockShared(&deleg->lock);
137  if (deleg->status == DELEGATION_GRANTED) {
138  arg->type = STATEID_DELEG_FILE;
139  memcpy(&arg->stateid, &deleg->state.stateid, sizeof(stateid4));
140  }
141  ReleaseSRWLockShared(&deleg->lock);
142 
143  if (arg->type == STATEID_DELEG_FILE)
144  goto out;
145 
146  dprintf(2, "delegation recalled, waiting for open stateid..\n");
147 
148  /* wait for nfs41_delegation_to_open() to recover open stateid */
149  while (!state->do_close)
150  SleepConditionVariableSRW(&state->delegation.cond, &state->lock,
151  INFINITE, CONDITION_VARIABLE_LOCKMODE_SHARED);
152  }
153 
154  if (state->locks.stateid.seqid) {
155  memcpy(&arg->stateid, &state->locks.stateid, sizeof(stateid4));
156  arg->type = STATEID_LOCK;
157  } else if (state->do_close) {
158  memcpy(&arg->stateid, &state->stateid, sizeof(stateid4));
159  arg->type = STATEID_OPEN;
160  } else {
161  memset(&arg->stateid, 0, sizeof(stateid4));
162  arg->type = STATEID_SPECIAL;
163  }
164 out:
165  ReleaseSRWLockShared(&state->lock);
166 }
#define dprintf
Definition: regdump.c:33
smooth NULL
Definition: ftsmooth.c:416
open_delegation4 state
Definition: nfs41.h:96
BOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK Lock, DWORD Timeout, ULONG Flags)
Definition: sync.c:121
static FILE * out
Definition: regtests2xml.c:44
static int state
Definition: maze.c:121
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
enum delegation_status status
Definition: nfs41.h:103
#define INFINITE
Definition: serial.h:102
#define memset(x, y, z)
Definition: compat.h:39
VOID WINAPI AcquireSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:61
VOID WINAPI ReleaseSRWLockShared(PSRWLOCK Lock)
Definition: sync.c:89

◆ open_for_attributes()

static BOOLEAN open_for_attributes ( uint32_t  type,
ULONG  access_mask,
ULONG  disposition,
int  status 
)
static

Definition at line 320 of file open.c.

Referenced by handle_open().

322 {
323  if (type == NF4DIR) {
324  if (disposition == FILE_OPEN || disposition == FILE_OVERWRITE ||
325  (!status && (disposition == FILE_OPEN_IF ||
326  disposition == FILE_OVERWRITE_IF ||
327  disposition == FILE_SUPERSEDE))) {
328  dprintf(1, "Opening a directory\n");
329  return TRUE;
330  } else {
331  dprintf(1, "Creating a directory\n");
332  return FALSE;
333  }
334  }
335 
336  if ((access_mask & FILE_READ_DATA) ||
337  (access_mask & FILE_WRITE_DATA) ||
338  (access_mask & FILE_APPEND_DATA) ||
339  (access_mask & FILE_EXECUTE) ||
340  disposition == FILE_CREATE ||
341  disposition == FILE_OVERWRITE_IF ||
342  disposition == FILE_SUPERSEDE ||
343  disposition == FILE_OPEN_IF ||
344  disposition == FILE_OVERWRITE)
345  return FALSE;
346  else {
347  dprintf(1, "Open call that wants to manage attributes\n");
348  return TRUE;
349  }
350 }
#define TRUE
Definition: types.h:120
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_CREATE
Definition: from_kernel.h:55
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define FILE_OVERWRITE
Definition: from_kernel.h:57
#define FILE_APPEND_DATA
Definition: nt_native.h:634
#define dprintf
Definition: regdump.c:33
#define FILE_READ_DATA
Definition: nt_native.h:628
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_WRITE_DATA
Definition: nt_native.h:631
#define FILE_EXECUTE
Definition: nt_native.h:642
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_SUPERSEDE
Definition: from_kernel.h:53
Definition: ps.c:97

◆ open_or_delegate()

static int open_or_delegate ( IN OUT nfs41_open_state state,
IN uint32_t  create,
IN uint32_t  createhow,
IN nfs41_file_info createattrs,
IN bool_t  try_recovery,
OUT nfs41_file_info info 
)
static

Definition at line 232 of file open.c.

Referenced by handle_open().

239 {
240  int status;
241 
242  /* check for existing delegation */
243  status = nfs41_delegate_open(state, create, createattrs, info);
244 
245  /* get an open stateid if we have no delegation stateid */
246  if (status)
247  status = do_open(state, create, createhow,
248  createattrs, try_recovery, info);
249 
250  state->pnfs_last_offset = info->size ? info->size - 1 : 0;
251 
252  /* register the client's open state on success */
253  if (status == NFS4_OK)
255  return status;
256 }
static void client_state_add(IN nfs41_open_state *state)
Definition: open.c:169
static int state
Definition: maze.c:121
int nfs41_delegate_open(IN nfs41_open_state *state, IN uint32_t create, IN OPTIONAL nfs41_file_info *createattrs, OUT nfs41_file_info *info)
Definition: delegation.c:462
static const struct access_res create[16]
Definition: package.c:7720
static SERVICE_STATUS status
Definition: service.c:31
static int do_open(IN OUT nfs41_open_state *state, IN uint32_t create, IN uint32_t createhow, IN nfs41_file_info *createattrs, IN bool_t try_recovery, OUT nfs41_file_info *info)
Definition: open.c:189

◆ open_state_free()

static void open_state_free ( IN nfs41_open_state state)
static

Definition at line 79 of file open.c.

Referenced by nfs41_open_state_deref().

81 {
82  struct list_entry *entry, *tmp;
83 
84  /* free associated lock state */
85  list_for_each_tmp(entry, tmp, &state->locks.list)
87  if (state->delegation.state)
88  nfs41_delegation_deref(state->delegation.state);
89  if (state->ea.list != INVALID_HANDLE_VALUE)
90  free(state->ea.list);
91  free(state);
92 }
#define free
Definition: debug_ros.c:5
uint8_t entry
Definition: isohybrid.c:63
#define INVALID_HANDLE_VALUE
Definition: compat.h:391
void nfs41_delegation_deref(IN nfs41_delegation_state *state)
Definition: delegation.c:79
#define list_container(entry, type, field)
Definition: list.h:33
if(!(yy_init))
Definition: macro.lex.yy.c:717
static int state
Definition: maze.c:121
Definition: _list.h:228
Definition: list.h:27
#define list_for_each_tmp(entry, tmp, head)
Definition: list.h:39
#define open_entry(pos)
Definition: delegation.c:89

◆ parse_abs_path()

static int parse_abs_path ( unsigned char **  buffer,
uint32_t length,
nfs41_abs_path path 
)
static

Definition at line 259 of file open.c.

Referenced by parse_open().

260 {
261  int status = safe_read(buffer, length, &path->len, sizeof(USHORT));
262  if (status) goto out;
263  if (path->len == 0)
264  goto out;
265  if (path->len >= NFS41_MAX_PATH_LEN) {
266  status = ERROR_BUFFER_OVERFLOW;
267  goto out;
268  }
269  status = safe_read(buffer, length, path->path, path->len);
270  if (status) goto out;
271  path->len--; /* subtract 1 for null */
272 out:
273  return status;
274 }
#define ERROR_BUFFER_OVERFLOW
Definition: winerror.h:185
GLuint buffer
Definition: glext.h:5915
#define NFS41_MAX_PATH_LEN
Definition: nfs41_const.h:46
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
unsigned short len
Definition: nfs41_types.h:43
static FILE * out
Definition: regtests2xml.c:44
unsigned short USHORT
Definition: pedump.c:61
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
static SERVICE_STATUS status
Definition: service.c:31
Definition: ps.c:97

◆ parse_close()

static int parse_close ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 826 of file open.c.

827 {
828  int status;
829  close_upcall_args *args = &upcall->args.close;
830 
831  status = safe_read(&buffer, &length, &args->remove, sizeof(BOOLEAN));
832  if (status) goto out;
833  status = safe_read(&buffer, &length, &args->srv_open, sizeof(HANDLE));
834  if (status) goto out;
835  if (args->remove) {
836  status = get_name(&buffer, &length, &args->path);
837  if (status) goto out;
838  status = safe_read(&buffer, &length, &args->renamed, sizeof(BOOLEAN));
839  if (status) goto out;
840  }
841 
842  dprintf(1, "parsing NFS41_CLOSE: remove=%d srv_open=%x renamed=%d "
843  "filename='%s'\n", args->remove, args->srv_open, args->renamed,
844  args->remove ? args->path : "");
845 out:
846  return status;
847 }
BOOLEAN renamed
Definition: upcall.h:65
GLuint buffer
Definition: glext.h:5915
Definition: match.c:390
close_upcall_args close
Definition: upcall.h:178
#define dprintf
Definition: regdump.c:33
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
HANDLE srv_open
Definition: upcall.h:62
unsigned char BOOLEAN
const char * path
Definition: upcall.h:63
upcall_args args
Definition: upcall.h:198
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
BOOLEAN remove
Definition: upcall.h:64
static FILE * out
Definition: regtests2xml.c:44
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
static SERVICE_STATUS status
Definition: service.c:31

◆ parse_open()

static int parse_open ( unsigned char buffer,
uint32_t  length,
nfs41_upcall upcall 
)
static

Definition at line 277 of file open.c.

278 {
279  int status;
280  open_upcall_args *args = &upcall->args.open;
281 
282  status = get_name(&buffer, &length, &args->path);
283  if (status) goto out;
284  status = safe_read(&buffer, &length, &args->access_mask, sizeof(ULONG));
285  if (status) goto out;
286  status = safe_read(&buffer, &length, &args->access_mode, sizeof(ULONG));
287  if (status) goto out;
288  status = safe_read(&buffer, &length, &args->file_attrs, sizeof(ULONG));
289  if (status) goto out;
290  status = safe_read(&buffer, &length, &args->create_opts, sizeof(ULONG));
291  if (status) goto out;
292  status = safe_read(&buffer, &length, &args->disposition, sizeof(ULONG));
293  if (status) goto out;
294  status = safe_read(&buffer, &length, &args->open_owner_id, sizeof(LONG));
295  if (status) goto out;
296  status = safe_read(&buffer, &length, &args->mode, sizeof(DWORD));
297  if (status) goto out;
298  status = safe_read(&buffer, &length, &args->srv_open, sizeof(HANDLE));
299  if (status) goto out;
300  status = parse_abs_path(&buffer, &length, &args->symlink);
301  if (status) goto out;
302  status = safe_read(&buffer, &length, &args->ea, sizeof(HANDLE));
303  if (status) goto out;
304 
305  dprintf(1, "parsing NFS41_OPEN: filename='%s' access mask=%d "
306  "access mode=%d\n\tfile attrs=0x%x create attrs=0x%x "
307  "(kernel) disposition=%d\n\topen_owner_id=%d mode=%o "
308  "srv_open=%p symlink=%s ea=%p\n", args->path, args->access_mask,
309  args->access_mode, args->file_attrs, args->create_opts,
310  args->disposition, args->open_owner_id, args->mode, args->srv_open,
311  args->symlink.path, args->ea);
312  print_disposition(2, args->disposition);
313  print_access_mask(2, args->access_mask);
314  print_share_mode(2, args->access_mode);
316 out:
317  return status;
318 }
nfs41_abs_path symlink
Definition: upcall.h:42
open_upcall_args open
Definition: upcall.h:177
static int parse_abs_path(unsigned char **buffer, uint32_t *length, nfs41_abs_path *path)
Definition: open.c:259
GLuint buffer
Definition: glext.h:5915
void print_create_attributes(int level, DWORD create_opts)
Definition: daemon_debug.c:126
ULONG disposition
Definition: upcall.h:49
Definition: match.c:390
HANDLE srv_open
Definition: upcall.h:54
long LONG
Definition: pedump.c:60
#define dprintf
Definition: regdump.c:33
int get_name(unsigned char **pos, uint32_t *remaining, const char **out_name)
Definition: util.c:55
ULONG file_attrs
Definition: upcall.h:48
ULONG access_mode
Definition: upcall.h:47
upcall_args args
Definition: upcall.h:198
GLenum GLuint GLenum GLsizei length
Definition: glext.h:5579
static FILE * out
Definition: regtests2xml.c:44
unsigned long DWORD
Definition: ntddk_ex.h:95
ULONG create_opts
Definition: upcall.h:50
PFILE_FULL_EA_INFORMATION ea
Definition: upcall.h:56
const char * path
Definition: upcall.h:45
LONG open_owner_id
Definition: upcall.h:51
void print_share_mode(int level, DWORD mode)
Definition: daemon_debug.c:215
void print_access_mask(int level, DWORD access_mask)
Definition: daemon_debug.c:181
unsigned int ULONG
Definition: retypes.h:1
int safe_read(unsigned char **pos, uint32_t *remaining, void *dest, uint32_t dest_len)
Definition: util.c:33
char path[NFS41_MAX_PATH_LEN]
Definition: nfs41_types.h:42
static SERVICE_STATUS status
Definition: service.c:31
ULONG access_mask
Definition: upcall.h:46
void print_disposition(int level, DWORD disposition)
Definition: daemon_debug.c:164

Variable Documentation

◆ nfs41_op_close

const nfs41_upcall_op nfs41_op_close
Initial value:
= {
}
static void cleanup_close(nfs41_upcall *upcall)
Definition: open.c:929
static int handle_close(nfs41_upcall *upcall)
Definition: open.c:868
smooth NULL
Definition: ftsmooth.c:416
static int parse_close(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: open.c:826

Definition at line 942 of file open.c.

◆ nfs41_op_open

const nfs41_upcall_op nfs41_op_open
Initial value:
= {
}
static void cancel_open(IN nfs41_upcall *upcall)
Definition: open.c:780
static int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upcall)
Definition: open.c:277
static int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *upcall)
Definition: open.c:743
static int handle_open(nfs41_upcall *upcall)
Definition: open.c:480

Definition at line 936 of file open.c.