- From 98db9c3f55b382a86a5fbcfe642c0e6a961a7393 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 6 Nov 2024 15:17:22 +0100
- Subject: [PATCH 1/3] mount,nfs41_build_features.h,sys: Add
- dircreatemode=,filecreatemode= mount options+POSIX octal mode
- 1. Add "dircreatemode=" and "filecreatemode=" mount options to set the
- default create mode for { files, dirs } indepedently.
- "createmode=" sets for both dirs+files
- 2. Allow traditional POSIX/ISO C octual values (e.g. 0777, 0644 etc),
- as the "0o" prefix used by Windows was too confusing.
- Example:
- $ /sbin/nfs_mount -o rw,dircreatemode=0750,filecreatemode=0640 N nfs://10.49.202.230//bigdisk
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- mount/mount.c | 22 +++++-
- nfs41_build_features.h | 4 +-
- sys/nfs41sys_driver.h | 17 ++---
- sys/nfs41sys_mount.c | 140 +++++++++++++++++++++++++++++----------
- sys/nfs41sys_openclose.c | 26 ++++++--
- 5 files changed, 157 insertions(+), 52 deletions(-)
- diff --git a/mount/mount.c b/mount/mount.c
- index dafa9ef..db6f94c 100644
- --- a/mount/mount.c
- +++ b/mount/mount.c
- @@ -112,11 +112,24 @@ void PrintMountUsage(LPWSTR pProcess)
- "\tnotimebasedcoherency\tturns off time-based coherency (default, due to bugs)\n"
- "\twsize=#\twrite buffer size in bytes\n"
- "\tcreatemode=\tspecify default POSIX permission mode\n"
- + "\t\tfor new directories and files created on the NFS share.\n"
- + "\t\tArgument is an octal value prefixed with '0' or '0o',\n"
- + "\t\tif this value is prefixed with 'nfsv3attrmode+'\n"
- + "\t\tthe mode value from a \"NfsV3Attributes\" EA will be used\n"
- + "\t\t(defaults \"nfsv3attrmode+0%o\" for dirs and \n"
- + "\t\t\"nfsv3attrmode+0%o\" for files).\n"
- + "\tdircreatemode=\tspecify default POSIX permission mode\n"
- + "\t\tfor new directories created on the NFS share.\n"
- + "\t\tArgument is an octal value prefixed with '0' or '0o',\n"
- + "\t\tif this value is prefixed with 'nfsv3attrmode+'\n"
- + "\t\tthe mode value from a \"NfsV3Attributes\" EA will be used\n"
- + "\t\t(defaults \"nfsv3attrmode+0%o\").\n"
- + "\tfilecreatemode=\tspecify default POSIX permission mode\n"
- "\t\tfor new files created on the NFS share.\n"
- - "\t\tArgument is an octal value prefixed with '0o',\n"
- + "\t\tArgument is an octal value prefixed with '0' or '0o',\n"
- "\t\tif this value is prefixed with 'nfsv3attrmode+'\n"
- "\t\tthe mode value from a \"NfsV3Attributes\" EA will be used\n"
- - "\t\t(defaults \"nfsv3attrmode+0o%o\").\n"
- + "\t\t(defaults \"nfsv3attrmode+0%o\").\n"
- "* URL parameters:\n"
- "\tro=1\tmount as read-only\n"
- @@ -147,7 +160,10 @@ void PrintMountUsage(LPWSTR pProcess)
- "\tnfs_mount.exe -o sec=sys S nfs://myhost1//dirwithspace/dir+space/test2?rw=1\n"
- "\tnfs_mount.exe -o sec=sys nfs://myhost1//dirwithspace/dir+space/test2?rw=1\n",
- pProcess, pProcess, pProcess, pProcess,
- - (int)NFS41_DRIVER_DEFAULT_CREATE_MODE);
- + (int)NFS41_DRIVER_DEFAULT_DIR_CREATE_MODE,
- + (int)NFS41_DRIVER_DEFAULT_FILE_CREATE_MODE,
- + (int)NFS41_DRIVER_DEFAULT_DIR_CREATE_MODE,
- + (int)NFS41_DRIVER_DEFAULT_FILE_CREATE_MODE);
- }
- diff --git a/nfs41_build_features.h b/nfs41_build_features.h
- index dfb144f..34843e1 100644
- --- a/nfs41_build_features.h
- +++ b/nfs41_build_features.h
- @@ -126,9 +126,11 @@
- /*
- * Default POSIX permission mode bits for new files
- + * and directories.
- * Can be ovrriden with a "NfsV3Attributes" EA
- */
- -#define NFS41_DRIVER_DEFAULT_CREATE_MODE (0755)
- +#define NFS41_DRIVER_DEFAULT_DIR_CREATE_MODE (0755)
- +#define NFS41_DRIVER_DEFAULT_FILE_CREATE_MODE (0644)
- /*
- * NFS41_DRIVER_DEBUG_FS_NAME - define which filesystem name should
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index ab52fb8..721815e 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -299,6 +299,11 @@ nfs41_updowncall_list upcall, downcall;
- #define MAX_SEC_FLAVOR_LEN 12
- #define UPCALL_TIMEOUT_DEFAULT 50 /* in seconds */
- +typedef struct _NFS41_MOUNT_CREATEMODE {
- + BOOLEAN use_nfsv3attrsea_mode;
- + DWORD mode;
- +} NFS41_MOUNT_CREATEMODE;
- +
- typedef struct _NFS41_MOUNT_CONFIG {
- BOOLEAN use_nfspubfh;
- DWORD ReadSize;
- @@ -314,10 +319,8 @@ typedef struct _NFS41_MOUNT_CONFIG {
- WCHAR sec_flavor_buffer[MAX_SEC_FLAVOR_LEN];
- UNICODE_STRING SecFlavor;
- DWORD timeout;
- - struct {
- - BOOLEAN use_nfsv3attrsea_mode;
- - DWORD mode;
- - } createmode;
- + NFS41_MOUNT_CREATEMODE dir_createmode;
- + NFS41_MOUNT_CREATEMODE file_createmode;
- } NFS41_MOUNT_CONFIG, *PNFS41_MOUNT_CONFIG;
- typedef struct _nfs41_mount_entry {
- @@ -407,10 +410,8 @@ typedef struct _NFS41_V_NET_ROOT_EXTENSION {
- FILE_FS_ATTRIBUTE_INFORMATION FsAttrs;
- DWORD sec_flavor;
- DWORD timeout;
- - struct {
- - BOOLEAN use_nfsv3attrsea_mode;
- - DWORD mode;
- - } createmode;
- + NFS41_MOUNT_CREATEMODE dir_createmode;
- + NFS41_MOUNT_CREATEMODE file_createmode;
- USHORT MountPathLen;
- BOOLEAN read_only;
- BOOLEAN write_thru;
- diff --git a/sys/nfs41sys_mount.c b/sys/nfs41sys_mount.c
- index 8317980..76da602 100644
- --- a/sys/nfs41sys_mount.c
- +++ b/sys/nfs41sys_mount.c
- @@ -58,6 +58,7 @@
- #include <winerror.h>
- #include <Ntstrsafe.h>
- +#include <stdbool.h>
- #include "nfs41sys_buildconfig.h"
- @@ -309,8 +310,12 @@ void nfs41_MountConfig_InitDefaults(
- Config->SecFlavor.Buffer = Config->sec_flavor_buffer;
- RtlCopyUnicodeString(&Config->SecFlavor, &AUTH_SYS_NAME);
- Config->timeout = UPCALL_TIMEOUT_DEFAULT;
- - Config->createmode.use_nfsv3attrsea_mode = TRUE;
- - Config->createmode.mode = NFS41_DRIVER_DEFAULT_CREATE_MODE;
- + Config->dir_createmode.use_nfsv3attrsea_mode = TRUE;
- + Config->dir_createmode.mode =
- + NFS41_DRIVER_DEFAULT_DIR_CREATE_MODE;
- + Config->file_createmode.use_nfsv3attrsea_mode = TRUE;
- + Config->file_createmode.mode =
- + NFS41_DRIVER_DEFAULT_FILE_CREATE_MODE;
- }
- static
- @@ -506,10 +511,39 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
- else
- RtlCopyUnicodeString(&Config->SecFlavor, &usValue);
- }
- - else if (wcsncmp(L"createmode", Name, NameLen) == 0) {
- + else if ((wcsncmp(L"createmode", Name, NameLen) == 0) ||
- + (wcsncmp(L"dircreatemode", Name, NameLen) == 0) ||
- + (wcsncmp(L"filecreatemode", Name, NameLen) == 0)) {
- #define NFSV3ATTRMODE_WSTR L"nfsv3attrmode+"
- #define NFSV3ATTRMODE_WCSLEN (14)
- #define NFSV3ATTRMODE_BYTELEN (NFSV3ATTRMODE_WCSLEN*sizeof(WCHAR))
- + bool set_dirmode = false;
- + bool set_filemode = false;
- +
- + switch(Name[0]) {
- + case L'c':
- + set_dirmode = true;
- + set_filemode = true;
- + break;
- + case L'd':
- + set_dirmode = true;
- + break;
- + case L'f':
- + set_filemode = true;
- + break;
- + default:
- + print_error("nfs41_MountConfig_ParseOptions: "
- + "invalid createmode name\n");
- + status = STATUS_INVALID_PARAMETER;
- + break;
- + }
- +
- +#ifdef DEBUG_MOUNTCONFIG
- + DbgP("nfs41_MountConfig_ParseOptions: "
- + "set_dirmode=%d set_filemode=%d\n",
- + (int)set_dirmode, (int)set_filemode);
- +#endif /* DEBUG_MOUNTCONFIG */
- +
- if ((usValue.Length >= NFSV3ATTRMODE_BYTELEN) &&
- (!wcsncmp(NFSV3ATTRMODE_WSTR,
- usValue.Buffer,
- @@ -524,8 +558,10 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
- "leftover option/usValue='%wZ'/%ld\n",
- &usValue, (long)usValue.Length);
- #endif /* DEBUG_MOUNTCONFIG */
- -
- - Config->createmode.use_nfsv3attrsea_mode = TRUE;
- + if (set_dirmode)
- + Config->dir_createmode.use_nfsv3attrsea_mode = TRUE;
- + if (set_filemode)
- + Config->file_createmode.use_nfsv3attrsea_mode = TRUE;
- }
- else {
- #ifdef DEBUG_MOUNTCONFIG
- @@ -533,28 +569,51 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
- "leftover option/usValue='%wZ'/%ld\n",
- &usValue, (long)usValue.Length);
- #endif /* DEBUG_MOUNTCONFIG */
- - Config->createmode.use_nfsv3attrsea_mode = FALSE;
- + if (set_dirmode)
- + Config->dir_createmode.use_nfsv3attrsea_mode = FALSE;
- + if (set_filemode)
- + Config->file_createmode.use_nfsv3attrsea_mode = FALSE;
- }
- - /*
- - * Reject mode values not prefixed with "0o", as
- - * |RtlUnicodeStringToInteger()| uses
- - * 0o (e.g. "0o123") as prefix for octal values,
- - * and does not understand the traditional
- - * UNIX/POSIX/ISO C "0" (e.g. "0123") prefix
- - */
- - if ((usValue.Length >= (3*sizeof(WCHAR))) &&
- - (usValue.Buffer[0] == L'0') &&
- - (usValue.Buffer[1] == L'o')) {
- - status = nfs41_MountConfig_ParseDword(Option,
- - &usValue,
- - &Config->createmode.mode, 0,
- - 0777);
- + if (usValue.Length >= (2*sizeof(WCHAR))) {
- + ULONG parse_base = 0;
- + ULONG cmode;
- +
- + if ((usValue.Buffer[0] == L'0') &&
- + iswdigit(usValue.Buffer[1])) {
- + /*
- + * Parse input as traditional POSIX/C octal number
- + * |RtlUnicodeStringToInteger()| only supports
- + * "0o" prefix for |parse_base==0|, so we skip
- + * the leading '0' and set |parse_base| to octal
- + * mode.
- + */
- + usValue.Buffer++;
- + usValue.Length-=sizeof(WCHAR);
- + parse_base = 8;
- +#ifdef DEBUG_MOUNTCONFIG
- + DbgP("nfs41_MountConfig_ParseOptions: "
- + "parsing POSIX/C octal number\n");
- +#endif /* DEBUG_MOUNTCONFIG */
- + }
- +
- + status = RtlUnicodeStringToInteger(&usValue,
- + parse_base, &cmode);
- if (status == STATUS_SUCCESS) {
- - if (Config->createmode.mode > 0777) {
- +#ifdef DEBUG_MOUNTCONFIG
- + DbgP("nfs41_MountConfig_ParseOptions: createmode "
- + "parsed mode=0%o\n", (int)cmode);
- +#endif /* DEBUG_MOUNTCONFIG */
- + if (cmode > 0777) {
- status = STATUS_INVALID_PARAMETER;
- print_error("mode 0%o out of bounds\n",
- - (int)Config->createmode.mode);
- + (int)cmode);
- + }
- + else {
- + if (set_dirmode)
- + Config->dir_createmode.mode = cmode;
- + if (set_filemode)
- + Config->file_createmode.mode = cmode;
- }
- }
- }
- @@ -566,10 +625,13 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
- DbgP("nfs41_MountConfig_ParseOptions: createmode: "
- "status=0x%lx, "
- - "createmode=(use_nfsv3attrsea_mode=%d, mode=0%o\n",
- + "dir_createmode=(use_nfsv3attrsea_mode=%d mode=0%o) "
- + "file_createmode=(use_nfsv3attrsea_mode=%d mode=0%o)\n",
- (long)status,
- - (int)Config->createmode.use_nfsv3attrsea_mode,
- - (int)Config->createmode.mode);
- + (int)Config->dir_createmode.use_nfsv3attrsea_mode,
- + (int)Config->dir_createmode.mode,
- + (int)Config->file_createmode.use_nfsv3attrsea_mode,
- + (int)Config->file_createmode.mode);
- }
- else {
- status = STATUS_INVALID_PARAMETER;
- @@ -945,14 +1007,14 @@ NTSTATUS nfs41_CreateVNetRoot(
- DbgP("Config->{ "
- "MntPt='%wZ', "
- "SrvName='%wZ', "
- - "use_nfspubfh=%d, "
- - "ReadOnly=%d, "
- - "write_thru=%d, "
- + "usenfspubfh=%d, "
- + "ro=%d, "
- + "writethru=%d, "
- "nocache=%d "
- "timebasedcoherency=%d "
- "timeout=%d "
- - "createmode.use_nfsv3attrsea_mode=%d "
- - "Config->createmode.mode=0%o "
- + "dir_cmode=(usenfsv3attrs=%d mode=0%o) "
- + "file_cmode=(usenfsv3attrs=%d mode=0%o) "
- "}\n",
- &Config->MntPt,
- &Config->SrvName,
- @@ -962,15 +1024,21 @@ NTSTATUS nfs41_CreateVNetRoot(
- Config->nocache?1:0,
- Config->timebasedcoherency?1:0,
- Config->timeout,
- - Config->createmode.use_nfsv3attrsea_mode?1:0,
- - Config->createmode.mode);
- + Config->dir_createmode.use_nfsv3attrsea_mode?1:0,
- + Config->dir_createmode.mode,
- + Config->file_createmode.use_nfsv3attrsea_mode?1:0,
- + Config->file_createmode.mode);
- pVNetRootContext->MountPathLen = Config->MntPt.Length;
- pVNetRootContext->timeout = Config->timeout;
- - pVNetRootContext->createmode.use_nfsv3attrsea_mode =
- - Config->createmode.use_nfsv3attrsea_mode;
- - pVNetRootContext->createmode.mode =
- - Config->createmode.mode;
- + pVNetRootContext->dir_createmode.use_nfsv3attrsea_mode =
- + Config->dir_createmode.use_nfsv3attrsea_mode;
- + pVNetRootContext->dir_createmode.mode =
- + Config->dir_createmode.mode;
- + pVNetRootContext->file_createmode.use_nfsv3attrsea_mode =
- + Config->file_createmode.use_nfsv3attrsea_mode;
- + pVNetRootContext->file_createmode.mode =
- + Config->file_createmode.mode;
- status = map_sec_flavor(&Config->SecFlavor, &pVNetRootContext->sec_flavor);
- if (status != STATUS_SUCCESS) {
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index 0018105..0a182af 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -58,6 +58,7 @@
- #include <winerror.h>
- #include <Ntstrsafe.h>
- +#include <stdbool.h>
- #include "nfs41sys_buildconfig.h"
- @@ -604,11 +605,26 @@ NTSTATUS nfs41_Create(
- entry->u.Open.open_owner_id = InterlockedIncrement(&open_owner_id);
- // if we are creating a file check if nfsv3attributes were passed in
- if (params->Disposition != FILE_OPEN && params->Disposition != FILE_OVERWRITE) {
- + bool is_dir;
- + bool use_nfsv3attrsea_mode;
- +
- + is_dir = (params->CreateOptions & FILE_DIRECTORY_FILE)?true:false;
- +
- /* Get default mode */
- - entry->u.Open.mode = pVNetRootContext->createmode.mode;
- + if (is_dir) {
- + entry->u.Open.mode = pVNetRootContext->dir_createmode.mode;
- + }
- + else {
- + entry->u.Open.mode = pVNetRootContext->file_createmode.mode;
- + }
- +
- + /* Prefer mode from NfsV3Attributes ? */
- + use_nfsv3attrsea_mode = (is_dir?
- + pVNetRootContext->dir_createmode.use_nfsv3attrsea_mode:
- + pVNetRootContext->file_createmode.use_nfsv3attrsea_mode);
- /* Use mode from NfsV3Attributes */
- - if (pVNetRootContext->createmode.use_nfsv3attrsea_mode &&
- + if (use_nfsv3attrsea_mode &&
- ea && AnsiStrEq(&NfsV3Attributes,
- ea->EaName, ea->EaNameLength)) {
- nfs3_attrs *attrs =
- @@ -616,13 +632,15 @@ NTSTATUS nfs41_Create(
- entry->u.Open.mode = attrs->mode;
- #ifdef DEBUG_OPEN
- - DbgP("creating file with EA mode 0%o\n",
- + DbgP("creating '%s' with EA mode 0%o\n",
- + (is_dir?"dir":"file"),
- entry->u.Open.mode);
- #endif
- }
- else {
- #ifdef DEBUG_OPEN
- - DbgP("creating file with default mode 0%o\n",
- + DbgP("creating '%s' with default mode 0%o\n",
- + (is_dir?"dir":"file"),
- entry->u.Open.mode);
- #endif
- }
- --
- 2.45.1
- From bc7972fb0d8bb6153efc6b422c7048bfbbcc3fba Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 6 Nov 2024 15:22:12 +0100
- Subject: [PATCH 2/3] daemon: |stateid4_cmp()| should compare each |stateid4|
- member seperately
- |stateid4_cmp()| should compare each |stateid4| member seperately
- to avoid issues with hidding padding bytes etc.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/util.h | 7 ++++++-
- 1 file changed, 6 insertions(+), 1 deletion(-)
- diff --git a/daemon/util.h b/daemon/util.h
- index 2b83bbf..7c90864 100644
- --- a/daemon/util.h
- +++ b/daemon/util.h
- @@ -162,7 +162,12 @@ static __inline int stateid4_cmp(
- IN const stateid4 *restrict s1,
- IN const stateid4 *restrict s2)
- {
- - return memcmp(s1, s2, sizeof(stateid4));
- + if (s1->seqid > s2->seqid)
- + return 1;
- + else if (s1->seqid < s2->seqid)
- + return -1;
- + else
- + return memcmp(s1->other, s2->other, NFS4_STATEID_OTHER);
- }
- static __inline void open_delegation4_cpy(
- --
- 2.45.1
- From 06165d72695d82ab254f941b834825519758c547 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Wed, 6 Nov 2024 15:39:08 +0100
- Subject: [PATCH 3/3] tests: Add nfs_server_setup.txt as notes how to setup
- servers for testing
- Add nfs_server_setup.txt as notes how to setup servers for testing
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/nfs_server_setup.txt | 43 ++++++++++++++++++++++++++++++++++++++
- 1 file changed, 43 insertions(+)
- create mode 100644 tests/nfs_server_setup.txt
- diff --git a/tests/nfs_server_setup.txt b/tests/nfs_server_setup.txt
- new file mode 100644
- index 0000000..68836e8
- --- /dev/null
- +++ b/tests/nfs_server_setup.txt
- @@ -0,0 +1,43 @@
- +#
- +# NFSv4.1 server setup for testing
- +#
- +
- +#
- +# TODO:
- +# - Debian Linux NFSv4.1 server setup
- +# - Solaris 11.4 NFSv4.1 server setup
- +# - Illumos 11.4 NFSv4.1 server setup
- +# - FreeBSD NFSv4.1 server setup
- +#
- +
- +#
- +# Windows Server 2019 NFSv4.1 server setup
- +#
- +
- +# Install Windows Server 2019, then run these commands in an
- +# Adminstrator PowerShell
- +Install-WindowsFeature -name Telnet-Client
- +
- +Import-Module ServerManager
- +Add-WindowsFeature FS-NFS-Service
- +Import-Module NFS
- +
- +mkdir C:\shares\nfsfolder
- +echo "hello world" >C:\shares\nfsfolder\testfile
- +icacls.exe C:\shares\nfsfolder /grant "Everyone:(F)"
- +
- +New-NfsShare -Name nfs1 -Path C:\shares\nfsfolder
- +Set-NfsShare -Name nfs1 -Permission readwrite -Authentication "sys" -EnableUnmappedAccess $True -AllowRootAccess $True
- +Set-NfsServerConfiguration -HideFilesBeginningInDot $True
- +
- +Grant-NfsSharePermission -Name nfs1 -ClientName "192.168.209.129" -ClientType "host" -AllowRootAccess $True -Permission readwrite
- +Grant-NfsSharePermission -Name nfs1 -ClientName "127.0.0.1" -ClientType "host" -AllowRootAccess $True -Permission readwrite
- +
- +nfsadmin server stop
- +nfsadmin server start
- +
- +Start-Service -Name ms-nfs41-client-service
- +
- +C:\cygwin64\sbin\nfs_mount -o rw N nfs://192.168.209.129//
- +
- +# EOF.
- --
- 2.45.1
msnfs41client: Add dircreatemode=,filecreatemode= mount options, POSIX/ISO C octal mode, Windows Server 2019 NFSV4.1 server setup+misc, 2024-11-06
Posted by Anonymous on Wed 6th Nov 2024 14:56
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.