- From 97087498e1359a59aa0af1e5ed5d5e2df0e32729 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 00:39:57 +0200
- Subject: [PATCH 1/8] cygwin: msnfs41client run_daemon/sys_run_daemon should
- use sync(1)
- msnfs41client run_daemon/sys_run_daemon should use sync(1) before
- starting the NFSv4.1 client daemon, to limit any filesystem damage
- if the nfs41_client.sys kernel module crashes on startup.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- cygwin/devel/msnfs41client.bash | 8 ++++++++
- 1 file changed, 8 insertions(+)
- diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
- index 1325d6f..7359f9d 100644
- --- a/cygwin/devel/msnfs41client.bash
- +++ b/cygwin/devel/msnfs41client.bash
- @@ -168,6 +168,10 @@ function nfsclient_rundeamon
- "$(uname -a)" \
- "$(is_windows_admin_account ; printf "%d\n" $((${?}?0:1)))"
- + # sync before starting nfs41 client daemon, to limit the damage
- + # if the kernel module generates a crash on startup
- + sync
- +
- set -o xtrace
- typeset -a nfsd_args=(
- @@ -261,6 +265,10 @@ function nfsclient_system_rundeamon
- "$(uname -a)" \
- "$(is_windows_admin_account ; printf "%d\n" $((${?}?0:1)))"
- + # sync before starting nfs41 client daemon, to limit the damage
- + # if the kernel module generates a crash on startup
- + sync
- +
- set -o xtrace
- typeset -a nfsd_args=(
- --
- 2.43.0
- From 0da8b2b93ec34db26b7725b47b8672d77d205074 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 00:43:28 +0200
- Subject: [PATCH 2/8] daemon: Add comment to |write_downcall()| that
- |IOCTL_NFS41_WRITE| will stop impersonation
- Add comment to |write_downcall()| that |IOCTL_NFS41_WRITE| will stop
- user impersonation, just to avoid confusion when debugging.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs41_daemon.c | 4 ++++
- 1 file changed, 4 insertions(+)
- diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
- index 78393be..b4f59e3 100644
- --- a/daemon/nfs41_daemon.c
- +++ b/daemon/nfs41_daemon.c
- @@ -183,6 +183,10 @@ write_downcall:
- upcall_marshall(&upcall, inbuf, (uint32_t)inbuf_len, (uint32_t*)&outbuf_len);
- DPRINTF(2, ("making a downcall: outbuf_len %ld\n\n", outbuf_len));
- + /*
- + * Note: Caller impersonation ends here - nfs41_driver.sys
- + * |IOCTL_NFS41_WRITE| calls |SeStopImpersonatingClient()|
- + */
- status = DeviceIoControl(pipe, IOCTL_NFS41_WRITE,
- inbuf, inbuf_len, NULL, 0, (LPDWORD)&outbuf_len, NULL);
- if (!status) {
- --
- 2.43.0
- From 1d742ec8a5e0531b2ea46a1b9e01d507f10127f5 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 00:48:13 +0200
- Subject: [PATCH 3/8] daemon: |handle_mount()| should reject mount requests
- without impersonation
- |handle_mount()| should reject mount requests without impersonation
- thread token.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/mount.c | 19 +++++++++++++++++++
- 1 file changed, 19 insertions(+)
- diff --git a/daemon/mount.c b/daemon/mount.c
- index 7ab88be..1631864 100644
- --- a/daemon/mount.c
- +++ b/daemon/mount.c
- @@ -3,6 +3,7 @@
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- + * Roland Mainz <roland.mainz@nrubsig.org>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- @@ -71,6 +72,24 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
- EASSERT(args->hostport != NULL);
- +#define MOUNT_REJECT_REQUESTS_WITHOUT_IMPERSONATION_TOKEN 1
- +
- +#ifdef MOUNT_REJECT_REQUESTS_WITHOUT_IMPERSONATION_TOKEN
- + logprintf("mount(hostport='%s', path='%s') request\n",
- + args->hostport?args->hostport:"<NULL>",
- + args->path?args->path:"<NULL>");
- +
- + HANDLE tok;
- + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tok)) {
- + (void)CloseHandle(tok);
- + }
- + else {
- + eprintf("handle_mount: Thread has no impersonation token\n");
- + status = ERROR_NO_IMPERSONATION_TOKEN;
- + goto out;
- + }
- +#endif /* MOUNT_REJECT_REQUESTS_WITHOUT_IMPERSONATION_TOKEN */
- +
- if ((args->path == NULL) || (strlen(args->path) == 0)) {
- DPRINTF(1, ("handle_mount: empty mount root\n"));
- status = ERROR_BAD_NETPATH;
- --
- 2.43.0
- From fb4ba5f8e4789b3f35a8fd02f0486fcaf3011426 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 01:06:19 +0200
- Subject: [PATCH 4/8] daemon: Add build option to print impersonation token
- user info for |DPRINTF()|
- Add build option to print impersonation token user info for |DPRINTF()|
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/daemon_debug.c | 40 ++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 40 insertions(+)
- diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c
- index 54fb411..ffc6ee2 100644
- --- a/daemon/daemon_debug.c
- +++ b/daemon/daemon_debug.c
- @@ -73,12 +73,52 @@ void open_log_files()
- }
- #endif
- +#define DPRINTF_PRINT_IMPERSONATION_USER 1
- void dprintf_out(LPCSTR format, ...)
- {
- va_list args;
- va_start(args, format);
- +#ifdef DPRINTF_PRINT_IMPERSONATION_USER
- + char username[UNLEN+1];
- + char groupname[GNLEN+1];
- + HANDLE tok;
- + const char *tok_src;
- + bool free_tok = false;
- +
- + if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &tok)) {
- + tok_src = "impersonated_user";
- + free_tok = true;
- + }
- + else {
- + int lasterr = GetLastError();
- + if (lasterr == ERROR_CANT_OPEN_ANONYMOUS) {
- + tok_src = "anon_user";
- + }
- + else {
- + tok_src = "proc_user";
- + }
- +
- + tok = GetCurrentProcessToken();
- + }
- +
- + if (!get_token_user_name(tok, username)) {
- + (void)strcpy(username, "<unknown>");
- + }
- + if (!get_token_primarygroup_name(tok, groupname)) {
- + (void)strcpy(groupname, "<unknown>");
- + }
- +
- + (void)fprintf(dlog_file, "%04x/%s='%s'/%s' ",
- + (int)GetCurrentThreadId(),
- + tok_src, username, groupname);
- +
- + if (free_tok) {
- + (void)CloseHandle(tok);
- + }
- +#else
- (void)fprintf(dlog_file, "%04x: ", (int)GetCurrentThreadId());
- +#endif /* DPRINTF_PRINT_IMPERSONATION_USER */
- (void)vfprintf(dlog_file, format, args);
- (void)fflush(dlog_file);
- va_end(args);
- --
- 2.43.0
- From 507db1179237605deb68bfb353567066a25e0d65 Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 01:10:19 +0200
- Subject: [PATCH 5/8] daemon: Workaround for Win10 bug that |GetAddrInfoExA()|
- ends impersonation
- Add workaround for Win10 bug that |GetAddrInfoExA()| ends user
- impersonation. The workaround creates a copy of the current
- impersonation/thread token, and sets that as thread token
- once |GetAddrInfoExA()| returns.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- daemon/nfs41_server.c | 42 ++++++++++++++++++++++++++++++++++++++++++
- 1 file changed, 42 insertions(+)
- diff --git a/daemon/nfs41_server.c b/daemon/nfs41_server.c
- index 23660dc..adfcdb4 100644
- --- a/daemon/nfs41_server.c
- +++ b/daemon/nfs41_server.c
- @@ -3,6 +3,7 @@
- *
- * Olga Kornievskaia <aglo@umich.edu>
- * Casey Bodley <cbodley@umich.edu>
- + * Roland Mainz <roland.mainz@nrubsig.org>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- @@ -311,7 +312,36 @@ int nfs41_server_resolve(
- hints.ai_flags |= AI_FILESERVER;
- #endif
- +/*
- + * Windows bug: |GetAddrInfoExA()| ends impersonation
- + * Tested on CYGWIN_NT-10.0-19045 3.6.0-0.115.g579064bf4d40.x86
- + */
- +#define WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG 1
- +
- +#ifdef WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG
- + HANDLE tok;
- +
- + /*
- + * Windows bug: |GetAddrInfoExA()| ends impersonation, so we copy
- + * the current (impersonation) thread token, and later
- + * set it after we are done with |GetAddrInfoExA()|
- + */
- + if (!OpenThreadToken(GetCurrentThread(),
- + TOKEN_QUERY|TOKEN_IMPERSONATE, FALSE, &tok)) {
- + tok = INVALID_HANDLE_VALUE;
- + DPRINTF(0, ("nfs41_server_resolve: OpenThreadToken() failed, "
- + "lasterr=%d.\n", (int)GetLastError()));
- + }
- +#endif /* WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG */
- +
- retry_getaddrinfoex:
- +#ifdef WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG
- + if (!SetThreadToken(NULL, tok)) {
- + DPRINTF(0, ("nfs41_server_resolve: SetThreadToken() failed, "
- + "lasterr=%d\n", (int)GetLastError()));
- + }
- +#endif /* WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG */
- +
- wse = GetAddrInfoExA(hostname, service, 0, NULL, &hints, &res,
- NULL, NULL, NULL, NULL);
- if (wse != 0) {
- @@ -330,6 +360,13 @@ retry_getaddrinfoex:
- goto out;
- }
- +#ifdef WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG
- + if (!SetThreadToken(NULL, tok)) {
- + DPRINTF(0, ("nfs41_server_resolve: SetThreadToken() failed, "
- + "lasterr=%d\n", (int)GetLastError()));
- + }
- +#endif /* WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG */
- +
- for (info = res; info != NULL; info = info->ai_next) {
- DPRINTF(SRVLVL, ("GetAddrInfoExA() returned: info.{ai_family=%d}\n",
- info->ai_family));
- @@ -398,5 +435,10 @@ out:
- DPRINTF(SRVLVL, ("<-- nfs41_server_resolve('%s':%u) returning "
- "OK { %s }\n", hostname, port, buff));
- }
- +
- +#ifdef WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG
- + /* FIXME: We leak the token here */
- +#endif /* WINDOWS_GETADDRINFOEXA_STOPS_IMPERSONATION_BUG */
- +
- return status;
- }
- --
- 2.43.0
- From 64e94f0633c194c90a1de8263101e8af422dbd21 Mon Sep 17 00:00:00 2001
- From: Martin Wege <martin.l.wege@gmail.com>
- Date: Fri, 26 Apr 2024 11:36:54 +0200
- Subject: [PATCH 6/8] tests: Provide correct start sequence for w32time service
- Provide correct start sequence for w32time service.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- tests/manual_testing.txt | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
- diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
- index 473fad7..fe40f2c 100644
- --- a/tests/manual_testing.txt
- +++ b/tests/manual_testing.txt
- @@ -32,7 +32,8 @@
- # NFSv4.1 server).
- # For example on Windows add timeserver 10.49.0.6 like this:
- # ---- snip ----
- -# net start w32time
- +# sc config w32time start=auto
- +# sc start w32time
- # w32tm /config /update /manualpeerlist:10.49.0.6
- # ---- snip ----
- # (see https://stackoverflow.com/questions/22862236/how-to-sync-windows-time-from-a-ntp-time-server-in-command)
- --
- 2.43.0
- From ed398d610abd5cb9a085ad6c2ae1ca0c85c8aa97 Mon Sep 17 00:00:00 2001
- From: Martin Wege <martin.l.wege@gmail.com>
- Date: Fri, 26 Apr 2024 11:40:12 +0200
- Subject: [PATCH 7/8] daemon: Fix annoying spelling error
- Signed-off-by: Roland Mainz <roland.mainz@nrubsig.org>
- ---
- daemon/nfs41_daemon.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
- diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
- index b4f59e3..2703d9b 100644
- --- a/daemon/nfs41_daemon.c
- +++ b/daemon/nfs41_daemon.c
- @@ -169,7 +169,7 @@ static unsigned int nfsd_worker_thread_main(void *args)
- }
- if (upcall.opcode == NFS41_SHUTDOWN) {
- - printf("Shutting down..\n");
- + printf("Shutting down...\n");
- exit(0);
- }
- --
- 2.43.0
- From b70db61bbf776268bd3540fcde1405ac4357c80d Mon Sep 17 00:00:00 2001
- From: Roland Mainz <roland.mainz@nrubsig.org>
- Date: Fri, 26 Apr 2024 15:52:14 +0200
- Subject: [PATCH 8/8] install: Rewrite nfs_install
- Rewrite nfs_install, as the old code had many problems with
- buffer overflows&&other issues reported by DrMemory.
- Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
- ---
- build.vc19/nfs_install/nfs_install.vcxproj | 4 -
- .../nfs_install/nfs_install.vcxproj.filters | 8 -
- cygwin/devel/msnfs41client.bash | 2 +-
- install/nfs_install.c | 198 +++++-
- install/nfsreginst.c | 655 ------------------
- install/nfsreginst.h | 98 ---
- install/sources | 2 +-
- 7 files changed, 178 insertions(+), 789 deletions(-)
- delete mode 100644 install/nfsreginst.c
- delete mode 100644 install/nfsreginst.h
- diff --git a/build.vc19/nfs_install/nfs_install.vcxproj b/build.vc19/nfs_install/nfs_install.vcxproj
- index ce0b42a..d7a336f 100644
- --- a/build.vc19/nfs_install/nfs_install.vcxproj
- +++ b/build.vc19/nfs_install/nfs_install.vcxproj
- @@ -150,12 +150,8 @@
- </Link>
- </ItemDefinitionGroup>
- <ItemGroup>
- - <ClCompile Include="..\..\install\nfsreginst.c" />
- <ClCompile Include="..\..\install\nfs_install.c" />
- </ItemGroup>
- - <ItemGroup>
- - <ClInclude Include="..\..\install\nfsreginst.h" />
- - </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
- diff --git a/build.vc19/nfs_install/nfs_install.vcxproj.filters b/build.vc19/nfs_install/nfs_install.vcxproj.filters
- index ae29609..80174df 100644
- --- a/build.vc19/nfs_install/nfs_install.vcxproj.filters
- +++ b/build.vc19/nfs_install/nfs_install.vcxproj.filters
- @@ -18,13 +18,5 @@
- <ClCompile Include="..\..\install\nfs_install.c">
- <Filter>Source Files</Filter>
- </ClCompile>
- - <ClCompile Include="..\..\install\nfsreginst.c">
- - <Filter>Source Files</Filter>
- - </ClCompile>
- - </ItemGroup>
- - <ItemGroup>
- - <ClInclude Include="..\..\install\nfsreginst.h">
- - <Filter>Header Files</Filter>
- - </ClInclude>
- </ItemGroup>
- </Project>
- \ No newline at end of file
- diff --git a/cygwin/devel/msnfs41client.bash b/cygwin/devel/msnfs41client.bash
- index 7359f9d..207153f 100644
- --- a/cygwin/devel/msnfs41client.bash
- +++ b/cygwin/devel/msnfs41client.bash
- @@ -74,7 +74,7 @@ function nfsclient_install
- #regtool -s set '/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/NetworkProvider/Order/ProviderOrder' 'RDPNP,LanmanWorkstation,webclient'
- printf 'before nfs_install: ProviderOrder="%s"\n' "$( strings -a '/proc/registry/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/NetworkProvider/Order/ProviderOrder')"
- - nfs_install
- + nfs_install -D
- printf 'after nfs_install: ProviderOrder="%s"\n' "$( strings -a '/proc/registry/HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/NetworkProvider/Order/ProviderOrder')"
- rundll32 setupapi.dll,InstallHinfSection DefaultInstall 132 ./nfs41rdr.inf
- diff --git a/install/nfs_install.c b/install/nfs_install.c
- index 16ba660..cab3f8f 100644
- --- a/install/nfs_install.c
- +++ b/install/nfs_install.c
- @@ -1,8 +1,8 @@
- -/* NFSv4.1 client for Windows
- - * Copyright (C) 2012 The Regents of the University of Michigan
- +/*
- + * NFSv4.1 client for Windows
- + * Copyright (C) 2024 Roland Mainz
- *
- - * Olga Kornievskaia <aglo@umich.edu>
- - * Casey Bodley <cbodley@umich.edu>
- + * Roland Mainz <roland.mainz@nrubsig.org>
- *
- * This library is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as published by
- @@ -20,31 +20,185 @@
- */
- /*
- - *
- - * This file is just for prepending nfs41_driver to the
- - * correct regestry entry
- - *
- + * nfs_install.exe - Tool to prepending nfs41_driver to the
- + * correct regestry entry
- */
- #if ((__STDC_VERSION__-0) < 201710L)
- #error Code requires ISO C17
- #endif
- -#include <tchar.h>
- +#define UNICODE 1
- +#define _UNICODE 1
- +
- +#include <windows.h>
- +#include <stdio.h>
- +#include <stdbool.h>
- +#include <string.h>
- +
- +#define RDRSERVICE "nfs41_driver"
- +#define PROVIDER_NAME RDRSERVICE
- +
- +#define PROVIDER_ORDER_KEY "SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order"
- -#include "nfs41_driver.h"
- -#include "nfsreginst.h"
- +#define PROVIDER_NAME_COMMA (PROVIDER_NAME ",")
- -void __cdecl _tmain(int argc, TCHAR *argv[])
- +#define DPRINTF(level, fmt) \
- + if ((level) <= _dprintf_debug_level) { \
- + (void)printf fmt; \
- + }
- +
- +static int _dprintf_debug_level = 0;
- +
- +int main(int ac, char *av[])
- {
- - if(argc == 1 || _tstoi(argv[1]) == 1)
- - {
- - RdrSetupProviderOrder();
- - }
- - else
- - {
- - while( RdrRemoveProviderFromOrder() ) {};
- - }
- -
- - return;
- + bool install_regkey = false;
- + bool uninstall_regkey = false;
- + bool provider_name_already_in_key = false;
- + int d_ac = 0;
- + int res = 1;
- + HKEY hKey;
- + DWORD dataSize = 0;
- + char *new_buffer = NULL;
- + char *originalValue = NULL;
- +
- + if ((ac > 1) && (!strcmp(av[1], "-D"))) {
- + _dprintf_debug_level = 1;
- + d_ac++;
- + }
- +
- + if ((ac == (2+d_ac)) && (!strcmp(av[1+d_ac], "0"))) {
- + uninstall_regkey = true;
- + DPRINTF(1, ("# Uninstalling key...\n"));
- + }
- + else if (ac == (1+d_ac)) {
- + install_regkey = true;
- + DPRINTF(1, ("# Installing key...\n"));
- + }
- + else {
- + (void)fprintf(stderr, "%s: Unsupported argument\n", av[0]);
- + return 1;
- + }
- +
- + LSTATUS result = RegOpenKeyExA(
- + HKEY_LOCAL_MACHINE,
- + PROVIDER_ORDER_KEY,
- + 0,
- + KEY_ALL_ACCESS,
- + &hKey);
- +
- + if (result != ERROR_SUCCESS) {
- + (void)fprintf(stderr, "%s: Error opening registry key: %d\n",
- + av[0], result);
- + return 1;
- + }
- +
- + /*
- + * Get the current value of the ProviderOrder key
- + */
- + result = RegQueryValueExA(hKey, "ProviderOrder", NULL, NULL, NULL, &dataSize);
- +
- + DPRINTF(1, ("# RegQueryValueExA(), result=%d, dataSize=%d\n",
- + (int)result, (int)dataSize));
- +
- + originalValue = malloc(dataSize+1);
- +
- + if (!originalValue) {
- + (void)fprintf(stderr, "%s: Out of memory\n", av[0]);
- + res = 1;
- + goto out;
- + }
- +
- + if (dataSize > 0) {
- + /* Read the existing data */
- + result = RegQueryValueExA(hKey, "ProviderOrder", NULL, NULL,
- + originalValue, &dataSize);
- + if (result != ERROR_SUCCESS) {
- + (void)fprintf(stderr, "%s: Error reading registry value: %d\n",
- + av[0], result);
- + res = 1;
- + goto out;
- + }
- +
- + DPRINTF(1, ("# data='%s'\n", originalValue));
- + }
- + else {
- + DPRINTF(1, ("# no data\n"));
- + /* If no data existed, set the dataSize to 0 */
- + dataSize = 0;
- + }
- +
- + if (strstr(originalValue, PROVIDER_NAME_COMMA) ||
- + (!strcmp(originalValue, PROVIDER_NAME))) {
- + DPRINTF(1, ("# original key value has '%s'\n", PROVIDER_NAME));
- + provider_name_already_in_key = true;
- + }
- +
- + if (install_regkey && (!provider_name_already_in_key)) {
- + size_t new_buffer_len = dataSize+strlen(PROVIDER_NAME_COMMA)+2;
- + new_buffer = malloc(new_buffer_len);
- +
- + if (!new_buffer) {
- + (void)fprintf(stderr, "%s: Out of memory\n", av[0]);
- + res = 1;
- + goto out;
- + }
- +
- + if ((dataSize > 0) && (originalValue[0] != ',')) {
- + (void)snprintf(new_buffer, new_buffer_len, "%s,%s",
- + PROVIDER_NAME, originalValue);
- + }
- + else {
- + (void)strcpy_s(new_buffer, new_buffer_len, PROVIDER_NAME);
- + }
- + }
- + else {
- + new_buffer = _strdup(originalValue);
- + if (!new_buffer) {
- + (void)fprintf(stderr, "%s: Out of memory\n", av[0]);
- + res = 1;
- + goto out;
- + }
- + }
- +
- + if (uninstall_regkey) {
- + char *s;
- +
- + DPRINTF(1, ("# value before removal '%s'\n", new_buffer));
- + while (s = strstr(new_buffer, PROVIDER_NAME_COMMA)) {
- + if (s) {
- + char *end = s+strlen(PROVIDER_NAME_COMMA);
- + (void)memmove(s, end, strlen(end)+1);
- + DPRINTF(1, ("# value after removal '%s'\n", new_buffer));
- + }
- + }
- +
- + if (!strcmp(new_buffer, PROVIDER_NAME)) {
- + new_buffer[0] = '\0';
- + }
- + }
- +
- + DPRINTF(1, ("# writing '%s'\n", new_buffer));
- +
- + /*
- + * Set the new value of the ProviderOrder key
- + */
- + result = RegSetValueExA(hKey, "ProviderOrder", 0, REG_SZ,
- + new_buffer, (DWORD)strlen(new_buffer));
- +
- + if (result != ERROR_SUCCESS) {
- + (void)fprintf(stderr, "%s: Error setting registry value: %d\n",
- + av[0], result);
- + res = 1;
- + }
- + else {
- + res = 0;
- + }
- +
- +out:
- + free(new_buffer);
- + free(originalValue);
- + (void)RegCloseKey(hKey);
- +
- + return res;
- }
- diff --git a/install/nfsreginst.c b/install/nfsreginst.c
- deleted file mode 100644
- index df7565c..0000000
- --- a/install/nfsreginst.c
- +++ /dev/null
- @@ -1,655 +0,0 @@
- -/* NFSv4.1 client for Windows
- - * Copyright (C) 2012 The Regents of the University of Michigan
- - *
- - * Olga Kornievskaia <aglo@umich.edu>
- - * Casey Bodley <cbodley@umich.edu>
- - *
- - * This library is free software; you can redistribute it and/or modify it
- - * under the terms of the GNU Lesser General Public License as published by
- - * the Free Software Foundation; either version 2.1 of the License, or (at
- - * your option) any later version.
- - *
- - * This library is distributed in the hope that it will be useful, but
- - * without any warranty; without even the implied warranty of merchantability
- - * or fitness for a particular purpose. See the GNU Lesser General Public
- - * License for more details.
- - *
- - * You should have received a copy of the GNU Lesser General Public License
- - * along with this library; if not, write to the Free Software Foundation,
- - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- - */
- -
- -/*++
- -
- -Module Name:
- -
- - nfsreginst.c
- -
- ---*/
- -
- -#include "nfsreginst.h"
- -
- -
- -
- -REGENTRY ProviderOrderKeyValues[] =
- -{
- - { TEXT("ProviderOrder"), REG_SZ, 0, 0 }
- -};
- -
- -BOOL RdrSetupProviderOrder( void )
- -{
- - LPTSTR pOrderString = NULL;
- - ULONG_PTR len;
- - BOOL success = TRUE;
- - LPTSTR pNewOrderString;
- -
- - while( RdrRemoveProviderFromOrder() ) {};
- -
- - len = RdrGetProviderOrderString( &pOrderString ) * sizeof(TCHAR);
- - if ( (len > 0) && pOrderString )
- - {
- - len += sizeof( PROVIDER_NAME ) + (2 * sizeof(TCHAR)); // add 2 for comma delimeter and null
- - pNewOrderString = malloc( len );
- - if ( pNewOrderString )
- - {
- - StringCbCopy( pNewOrderString, len, PROVIDER_NAME );
- - StringCbCat( pNewOrderString, len, TEXT(",") );
- - StringCbCat( pNewOrderString, len, pOrderString );
- - success = RdrSetProviderOrderString( pNewOrderString );
- - free( pNewOrderString );
- - }
- - }
- - else
- - {
- - success = RdrSetProviderOrderString( PROVIDER_NAME );
- - }
- - if ( pOrderString )
- - {
- - free( pOrderString );
- - }
- -
- - return success;
- -}
- -
- -
- -ULONG_PTR RdrGetProviderOrderString( __out LPTSTR *OrderString )
- -{
- - HKEY hOrderKey = NULL;
- - ULONG_PTR len = 0;
- -
- - if ( OpenKey( PROVIDER_ORDER_KEY, &hOrderKey ) )
- - {
- - if (hOrderKey == NULL)
- - return 0;
- -
- - ReadRegistryKeyValues( hOrderKey,
- - sizeof(ProviderOrderKeyValues) / sizeof(REGENTRY),
- - ProviderOrderKeyValues);
- -
- - RegCloseKey(hOrderKey);
- - len = ProviderOrderKeyValues[0].dwLength / sizeof( TCHAR ) - 1;
- - *OrderString = (LPTSTR) ProviderOrderKeyValues[0].pvValue;
- - }
- -
- - return len;
- -}
- -
- -
- -BOOL RdrSetProviderOrderString( __in LPTSTR OrderString )
- -{
- - HKEY hOrderKey;
- - BOOL rc = FALSE;
- -
- - if ( CreateKey( PROVIDER_ORDER_KEY, &hOrderKey ) )
- - {
- - ProviderOrderKeyValues[0].dwLength = (DWORD)(( _tcsclen( OrderString ) + 1 ) * sizeof( TCHAR ));
- - ProviderOrderKeyValues[0].pvValue = OrderString;
- - WriteRegistryKeyValues( hOrderKey,
- - sizeof(ProviderOrderKeyValues) / sizeof(REGENTRY),
- - ProviderOrderKeyValues);
- - RegCloseKey(hOrderKey);
- -
- - rc = TRUE;
- - }
- -
- - return rc;
- -}
- -
- -
- -BOOL RdrRemoveProviderFromOrder( void )
- -{
- - LPTSTR pCompare = NULL, OrderString = NULL, pOrig = NULL, Provider = PROVIDER_NAME;
- - BOOL match = FALSE;
- - ULONG_PTR len = 0;
- -
- - len = RdrGetProviderOrderString( &pOrig );
- - OrderString = pOrig;
- - if ( OrderString && Provider && *Provider )
- - {
- - pCompare = Provider;
- -
- - while ( *OrderString )
- - {
- - if ( _toupper(*OrderString) != _toupper(*pCompare++) )
- - {
- - pCompare = Provider;
- - while ( ( *OrderString != TEXT(',') ) && ( *OrderString != TEXT('\0') ) )
- - {
- - OrderString++;
- - }
- - }
- - if ( *OrderString != TEXT('\0') ) OrderString++;
- - if ( *pCompare == TEXT('\0') )
- - {
- - if ( ( *OrderString == TEXT(',') ) || ( *OrderString == TEXT('\0') ) )
- - {
- - LPTSTR pNewString;
- - len += 4096;
- - pNewString = malloc( len ); //Yes, this is a little larger than necessary
- - //No, I don't care that much
- - StringCchCopy(pNewString, len, pOrig);
- - //if ((DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider == 0 ) OrderString += 1;
- - if ( *OrderString == TEXT(',') )
- - {
- - StringCchCopy(pNewString + (DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider, len, OrderString + 1);
- - }
- - else
- - {
- - StringCchCopy(pNewString + (DWORD_PTR)OrderString - (DWORD_PTR)pOrig - (DWORD_PTR)pCompare + (DWORD_PTR)Provider - 1, len, OrderString);
- - }
- - match = RdrSetProviderOrderString( pNewString );
- - free(pNewString);
- - break;
- - }
- - else // hmm, it's a substring of another provider name
- - {
- - while ( ( *OrderString != TEXT(',') ) && ( *OrderString != TEXT('\0') ) )
- - {
- - OrderString++;
- - }
- - pCompare = Provider;
- - }
- - }
- -
- - }
- - }
- - free( pOrig );
- -
- - return match;
- -}
- -
- -void
- -ReadRegistryKeyValues(
- - HKEY hCurrentKey,
- - DWORD NumberOfValues,
- - PREGENTRY pValues)
- -/*++
- -
- -Routine Description:
- -
- - This routine reads a bunch of values associated with a given key.
- -
- -Arguments:
- -
- - hCurrentKey - the key
- -
- - NumberOfValues - the number of values
- -
- - pValues - the array of values
- -
- -Return Value:
- -
- - None
- -
- ---*/
- -{
- - //
- - // Iterate through table reading the values along the way
- - //
- -
- - DWORD i;
- -
- - for (i = 0; i < NumberOfValues; i++)
- - {
- - DWORD dwType;
- - LPTSTR pszKey;
- -
- - dwType = pValues[i].dwType;
- - pszKey = pValues[i].pszKey;
- -
- - switch (dwType)
- - {
- - case REG_SZ:
- - GetRegsz(hCurrentKey, pszKey, &pValues[i].pvValue,
- - &pValues[i].dwLength);
- - break;
- -
- - case REG_DWORD:
- - GetRegdw(hCurrentKey, pszKey, &pValues[i].pvValue,
- - &pValues[i].dwLength);
- - break;
- -
- - case REG_EXPAND_SZ:
- - GetRegesz(hCurrentKey, pszKey, &pValues[i].pvValue,
- - &pValues[i].dwLength);
- - break;
- -
- - case REG_MULTI_SZ:
- - GetRegmsz(hCurrentKey, pszKey, &pValues[i].pvValue,
- - &pValues[i].dwLength);
- - break;
- -
- - case REG_BINARY:
- - break;
- -
- - default:
- - break;
- -
- - }
- - }
- -}
- -
- -//
- -// Get a REG_SZ value and stick it in the table entry, along with the
- -// length
- -//
- -
- -BOOL GetRegsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD *pdwLength)
- -{
- - BYTE achValue[1024];
- -
- - DWORD dwLength;
- - LONG Status;
- - DWORD dwType = REG_SZ;
- - PBYTE pszValue = NULL;
- -
- -
- -
- - if ( (NULL == pszKey) || (NULL == ppvValue) ||
- - (NULL == hKey) || (NULL == pdwLength))
- - {
- - return FALSE;
- - }
- -
- -#ifdef _DEBUG
- - FillMemory(achValue, sizeof(achValue), 0xcd);
- -#endif
- -
- - dwLength = sizeof(achValue);
- -
- -
- - Status = RegGetValue( hKey,
- - NULL,
- - pszKey,
- - 0x0000002, //RRF_RD_REG_SZ
- - &dwType,
- - (PVOID) &achValue[0],
- - &dwLength);
- -
- - if ((ERROR_SUCCESS != Status) || (REG_SZ != dwType) )
- - {
- - return FALSE;
- - }
- -
- - pszValue = malloc(dwLength);
- -
- - if (NULL == pszValue)
- - {
- - return FALSE;
- - }
- -
- -
- - CopyMemory(pszValue, achValue, dwLength);
- -
- - *ppvValue = pszValue;
- - *pdwLength = dwLength;
- -
- - return TRUE;
- -}
- -
- -//
- -// Get the value of a REG_EXPAND_SZ and its length
- -//
- -
- -BOOL GetRegesz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
- -{
- - BYTE achValue[1024];
- -
- - DWORD dwLength;
- - LONG Status;
- - DWORD dwType = REG_EXPAND_SZ;
- - PBYTE pszValue = NULL;
- -
- -
- - if ( (NULL == pszKey) || (NULL == ppvValue) ||
- - (NULL == hKey) || (NULL == pdwLength))
- - {
- - return FALSE;
- - }
- -
- -#ifdef _DEBUG
- - FillMemory(achValue, sizeof(achValue), 0xcd);
- -#endif
- -
- - dwLength = sizeof(achValue);
- -
- - Status = RegQueryValueEx( hKey,
- - pszKey,
- - NULL,
- - &dwType,
- - (PUCHAR) &achValue[0],
- - &dwLength);
- -
- - if ((ERROR_SUCCESS != Status) || (REG_EXPAND_SZ != dwType))
- - {
- - return FALSE;
- - }
- -
- - pszValue = malloc(dwLength);
- -
- - if (NULL == pszValue)
- - {
- - return FALSE;
- - }
- -
- - CopyMemory(pszValue, achValue, dwLength);
- -
- - *ppvValue = pszValue;
- - *pdwLength = dwLength;
- -
- - return TRUE;
- -}
- -
- -
- -//
- -// Get value and length of REG_MULTI_SZ
- -//
- -
- -BOOL GetRegmsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount( *pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
- -{
- - //BYTE achValue[1024];
- - BYTE achValue[2048]; // careful, some of these strings are quite long
- -
- - DWORD dwLength;
- - LONG Status;
- - DWORD dwType = REG_MULTI_SZ;
- - PBYTE pszValue = NULL;
- -
- -
- - if ( (NULL == pszKey) || (NULL == ppvValue) ||
- - (NULL == hKey) || (NULL == pdwLength))
- - {
- - return FALSE;
- - }
- -
- -#ifdef _DEBUG
- - FillMemory(achValue, sizeof(achValue), 0xcd);
- -#endif
- -
- -
- - dwLength = sizeof(achValue);
- -
- -
- - Status = RegQueryValueEx( hKey,
- - pszKey,
- - NULL,
- - &dwType,
- - (PUCHAR) &achValue[0],
- - &dwLength);
- -
- - if ((ERROR_SUCCESS != Status) || (REG_MULTI_SZ != dwType))
- - {
- - return FALSE;
- - }
- -
- - pszValue = malloc(dwLength);
- -
- - if (NULL == pszValue)
- - {
- - return FALSE;
- - }
- -
- - CopyMemory(pszValue, achValue, dwLength);
- -
- - *ppvValue = pszValue;
- - *pdwLength = dwLength;
- -
- - return TRUE;
- -}
- -
- -
- -//
- -// Get value and length of REG_DWORD
- -//
- -
- -
- -BOOL GetRegdw(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength)
- -{
- - DWORD dwValue = 0;
- -
- - DWORD dwLength;
- - LONG Status;
- - DWORD dwType = REG_DWORD;
- -
- -
- -
- - if ( (NULL == pszKey) || (NULL == ppvValue) ||
- - (NULL == hKey) || (NULL == pdwLength) )
- - {
- - return FALSE;
- - }
- -
- - dwLength = sizeof(dwValue);
- -
- -
- - Status = RegQueryValueEx( hKey,
- - pszKey,
- - NULL,
- - &dwType,
- - (PUCHAR) &dwValue,
- - &dwLength);
- -
- - if ((ERROR_SUCCESS != Status) || (REG_DWORD != dwType))
- - {
- - return FALSE;
- - }
- -
- - *ppvValue = (PVOID) (ULONG_PTR) dwValue;
- - *pdwLength = dwLength;
- -
- - return TRUE;
- -}
- -
- -
- -
- -void
- -WriteRegistryKeyValues(
- - HKEY hCurrentKey,
- - DWORD NumberOfValues,
- - PREGENTRY pValues)
- -/*++
- -
- -Routine Description:
- -
- - This routine reads a bunch of values associated with a given key.
- -
- -Arguments:
- -
- - hCurrentKey - the key
- -
- - NumberOfValues - the number of values
- -
- - pValues - the array of values
- -
- -Return Value:
- -
- - None
- -
- ---*/
- -{
- - DWORD i;
- -
- -
- - for (i = 0; i < NumberOfValues; i++)
- - {
- - DWORD dwType;
- - PVOID pvValue;
- - DWORD dwLength;
- - LPTSTR pszKey;
- -
- - pszKey = pValues[i].pszKey;
- - dwType = pValues[i].dwType;
- - dwLength = pValues[i].dwLength;
- - pvValue = pValues[i].pvValue;
- -
- - switch (dwType)
- - {
- - case REG_SZ:
- - AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
- - break;
- -
- - case REG_DWORD:
- - AddValue(hCurrentKey, pszKey, dwType, dwLength, &pvValue);
- - break;
- -
- - case REG_EXPAND_SZ:
- - AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
- - break;
- -
- - case REG_MULTI_SZ:
- - AddValue(hCurrentKey, pszKey, dwType, dwLength, pvValue);
- - break;
- -
- - case REG_BINARY:
- - //
- - // There are no binary values we need to copy. If we did, we'd
- - // put something here
- - //
- -
- - break;
- -
- - default:
- - break;
- -
- - }
- - }
- -}
- -
- -//
- -// Open a key so we can read the values
- -//
- -
- -
- -BOOL OpenKey(
- - __in LPTSTR pszKey,
- - __out PHKEY phKey)
- -/*++
- -
- -Routine Description:
- -
- - This routine opens a registry key.
- -
- -Arguments:
- -
- - pszKey - the name of the key relative to HKEY_LOCAL_MACHINE
- -
- - phKey - the key handlle
- -
- -Return Value:
- -
- - TRUE if successful, otherwise FALSE
- -
- ---*/
- -{
- - HKEY hNewKey = 0;
- - DWORD Status;
- -
- - Status = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
- - pszKey,
- - 0,
- - KEY_QUERY_VALUE,
- - &hNewKey);
- -
- - if (ERROR_SUCCESS != Status)
- - {
- - *phKey = NULL;
- - return FALSE;
- - }
- - else
- - {
- - *phKey = hNewKey;
- - return TRUE;
- - }
- -}
- -
- -
- -BOOL CreateKey(__in LPTSTR pszKey, __out PHKEY phKey)
- -/*++
- -
- -Routine Description:
- -
- - This routine creates a registry key.
- -
- -Arguments:
- -
- - pszKey - the name of the key relative to HKEY_LOCAL_MACHINE
- -
- - phKey - the key handlle
- -
- -Return Value:
- -
- - TRUE if successful, otherwise FALSE
- -
- ---*/
- -{
- - LONG Status;
- - DWORD Disposition;
- -
- - Status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,
- - pszKey,
- - 0,
- - REG_NONE,
- - REG_OPTION_NON_VOLATILE,
- - KEY_ALL_ACCESS,
- - NULL,
- - phKey,
- - &Disposition);
- -
- - if ( ERROR_SUCCESS == Status)
- - {
- - return TRUE;
- - }
- - else
- - {
- - return FALSE;
- - }
- -}
- -
- -
- -//
- -// Add a value to the registry
- -//
- -
- -
- -BOOL AddValue(__in HKEY hKey, __in LPTSTR pszKey, __in DWORD dwType, __in DWORD dwLength, __in PVOID pvValue)
- -{
- -
- - BOOL fSuccess = TRUE;
- - LONG Status = ERROR_SUCCESS;
- -
- - Status = RegSetValueEx( hKey,
- - pszKey,
- - 0,
- - dwType,
- - pvValue,
- - dwLength);
- -
- -
- - if (Status != ERROR_SUCCESS)
- - {
- - fSuccess = FALSE;
- - //RegCloseKey(hKey);
- - }
- -
- - return fSuccess;
- -}
- diff --git a/install/nfsreginst.h b/install/nfsreginst.h
- deleted file mode 100644
- index 3624775..0000000
- --- a/install/nfsreginst.h
- +++ /dev/null
- @@ -1,98 +0,0 @@
- -/* NFSv4.1 client for Windows
- - * Copyright (C) 2012 The Regents of the University of Michigan
- - *
- - * Olga Kornievskaia <aglo@umich.edu>
- - * Casey Bodley <cbodley@umich.edu>
- - *
- - * This library is free software; you can redistribute it and/or modify it
- - * under the terms of the GNU Lesser General Public License as published by
- - * the Free Software Foundation; either version 2.1 of the License, or (at
- - * your option) any later version.
- - *
- - * This library is distributed in the hope that it will be useful, but
- - * without any warranty; without even the implied warranty of merchantability
- - * or fitness for a particular purpose. See the GNU Lesser General Public
- - * License for more details.
- - *
- - * You should have received a copy of the GNU Lesser General Public License
- - * along with this library; if not, write to the Free Software Foundation,
- - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- - */
- -
- -/*++
- -
- -Copyright (c) 1997 - 1999 Microsoft Corporation
- -
- -Module Name:
- -
- - srfunc.h
- -
- -Abstract:
- -
- ---*/
- -
- -#include <windows.h>
- -#include <stdlib.h>
- -#include <tchar.h>
- -#include <strsafe.h>
- -
- -#include "nfs41_driver.h"
- -
- -typedef struct {
- - LPTSTR pszKey;
- - DWORD dwType;
- - DWORD dwLength;
- - PVOID pvValue;
- -} REGENTRY, *PREGENTRY;
- -
- -void
- -ReadRegistryKeyValues(
- - HKEY hKey,
- - DWORD Count,
- - PREGENTRY pValues);
- -
- -void
- -WriteRegistryKeyValues(
- - HKEY hKey,
- - DWORD Count,
- - PREGENTRY pValues);
- -
- -
- -//
- -// routines for manipulating registry key values
- -//
- -
- -BOOL GetRegsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD *pdwLength);
- -
- -BOOL GetRegesz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
- -
- -BOOL GetRegmsz(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
- -
- -BOOL GetRegdw(__in HKEY hKey, __in LPTSTR pszKey, __deref_out_bcount(*pdwLength) PVOID * ppvValue, __out DWORD * pdwLength);
- -
- -
- -//
- -// routines for manipulating registry keys
- -//
- -
- -BOOL OpenKey(
- - __in LPTSTR pszKey,
- - __out PHKEY phKey);
- -
- -BOOL CreateKey(__in LPTSTR pszKey, __out PHKEY phKey);
- -BOOL AddValue(__in HKEY hKey, __in LPTSTR pszKey, __in DWORD dwType, __in DWORD dwLength, __in PVOID pvValue);
- -
- -BOOL RdrSetupProviderOrder( void );
- -BOOL RdrRemoveProviderFromOrder( void );
- -
- -ULONG_PTR RdrGetProviderOrderString( __out LPTSTR *OrderString );
- -BOOL RdrSetProviderOrderString( __in LPTSTR OrderString );
- -
- -
- -typedef BOOL (*ACTIONVECTOR) ( void );
- -
- -#define RDRSERVICE TEXT("nfs41_driver")
- -#define PROVIDER_NAME RDRSERVICE
- -
- -#define PROVIDER_ORDER_KEY TEXT("System\\CurrentControlSet\\Control\\NetworkProvider\\Order")
- -
- diff --git a/install/sources b/install/sources
- index 71c5e6b..6c56519 100644
- --- a/install/sources
- +++ b/install/sources
- @@ -1,6 +1,6 @@
- TARGETTYPE=PROGRAM
- TARGETNAME=nfs_install
- -SOURCES=nfs_install.c nfsreginst.c
- +SOURCES=nfs_install.c
- UMTYPE=console
- USE_MSVCRT=1
- INCLUDES=..\sys
- --
- 2.43.0
msnfs41client: Patches for impersonation fixes, nfs_install rewrite+misc, 2024-04-26
Posted by Anonymous on Fri 26th Apr 2024 15:03
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.