pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


pubnfs4 backup 20240712
Posted by Anonymous on Fri 12th Jul 2024 14:33
raw | new post

  1. diff --git a/daemon/lookup.c b/daemon/lookup.c
  2. index f747e8a..2312e06 100644
  3. --- a/daemon/lookup.c
  4. +++ b/daemon/lookup.c
  5. @@ -141,11 +141,13 @@ static int lookup_rpc(
  6.      nfs41_session_sequence(&args->sequence, session, 0);
  7.  
  8.      if (dir == &res->root) {
  9. -#ifdef USE_PUBFH
  10. +        if (session->client->root->is_pubfh) {
  11.              compound_add_op(&compound, OP_PUTPUBFH, NULL, &res->putfh);
  12. -#else
  13. +        }
  14. +        else {
  15.              compound_add_op(&compound, OP_PUTROOTFH, NULL, &res->putfh);
  16. -#endif
  17. +        }
  18. +
  19.          compound_add_op(&compound, OP_GETFH, NULL, &res->getrootfh);
  20.          compound_add_op(&compound, OP_GETATTR, &args->getrootattr,
  21.              &res->getrootattr);
  22. diff --git a/daemon/mount.c b/daemon/mount.c
  23. index cc9053b..516f0e6 100644
  24. --- a/daemon/mount.c
  25. +++ b/daemon/mount.c
  26. @@ -50,11 +50,13 @@ static int parse_mount(unsigned char *buffer, uint32_t length, nfs41_upcall *upc
  27.      if (status) goto out;
  28.      status = safe_read(&buffer, &length, &args->wsize, sizeof(DWORD));
  29.      if (status) goto out;
  30. +    status = safe_read(&buffer, &length, &args->is_pubfh, sizeof(DWORD));
  31. +    if (status) goto out;
  32.  
  33.      DPRINTF(1, ("parsing NFS41_MOUNT: hostport='%s' root='%s' "
  34. -        "sec_flavor='%s' rsize=%d wsize=%d\n",
  35. +        "sec_flavor='%s' rsize=%d wsize=%d is_pubfh=%d\n",
  36.          args->hostport, args->path, secflavorop2name(args->sec_flavor),
  37. -        args->rsize, args->wsize));
  38. +        args->rsize, args->wsize, args->is_pubfh));
  39.      return status;
  40.  out:
  41.      DPRINTF(1, ("parsing NFS41_MOUNT: failed %d\n", status));
  42. @@ -83,9 +85,11 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  43.      (void)get_token_authenticationid(upcall->currentthread_token,
  44.          &authenticationid);
  45.  
  46. -    logprintf("mount(hostport='%s', path='%s', "
  47. +    logprintf("mount(hostport='%s', "
  48. +        "is_pubfh=%d, path='%s', "
  49.          "authid=(0x%lx.0x%lx)) request\n",
  50.          args->hostport?args->hostport:"<NULL>",
  51. +        (int)args->is_pubfh,
  52.          args->path?args->path:"<NULL>",
  53.          (long)authenticationid.HighPart,
  54.          (long)authenticationid.LowPart);
  55. @@ -143,7 +147,8 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  56.          root = upcall->root_ref;
  57.      } else {
  58.          // create root
  59. -        status = nfs41_root_create(hostname, port, args->sec_flavor,
  60. +        status = nfs41_root_create(hostname, port,
  61. +            args->is_pubfh?true:false, args->sec_flavor,
  62.              args->wsize + WRITE_OVERHEAD, args->rsize + READ_OVERHEAD, &root);
  63.          if (status) {
  64.              eprintf("nfs41_root_create(hostname='%s', port=%d) failed %d\n",
  65. @@ -187,32 +192,37 @@ static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  66.  out:
  67.      if (status == 0) {
  68.  #ifdef NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE
  69. -        logprintf("mount(hostport='%s', path='%s', "
  70. +        logprintf("mount(hostport='%s', is_pubfh=%d, path='%s', "
  71.              "authid=(0x%lx.0x%lx)) success, root=0x%p\n",
  72.              args->hostport?args->hostport:"<NULL>",
  73. +            (int)args->is_pubfh,
  74.              args->path?args->path:"<NULL>",
  75.              (long)authenticationid.HighPart,
  76.              (long)authenticationid.LowPart,
  77.              root);
  78.  #else
  79. -        logprintf("mount(hostport='%s', path='%s') success, root=0x%p\n",
  80. +        logprintf("mount(hostport='%s', is_pubfh=%d, path='%s') success, "
  81. +            "root=0x%p\n",
  82.              args->hostport?args->hostport:"<NULL>",
  83. +            (int)args->is_pubfh,
  84.              args->path?args->path:"<NULL>",
  85.              root);
  86.  #endif /* NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE */
  87.      }
  88.      else {
  89.  #ifdef NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE
  90. -        logprintf("mount(hostport='%s', path='%s', "
  91. +        logprintf("mount(hostport='%s', is_pubfh=%d, path='%s', "
  92.              "authid=(0x%lx.0x%lx))) failed, status=%d\n",
  93.              args->hostport?args->hostport:"<NULL>",
  94. +            (int)args->is_pubfh,
  95.              args->path?args->path:"<NULL>",
  96.              (long)authenticationid.HighPart,
  97.              (long)authenticationid.LowPart,
  98.              (int)status);
  99.  #else
  100. -        logprintf("mount(hostport='%s', path='%s') failed, status=%d\n",
  101. +        logprintf("mount(hostport='%s', is_pubfh=%d, path='%s') failed, status=%d\n",
  102.              args->hostport?args->hostport:"<NULL>",
  103. +            (int)args->is_pubfh,
  104.              args->path?args->path:"<NULL>",
  105.              (int)status);
  106.  #endif /* NFS41_DRIVER_USE_AUTHENTICATIONID_FOR_MOUNT_NAMESPACE */
  107. diff --git a/daemon/namespace.c b/daemon/namespace.c
  108. index e490aad..ec44311 100644
  109. --- a/daemon/namespace.c
  110. +++ b/daemon/namespace.c
  111. @@ -37,6 +37,7 @@
  112.  int nfs41_root_create(
  113.      IN const char *name,
  114.      IN uint32_t port,
  115. +    IN bool is_pubfh,
  116.      IN uint32_t sec_flavor,
  117.      IN uint32_t wsize,
  118.      IN uint32_t rsize,
  119. @@ -54,6 +55,7 @@ int nfs41_root_create(
  120.      }
  121.  
  122.      list_init(&root->clients);
  123. +    root->is_pubfh = is_pubfh;
  124.      root->wsize = wsize;
  125.      root->rsize = rsize;
  126.      InitializeCriticalSection(&root->lock);
  127. @@ -61,7 +63,7 @@ int nfs41_root_create(
  128.      root->sec_flavor = sec_flavor;
  129.  
  130.      /* generate a unique client_owner */
  131. -    status = nfs41_client_owner(name, port, sec_flavor, &root->client_owner);
  132. +    status = nfs41_client_owner(name, port, is_pubfh, sec_flavor, &root->client_owner);
  133.      if (status) {
  134.          eprintf("nfs41_client_owner() failed with %d\n", status);
  135.          free(root);
  136. diff --git a/daemon/nfs41.h b/daemon/nfs41.h
  137. index f1617a9..41b3838 100644
  138. --- a/daemon/nfs41.h
  139. +++ b/daemon/nfs41.h
  140. @@ -299,6 +299,7 @@ typedef struct __nfs41_root {
  141.      client_owner4 client_owner;
  142.      CRITICAL_SECTION lock;
  143.      struct list_entry clients;
  144. +    bool is_pubfh;
  145.      uint32_t wsize;
  146.      uint32_t rsize;
  147.  #pragma warning( push )
  148. @@ -316,6 +317,7 @@ typedef struct __nfs41_root {
  149.  int nfs41_root_create(
  150.      IN const char *name,
  151.      IN uint32_t port,
  152. +    IN bool is_pubfh,
  153.      IN uint32_t sec_flavor,
  154.      IN uint32_t wsize,
  155.      IN uint32_t rsize,
  156. @@ -434,6 +436,7 @@ void nfs41_server_addrs(
  157.  int nfs41_client_owner(
  158.      IN const char *name,
  159.      IN uint32_t port,
  160. +    IN bool is_pubfh,
  161.      IN uint32_t sec_flavor,
  162.      OUT client_owner4 *owner);
  163.  
  164. diff --git a/daemon/nfs41_client.c b/daemon/nfs41_client.c
  165. index 847aa0c..00e340b 100644
  166. --- a/daemon/nfs41_client.c
  167. +++ b/daemon/nfs41_client.c
  168. @@ -362,6 +362,7 @@ out:
  169.  int nfs41_client_owner(
  170.      IN const char *name,
  171.      IN uint32_t port,
  172. +    IN bool is_pubfh,
  173.      IN uint32_t sec_flavor,
  174.      OUT client_owner4 *owner)
  175.  {
  176. @@ -420,6 +421,12 @@ int nfs41_client_owner(
  177.          goto out_context;
  178.      }
  179.  
  180. +    if (!CryptHashData(hash, (const BYTE*)&is_pubfh, (DWORD)sizeof(bool), 0)) {
  181. +        status = GetLastError();
  182. +        eprintf("CryptHashData() failed with %d\n", status);
  183. +        goto out_hash;
  184. +    }
  185. +
  186.      if (!CryptHashData(hash, (const BYTE*)&sec_flavor, (DWORD)sizeof(sec_flavor), 0)) {
  187.          status = GetLastError();
  188.          eprintf("CryptHashData() failed with %d\n", status);
  189. diff --git a/daemon/nfs41_ops.c b/daemon/nfs41_ops.c
  190. index 9ab7cef..5125cc8 100644
  191. --- a/daemon/nfs41_ops.c
  192. +++ b/daemon/nfs41_ops.c
  193. @@ -1154,11 +1154,12 @@ int nfs41_getattr(
  194.          putfh_args.file = file;
  195.          putfh_args.in_recovery = 0;
  196.      } else {
  197. -#ifdef USE_PUBFH
  198. +        if (session->client->root->is_pubfh) {
  199.              compound_add_op(&compound, OP_PUTPUBFH, NULL, &putfh_res);
  200. -#else
  201. +        }
  202. +        else {
  203.              compound_add_op(&compound, OP_PUTROOTFH, NULL, &putfh_res);
  204. -#endif
  205. +        }
  206.      }
  207.  
  208.      compound_add_op(&compound, OP_GETATTR, &getattr_args, &getattr_res);
  209. @@ -1901,11 +1902,12 @@ int nfs41_secinfo(
  210.      nfs41_session_sequence(&sequence_args, session, 0);
  211.  
  212.      if (file == NULL) {
  213. -#ifdef USE_PUBFH
  214. +        if (session->client->root->is_pubfh) {
  215.              compound_add_op(&compound, OP_PUTPUBFH, NULL, &putfh_res);
  216. -#else
  217. +        }
  218. +        else {
  219.              compound_add_op(&compound, OP_PUTROOTFH, NULL, &putfh_res);
  220. -#endif
  221. +        }
  222.      }
  223.      else {
  224.          compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
  225. @@ -1948,11 +1950,12 @@ int nfs41_secinfo_noname(
  226.      nfs41_session_sequence(&sequence_args, session, 0);
  227.  
  228.      if (file == NULL) {
  229. -#ifdef USE_PUBFH
  230. +        if (session->client->root->is_pubfh) {
  231.              compound_add_op(&compound, OP_PUTPUBFH, NULL, &putfh_res);
  232. -#else
  233. +        }
  234. +        else {
  235.              compound_add_op(&compound, OP_PUTROOTFH, NULL, &putfh_res);
  236. -#endif
  237. +        }
  238.      }
  239.      else {
  240.          compound_add_op(&compound, OP_PUTFH, &putfh_args, &putfh_res);
  241. diff --git a/daemon/upcall.h b/daemon/upcall.h
  242. index 50b62be..5fd9d96 100644
  243. --- a/daemon/upcall.h
  244. +++ b/daemon/upcall.h
  245. @@ -35,6 +35,7 @@ typedef struct __mount_upcall_args {
  246.      DWORD       sec_flavor;
  247.      DWORD       rsize;
  248.      DWORD       wsize;
  249. +    DWORD       is_pubfh;
  250.      DWORD       lease_time;
  251.      FILE_FS_ATTRIBUTE_INFORMATION FsAttrs;
  252.  } mount_upcall_args;
  253. diff --git a/dll/nfs41_np.c b/dll/nfs41_np.c
  254. index 1720558..6e24e21 100644
  255. --- a/dll/nfs41_np.c
  256. +++ b/dll/nfs41_np.c
  257. @@ -638,8 +638,10 @@ NPAddConnection3(
  258.  #endif
  259.  
  260.  #ifdef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  261. -    if (wcsncmp(&p[i], L"\\nfs4", 5) != 0) {
  262. -        DbgP((L"Connection name '%s' not prefixed with '\\nfs41'\n",
  263. +    if (wcsncmp(&p[i], L"\\nfs4", 5) &&
  264. +        wcsncmp(&p[i], L"\\pubnfs4", 8)) {
  265. +        DbgP((L"Connection name '%s' not prefixed with "
  266. +            "'\\nfs41' or '\\pubnfs41'\n",
  267.              &p[i]));
  268.          Status = WN_BAD_NETNAME;
  269.          goto out;
  270. diff --git a/mount/enum.c b/mount/enum.c
  271. index 8a30260..7719c45 100644
  272. --- a/mount/enum.c
  273. +++ b/mount/enum.c
  274. @@ -21,6 +21,7 @@
  275.  
  276.  #include <Windows.h>
  277.  #include <tchar.h>
  278. +#include <stdbool.h>
  279.  #include <stdio.h>
  280.  #include <malloc.h>
  281.  
  282. @@ -38,13 +39,17 @@ void PrintMountLine(
  283.      LPCTSTR remote)
  284.  {
  285.      TCHAR *cygwin_unc_buffer = alloca((_tcslen(remote)+32)*sizeof(TCHAR));
  286. -    char *cygwin_nfsurl_buffer = alloca(((_tcslen(remote)+32)*3)+8);
  287. +    char *cygwin_nfsurl_buffer = alloca(
  288. +        ((_tcslen(remote)+32)*3)+8 +
  289. +        9 /* "?public=1" */
  290. +        );
  291.      TCHAR *b;
  292.      LPCTSTR s;
  293.      TCHAR sc;
  294.  #ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  295.      unsigned int backslash_counter;
  296.  #endif
  297. +    bool is_pubfh = false;
  298.  
  299.      for(b = cygwin_unc_buffer, s = remote
  300.  #ifndef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  301. @@ -127,7 +132,22 @@ void PrintMountLine(
  302.           */
  303.          if (slash_counter == 1) {
  304.              *us++ = uc;
  305. +            if (*utf8unc_p == 'p') {
  306. +                /* Skip "pubnfs4" */
  307. +                utf8unc_p += 7;
  308. +                is_pubfh = true;
  309. +            }
  310. +            else if (*utf8unc_p == 'n') {
  311. +                /* Skip "nfs4" */
  312.                  utf8unc_p += 4;
  313. +            }
  314. +            else {
  315. +                (void)fwprintf(stderr,
  316. +                    L"PrintMountLine: ## Internal error, "
  317. +                    "unknown provider prefix\n");
  318. +                return;
  319. +            }
  320. +
  321.              continue;
  322.          }
  323.  
  324. @@ -151,6 +171,17 @@ void PrintMountLine(
  325.      }
  326.      *us = '\0';
  327.      
  328. +    if (is_pubfh) {
  329. +#pragma warning( push )
  330. +    /*
  331. +     * Disable "'strcat': This function or variable may be unsafe",
  332. +     * in this context it is safe to use
  333. +     */
  334. +#pragma warning (disable : 4996)
  335. +        (void)strcat(cygwin_nfsurl_buffer, "?public=1");
  336. +#pragma warning( pop )
  337. +    }
  338. +
  339.      (void)_tprintf(TEXT("%-8s\t%-50s\t%-50s\t%-50S\n"),
  340.          local, remote, cygwin_unc_buffer, cygwin_nfsurl_buffer);
  341.  
  342. diff --git a/mount/mount.c b/mount/mount.c
  343. index c4d8170..d04090e 100644
  344. --- a/mount/mount.c
  345. +++ b/mount/mount.c
  346. @@ -30,6 +30,7 @@
  347.  #include <strsafe.h>
  348.  #include <Winnetwk.h> /* for WNet*Connection */
  349.  #include <stdlib.h>
  350. +#include <stdbool.h>
  351.  #include <stdio.h>
  352.  
  353.  #include "nfs41_build_features.h"
  354. @@ -51,6 +52,7 @@ DWORD EnumMounts(
  355.      IN LPNETRESOURCE pContainer);
  356.  
  357.  static DWORD ParseRemoteName(
  358. +    IN bool is_pubfh,
  359.      IN LPTSTR pRemoteName,
  360.      IN OUT PMOUNT_OPTION_LIST pOptions,
  361.      OUT LPTSTR pParsedRemoteName,
  362. @@ -91,6 +93,8 @@ static VOID PrintUsage(LPTSTR pProcess)
  363.          TEXT("\t-w\tAlias for -o rw (read-write mount)\n")
  364.  
  365.          TEXT("* Mount options:\n")
  366. +        TEXT("\tpublic\tconnect to the server using the public file handle lookup protocol.\n")
  367. +        TEXT("\t\t(See WebNFS Client Specification, RFC 2054).\n")
  368.          TEXT("\tro\tmount as read-only\n")
  369.          TEXT("\trw\tmount as read-write (default)\n")
  370.          TEXT("\tport=#\tTCP port to use (defaults to 2049)\n")
  371. @@ -176,6 +180,8 @@ DWORD __cdecl _tmain(DWORD argc, LPTSTR argv[])
  372.          goto out;
  373.      }
  374.  
  375. +    bool is_pubfh = false;
  376. +
  377.      /* parse command line */
  378.      for (i = 1; i < argc; i++)
  379.      {
  380. @@ -218,6 +224,20 @@ DWORD __cdecl _tmain(DWORD argc, LPTSTR argv[])
  381.                  }
  382.  
  383.                  mntopts[num_mntopts++] = argv[i];
  384. +
  385. +                /*
  386. +                 * Extract "public" option here, as we need this for
  387. +                 * |ParseRemoteName()|. General parsing of -o options
  388. +                 * happens *AFTER* |ParseRemoteName()|, so any
  389. +                 * settings from a nfs://-URL can be overridden
  390. +                 * via -o options.
  391. +                 */
  392. +                if (wcsstr(argv[i], L"public=0")) {
  393. +                    is_pubfh = false;
  394. +                }
  395. +                else if (wcsstr(argv[i], L"public")) {
  396. +                    is_pubfh = true;
  397. +                }
  398.              }
  399.              else if (_tcscmp(argv[i], TEXT("-r")) == 0) /* mount option */
  400.              {
  401. @@ -333,7 +353,7 @@ DWORD __cdecl _tmain(DWORD argc, LPTSTR argv[])
  402.           * options for a NFS mount point, which can be overridden via
  403.           * -o below.
  404.           */
  405. -        result = ParseRemoteName(pRemoteName, &Options,
  406. +        result = ParseRemoteName(is_pubfh, pRemoteName, &Options,
  407.              szParsedRemoteName, szRemoteName, NFS41_SYS_MAX_PATH_LEN);
  408.          if (result)
  409.              goto out;
  410. @@ -411,6 +431,7 @@ wchar_t *utf8str2wcs(const char *utf8str)
  411.  }
  412.  
  413.  static DWORD ParseRemoteName(
  414. +    IN bool is_pubfh,
  415.      IN LPTSTR pRemoteName,
  416.      IN OUT PMOUNT_OPTION_LIST pOptions,
  417.      OUT LPTSTR pParsedRemoteName,
  418. @@ -712,7 +733,8 @@ static DWORD ParseRemoteName(
  419.      if (FAILED(result))
  420.          goto out;
  421.  #ifdef NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX
  422. -    result = StringCbCat(pConnectionName, cchConnectionLen, TEXT("\\nfs4"));
  423. +    result = StringCbCat(pConnectionName, cchConnectionLen,
  424. +        (is_pubfh?(TEXT("\\pubnfs4")):(TEXT("\\nfs4"))));
  425.      if (FAILED(result))
  426.          goto out;
  427.  #endif /* NFS41_DRIVER_MOUNT_DOES_NFS4_PREFIX */
  428. @@ -723,9 +745,10 @@ static DWORD ParseRemoteName(
  429.  
  430.  #ifdef DEBUG_MOUNT
  431.      (void)_ftprintf(stderr,
  432. -        TEXT("pConnectionName='%s', pParsedRemoteName='%s'\n"),
  433. +        TEXT("pConnectionName='%s', pParsedRemoteName='%s', is_pubfh='%d'\n"),
  434.          pConnectionName,
  435. -        pParsedRemoteName);
  436. +        pParsedRemoteName,
  437. +        (int)is_pubfh);
  438.  #endif
  439.  
  440.  out:
  441. diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c
  442. index 613f7df..5b18e10 100644
  443. --- a/sys/nfs41_driver.c
  444. +++ b/sys/nfs41_driver.c
  445. @@ -189,6 +189,7 @@ typedef struct _updowncall_entry {
  446.              DWORD rsize;
  447.              DWORD wsize;
  448.              DWORD lease_time;
  449. +            DWORD is_pubfh;
  450.          } Mount;
  451.          struct {                      
  452.              PMDL MdlAddress;
  453. @@ -276,9 +277,13 @@ nfs41_updowncall_list upcall, downcall;
  454.  
  455.  
  456.  
  457. -/* In order to cooperate with other network providers,
  458. - * we only claim paths of the format '\\server\nfs4\path' */
  459. +/*
  460. + * In order to cooperate with other network providers,
  461. + * we only claim paths of the format '\\server\nfs4\path' or
  462. + * '\\server\pubnfs4\path'
  463. + */
  464.  DECLARE_CONST_UNICODE_STRING(NfsPrefix, L"\\nfs4");
  465. +DECLARE_CONST_UNICODE_STRING(PubNfsPrefix, L"\\pubnfs4");
  466.  DECLARE_CONST_UNICODE_STRING(AUTH_SYS_NAME, L"sys");
  467.  DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5_NAME, L"krb5");
  468.  DECLARE_CONST_UNICODE_STRING(AUTHGSS_KRB5I_NAME, L"krb5i");
  469. @@ -294,6 +299,7 @@ DECLARE_CONST_UNICODE_STRING(EMPTY_STRING, L"");
  470.  #define UPCALL_TIMEOUT_DEFAULT          50  /* in seconds */
  471.  
  472.  typedef struct _NFS41_MOUNT_CONFIG {
  473. +    BOOLEAN is_pubfh;
  474.      DWORD ReadSize;
  475.      DWORD WriteSize;
  476.      BOOLEAN ReadOnly;
  477. @@ -682,7 +688,7 @@ NTSTATUS marshal_nfs41_mount(
  478.          goto out;
  479.      }
  480.      header_len = *len + length_as_utf8(entry->u.Mount.srv_name) +
  481. -        length_as_utf8(entry->u.Mount.root) + 3 * sizeof(DWORD);
  482. +        length_as_utf8(entry->u.Mount.root) + 4 * sizeof(DWORD);
  483.      if (header_len > buf_len) {
  484.          status = STATUS_INSUFFICIENT_RESOURCES;
  485.          goto out;
  486. @@ -696,15 +702,18 @@ NTSTATUS marshal_nfs41_mount(
  487.      RtlCopyMemory(tmp, &entry->u.Mount.rsize, sizeof(DWORD));
  488.      tmp += sizeof(DWORD);
  489.      RtlCopyMemory(tmp, &entry->u.Mount.wsize, sizeof(DWORD));
  490. +    tmp += sizeof(DWORD);
  491. +    RtlCopyMemory(tmp, &entry->u.Mount.is_pubfh, sizeof(DWORD));
  492.  
  493.      *len = header_len;
  494.  
  495.  #ifdef DEBUG_MARSHAL_DETAIL
  496.      DbgP("marshal_nfs41_mount: server name='%wZ' mount point='%wZ' "
  497. -         "sec_flavor='%s' rsize=%d wsize=%d\n",
  498. +         "sec_flavor='%s' rsize=%d wsize=%d is_pubfh=%d\n",
  499.          entry->u.Mount.srv_name, entry->u.Mount.root,
  500. -         secflavorop2name(entry->u.Mount.sec_flavor), entry->u.Mount.rsize,
  501. -         entry->u.Mount.wsize);
  502. +         secflavorop2name(entry->u.Mount.sec_flavor),
  503. +         (int)entry->u.Mount.rsize, (int)entry->u.Mount.wsize,
  504. +         (int)entry->u.Mount.is_pubfh);
  505.  #endif
  506.  out:
  507.      return status;
  508. @@ -2812,6 +2821,7 @@ NTSTATUS nfs41_mount(
  509.      entry->u.Mount.root = &config->MntPt;
  510.      entry->u.Mount.rsize = config->ReadSize;
  511.      entry->u.Mount.wsize = config->WriteSize;
  512. +    entry->u.Mount.is_pubfh = config->is_pubfh;
  513.      entry->u.Mount.sec_flavor = sec_flavor;
  514.      entry->u.Mount.FsAttrs = FsAttrs;
  515.  
  516. @@ -2846,6 +2856,7 @@ void nfs41_MountConfig_InitDefaults(
  517.  
  518.      Config->ReadSize = MOUNT_CONFIG_RW_SIZE_DEFAULT;
  519.      Config->WriteSize = MOUNT_CONFIG_RW_SIZE_DEFAULT;
  520. +    Config->is_pubfh = FALSE;
  521.      Config->ReadOnly = FALSE;
  522.      Config->write_thru = FALSE;
  523.      Config->nocache = FALSE;
  524. @@ -2992,6 +3003,15 @@ NTSTATUS nfs41_MountConfig_ParseOptions(
  525.                  &Config->WriteSize, MOUNT_CONFIG_RW_SIZE_MIN,
  526.                  MOUNT_CONFIG_RW_SIZE_MAX);
  527.          }
  528. +        else if (wcsncmp(L"public", Name, NameLen) == 0) {
  529. +            /*
  530. +             + We ignore this value here, and instead rely on the
  531. +             * /pubnfs4 prefix
  532. +             */
  533. +            BOOLEAN dummy;
  534. +            status = nfs41_MountConfig_ParseBoolean(Option, &usValue,
  535. +                FALSE, &dummy);
  536. +        }
  537.          else if (wcsncmp(L"srvname", Name, NameLen) == 0) {
  538.              if (usValue.Length > Config->SrvName.MaximumLength)
  539.                  status = STATUS_NAME_TOO_LONG;
  540. @@ -3107,7 +3127,8 @@ out:
  541.  
  542.  NTSTATUS has_nfs_prefix(
  543.      IN PUNICODE_STRING SrvCallName,
  544. -    IN PUNICODE_STRING NetRootName)
  545. +    IN PUNICODE_STRING NetRootName,
  546. +    OUT BOOLEAN *pubfh_prefix)
  547.  {
  548.      NTSTATUS status = STATUS_BAD_NETWORK_NAME;
  549.  
  550. @@ -3140,20 +3161,42 @@ NTSTATUS has_nfs_prefix(
  551.              }
  552.          }
  553.  
  554. -        if ((state == 3) &&
  555. -            (!memcmp(&NetRootName->Buffer[i], L"\\nfs4",
  556. +        if (state == 3) {
  557. +            if (!memcmp(&NetRootName->Buffer[i], L"\\nfs4",
  558.                  (4*sizeof(wchar_t))))) {
  559. +                *pubfh_prefix = FALSE;
  560.                  status = STATUS_SUCCESS;
  561.              }
  562. +            if ((NetRootName->Length >=
  563. +                (SrvCallName->Length + PubNfsPrefix.Length)) &&
  564. +                (!memcmp(&NetRootName->Buffer[i], L"\\pubnfs4",
  565. +                    (4*sizeof(wchar_t))))) {
  566. +                *pubfh_prefix = TRUE;
  567. +                status = STATUS_SUCCESS;
  568. +            }
  569. +        }
  570.      }
  571.  #else
  572. -    if (NetRootName->Length == SrvCallName->Length + NfsPrefix.Length) {
  573. +    if (NetRootName->Length ==
  574. +        (SrvCallName->Length + NfsPrefix.Length)) {
  575.          const UNICODE_STRING NetRootPrefix = {
  576.              NfsPrefix.Length,
  577.              NetRootName->MaximumLength - SrvCallName->Length,
  578.              &NetRootName->Buffer[SrvCallName->Length/2]
  579.          };
  580. -        if (RtlCompareUnicodeString(&NetRootPrefix, &NfsPrefix, FALSE) == 0)
  581. +        if (!RtlCompareUnicodeString(&NetRootPrefix, &NfsPrefix, FALSE))
  582. +            *pubfh_prefix = FALSE;
  583. +            status = STATUS_SUCCESS;
  584. +    }
  585. +    else if (NetRootName->Length ==
  586. +        (SrvCallName->Length + PubNfsPrefix.Length)) {
  587. +        const UNICODE_STRING PubNetRootPrefix = {
  588. +            PubNfsPrefix.Length,
  589. +            NetRootName->MaximumLength - SrvCallName->Length,
  590. +            &NetRootName->Buffer[SrvCallName->Length/2]
  591. +        };
  592. +        if (!RtlCompareUnicodeString(&PubNetRootPrefix, &PubNfsPrefix, FALSE))
  593. +            *pubfh_prefix = TRUE;
  594.              status = STATUS_SUCCESS;
  595.      }
  596.  #endif
  597. @@ -3296,12 +3339,16 @@ NTSTATUS nfs41_CreateVNetRoot(
  598.  
  599.      pVNetRootContext->session = INVALID_HANDLE_VALUE;
  600.  
  601. -    /* In order to cooperate with other network providers, we must
  602. -     * only claim paths of the form '\\server\nfs4\path' */
  603. -    status = has_nfs_prefix(pSrvCall->pSrvCallName, pNetRoot->pNetRootName);
  604. +    /*
  605. +     * In order to cooperate with other network providers, we
  606. +     * must only claim paths of the form '\\server\nfs4\path'
  607. +     * or '\\server\pubnfs4\path'
  608. +     */
  609. +    BOOLEAN pubfh_prefix = FALSE;
  610. +    status = has_nfs_prefix(pSrvCall->pSrvCallName, pNetRoot->pNetRootName, &pubfh_prefix);
  611.      if (status) {
  612.          print_error("nfs41_CreateVNetRoot: NetRootName '%wZ' doesn't match "
  613. -            "'\\nfs4'!\n", pNetRoot->pNetRootName);
  614. +            "'\\nfs4' or '\\pubnfs4'!\n", pNetRoot->pNetRootName);
  615.          goto out;
  616.      }
  617.      pNetRoot->MRxNetRootState = MRX_NET_ROOT_STATE_GOOD;
  618. @@ -3335,8 +3382,11 @@ NTSTATUS nfs41_CreateVNetRoot(
  619.          pVNetRootContext->write_thru = Config->write_thru;
  620.          pVNetRootContext->nocache = Config->nocache;
  621.      } else {
  622. -        /* Codepath for \\server@port\nfs4\path */
  623. -        DbgP("Codepath for \\\\server@port\\nfs4\\path\n");
  624. +        /*
  625. +         * Codepath for \\server@port\nfs4\path or
  626. +         * \\server@port\pubnfs4\path
  627. +         */
  628. +        DbgP("Codepath for \\\\server@port\\@(pubnfs4|nfs4)\\path\n");
  629.  
  630.          /*
  631.           * STATUS_NFS_SHARE_NOT_MOUNTED - status code for the case
  632. @@ -3427,9 +3477,12 @@ NTSTATUS nfs41_CreateVNetRoot(
  633.          pVNetRootContext->nocache = Config->nocache;
  634.      }
  635.  
  636. +    Config->is_pubfh = pubfh_prefix;
  637. +
  638.      DbgP("Config->{ "
  639.          "MntPt='%wZ', "
  640.          "SrvName='%wZ', "
  641. +        "is_pubfh=%d, "
  642.          "ReadOnly=%d, "
  643.          "write_thru=%d, "
  644.          "nocache=%d "
  645. @@ -3439,6 +3492,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  646.          "}\n",
  647.          &Config->MntPt,
  648.          &Config->SrvName,
  649. +        Config->is_pubfh?1:0,
  650.          Config->ReadOnly?1:0,
  651.          Config->write_thru?1:0,
  652.          Config->nocache?1:0,
  653. @@ -3564,7 +3618,7 @@ NTSTATUS nfs41_CreateVNetRoot(
  654.          RtlCopyLuid(&entry->login_id, &luid);
  655.          /*
  656.           * Save mount config so we can use it for
  657. -         * \\server@port\nfs4\path mounts later
  658. +         * \\server@port\@(pubnfs4|nfs4)\path mounts later
  659.           */
  660.          copy_nfs41_mount_config(&entry->Config, Config);
  661.          nfs41_AddEntry(pNetRootContext->mountLock,

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.

Syntax highlighting:

To highlight particular lines, prefix each line with {%HIGHLIGHT}




All content is user-submitted.
The administrators of this site (kpaste.net) are not responsible for their content.
Abuse reports should be emailed to us at