- From 2ff6132b3aa8945db795e5ffb3824358d99b041e Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 13 Dec 2025 21:51:46 +0100
- Subject: [PATCH 1/7] tests: Add parallel and serial build modes to
- nfsbuildtest.ksh93
- Add parallel and serial build modes to nfsbuildtest.ksh93.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/manual_testing.txt | 4 +-
- tests/nfsbuildtest/nfsbuildtest.ksh93 | 136 ++++++++++++++++++++++----
- 2 files changed, 117 insertions(+), 23 deletions(-)
- diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
- index 57c9013..3305a6a 100644
- --- a/tests/manual_testing.txt
- +++ b/tests/manual_testing.txt
- @@ -1,5 +1,5 @@
- #
- -# ms-nfs41-client manual testing sequence, 2025-11-03
- +# ms-nfs41-client manual testing sequence, 2025-12-12
- #
- # Draft version, needs to be turned into automated tests
- # if possible
- @@ -1185,7 +1185,7 @@ rm -f /cygdrive/n/winntfs_filedisk_001.img
- filedisk /mount 2 'N:\winntfs_filedisk_001.img' 1T U:
- format.com U: /FS:NTFS /A:8192 "/V:NTFSonNFS4_001" /Q /X
- mkdir /cygdrive/u/test1 && cd /cygdrive/u/test1
- -rm -Rfv bash && time nice ksh93 /home/roland_mainz/work/msnfs41_uidmapping/ms-nfs41-client/tests/nfsbuildtest/nfsbuildtest.ksh93 bash build
- +rm -Rfv bash && time nice ksh93 /home/roland_mainz/work/msnfs41_uidmapping/ms-nfs41-client/tests/nfsbuildtest/nfsbuildtest.ksh93 bash build.parallel
- cd
- filedisk /umount U:
- lssparse /cygdrive/n/winntfs_filedisk_001.img
- diff --git a/tests/nfsbuildtest/nfsbuildtest.ksh93 b/tests/nfsbuildtest/nfsbuildtest.ksh93
- index 5cd2015..11671ca 100644
- --- a/tests/nfsbuildtest/nfsbuildtest.ksh93
- +++ b/tests/nfsbuildtest/nfsbuildtest.ksh93
- @@ -36,17 +36,17 @@
- # - build bash:
- # $ ksh93 nfsbuildtest.ksh93 bash clean
- # $ ksh93 nfsbuildtest.ksh93 bash createcache
- -# $ ksh93 nfsbuildtest.ksh93 bash build
- +# $ ksh93 nfsbuildtest.ksh93 bash build.parallel
- #
- # - build gcc:
- # $ ksh93 nfsbuildtest.ksh93 gcc clean
- # $ ksh93 nfsbuildtest.ksh93 gcc createcache
- -# $ ksh93 nfsbuildtest.ksh93 gcc build
- +# $ ksh93 nfsbuildtest.ksh93 gcc build.parallel
- #
- # - build ms-nfs41-client:
- # $ ksh93 nfsbuildtest.ksh93 msnfs41client clean
- # $ ksh93 nfsbuildtest.ksh93 msnfs41client createcache
- -# $ ksh93 nfsbuildtest.ksh93 msnfs41client build
- +# $ ksh93 nfsbuildtest.ksh93 msnfs41client build.serial
- #
- function gcc_createcache
- @@ -98,6 +98,18 @@ function gcc_build
- set -o errexit
- set -o nounset
- + typeset subcmd="$1"
- + integer build_parallel
- +
- + if [[ "$subcmd" == *.serial* ]] ; then
- + (( build_parallel=0 ))
- + elif [[ "$subcmd" == *.parallel* ]] ; then
- + (( build_parallel=1 ))
- + else
- + print -u2 -f $"Neither '.serial' or '.parallel' set in subcmd='%q'.\n" "$subcmd"
- + return 1
- + fi
- +
- #
- # build config
- #
- @@ -235,10 +247,24 @@ function gcc_build
- # during $ make -j32 all # missing
- #
- (
- + typeset -a make_options=( )
- +
- + if (( build_parallel == 1 )) ; then
- + make_options+=(
- + '--load-average 32'
- + '-j16'
- + )
- + else
- + make_options+=(
- + '--load-average 32'
- + '-j1'
- + )
- + fi
- +
- set -o xtrace
- - time ksh93 -c 'export SHELL=/bin/ksh93 ; (yes | make --load-average 32 -j12 all)'
- + time ksh93 -c 'set -o xtrace ; export SHELL=/bin/ksh93 ; (yes | make "$@" all)' dummy "${make_options[@]}"
- printf "######## gcc build make all returned %d\n" $?
- - time ksh93 -c 'export SHELL=/bin/ksh93 ; (yes | make --load-average 32 -j12 install DESTDIR="$PWD/install_root")'
- + time ksh93 -c 'set -o xtrace ; export SHELL=/bin/ksh93 ; (yes | make "$@" install DESTDIR="$PWD/install_root")' dummy "${make_options[@]}"
- printf "######## gcc build make install returned %d\n" $?
- )
- @@ -285,6 +311,18 @@ function bash_build
- set -o errexit
- set -o nounset
- + typeset subcmd="$1"
- + integer build_parallel
- +
- + if [[ "$subcmd" == *.serial* ]] ; then
- + (( build_parallel=0 ))
- + elif [[ "$subcmd" == *.parallel* ]] ; then
- + (( build_parallel=1 ))
- + else
- + print -u2 -f $"Neither '.serial' or '.parallel' set in subcmd='%q'.\n" "$subcmd"
- + return 1
- + fi
- +
- compound cygwin_vers
- get_cpv_cygwin_version cygwin_vers
- @@ -413,17 +451,26 @@ function bash_build
- #
- # build bash
- #
- + typeset -a make_options=( )
- +
- + if (( build_parallel == 1 )) ; then
- + make_options+=( '-j16' )
- + else
- + make_options+=( '-j1' )
- + fi
- +
- + set -o xtrace
- if $config_use_posix_ksh93_builtins ; then
- if is_cygwin && (( (cygwin_vers.major*1000+cygwin_vers.minor) >= 3005 )) ; then
- - time ksh93 -c 'export SHELL=/bin/ksh93 ; bmake -j16 install DESTDIR="$PWD/install_root"'
- + time ksh93 -c 'set -o xtrace ; export SHELL=/bin/ksh93 ; bmake "$@" install DESTDIR="$PWD/install_root"' dummy "${make_options[@]}"
- else
- - time ksh93 -c 'export SHELL=/bin/ksh93 ; make -j16 install DESTDIR="$PWD/install_root"'
- + time ksh93 -c 'set -o xtrace ; export SHELL=/bin/ksh93 ; make "$@" install DESTDIR="$PWD/install_root"' dummy "${make_options[@]}"
- fi
- else
- if is_cygwin && (( (cygwin_vers.major*1000+cygwin_vers.minor) >= 3005 )) ; then
- - time bash -c 'export SHELL=/bin/bash ; bmake -j16 install DESTDIR="$PWD/install_root"'
- + time bash -c 'set -o xtrace ; export SHELL=/bin/bash ; bmake "$@" install DESTDIR="$PWD/install_root"' dummy "${make_options[@]}"
- else
- - time bash -c 'export SHELL=/bin/bash ; make -j16 install DESTDIR="$PWD/install_root"'
- + time bash -c 'set -o xtrace ; export SHELL=/bin/bash ; make "$@" install DESTDIR="$PWD/install_root"' dummy "${make_options[@]}"
- fi
- fi
- echo $?
- @@ -470,6 +517,45 @@ function msnfs41client_build
- set -o errexit
- set -o nounset
- + typeset subcmd="$1"
- + integer build_parallel
- +
- + if [[ "$subcmd" == *.serial* ]] ; then
- + (( build_parallel=0 ))
- + elif [[ "$subcmd" == *.parallel* ]] ; then
- + typeset file_case_sensitive_search_val
- +
- + #
- + # Visual Studio 2019/2022 randomly fails to do a parallel build
- + # on a case-sensitive filesystem, usually project include
- + # files cannot be found.
- + # (looking at the kernel debug log it seems the characters
- + # in the include filename path are turned into uppercase
- + # letters, but we do not know whether this a kernel or Visual
- + # Studio issue)
- + #
- + file_case_sensitive_search_val="$(/usr/lib/csih/getVolInfo "$PWD" | awk '/FILE_CASE_SENSITIVE_SEARCH/ { print $NF; exit }')"
- +
- + case "$file_case_sensitive_search_val" in
- + 'FALSE')
- + # OK
- + ;;
- + 'TRUE')
- + print -u2 -f $"ERROR: Visual Studio MSBuild+compiler require a case-insensitive filesystem for parallel builds.\n"
- + return 1
- + ;;
- + *)
- + print -u2 -f $"ERROR: Unexpected value from getVolInfo/FILE_CASE_SENSITIVE_SEARCH '%q'\n" "$file_case_sensitive_search_val"
- + return 1
- + ;;
- + esac
- +
- + (( build_parallel=1 ))
- + else
- + print -u2 -f $"Neither '.serial' or '.parallel' set in subcmd='%q'.\n" "$subcmd"
- + return 1
- + fi
- +
- #
- # build config
- #
- @@ -549,6 +635,14 @@ function msnfs41client_build
- # build ms-nfs41-client
- #
- (
- + typeset -a make_options=( )
- +
- + if (( build_parallel == 1 )) ; then
- + make_options+=( '-j8' )
- + else
- + make_options+=( '-j1' )
- + fi
- +
- #
- # We assume here:
- # Visual Studio 2019 --> Win10 64bit+32bit build,
- @@ -564,9 +658,9 @@ function msnfs41client_build
- sed -i -E 's/<PlatformToolset>v...<\/PlatformToolset>/<PlatformToolset>v143<\/PlatformToolset>/g' $(find 'build.vc19' -name \*.vcxproj)
- # build
- - time make -j1 -f cygwin/Makefile build64
- - time make -j1 -f cygwin/Makefile installdest64
- - time make -j1 -f cygwin/Makefile bintarball64
- + time make "${make_options[@]}" -f cygwin/Makefile build64
- + time make "${make_options[@]}" -f cygwin/Makefile installdest64
- + time make "${make_options[@]}" -f cygwin/Makefile bintarball64
- elif [[ -x '/cygdrive/c/Program Files/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe' || \
- -x '/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/MSBuild.exe' ]] ; then
- # Visual Studio 19 64bit+32bit kernel codepath
- @@ -582,9 +676,9 @@ function msnfs41client_build
- sed -i -E 's/<PlatformToolset>v...<\/PlatformToolset>/<PlatformToolset>v142<\/PlatformToolset>/g' $(find 'build.vc19' -name \*.vcxproj)
- # build
- - time make -j1 -f cygwin/Makefile build
- - time make -j1 -f cygwin/Makefile installdest
- - time make -j1 -f cygwin/Makefile bintarball
- + time make "${make_options[@]}" -f cygwin/Makefile build
- + time make "${make_options[@]}" -f cygwin/Makefile installdest
- + time make "${make_options[@]}" -f cygwin/Makefile bintarball
- else
- print -u2 -f "%s: Unknown compiler.\n" "$0"
- exit 5
- @@ -718,7 +812,7 @@ function main
- gcc_createcache
- return $?
- ;;
- - 'gcc_build')
- + 'gcc_build'*)
- is_toolkit_pkg_installed itp 'git' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-core' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-g++' || (( errc++ ))
- @@ -736,7 +830,7 @@ function main
- is_toolkit_pkg_installed itp 'gettext' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gettext-devel' || (( errc++ ))
- (( errc > 0 )) && return 1
- - gcc_build
- + gcc_build "${subcmd}"
- return $?
- ;;
- 'gcc_clean')
- @@ -748,7 +842,7 @@ function main
- bash_createcache
- return $?
- ;;
- - 'bash_build')
- + 'bash_build'*)
- is_toolkit_pkg_installed itp 'git' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-core' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-g++' || (( errc++ ))
- @@ -776,7 +870,7 @@ function main
- is_toolkit_pkg_installed itp 'gettext-devel' || (( errc++ ))
- is_toolkit_pkg_installed itp 'texinfo' || (( errc++ ))
- (( errc > 0 )) && return 1
- - bash_build
- + bash_build "${subcmd}"
- return $?
- ;;
- 'bash_clean')
- @@ -788,7 +882,7 @@ function main
- msnfs41client_createcache
- return $?
- ;;
- - 'msnfs41client_build')
- + 'msnfs41client_build'*)
- is_toolkit_pkg_installed itp 'git' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-core' || (( errc++ ))
- is_toolkit_pkg_installed itp 'gcc-g++' || (( errc++ ))
- @@ -799,7 +893,7 @@ function main
- is_toolkit_pkg_installed itp 'bzip2' || (( errc++ ))
- is_toolkit_pkg_installed itp 'openssl' || (( errc++ ))
- (( errc > 0 )) && return 1
- - msnfs41client_build
- + msnfs41client_build "${subcmd}"
- return $?
- ;;
- 'msnfs41client_clean')
- --
- 2.51.0
- From 4cad86d863d45584198a46573f0527ff0bb4401b Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 13 Dec 2025 21:58:07 +0100
- Subject: [PATCH 2/7] tests: Update manual build instructions msnfs41client
- itself in manual_testing.txt
- Update manual build instructions msnfs41client itself in manual_testing.txt.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/manual_testing.txt | 11 ++++++-----
- 1 file changed, 6 insertions(+), 5 deletions(-)
- diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
- index 3305a6a..a520bfb 100644
- --- a/tests/manual_testing.txt
- +++ b/tests/manual_testing.txt
- @@ -713,17 +713,18 @@ make clean && make -j4 all
- #
- -# ms-nfs41-client
- +# ms-nfs41-client with Visual Studio 2019 on Windows 10/64bit
- #
- git clone https://github.com/kofemann/ms-nfs41-client.git
- cd ms-nfs41-client
- -export PATH+=":/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/"
- +git config --global --add safe.directory "$PWD"
- +
- +export PATH="/cygdrive/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/:$PATH" CERTIFICATE_THUMBPRINT="$(powershell -c 'Get-ChildItem -Path Cert:\CurrentUser\My | Where-Object {$_.Subject -like "*WDKTestCert*"} | Select-Object -ExpandProperty Thumbprint')"
- # repeat:
- # clean
- -rm -vRf $(find . -name Debug -o -name Release)
- +make -f cygwin/Makefile clean ; rm -Rfv destdir
- # build
- -MSBuild.exe build.vc19/nfs41-client.sln -t:Build -p:Configuration=Debug -p:Platform=x64
- -MSBuild.exe build.vc19/nfs41-client.sln -t:Build -p:Configuration=Release -p:Platform=x64
- +time ksh93 -c 'make -j8 -f cygwin/Makefile build && make -j8 -f cygwin/Makefile installdest && make -j8 -f cygwin/Makefile bintarball'
- #
- --
- 2.51.0
- From 71df20ce0904db5e3788103d9a8e260d4a734add Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Sat, 13 Dec 2025 22:17:53 +0100
- Subject: [PATCH 3/7] README.md,docs: Update kernel debug log instructions
- Update kernel debug log instructions.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- README.md | 19 ++++++++++++-------
- docs/README.xml | 21 +++++++++++++++++----
- 2 files changed, 29 insertions(+), 11 deletions(-)
- diff --git a/README.md b/README.md
- index 0b9c4a0..b8bdbe7 100644
- --- a/README.md
- +++ b/README.md
- @@ -829,17 +829,22 @@ Within WSL mount UNC path returned by `/sbin/nfs_mount`
- # Troubleshooting && finding bugs/debugging
- -- `nfsd_debug.exe` has the `-d` option to set a level for debug output.
- +- Debug level of NFS Client daemon:
- +
- + `nfsd_debug.exe` has the `-d` option to set a level for debug output.
- Edit `/sbin/msnfs41client` to set the `"-d"` option.
- -- The "msnfs41client" script has the option "`watch_kernel_debuglog`" to
- - get the debug output of the kernel module.
- +- Viewing kernel debug output:
- +
- + - The `/sbin/msnfs41client` script has the option
- + "`watch_kernel_debuglog`" to get the debug output of the kernel
- + module.
- - Run as Administrator: `$ /sbin/msnfs41client watch_kernel_debuglog #`
- + Run as Administrator:
- + `$ /sbin/msnfs41client watch_kernel_debuglog #`
- - Currently requires DebugView
- - (<https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview>)
- - to be installed.
- + - Use Windows Internals `DebugView`
- + (<https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview>).
- - Watching network traffic:
- diff --git a/docs/README.xml b/docs/README.xml
- index 4821cf9..45ba334 100644
- --- a/docs/README.xml
- +++ b/docs/README.xml
- @@ -924,15 +924,28 @@ Datei befindet. Versuchen Sie, die Datei woanders zu speichern.</programlisting>
- <title>Troubleshooting && finding bugs/debugging</title>
- <itemizedlist>
- <listitem>
- + <para>Debug level of NFS Client daemon:</para>
- <para><filename>nfsd_debug.exe</filename> has the <literal>-d</literal> option to set a level for debug output. Edit <filename>/sbin/msnfs41client</filename> to set the <literal>"-d"</literal> option.</para>
- </listitem>
- <listitem>
- - <para>The "msnfs41client" script has the option "<literal>watch_kernel_debuglog</literal>" to get the debug output of the kernel module.</para>
- - <para>Run as Administrator: <command>$ /sbin/msnfs41client watch_kernel_debuglog #</command></para>
- - <para>Currently requires DebugView (<link xl:href="https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview">https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview</link>) to be installed.</para>
- + <para>Viewing kernel debug output:</para>
- + <para>
- + <itemizedlist>
- + <listitem>
- + <para>The <command>/sbin/msnfs41client</command> script has the option "<literal>watch_kernel_debuglog</literal>"
- + to get the debug output of the kernel module.</para>
- + <para>Run as Administrator: <command>$ /sbin/msnfs41client watch_kernel_debuglog #</command></para>
- + </listitem>
- + <listitem>
- + <para>Use Windows Internals <command>DebugView</command>
- + (<link xl:href="https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview">https://learn.microsoft.com/en-gb/sysinternals/downloads/debugview</link>).</para>
- + </listitem>
- + </itemizedlist>
- + </para>
- </listitem>
- <listitem>
- - <para>Watching network traffic:
- + <para>Watching network traffic:</para>
- + <para>
- <itemizedlist>
- <listitem><para>Use <command>$ /sbin/msnfs41client watch_nfs_traffic #</command> to watch the NFS network traffic</para></listitem>
- <listitem>
- --
- 2.51.0
- From 094b610affe9e7475e9792f5278d643c1089f9b1 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 15 Dec 2025 20:38:45 +0100
- Subject: [PATCH 4/7] daemon,include,sys,tests: Provide future-proof unified
- SID buffer size macro
- Provide future-proof unified SID buffer size macro, rounded up to
- the next 64 byte value (=128 bytes).
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/sid.c | 12 ++++++------
- daemon/sid.h | 4 ++--
- include/nfs41_driver.h | 7 +++++++
- sys/nfs41sys_driver.h | 7 ++-----
- sys/nfs41sys_openclose.c | 4 ++--
- sys/nfs41sys_util.c | 6 +++---
- sys/nfs41sys_util.h | 2 +-
- tests/winsg/winsg.c | 13 ++++++++++---
- 8 files changed, 33 insertions(+), 22 deletions(-)
- diff --git a/daemon/sid.c b/daemon/sid.c
- index afd2ee3..d866f5c 100644
- --- a/daemon/sid.c
- +++ b/daemon/sid.c
- @@ -47,7 +47,7 @@ int create_unknownsid(WELL_KNOWN_SID_TYPE type, PSID *sid, DWORD *sid_len)
- int status;
- int lasterr;
- - *sid_len = SECURITY_MAX_SID_SIZE+1;
- + *sid_len = MAX_SID_BUFFER_SIZE;
- *sid = malloc(*sid_len);
- if (*sid == NULL) {
- status = ERROR_INSUFFICIENT_BUFFER;
- @@ -338,7 +338,7 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
- /* Replace the cache entry */
- sidcache_entry *e = &cache->entries[freeEntryIndex];
- DWORD sid_len = GetLengthSid(value);
- - EASSERT_MSG((sid_len <= SECURITY_MAX_SID_SIZE),
- + EASSERT_MSG((sid_len <= MAX_SID_BUFFER_SIZE),
- ("sid_len=%ld\n", (long)sid_len));
- e->sid = (PSID)e->sid_buffer;
- if (!CopySid(sid_len, e->sid, value)) {
- @@ -510,12 +510,12 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
- }
- #endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
- - *sid = malloc(SECURITY_MAX_SID_SIZE+1);
- + *sid = malloc(MAX_SID_BUFFER_SIZE);
- if (*sid == NULL) {
- status = GetLastError();
- goto out;
- }
- - *sid_len = SECURITY_MAX_SID_SIZE;
- + *sid_len = MAX_SID_BUFFER_SIZE;
- domain_len = sizeof(domain_buff);
- status = lookupaccountnameutf8(NULL, nfsname, *sid, sid_len,
- @@ -547,8 +547,8 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
- switch(status) {
- case ERROR_INSUFFICIENT_BUFFER:
- /*
- - * This should never happen, as |SECURITY_MAX_SID_SIZE| is
- - * the largest possible SID buffer size for Windows
- + * This should never happen, as |MAX_SID_BUFFER_SIZE| should be
- + * larger than the largest possible SID buffer size for Windows
- */
- eprintf("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
- "LookupAccountName failed with "
- diff --git a/daemon/sid.h b/daemon/sid.h
- index 3e12c6d..e6f2be8 100644
- --- a/daemon/sid.h
- +++ b/daemon/sid.h
- @@ -56,11 +56,11 @@ extern sidcache group_sidcache;
- #ifdef _MSC_BUILD
- /* Visual Studio */
- #define DECLARE_SID_BUFFER(varname) \
- - __declspec(align(16)) char (varname)[SECURITY_MAX_SID_SIZE+1]
- + __declspec(align(16)) char (varname)[MAX_SID_BUFFER_SIZE]
- #else
- /* clang */
- #define DECLARE_SID_BUFFER(varname) \
- - char (varname)[SECURITY_MAX_SID_SIZE+1] __attribute__((aligned(16)))
- + char (varname)[MAX_SID_BUFFER_SIZE] __attribute__((aligned(16)))
- #endif /* _MSC_BUILD */
- diff --git a/include/nfs41_driver.h b/include/nfs41_driver.h
- index 8aad552..12f14bf 100644
- --- a/include/nfs41_driver.h
- +++ b/include/nfs41_driver.h
- @@ -65,6 +65,13 @@
- */
- #define NFS41_SYS_MAX_PATH_LEN 4096
- +/*
- + * |MAX_SID_BUFFER_SIZE| - Number of bytes needed to store an SID,
- + * rounded up to 64byte boundaries
- + * (note this must ALWAYS be equal or larger than |SECURITY_MAX_SID_SIZE|)
- + */
- +#define MAX_SID_BUFFER_SIZE (128)
- +
- /* |_nfs41_opcodes| and |g_upcall_op_table| must be in sync! */
- typedef enum _nfs41_opcodes {
- NFS41_SYSOP_INVALID_OPCODE0,
- diff --git a/sys/nfs41sys_driver.h b/sys/nfs41sys_driver.h
- index a998ed6..6eb05d1 100644
- --- a/sys/nfs41sys_driver.h
- +++ b/sys/nfs41sys_driver.h
- @@ -97,9 +97,6 @@ typedef struct __nfs41_timings {
- /* Windows SMB driver also uses |IO_NETWORK_INCREMENT| */
- #define IO_NFS41FS_INCREMENT IO_NETWORK_INCREMENT
- -/* Number of bytes needed to store an SID */
- -#define SID_BUF_SIZE (SECURITY_MAX_SID_SIZE)
- -
- #define DISABLE_CACHING 0
- #define ENABLE_READ_CACHING 1
- #define ENABLE_WRITE_CACHING 2
- @@ -517,9 +514,9 @@ typedef struct _NFS41_SRV_OPEN {
- * aligned on Windows 10/32bit
- */
- #ifdef _MSC_BUILD
- - __declspec(align(16)) char open_pg_sidbuff[SID_BUF_SIZE];
- + __declspec(align(16)) char open_pg_sidbuff[MAX_SID_BUFFER_SIZE];
- #else
- - char open_pg_sidbuff[SID_BUF_SIZE] __attribute__((aligned(16)));
- + char open_pg_sidbuff[MAX_SID_BUFFER_SIZE] __attribute__((aligned(16)));
- #endif /* _MSC_BUILD */
- /* |open_pg_sid| - PrimaryGroup SID used for opening this NFS handle */
- diff --git a/sys/nfs41sys_openclose.c b/sys/nfs41sys_openclose.c
- index ba3c847..79b7e8a 100644
- --- a/sys/nfs41sys_openclose.c
- +++ b/sys/nfs41sys_openclose.c
- @@ -1388,9 +1388,9 @@ NTSTATUS nfs41_ShouldTryToCollapseThisOpen(
- * aligned on Windows 10/32bit
- */
- #ifdef _MSC_BUILD
- - __declspec(align(16)) char pg_sidbuff[SID_BUF_SIZE];
- + __declspec(align(16)) char pg_sidbuff[MAX_SID_BUFFER_SIZE];
- #else
- - char pg_sidbuff[SID_BUF_SIZE] __attribute__((aligned(16)));
- + char pg_sidbuff[MAX_SID_BUFFER_SIZE] __attribute__((aligned(16)));
- #endif /* _MSC_BUILD */
- PSID pg_sid = (PSID)&pg_sidbuff[0];
- diff --git a/sys/nfs41sys_util.c b/sys/nfs41sys_util.c
- index c6e95de..345a4b9 100644
- --- a/sys/nfs41sys_util.c
- +++ b/sys/nfs41sys_util.c
- @@ -224,7 +224,7 @@ PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- _Success_(return == true) bool
- get_primarygroup_id(
- - _Out_writes_bytes_(SID_BUF_SIZE) SID *restrict ret_sid)
- + _Out_writes_bytes_(MAX_SID_BUFFER_SIZE) SID *restrict ret_sid)
- {
- PACCESS_TOKEN token = NULL;
- PVOID infoBuffer = NULL;
- @@ -263,10 +263,10 @@ get_primarygroup_id(
- }
- ULONG sidLength = RtlLengthSid(primaryGroup->PrimaryGroup);
- - if ((sidLength == 0UL) || (sidLength > SID_BUF_SIZE)) {
- + if ((sidLength == 0UL) || (sidLength > MAX_SID_BUFFER_SIZE)) {
- DbgP("get_primarygroup_id: "
- "SID length (%lu) invalid or too large for buffer (%u)\n",
- - sidLength, (unsigned)SID_BUF_SIZE);
- + sidLength, (unsigned)MAX_SID_BUFFER_SIZE);
- retval = false;
- goto out_cleanup_sequeryinfotok;
- }
- diff --git a/sys/nfs41sys_util.h b/sys/nfs41sys_util.h
- index 39f49de..a003fea 100644
- --- a/sys/nfs41sys_util.h
- +++ b/sys/nfs41sys_util.h
- @@ -73,7 +73,7 @@ PQUERY_ON_CREATE_ECP_CONTEXT get_queryoncreateecpcontext(
- __in PIRP Irp);
- _Success_(return == true) bool
- get_primarygroup_id(
- - _Out_writes_bytes_(SID_BUF_SIZE) SID *restrict ret_sid);
- + _Out_writes_bytes_(MAX_SID_BUFFER_SIZE) SID *restrict ret_sid);
- void qocec_file_stat_information(
- OUT QUERY_ON_CREATE_FILE_STAT_INFORMATION *restrict qocfsi,
- IN const NFS41_FCB *restrict nfs41_fcb);
- diff --git a/tests/winsg/winsg.c b/tests/winsg/winsg.c
- index bce272e..ba8e8d2 100644
- --- a/tests/winsg/winsg.c
- +++ b/tests/winsg/winsg.c
- @@ -62,6 +62,13 @@
- #define WIN32_POWERSHELLEXE_PATH \
- L"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
- +/*
- + * |MAX_SID_BUFFER_SIZE| - Number of bytes needed to store an SID,
- + * rounded up to 64byte boundaries
- + * (note this must ALWAYS be equal or larger than |SECURITY_MAX_SID_SIZE|)
- + */
- +#define MAX_SID_BUFFER_SIZE (128)
- +
- /*
- * DECLARE_SID_BUFFER - declare a buffer for a SID value
- * Note that buffers with SID values must be 16byte aligned
- @@ -71,11 +78,11 @@
- #ifdef _MSC_BUILD
- /* Visual Studio */
- #define DECLARE_SID_BUFFER(varname) \
- - __declspec(align(16)) char (varname)[SECURITY_MAX_SID_SIZE+1]
- + __declspec(align(16)) char (varname)[MAX_SID_BUFFER_SIZE]
- #else
- /* clang */
- #define DECLARE_SID_BUFFER(varname) \
- - char (varname)[SECURITY_MAX_SID_SIZE+1] __attribute__((aligned(16)))
- + char (varname)[MAX_SID_BUFFER_SIZE] __attribute__((aligned(16)))
- #endif /* _MSC_BUILD */
- /*
- @@ -492,7 +499,7 @@ int wmain(int ac, wchar_t *av[])
- DECLARE_SID_BUFFER(sidbuff);
- PSID pgsid = (PSID)sidbuff;
- - DWORD pgsid_size = SECURITY_MAX_SID_SIZE;
- + DWORD pgsid_size = MAX_SID_BUFFER_SIZE;
- if (!get_group_sid(newgrpname, pgsid, &pgsid_size)) {
- (void)fwprintf(stderr, L"%ls: Could not find group '%ls'.\n",
- --
- 2.51.0
- From edf35ddde43102820efd92fff4f12a1247ba5291 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Mon, 15 Dec 2025 22:05:33 +0100
- Subject: [PATCH 5/7] daemon: Symlink creation should use authtoken
- PrimaryGroup for newgrp(1)/setgid() support
- Symlink creation should use authtoken PrimaryGroup for
- newgrp(1)/setgid() support.
- Reported-by: Cedric Blancher <cedric.blancher@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/open.c | 58 +++++++++++++++++++++++++++++++++++++++++++-
- daemon/symlink.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++--
- 2 files changed, 117 insertions(+), 3 deletions(-)
- diff --git a/daemon/open.c b/daemon/open.c
- index 9cfc28b..5b120bb 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -1116,13 +1116,69 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
- args->symlink.path, &state->parent, &state->file, &info);
- if (status) {
- eprintf("handle_open(args->path='%s'): "
- - "nfs41_create() for symlink='%s' failed with '%s'\n",
- + "nfs41_create() for cygwin symlink='%s' failed with '%s'\n",
- args->path,
- args->symlink.path,
- nfs_error_string(status));
- status = map_symlink_errors(status);
- goto out_free_state;
- }
- +
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- + /*
- + * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- + * fetching groupname from auth token for new files and
- + * do a "manual" chgrp on the new file
- + *
- + * Note that |RPCSEC_AUTH_NONE| does not have any
- + * user/group information, therefore newgrp will be a
- + * NOP here.
- + */
- + if (state->session->client->rpc->sec_flavor != RPCSEC_AUTH_NONE) {
- + char *s;
- + int chgrp_status;
- + stateid_arg stateid;
- + nfs41_file_info createchgrpattrs = {
- + .attrmask.count = 2,
- + .attrmask.arr[0] = 0,
- + .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
- + .owner_group = createchgrpattrs.owner_group_buf
- + };
- +
- + /* fixme: we should store the |owner_group| name in |upcall| */
- + if (!get_token_primarygroup_name(upcall->currentthread_token,
- + createchgrpattrs.owner_group)) {
- + eprintf("handle_open(args->path='%s')/cygwin symlink: "
- + "get_token_primarygroup_name() failed.\n",
- + args->path);
- + goto create_symlink_chgrp_out;
- + }
- + s = createchgrpattrs.owner_group+
- + strlen(createchgrpattrs.owner_group);
- + s = stpcpy(s, "@");
- + (void)stpcpy(s, nfs41dg->localdomain_name);
- + DPRINTF(1,
- + ("handle_open(state->file.name.name='%s')/cygwin symlink: "
- + "owner_group='%s'\n",
- + state->file.name.name,
- + createchgrpattrs.owner_group));
- +
- + nfs41_open_stateid_arg(state, &stateid);
- + chgrp_status = nfs41_setattr(state->session,
- + &state->file, &stateid, &createchgrpattrs);
- + if (chgrp_status) {
- + eprintf("handle_open(args->path='%s')/cygwin symlink: "
- + "nfs41_setattr(owner_group='%s') "
- + "failed with error '%s'.\n",
- + args->path,
- + createchgrpattrs.owner_group,
- + nfs_error_string(chgrp_status));
- + }
- +create_symlink_chgrp_out:
- + ;
- + }
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- +
- nfs_to_basic_info(state->file.name.name,
- state->file.fh.superblock,
- &info,
- diff --git a/daemon/symlink.c b/daemon/symlink.c
- index d03c738..4efb022 100644
- --- a/daemon/symlink.c
- +++ b/daemon/symlink.c
- @@ -26,9 +26,14 @@
- #include "nfs41_driver.h"
- #include "nfs41_ops.h"
- +#include "nfs41_daemon.h" /* Required for |nfs41_daemon_globals| */
- #include "upcall.h"
- #include "util.h"
- #include "daemon_debug.h"
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- +#include "accesstoken.h"
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- +
- /* |DPRINTF()| levels for acl logging */
- #define SYMLLVL1 1
- @@ -369,6 +374,7 @@ out:
- static int handle_symlink_set(void *daemon_context, nfs41_upcall *upcall)
- {
- symlink_upcall_args *args = &upcall->args.symlink;
- + nfs41_daemon_globals *nfs41dg = daemon_context;
- nfs41_open_state *state = upcall->state_ref;
- int status = NO_ERROR;
- @@ -404,10 +410,9 @@ static int handle_symlink_set(void *daemon_context, nfs41_upcall *upcall)
- createattrs.attrmask.count = 2;
- createattrs.attrmask.arr[0] = 0;
- createattrs.attrmask.arr[1] = FATTR4_WORD1_MODE;
- + /* FIXME: We should get the "mode" value from the kernel */
- createattrs.mode = 0777;
- - /* FIXME: What about newgrp support ? */
- -
- status = nfs41_create(state->session, NF4LNK, &createattrs,
- args->target_set, &state->parent, &state->file, &info);
- if (status) {
- @@ -418,6 +423,59 @@ static int handle_symlink_set(void *daemon_context, nfs41_upcall *upcall)
- goto out;
- }
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- + /*
- + * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- + * fetching groupname from auth token for new files and
- + * do a "manual" chgrp on the new file
- + *
- + * Note that |RPCSEC_AUTH_NONE| does not have any
- + * user/group information, therefore newgrp will be a
- + * NOP here.
- + */
- + if (state->session->client->rpc->sec_flavor != RPCSEC_AUTH_NONE) {
- + char *s;
- + int chgrp_status;
- + stateid_arg stateid;
- + nfs41_file_info createchgrpattrs = {
- + .attrmask.count = 2,
- + .attrmask.arr[0] = 0,
- + .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
- + .owner_group = createchgrpattrs.owner_group_buf
- + };
- +
- + /* fixme: we should store the |owner_group| name in |upcall| */
- + if (!get_token_primarygroup_name(upcall->currentthread_token,
- + createchgrpattrs.owner_group)) {
- + eprintf("handle_symlink_set(args->path='%s'): "
- + "get_token_primarygroup_name() failed.\n",
- + args->path);
- + goto create_symlink_chgrp_out;
- + }
- + s = createchgrpattrs.owner_group+strlen(createchgrpattrs.owner_group);
- + s = stpcpy(s, "@");
- + (void)stpcpy(s, nfs41dg->localdomain_name);
- + DPRINTF(1, ("handle_symlink_set(state->file.name.name='%s'): "
- + "owner_group='%s'\n",
- + state->file.name.name,
- + createchgrpattrs.owner_group));
- +
- + nfs41_open_stateid_arg(state, &stateid);
- + chgrp_status = nfs41_setattr(state->session,
- + &state->file, &stateid, &createchgrpattrs);
- + if (chgrp_status) {
- + eprintf("handle_symlink_set(args->path='%s'): "
- + "nfs41_setattr(owner_group='%s') "
- + "failed with error '%s'.\n",
- + args->path,
- + createchgrpattrs.owner_group,
- + nfs_error_string(chgrp_status));
- + }
- +create_symlink_chgrp_out:
- + ;
- + }
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- +
- out:
- return status;
- }
- --
- 2.51.0
- From 3fa2e3b7f98c8307d12c3eb2efb68512d0e2edd1 Mon Sep 17 00:00:00 2001
- From: Lionel Cons <lionelcons1972@gmail.com>
- Date: Mon, 15 Dec 2025 22:57:17 +0100
- Subject: [PATCH 6/7] README.md,docs: Provide instructions how to get VS2022
- via winget(1)
- Provide instructions how to get Visual Studio 2022 Community Edition
- via winget(1).
- Reported-by: Lionel Cons <lionelcons1972@gmail.com>
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- README.md | 38 +++++++++++++++++++++++++++++++-------
- docs/README.xml | 29 ++++++++++++++++++++++++-----
- 2 files changed, 55 insertions(+), 12 deletions(-)
- diff --git a/README.md b/README.md
- index b8bdbe7..2bbb83d 100644
- --- a/README.md
- +++ b/README.md
- @@ -901,14 +901,38 @@ Source code can be obtained from
- - **Option 2:** Windows 11 with Visual Studio 2022 Community
- - - Start Visual Studio 2022 installer and import the installer config
- - file `ms-nfs41-client/build.vc19/ms-nfs41-client_vs2022.vsconfig`,
- - and then install Visual Studio.
- + - Compiler:
- - > [!NOTE]
- - > Due to a bug in the VS installer, it is sometimes required to
- - > manually add another (random) component to be installed;
- - > otherwise, the imported config might be ignored.
- + - **Option 2a:**Use GUI installer
- +
- + Start Visual Studio 2022 installer and import the installer config
- + file `ms-nfs41-client/build.vc19/ms-nfs41-client_vs2022.vsconfig`,
- + and then install Visual Studio.
- +
- + > [!NOTE]
- + > Due to a bug in the VS installer, it is sometimes required to
- + > manually add another (random) component to be installed;
- + > otherwise, the imported config might be ignored.
- +
- + - **Option 2b:**Use command-line
- +
- + <div class="example">
- +
- + <div class="title">
- +
- + Install VS2022 Community Edition from a Cygwin Administrator shell
- +
- + </div>
- +
- + ``` bash
- + # get Visual Studio 2022 installer config
- + wget 'https://raw.githubusercontent.com/kofemann/ms-nfs41-client/refs/heads/master/build.vc19/ms-nfs41-client_vs2022.vsconfig'
- +
- + # install Visual Studio 2022 via winget(1)
- + winget install -e --id Microsoft.VisualStudio.2022.Community --silent --accept-package-agreements --accept-source-agreements --override "--quiet --wait --norestart --config \"$(cygpath -w "$PWD/ms-nfs41-client_vs2022.vsconfig")\""
- + ```
- +
- + </div>
- - WDK for Windows 11, version 1591, from
- <https://go.microsoft.com/fwlink/?linkid=2286137>
- diff --git a/docs/README.xml b/docs/README.xml
- index 45ba334..e7f3a6c 100644
- --- a/docs/README.xml
- +++ b/docs/README.xml
- @@ -1004,11 +1004,30 @@ Datei befindet. Versuchen Sie, die Datei woanders zu speichern.</programlisting>
- <para><emphasis role="bold">Option 2:</emphasis> Windows 11 with Visual Studio 2022 Community</para>
- <itemizedlist>
- <listitem>
- - <para>Start Visual Studio 2022 installer and import the installer config file
- - <filename>ms-nfs41-client/build.vc19/ms-nfs41-client_vs2022.vsconfig</filename>, and then install Visual Studio.</para>
- - <note>
- - <para>Due to a bug in the VS installer, it is sometimes required to manually add another (random) component to be installed; otherwise, the imported config might be ignored.</para>
- - </note>
- + <para>Compiler:</para>
- + <itemizedlist>
- + <listitem>
- + <para><emphasis role="bold">Option 2a:</emphasis>Use GUI installer</para>
- + <para>Start Visual Studio 2022 installer and import the installer config file
- + <filename>ms-nfs41-client/build.vc19/ms-nfs41-client_vs2022.vsconfig</filename>, and then install Visual Studio.</para>
- + <note>
- + <para>Due to a bug in the VS installer, it is sometimes required to manually add another (random) component to be installed; otherwise, the imported config might be ignored.</para>
- + </note>
- + </listitem>
- +
- + <listitem>
- + <para><emphasis role="bold">Option 2b:</emphasis>Use command-line</para>
- + <example>
- + <title>Install VS2022 Community Edition from a Cygwin Administrator shell</title>
- + <programlisting language="bash"># get Visual Studio 2022 installer config
- +wget 'https://raw.githubusercontent.com/kofemann/ms-nfs41-client/refs/heads/master/build.vc19/ms-nfs41-client_vs2022.vsconfig'
- +
- +# install Visual Studio 2022 via winget(1)
- +winget install -e --id Microsoft.VisualStudio.2022.Community --silent --accept-package-agreements --accept-source-agreements --override "--quiet --wait --norestart --config \"$(cygpath -w "$PWD/ms-nfs41-client_vs2022.vsconfig")\""
- +</programlisting>
- + </example>
- + </listitem>
- + </itemizedlist>
- </listitem>
- <listitem>
- <para>WDK for Windows 11, version 1591, from <link xl:href="https://go.microsoft.com/fwlink/?linkid=2286137">https://go.microsoft.com/fwlink/?linkid=2286137</link></para>
- --
- 2.51.0
- From 0a6c443a96125f192a144bdae7dd831dfb801342 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Tue, 16 Dec 2025 00:07:42 +0100
- Subject: [PATCH 7/7] daemon: Move code to fix gid after file/dir/symlink
- creation to an utility function
- Move code to fix gid after file/dir/symlink creation to an utility function.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/open.c | 112 +++++++----------------------------------------
- daemon/symlink.c | 48 ++------------------
- daemon/util.c | 69 +++++++++++++++++++++++++++++
- daemon/util.h | 14 ++++++
- 4 files changed, 102 insertions(+), 141 deletions(-)
- diff --git a/daemon/open.c b/daemon/open.c
- index 5b120bb..b5e72c7 100644
- --- a/daemon/open.c
- +++ b/daemon/open.c
- @@ -37,7 +37,6 @@
- #include "fileinfoutil.h"
- #include "util.h"
- #include "idmap.h"
- -#include "accesstoken.h"
- static int create_open_state(
- IN const char *path,
- @@ -1134,49 +1133,9 @@ static int handle_open(void *daemon_context, nfs41_upcall *upcall)
- * user/group information, therefore newgrp will be a
- * NOP here.
- */
- - if (state->session->client->rpc->sec_flavor != RPCSEC_AUTH_NONE) {
- - char *s;
- - int chgrp_status;
- - stateid_arg stateid;
- - nfs41_file_info createchgrpattrs = {
- - .attrmask.count = 2,
- - .attrmask.arr[0] = 0,
- - .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
- - .owner_group = createchgrpattrs.owner_group_buf
- - };
- -
- - /* fixme: we should store the |owner_group| name in |upcall| */
- - if (!get_token_primarygroup_name(upcall->currentthread_token,
- - createchgrpattrs.owner_group)) {
- - eprintf("handle_open(args->path='%s')/cygwin symlink: "
- - "get_token_primarygroup_name() failed.\n",
- - args->path);
- - goto create_symlink_chgrp_out;
- - }
- - s = createchgrpattrs.owner_group+
- - strlen(createchgrpattrs.owner_group);
- - s = stpcpy(s, "@");
- - (void)stpcpy(s, nfs41dg->localdomain_name);
- - DPRINTF(1,
- - ("handle_open(state->file.name.name='%s')/cygwin symlink: "
- - "owner_group='%s'\n",
- - state->file.name.name,
- - createchgrpattrs.owner_group));
- -
- - nfs41_open_stateid_arg(state, &stateid);
- - chgrp_status = nfs41_setattr(state->session,
- - &state->file, &stateid, &createchgrpattrs);
- - if (chgrp_status) {
- - eprintf("handle_open(args->path='%s')/cygwin symlink: "
- - "nfs41_setattr(owner_group='%s') "
- - "failed with error '%s'.\n",
- - args->path,
- - createchgrpattrs.owner_group,
- - nfs_error_string(chgrp_status));
- - }
- -create_symlink_chgrp_out:
- - ;
- - }
- + (void)chgrp_to_primarygroup(nfs41dg,
- + upcall->currentthread_token,
- + state);
- #endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- nfs_to_basic_info(state->file.name.name,
- @@ -1305,58 +1264,19 @@ supersede_retry:
- goto out_free_state;
- } else {
- #ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- - /*
- - * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- - * fetching groupname from auth token for new files and
- - * do a "manual" chgrp on the new file
- - *
- - * Note that |RPCSEC_AUTH_NONE| does not have any
- - * user/group information, therefore newgrp will be a
- - * NOP here.
- - */
- - if ((create == OPEN4_CREATE) &&
- - (state->session->client->rpc->sec_flavor !=
- - RPCSEC_AUTH_NONE)) {
- - char *s;
- - int chgrp_status;
- - stateid_arg stateid;
- - nfs41_file_info createchgrpattrs;
- -
- - createchgrpattrs.attrmask.count = 2;
- - createchgrpattrs.attrmask.arr[0] = 0;
- - createchgrpattrs.attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP;
- - createchgrpattrs.owner_group = createchgrpattrs.owner_group_buf;
- - /* fixme: we should store the |owner_group| name in |upcall| */
- - if (!get_token_primarygroup_name(upcall->currentthread_token,
- - createchgrpattrs.owner_group)) {
- - eprintf("handle_open(args->path='%s'): "
- - "OPEN4_CREATE: "
- - "get_token_primarygroup_name() failed.\n",
- - args->path);
- - goto create_chgrp_out;
- - }
- - s = createchgrpattrs.owner_group+strlen(createchgrpattrs.owner_group);
- - s = stpcpy(s, "@");
- - (void)stpcpy(s, nfs41dg->localdomain_name);
- - DPRINTF(1, ("handle_open(state->file.name.name='%s'): "
- - "OPEN4_CREATE: owner_group='%s'\n",
- - state->file.name.name,
- - createchgrpattrs.owner_group));
- -
- - nfs41_open_stateid_arg(state, &stateid);
- - chgrp_status = nfs41_setattr(state->session,
- - &state->file, &stateid, &createchgrpattrs);
- - if (chgrp_status) {
- - eprintf("handle_open(args->path='%s'): "
- - "OPEN4_CREATE: "
- - "nfs41_setattr(owner_group='%s') "
- - "failed with error '%s'.\n",
- - args->path,
- - createchgrpattrs.owner_group,
- - nfs_error_string(chgrp_status));
- - }
- -create_chgrp_out:
- - ;
- + if (create == OPEN4_CREATE) {
- + /*
- + * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- + * fetching groupname from auth token for new files and
- + * do a "manual" chgrp on the new file
- + *
- + * Note that |RPCSEC_AUTH_NONE| does not have any
- + * user/group information, therefore newgrp will be a
- + * NOP here.
- + */
- + (void)chgrp_to_primarygroup(nfs41dg,
- + upcall->currentthread_token,
- + state);
- }
- #endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- diff --git a/daemon/symlink.c b/daemon/symlink.c
- index 4efb022..32bfca7 100644
- --- a/daemon/symlink.c
- +++ b/daemon/symlink.c
- @@ -30,10 +30,6 @@
- #include "upcall.h"
- #include "util.h"
- #include "daemon_debug.h"
- -#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- -#include "accesstoken.h"
- -#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- -
- /* |DPRINTF()| levels for acl logging */
- #define SYMLLVL1 1
- @@ -433,47 +429,9 @@ static int handle_symlink_set(void *daemon_context, nfs41_upcall *upcall)
- * user/group information, therefore newgrp will be a
- * NOP here.
- */
- - if (state->session->client->rpc->sec_flavor != RPCSEC_AUTH_NONE) {
- - char *s;
- - int chgrp_status;
- - stateid_arg stateid;
- - nfs41_file_info createchgrpattrs = {
- - .attrmask.count = 2,
- - .attrmask.arr[0] = 0,
- - .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
- - .owner_group = createchgrpattrs.owner_group_buf
- - };
- -
- - /* fixme: we should store the |owner_group| name in |upcall| */
- - if (!get_token_primarygroup_name(upcall->currentthread_token,
- - createchgrpattrs.owner_group)) {
- - eprintf("handle_symlink_set(args->path='%s'): "
- - "get_token_primarygroup_name() failed.\n",
- - args->path);
- - goto create_symlink_chgrp_out;
- - }
- - s = createchgrpattrs.owner_group+strlen(createchgrpattrs.owner_group);
- - s = stpcpy(s, "@");
- - (void)stpcpy(s, nfs41dg->localdomain_name);
- - DPRINTF(1, ("handle_symlink_set(state->file.name.name='%s'): "
- - "owner_group='%s'\n",
- - state->file.name.name,
- - createchgrpattrs.owner_group));
- -
- - nfs41_open_stateid_arg(state, &stateid);
- - chgrp_status = nfs41_setattr(state->session,
- - &state->file, &stateid, &createchgrpattrs);
- - if (chgrp_status) {
- - eprintf("handle_symlink_set(args->path='%s'): "
- - "nfs41_setattr(owner_group='%s') "
- - "failed with error '%s'.\n",
- - args->path,
- - createchgrpattrs.owner_group,
- - nfs_error_string(chgrp_status));
- - }
- -create_symlink_chgrp_out:
- - ;
- - }
- + (void)chgrp_to_primarygroup(nfs41dg,
- + upcall->currentthread_token,
- + state);
- #endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- out:
- diff --git a/daemon/util.c b/daemon/util.c
- index 3d36780..8d7f950 100644
- --- a/daemon/util.c
- +++ b/daemon/util.c
- @@ -33,6 +33,9 @@
- #include "nfs41_ops.h"
- #include <devioctl.h>
- #include "nfs41_driver.h" /* for |delayxid()| */
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- +#include "accesstoken.h"
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- char *stpcpy(char *restrict s1, const char *restrict s2)
- @@ -853,3 +856,69 @@ int delayxid(LONGLONG xid, LONGLONG moredelaysecs)
- return status;
- }
- +
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- +/*
- + * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- + * fetching groupname from auth token for new files and
- + * do a "manual" chgrp on the new file
- + */
- +int chgrp_to_primarygroup(
- + IN nfs41_daemon_globals *nfs41dg,
- + IN HANDLE currentthread_token,
- + IN nfs41_open_state *state)
- +{
- + int chgrp_status = NO_ERROR;
- +
- + /*
- + * |RPCSEC_AUTH_NONE| does not have any
- + * user/group information, therefore newgrp will be a
- + * NOP here.
- + */
- + if (state->session->client->rpc->sec_flavor == RPCSEC_AUTH_NONE) {
- + return NO_ERROR;
- + }
- +
- + char *s;
- + stateid_arg stateid;
- + nfs41_file_info createchgrpattrs = {
- + .attrmask.count = 2,
- + .attrmask.arr[0] = 0,
- + .attrmask.arr[1] = FATTR4_WORD1_OWNER_GROUP,
- + .owner_group = createchgrpattrs.owner_group_buf
- + };
- +
- + /* fixme: we should store the |owner_group| name in |upcall| */
- + if (!get_token_primarygroup_name(currentthread_token,
- + createchgrpattrs.owner_group)) {
- + eprintf("chgrp_to_primarygroup(state->file.name.name='%s'): "
- + "get_token_primarygroup_name() failed.\n",
- + state->file.name.name);
- + goto create_symlink_chgrp_out;
- + }
- + s = createchgrpattrs.owner_group+strlen(createchgrpattrs.owner_group);
- + s = stpcpy(s, "@");
- + (void)stpcpy(s, nfs41dg->localdomain_name);
- + DPRINTF(1, ("chgrp_to_primarygroup(state->file.name.name='%s'): "
- + "owner_group='%s'\n",
- + state->file.name.name,
- + createchgrpattrs.owner_group));
- +
- + nfs41_open_stateid_arg(state, &stateid);
- + chgrp_status = nfs41_setattr(state->session,
- + &state->file, &stateid, &createchgrpattrs);
- + if (chgrp_status) {
- + eprintf("chgrp_to_primarygroup(state->file.name.name='%s'): "
- + "nfs41_setattr(owner_group='%s') "
- + "failed with error '%s'.\n",
- + state->file.name.name,
- + createchgrpattrs.owner_group,
- + nfs_error_string(chgrp_status));
- + }
- +
- +create_symlink_chgrp_out:
- + ;
- +
- + return chgrp_status;
- +}
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- diff --git a/daemon/util.h b/daemon/util.h
- index ab62721..dc0ea07 100644
- --- a/daemon/util.h
- +++ b/daemon/util.h
- @@ -444,4 +444,18 @@ void close_nfs41sys_device_pipe(HANDLE pipe);
- int delayxid(LONGLONG xid, LONGLONG moredelaysecs);
- +#ifdef NFS41_DRIVER_SETGID_NEWGRP_SUPPORT
- +typedef struct __nfs41_daemon_globals nfs41_daemon_globals;
- +
- +/*
- + * Hack: Support |setgid()|/newgrp(1)/sg(1)/winsg(1) by
- + * fetching groupname from auth token for new files and
- + * do a "manual" chgrp on the new file
- + */
- +int chgrp_to_primarygroup(
- + IN nfs41_daemon_globals *nfs41dg,
- + IN HANDLE currentthread_token,
- + IN nfs41_open_state *state);
- +#endif /* NFS41_DRIVER_SETGID_NEWGRP_SUPPORT */
- +
- #endif /* !__NFS41_DAEMON_UTIL_H__ */
- --
- 2.51.0
msnfs41client: Patches to support newgrp(1)/|setgid()| for symlinks, docs updates+misc, 2025-12-16
Posted by Anonymous on Wed 17th Dec 2025 10:30
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.
rovema.kpaste.net RSS