pastebin - collaborative debugging tool
rovema.kpaste.net RSS


msnfs41client: Patch for non-ASCII characters in Win32 user+group names+misc, 2025-06-13
Posted by Anonymous on Fri 13th Jun 2025 16:41
raw | new post

  1. From f8a53c192eb697b88c5d7dcd29834129c7c0e842 Mon Sep 17 00:00:00 2001
  2. From: Lionel Cons <lionelcons1972@gmail.com>
  3. Date: Fri, 13 Jun 2025 14:58:14 +0200
  4. Subject: [PATCH 1/6] tests: Fix tests/winclonefile/winclonefile.c build
  5.  failure with newer MinGW headers
  6.  
  7. Fix tests/winclonefile/winclonefile.c build failure with newer MinGW headers.
  8.  
  9. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  10. ---
  11. tests/winclonefile/winclonefile.c | 14 ++++++++++++--
  12.  1 file changed, 12 insertions(+), 2 deletions(-)
  13.  
  14. diff --git a/tests/winclonefile/winclonefile.c b/tests/winclonefile/winclonefile.c
  15. index 39b019b..c79672d 100644
  16. --- a/tests/winclonefile/winclonefile.c
  17. +++ b/tests/winclonefile/winclonefile.c
  18. @@ -37,7 +37,17 @@
  19.  
  20.  #define EXIT_USAGE (2)
  21.  
  22. -#if 1
  23. +#ifdef DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC
  24. +/*
  25. + * MinGW commit
  26. + * https://github.com/mingw-w64/mingw-w64/commit/dd725c39e8eace4bfaa76e30e648b2bf7e7541e3
  27. + * added |DUPLICATE_EXTENTS_DATA| and |DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC|
  28. + */
  29. +#define WIN32_HEADERS_HAVE_DUPLICATE_EXTENTS_DATA 1
  30. +#endif /* WIN32_HEADERS_HAVE_DUPLICATE_EXTENTS_DATA */
  31. +
  32. +
  33. +#ifndef WIN32_HEADERS_HAVE_DUPLICATE_EXTENTS_DATA
  34.  /*
  35.   * MinGW include do not define |DUPLICATE_EXTENTS_DATA| yet, see
  36.   * https://github.com/mingw-w64/mingw-w64/issues/90 ("[mingw-w64/mingw-w64]
  37. @@ -49,7 +59,7 @@ typedef struct _DUPLICATE_EXTENTS_DATA {
  38.      LARGE_INTEGER TargetFileOffset;
  39.      LARGE_INTEGER ByteCount;
  40.  } DUPLICATE_EXTENTS_DATA, *PDUPLICATE_EXTENTS_DATA;
  41. -#endif
  42. +#endif /* WIN32_HEADERS_HAVE_DUPLICATE_EXTENTS_DATA */
  43.  
  44.  
  45.  void
  46. --
  47. 2.45.1
  48.  
  49. From 3c83bad5284c8d9c88ff8a5f7fad81487e1b976f Mon Sep 17 00:00:00 2001
  50. From: Lionel Cons <lionelcons1972@gmail.com>
  51. Date: Fri, 13 Jun 2025 15:01:23 +0200
  52. Subject: [PATCH 2/6] tests: Fix bogus trailing backslash in tests/*/Makefiles
  53.  
  54. Fix bogus trailing backslash in tests/*/Makefiles.
  55.  
  56. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  57. ---
  58. tests/ea/Makefile           | 2 +-
  59.  tests/lssparse/Makefile     | 2 +-
  60.  tests/winclonefile/Makefile | 2 +-
  61.  tests/winfsinfo1/Makefile   | 2 +-
  62.  tests/winsg/Makefile        | 2 +-
  63.  5 files changed, 5 insertions(+), 5 deletions(-)
  64.  
  65. diff --git a/tests/ea/Makefile b/tests/ea/Makefile
  66. index 65e58a3..4e49afd 100644
  67. --- a/tests/ea/Makefile
  68. +++ b/tests/ea/Makefile
  69. @@ -20,5 +20,5 @@ clean:
  70.         rm -fv \
  71.                 nfs_ea.i686.exe \
  72.                 nfs_ea.x86_64.exe \
  73. -               nfs_ea.exe \
  74. +               nfs_ea.exe
  75.  # EOF.
  76. diff --git a/tests/lssparse/Makefile b/tests/lssparse/Makefile
  77. index 4f92fc1..6b591ac 100644
  78. --- a/tests/lssparse/Makefile
  79. +++ b/tests/lssparse/Makefile
  80. @@ -19,5 +19,5 @@ lssparse.exe: lssparse.x86_64.exe
  81.  clean:
  82.         rm -fv \
  83.                 lssparse.x86_64.exe \
  84. -               lssparse.exe \
  85. +               lssparse.exe
  86.  # EOF.
  87. diff --git a/tests/winclonefile/Makefile b/tests/winclonefile/Makefile
  88. index bf548b7..f541936 100644
  89. --- a/tests/winclonefile/Makefile
  90. +++ b/tests/winclonefile/Makefile
  91. @@ -19,5 +19,5 @@ clean:
  92.         rm -fv \
  93.                 winclonefile.i686.exe \
  94.                 winclonefile.x86_64.exe \
  95. -               winclonefile.exe \
  96. +               winclonefile.exe
  97.  # EOF.
  98. diff --git a/tests/winfsinfo1/Makefile b/tests/winfsinfo1/Makefile
  99. index 6ef7039..7a529a6 100644
  100. --- a/tests/winfsinfo1/Makefile
  101. +++ b/tests/winfsinfo1/Makefile
  102. @@ -19,5 +19,5 @@ clean:
  103.         rm -fv \
  104.                 winfsinfo.i686.exe \
  105.                 winfsinfo.x86_64.exe \
  106. -               winfsinfo.exe \
  107. +               winfsinfo.exe
  108.  # EOF.
  109. diff --git a/tests/winsg/Makefile b/tests/winsg/Makefile
  110. index 19f96db..6c548ca 100644
  111. --- a/tests/winsg/Makefile
  112. +++ b/tests/winsg/Makefile
  113. @@ -19,5 +19,5 @@ clean:
  114.         rm -fv \
  115.                 winsg.i686.exe \
  116.                 winsg.x86_64.exe \
  117. -               winsg.exe \
  118. +               winsg.exe
  119.  # EOF.
  120. --
  121. 2.45.1
  122.  
  123. From 4501f442aed934d4c7e39ffb5548266ff574b4a0 Mon Sep 17 00:00:00 2001
  124. From: Roland Mainz <roland.mainz@nrubsig.org>
  125. Date: Fri, 13 Jun 2025 15:05:17 +0200
  126. Subject: [PATCH 3/6] tests: Add test entry for directory ACL "X" flag
  127.  
  128. Add test entry for directory ACL "X" flag.
  129.  
  130. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  131. ---
  132. tests/manual_testing.txt | 11 +++++++++--
  133.  1 file changed, 9 insertions(+), 2 deletions(-)
  134.  
  135. diff --git a/tests/manual_testing.txt b/tests/manual_testing.txt
  136. index 29691e4..ea82965 100644
  137. --- a/tests/manual_testing.txt
  138. +++ b/tests/manual_testing.txt
  139. @@ -377,11 +377,18 @@ ksh93 -c 'rm -f test1.txt test2.txt aclspec.icacls aclspec2.icacls ; touch test1
  140.  -------- snip --------
  141.  
  142.  #
  143. -# Test for "Generic Write" ACL:
  144. +# Test for file "Generic Write" ACL:
  145.  #
  146.  $ ksh93 -c 'set -o xtrace ; rm -f test1.txt ; touch test1.txt ; icacls test1.txt /grant "siegfried_wulsch:(GW)" ; icacls test1.txt | grep --colour -E "siegfried_wulsch.+GW"'
  147.  # Expectation:
  148. -The ACL entry for user "siegfried_wulsch" should have the "GW" flag set
  149. +# The ACL entry for user "siegfried_wulsch" should have the "GW" flag set
  150. +
  151. +#
  152. +# Test for directory "X" ACL:
  153. +#
  154. +$ ksh93 -c 'set -o xtrace ; rm -rf test1.dir ; mkdir test1.dir ; icacls test1.dir /grant "siegfried_wulsch:(W,X)" ; icacls test1.dir | grep --colour -E "siegfried_wulsch.+X"'
  155. +# Expectation:
  156. +# The ACL entry for user "siegfried_wulsch" should have the "X" flag set
  157.  
  158.  #
  159.  # Test for default (inheritance) ACLs:
  160. --
  161. 2.45.1
  162.  
  163. From f71e60aa629ca308d286d03e978a4f4d1d4e5574 Mon Sep 17 00:00:00 2001
  164. From: Roland Mainz <roland.mainz@nrubsig.org>
  165. Date: Fri, 13 Jun 2025 16:08:45 +0200
  166. Subject: [PATCH 4/6] cygwin_idmapper.ksh: printf %q does not need to be in
  167.  quotes
  168.  
  169. printf %q does not need to be in quotes, because ksh93 printf %q
  170. already does quoting itself.
  171.  
  172. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  173. ---
  174. cygwin_idmapper.ksh | 6 +++---
  175.  1 file changed, 3 insertions(+), 3 deletions(-)
  176.  
  177. diff --git a/cygwin_idmapper.ksh b/cygwin_idmapper.ksh
  178. index 84686c2..e55fe96 100644
  179. --- a/cygwin_idmapper.ksh
  180. +++ b/cygwin_idmapper.ksh
  181. @@ -46,7 +46,7 @@ typeset -A c.localised_groupnames
  182.  # versions use different values
  183.  typeset machine_sid="$(mkgroup -l | sed -n 's/[^:]*:\(S-[-0-9]*\)-513:.*$/\1/p')"
  184.  if [[ "$machine_sid" != ~(El)S-1-5-21- ]] ; then
  185. -       print -u2 -f "%s: Unexpected machine SID '%q'\n" \
  186. +       print -u2 -f "%s: Unexpected machine SID %q\n" \
  187.                 "$0" "$machine_sid"
  188.         exit 1
  189.  fi
  190. @@ -302,7 +302,7 @@ case "${c.mode}" in
  191.                         fi
  192.                 fi
  193.  
  194. -               print -u2 -f "cygwin_idmapper.ksh: Account '%q' not found.\n" "${c.name}"
  195. +               print -u2 -f "cygwin_idmapper.ksh: Account %q not found.\n" "${c.name}"
  196.                 exit 1
  197.                 ;;
  198.         'nfsserver_owner_group2localgroup')
  199. @@ -341,7 +341,7 @@ case "${c.mode}" in
  200.                         fi
  201.                 fi
  202.  
  203. -               print -u2 -f "cygwin_idmapper.ksh: Group '%q' not found.\n" "${c.name}"
  204. +               print -u2 -f "cygwin_idmapper.ksh: Group %q not found.\n" "${c.name}"
  205.                 exit 1
  206.                 ;;
  207.         *)
  208. --
  209. 2.45.1
  210.  
  211. From af233024aee6a489ab489b6bf83fe7b50f579168 Mon Sep 17 00:00:00 2001
  212. From: Roland Mainz <roland.mainz@nrubsig.org>
  213. Date: Fri, 13 Jun 2025 17:20:35 +0200
  214. Subject: [PATCH 5/6] daemon: |subcmd_popen()| should be able to pass arguments
  215.  with non-ASCII characters to child processes
  216.  
  217. |subcmd_popen()| should be able to pass arguments with non-ASCII characters
  218. to child processes.
  219.  
  220. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  221. ---
  222. daemon/util.c | 22 +++++++++++++++++++---
  223.  1 file changed, 19 insertions(+), 3 deletions(-)
  224.  
  225. diff --git a/daemon/util.c b/daemon/util.c
  226. index aa3883f..1317fbe 100644
  227. --- a/daemon/util.c
  228. +++ b/daemon/util.c
  229. @@ -424,7 +424,7 @@ out:
  230.  subcmd_popen_context *subcmd_popen(const char *command)
  231.  {
  232.      subcmd_popen_context *pinfo;
  233. -    STARTUPINFOA si;
  234. +    STARTUPINFOW si;
  235.      SECURITY_ATTRIBUTES sa = { 0 };
  236.  
  237.      if (!command) {
  238. @@ -483,8 +483,24 @@ subcmd_popen_context *subcmd_popen(const char *command)
  239.      si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  240.      si.dwFlags |= STARTF_USESTDHANDLES;
  241.  
  242. -    if (!CreateProcessA(NULL,
  243. -        (LPSTR)command, NULL, NULL, TRUE, 0, NULL, NULL, &si,
  244. +    size_t commandWSize = strlen(command)+1;
  245. +    wchar_t *commandW = _alloca(commandWSize * sizeof(wchar_t));
  246. +
  247. +    if (MultiByteToWideChar(CP_UTF8,
  248. +        0,
  249. +        command,
  250. +        -1,
  251. +        commandW,
  252. +        (int)commandWSize) == 0) {
  253. +        if (GetLastError() == ERROR_SUCCESS) {
  254. +            SetLastError(ERROR_INVALID_DATA);
  255. +        }
  256. +        DPRINTF(0, ("subcmd_popen: cannot convert cmdline to widechar\n"));
  257. +        goto fail;
  258. +    }
  259. +
  260. +    if (!CreateProcessW(NULL,
  261. +        commandW, NULL, NULL, TRUE, 0, NULL, NULL, &si,
  262.          &pinfo->pi)) {
  263.          DPRINTF(0, ("subcmd_popen: cannot create process\n"));
  264.          goto fail;
  265. --
  266. 2.45.1
  267.  
  268. From fa71019ba355e9c604293f715248a5018bd2a2b1 Mon Sep 17 00:00:00 2001
  269. From: Roland Mainz <roland.mainz@nrubsig.org>
  270. Date: Fri, 13 Jun 2025 17:23:41 +0200
  271. Subject: [PATCH 6/6] daemon: Allow non-ASCII characters in Win32 user+group
  272.  names
  273. MIME-Version: 1.0
  274. Content-Type: text/plain; charset=UTF-8
  275. Content-Transfer-Encoding: 8bit
  276.  
  277. Allow non-ASCII characters in Win32 user+group names, by converting
  278. the NFSv4 { owner, owner_group, ACL } UTF-8 strings from/to
  279. Win32 |wchar_t| strings, and use |LookupAccountSidW()| and
  280. |LookupAccountNameW()| instead of the Win32 codepage-specific
  281. |LookupAccountSidA()| and |LookupAccountNameA()|.
  282.  
  283. Reported-by: Aurelien Couderc <aurelien.couderc2002@gmail.com>
  284. Reported-by: Horacio Campoy Vidaña <horacio.campoy-vidana@rovema.de>
  285. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  286. ---
  287. daemon/accesstoken.c  |  18 ++-
  288.  daemon/acl.c          |  16 +-
  289.  daemon/nfs41_daemon.c |   4 +
  290.  daemon/sid.c          | 356 +++++++++++++++++++++++++++++++++++++++++-
  291.  daemon/sid.h          |  22 ++-
  292.  5 files changed, 393 insertions(+), 23 deletions(-)
  293.  
  294. diff --git a/daemon/accesstoken.c b/daemon/accesstoken.c
  295. index 6432bdb..eae34c6 100644
  296. --- a/daemon/accesstoken.c
  297. +++ b/daemon/accesstoken.c
  298. @@ -72,10 +72,10 @@ bool get_token_user_name(HANDLE tok, char *out_buffer)
  299.      }
  300.  #endif /* NFS41_DRIVER_SID_CACHE */
  301.  
  302. -    if (!LookupAccountSidA(NULL, pusid, out_buffer, &namesize,
  303. +    if (!lookupaccountsidutf8(NULL, pusid, out_buffer, &namesize,
  304.          domainbuffer, &domainbuffer_size, &name_use)) {
  305.          eprintf("get_token_user_name: "
  306. -            "LookupAccountSidA() failed, status=%d\n",
  307. +            "lookupaccountsidutf8() failed, status=%d\n",
  308.              (int)GetLastError());
  309.          return false;
  310.      }
  311. @@ -116,10 +116,10 @@ bool get_token_primarygroup_name(HANDLE tok, char *out_buffer)
  312.      }
  313.  #endif /* NFS41_DRIVER_SID_CACHE */
  314.  
  315. -    if (!LookupAccountSidA(NULL, pgsid, out_buffer, &namesize,
  316. +    if (!lookupaccountsidutf8(NULL, pgsid, out_buffer, &namesize,
  317.          domainbuffer, &domainbuffer_size, &name_use)) {
  318.          eprintf("get_token_primarygroup_name: "
  319. -            "LookupAccountSidA() failed, status=%d\n",
  320. +            "lookupaccountsidutf8() failed, status=%d\n",
  321.              (int)GetLastError());
  322.          return false;
  323.      }
  324. @@ -241,10 +241,14 @@ bool get_token_groups_names(HANDLE tok,
  325.          namesize = sizeof(namebuffer)-1;
  326.          domainbuffer_size = sizeof(domainbuffer)-1;
  327.  
  328. -        if (!LookupAccountSidA(NULL, ptgroups->Groups[i].Sid,
  329. -            namebuffer, &namesize, domainbuffer, &domainbuffer_size, &name_use)) {
  330. +        if (!lookupaccountsidutf8(NULL, ptgroups->Groups[i].Sid,
  331. +            namebuffer,
  332. +            &namesize,
  333. +            domainbuffer,
  334. +            &domainbuffer_size,
  335. +            &name_use)) {
  336.              DPRINTF(0, ("get_token_groups_names: "
  337. -                "LookupAccountSidA() failed, status=%d.\n",
  338. +                "lookupaccountsidutf8() failed, status=%d.\n",
  339.                  (int)GetLastError()));
  340.              continue;
  341.          }
  342. diff --git a/daemon/acl.c b/daemon/acl.c
  343. index ecf6156..45dda26 100644
  344. --- a/daemon/acl.c
  345. +++ b/daemon/acl.c
  346. @@ -1,5 +1,6 @@
  347.  /* NFSv4.1 client for Windows
  348. - * Copyright (C) 2012 The Regents of the University of Michigan
  349. + * Copyright (C) 2012 The Regents of the University of Michigan
  350. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  351.   *
  352.   * Olga Kornievskaia <aglo@umich.edu>
  353.   * Casey Bodley <cbodley@umich.edu>
  354. @@ -987,8 +988,8 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  355.          goto out;
  356.      }
  357.  
  358. -    status = LookupAccountSidA(NULL, sid, who_buf, &who_size, domain_buf,
  359. -                                &domain_size, &sid_type);
  360. +    status = lookupaccountsidutf8(NULL, sid, who_buf, &who_size, domain_buf,
  361. +        &domain_size, &sid_type);
  362.      lasterr = GetLastError();
  363.  
  364.      if (status) {
  365. @@ -1074,14 +1075,15 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  366.                      goto err_none_mapped;
  367.                  }
  368.  
  369. -                eprintf("map_sid2nfs4ace_who: LookupAccountSidA() "
  370. +                eprintf("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  371.                      "returned ERROR_NONE_MAPPED+no "
  372.                      "Unix_@(User|Group)+ mapping for sidstr='%s'\n",
  373.                      sidstr);
  374.  err_none_mapped:
  375.                  status = ERROR_NONE_MAPPED;
  376.  #else
  377. -                DPRINTF(ACLLVL2, ("map_sid2nfs4ace_who: LookupAccountSidA() "
  378. +                DPRINTF(ACLLVL2,
  379. +                    ("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  380.                      "returned ERROR_NONE_MAPPED for sidstr='%s'\n",
  381.                      sidstr));
  382.                  status = lasterr;
  383. @@ -1091,7 +1093,7 @@ err_none_mapped:
  384.              /* Catch other cases */
  385.              case ERROR_NO_SUCH_USER:
  386.              case ERROR_NO_SUCH_GROUP:
  387. -                eprintf("map_sid2nfs4ace_who: LookupAccountSidA() "
  388. +                eprintf("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  389.                      "returned ERROR_NO_SUCH_@(USER|GROUP) for "
  390.                      "sidstr='%s'\n",
  391.                      sidstr);
  392. @@ -1099,7 +1101,7 @@ err_none_mapped:
  393.                  goto out;
  394.              default:
  395.                  eprintf("map_sid2nfs4ace_who: Internal error, "
  396. -                    "LookupAccountSidA() returned unexpected ERROR_%d "
  397. +                    "lookupaccountsidutf8() returned unexpected ERROR_%d "
  398.                      "for sidstr='%s'\n",
  399.                      status, sidstr);
  400.                  status = ERROR_INTERNAL_ERROR;
  401. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  402. index 93d66b2..0fd2255 100644
  403. --- a/daemon/nfs41_daemon.c
  404. +++ b/daemon/nfs41_daemon.c
  405. @@ -792,6 +792,10 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  406.      DPRINTF(0, ("SID cache disabled\n"));
  407.  #endif /* NFS41_DRIVER_SID_CACHE */
  408.  
  409. +#if 1
  410. +    DPRINTF(0, ("wmain: GetACP()=%d\n", (int)GetACP()));
  411. +#endif
  412. +
  413.  #ifdef _DEBUG
  414.      logprintf("NFS client daemon (DEBUG build) %s starting...\n",
  415.          GIT_COMMIT_ID);
  416. diff --git a/daemon/sid.c b/daemon/sid.c
  417. index 0ea20ee..0ce84f8 100644
  418. --- a/daemon/sid.c
  419. +++ b/daemon/sid.c
  420. @@ -1,5 +1,6 @@
  421.  /* NFSv4.1 client for Windows
  422. - * Copyright (C) 2012 The Regents of the University of Michigan
  423. + * Copyright (C) 2012 The Regents of the University of Michigan
  424. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  425.   *
  426.   * Olga Kornievskaia <aglo@umich.edu>
  427.   * Casey Bodley <cbodley@umich.edu>
  428. @@ -327,7 +328,8 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
  429.      /* Replace the cache entry */
  430.      sidcache_entry *e = &cache->entries[freeEntryIndex];
  431.      DWORD sid_len = GetLengthSid(value);
  432. -    EASSERT(sid_len <= SECURITY_MAX_SID_SIZE);
  433. +    EASSERT_MSG((sid_len <= SECURITY_MAX_SID_SIZE),
  434. +        ("sid_len=%ld\n", (long)sid_len));
  435.      e->sid = (PSID)e->sid_buffer;
  436.      if (!CopySid(sid_len, e->sid, value)) {
  437.          e->sid = NULL;
  438. @@ -506,15 +508,15 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  439.      *sid_len = SECURITY_MAX_SID_SIZE;
  440.      domain_len = sizeof(domain_buff);
  441.  
  442. -    status = LookupAccountNameA(NULL, nfsname, *sid, sid_len,
  443. +    status = lookupaccountnameutf8(NULL, nfsname, *sid, sid_len,
  444.          domain_buff, &domain_len, &sid_type);
  445.  
  446.      if (status) {
  447. -        /* |LookupAccountNameA()| success */
  448. +        /* |lookupaccountnameutf8()| success */
  449.  
  450.          DPRINTF(ACLLVL,
  451.              ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  452. -            "LookupAccountNameA() returned status=%d "
  453. +            "lookupaccountnameutf8() returned status=%d "
  454.              "GetLastError=%d *sid_len=%d domain_buff='%s' domain_len=%d\n",
  455.              query, nfsname, status, GetLastError(), *sid_len, domain_buff,
  456.              domain_len));
  457. @@ -524,10 +526,10 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  458.          goto out_cache;
  459.      }
  460.  
  461. -    /* |LookupAccountNameA()| failed... */
  462. +    /* |lookupaccountnameutf8()| failed... */
  463.      DPRINTF(ACLLVL,
  464.          ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  465. -        "LookupAccountNameA() returned status=%d "
  466. +        "lookupaccountnameutf8() returned status=%d "
  467.          "GetLastError=%d\n",
  468.          query, nfsname, status, GetLastError()));
  469.  
  470. @@ -648,7 +650,7 @@ out_cache:
  471.              /*
  472.               * Treat |SidTypeAlias| as (local) group
  473.               *
  474. -             * It seems that |LookupAccountNameA()| will always return
  475. +             * It seems that |lookupaccountnameutf8()| will always return
  476.               * |SidTypeAlias| for local groups created with
  477.               * $ net localgroup cygwingrp1 /add #
  478.               *
  479. @@ -743,3 +745,341 @@ out_free_sid:
  480.      *sid = NULL;
  481.      goto out;
  482.  }
  483. +
  484. +
  485. +/* Maximum number of bytes required to store one |wchar_t| as UTF-8 */
  486. +#define MAX_UTF8_BYTES_PER_WCHAR_T (5)
  487. +
  488. +/*
  489. + * |lookupaccountnameutf8()| - UTF-8 version of |LookupAccountNameA()|
  490. + *
  491. + * We need this because Windows user+group names can contain Unicode
  492. + * characters, and |*A()| functions depend on the current code page,
  493. + * which might not cover all code points needed
  494. + */
  495. +BOOL lookupaccountnameutf8(
  496. +    const char *restrict pSystemNameUTF8,
  497. +    const char *restrict pAccountNameUTF8,
  498. +    PSID restrict pSid,
  499. +    LPDWORD restrict pSidSize,
  500. +    char *restrict pReferencedDomainNameUTF8,
  501. +    LPDWORD restrict pReferencedDomainNameUTF8size,
  502. +    PSID_NAME_USE restrict peUse)
  503. +{
  504. +#ifdef NO_UTF8_ACCOUNT_CONV
  505. +    return LookupAccountNameA(
  506. +        pSystemNameUTF8,
  507. +        pAccountNameUTF8,
  508. +        pSid,
  509. +        pSidSize,
  510. +        pReferencedDomainNameUTF8,
  511. +        pReferencedDomainNameUTF8size,
  512. +        peUse);
  513. +#else
  514. +    if ((pAccountNameUTF8 == NULL) ||
  515. +        (pReferencedDomainNameUTF8size == NULL) ||
  516. +        (pSidSize == NULL) || (peUse == NULL)) {
  517. +        SetLastError(ERROR_INVALID_PARAMETER);
  518. +        return FALSE;
  519. +    }
  520. +
  521. +    LPWSTR pSystemNameW;
  522. +
  523. +    if (pSystemNameUTF8) {
  524. +        DWORD systemNameWsize;
  525. +
  526. +        /*
  527. +         * Use |strlen()| here as optimisation, saving one around of
  528. +         * |MultiByteToWideChar()|
  529. +         */
  530. +        systemNameWsize = (DWORD)strlen(pSystemNameUTF8)+1;
  531. +        pSystemNameW = (LPWSTR)_alloca(systemNameWsize * sizeof(wchar_t));
  532. +
  533. +        if (MultiByteToWideChar(CP_UTF8,
  534. +            0,
  535. +            pSystemNameUTF8,
  536. +            -1,
  537. +            pSystemNameW,
  538. +            systemNameWsize) == 0) {
  539. +            if (GetLastError() == ERROR_SUCCESS) {
  540. +                SetLastError(ERROR_INVALID_DATA);
  541. +            }
  542. +            return FALSE;
  543. +        }
  544. +    }
  545. +    else {
  546. +        pSystemNameW = NULL;
  547. +    }
  548. +
  549. +    LPWSTR pAccountNameW;
  550. +    DWORD accountNameWsize;
  551. +
  552. +    /*
  553. +     * Use |strlen()| here as optimisation, saving one around of
  554. +     * |MultiByteToWideChar()|
  555. +     */
  556. +    accountNameWsize = (DWORD)strlen(pAccountNameUTF8)+1;
  557. +    pAccountNameW = (LPWSTR)_alloca(accountNameWsize * sizeof(wchar_t));
  558. +
  559. +    if (MultiByteToWideChar(CP_UTF8,
  560. +        0,
  561. +        pAccountNameUTF8,
  562. +        -1,
  563. +        pAccountNameW,
  564. +        accountNameWsize) == 0) {
  565. +        if (GetLastError() == ERROR_SUCCESS) {
  566. +            SetLastError(ERROR_INVALID_DATA);
  567. +        }
  568. +        return FALSE;
  569. +    }
  570. +
  571. +    DWORD referencedDomainNameWsize =
  572. +        (DWORD)*pReferencedDomainNameUTF8size / sizeof(wchar_t);
  573. +    LPWSTR pReferencedDomainNameW = NULL;
  574. +
  575. +    if ((pReferencedDomainNameUTF8 == NULL) ||
  576. +        (*pReferencedDomainNameUTF8size == 0)) {
  577. +        referencedDomainNameWsize = 256;
  578. +    }
  579. +
  580. +    pReferencedDomainNameW =
  581. +        (LPWSTR)_alloca(referencedDomainNameWsize * sizeof(wchar_t));
  582. +
  583. +    BOOL success = LookupAccountNameW(
  584. +        pSystemNameW,
  585. +        pAccountNameW,
  586. +        pSid,
  587. +        pSidSize,
  588. +        pReferencedDomainNameW,
  589. +        &referencedDomainNameWsize,
  590. +        peUse);
  591. +
  592. +    if (!success) {
  593. +        DWORD lastError = GetLastError();
  594. +
  595. +        if (lastError == ERROR_INSUFFICIENT_BUFFER) {
  596. +            int requiredDomainNameUTF8Size = WideCharToMultiByte(CP_UTF8,
  597. +                0,
  598. +                pReferencedDomainNameW,
  599. +                referencedDomainNameWsize+1,
  600. +                NULL,
  601. +                0,
  602. +                NULL,
  603. +                NULL);
  604. +            if (requiredDomainNameUTF8Size == 0) {
  605. +                if (GetLastError() == ERROR_SUCCESS) {
  606. +                    SetLastError(ERROR_INVALID_DATA);
  607. +                }
  608. +                return FALSE;
  609. +            }
  610. +
  611. +            *pReferencedDomainNameUTF8size =
  612. +                (size_t)requiredDomainNameUTF8Size+1;
  613. +        } else if (lastError == ERROR_NONE_MAPPED) {
  614. +            *pReferencedDomainNameUTF8size = 0;
  615. +            *pSidSize = 0;
  616. +            *peUse = SidTypeUnknown;
  617. +        } else {
  618. +            *pReferencedDomainNameUTF8size = 0;
  619. +            *pSidSize = 0;
  620. +            *peUse = SidTypeUnknown;
  621. +        }
  622. +
  623. +        return FALSE;
  624. +    }
  625. +
  626. +    int domainNameUTF8size = WideCharToMultiByte(CP_UTF8,
  627. +        0,
  628. +        pReferencedDomainNameW,
  629. +        referencedDomainNameWsize+1,
  630. +        NULL,
  631. +        0,
  632. +        NULL,
  633. +        NULL);
  634. +    if (domainNameUTF8size == 0) {
  635. +        if (GetLastError() == ERROR_SUCCESS) {
  636. +            SetLastError(ERROR_INVALID_DATA);
  637. +        }
  638. +        return FALSE;
  639. +    }
  640. +
  641. +    if (*pReferencedDomainNameUTF8size < (size_t)domainNameUTF8size) {
  642. +        *pReferencedDomainNameUTF8size = (size_t)domainNameUTF8size;
  643. +        SetLastError(ERROR_INSUFFICIENT_BUFFER);
  644. +        return FALSE;
  645. +    }
  646. +
  647. +    (void)WideCharToMultiByte(CP_UTF8,
  648. +        0,
  649. +        pReferencedDomainNameW,
  650. +        referencedDomainNameWsize+1,
  651. +        pReferencedDomainNameUTF8,
  652. +        domainNameUTF8size,
  653. +        NULL,
  654. +        NULL);
  655. +    *pReferencedDomainNameUTF8size = (size_t)domainNameUTF8size-1;
  656. +
  657. +    SetLastError(ERROR_SUCCESS);
  658. +    return TRUE;
  659. +#endif /* NO_UTF8_ACCOUNT_CONV */
  660. +}
  661. +
  662. +
  663. +/*
  664. + * |lookupaccountsidutf8()| - UTF-8 version of |LookupAccountSidA()|
  665. + *
  666. + * We need this because Windows user+group names can contain Unicode
  667. + * characters, and |*A()| functions depend on the current code page,
  668. + * which might not cover all code points needed
  669. + */
  670. +BOOL lookupaccountsidutf8(
  671. +    const char *restrict pSystemNameUTF8,
  672. +    PSID restrict Sid,
  673. +    char *restrict pNameUTF8,
  674. +    LPDWORD restrict pNameSize,
  675. +    char *restrict pReferencedDomainNameUTF8,
  676. +    LPDWORD restrict pReferencedDomainNameUTF8Size,
  677. +    PSID_NAME_USE restrict peUse)
  678. +{
  679. +#ifdef NO_UTF8_ACCOUNT_CONV
  680. +    return LookupAccountSidA(pSystemNameUTF8,
  681. +        Sid, pNameUTF8, pNameSize,
  682. +        pReferencedDomainNameUTF8, pReferencedDomainNameUTF8Size,
  683. +        peUse);
  684. +#else
  685. +    if ((Sid == NULL) ||
  686. +        (pNameUTF8 == NULL) ||
  687. +        (pNameSize == NULL) ||
  688. +        (pReferencedDomainNameUTF8 == NULL) ||
  689. +        (pReferencedDomainNameUTF8Size == NULL) ||
  690. +        (peUse == NULL)) {
  691. +        SetLastError(ERROR_INVALID_PARAMETER);
  692. +        return FALSE;
  693. +    }
  694. +
  695. +    wchar_t *systemNameW;
  696. +    wchar_t *nameW;
  697. +    wchar_t *referencedDomainNameW;
  698. +
  699. +    if (pSystemNameUTF8) {
  700. +        DWORD wide_len = (DWORD)strlen(pSystemNameUTF8)+1;
  701. +
  702. +        systemNameW = (wchar_t *)_alloca(wide_len * sizeof(wchar_t));
  703. +
  704. +        if (MultiByteToWideChar(CP_UTF8,
  705. +            0,
  706. +            pSystemNameUTF8,
  707. +            -1,
  708. +            systemNameW,
  709. +            wide_len) == 0) {
  710. +            if (GetLastError() == ERROR_SUCCESS) {
  711. +                SetLastError(ERROR_INVALID_DATA);
  712. +            }
  713. +            return FALSE;
  714. +        }
  715. +    }
  716. +    else {
  717. +        systemNameW = NULL;
  718. +    }
  719. +
  720. +    nameW = (wchar_t *)_alloca(((size_t)*pNameSize+1) * sizeof(wchar_t));
  721. +    referencedDomainNameW =
  722. +        (wchar_t *)_alloca(((size_t)*pReferencedDomainNameUTF8Size+1) *
  723. +            sizeof(wchar_t));
  724. +
  725. +    DWORD nameSizeW = *pNameSize;
  726. +    DWORD referencedDomainNameSizeW =
  727. +        *pReferencedDomainNameUTF8Size;
  728. +
  729. +    if (!LookupAccountSidW(
  730. +        systemNameW,
  731. +        Sid,
  732. +        nameW,
  733. +        &nameSizeW,
  734. +        referencedDomainNameW,
  735. +        &referencedDomainNameSizeW,
  736. +        peUse))
  737. +    {
  738. +        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  739. +            /* Assume that each |wchar_t| needs a maximum of 5 bytes */
  740. +            *pNameSize = nameSizeW * MAX_UTF8_BYTES_PER_WCHAR_T;
  741. +            *pReferencedDomainNameUTF8Size =
  742. +                referencedDomainNameSizeW * MAX_UTF8_BYTES_PER_WCHAR_T;
  743. +        }
  744. +        return FALSE;
  745. +    }
  746. +
  747. +    int required_name_utf8_bytes = WideCharToMultiByte(CP_UTF8,
  748. +        0,
  749. +        nameW,
  750. +        nameSizeW+1,
  751. +        NULL,
  752. +        0,
  753. +        NULL,
  754. +        NULL);
  755. +    if (required_name_utf8_bytes == 0) {
  756. +        if (GetLastError() == ERROR_SUCCESS) {
  757. +            SetLastError(ERROR_INVALID_DATA);
  758. +        }
  759. +        return FALSE;
  760. +    }
  761. +
  762. +    int required_domain_utf8_bytes = WideCharToMultiByte(CP_UTF8,
  763. +        0,
  764. +        referencedDomainNameW,
  765. +        referencedDomainNameSizeW+1,
  766. +        NULL,
  767. +        0,
  768. +        NULL,
  769. +        NULL);
  770. +    if (required_domain_utf8_bytes == 0) {
  771. +        if (GetLastError() == ERROR_SUCCESS) {
  772. +            SetLastError(ERROR_INVALID_DATA);
  773. +        }
  774. +        return FALSE;
  775. +    }
  776. +
  777. +    if ((*pNameSize < (DWORD)required_name_utf8_bytes) ||
  778. +        (*pReferencedDomainNameUTF8Size < (DWORD)required_domain_utf8_bytes)) {
  779. +        *pNameSize = (DWORD)required_name_utf8_bytes;
  780. +        *pReferencedDomainNameUTF8Size = (DWORD)required_domain_utf8_bytes;
  781. +        SetLastError(ERROR_INSUFFICIENT_BUFFER);
  782. +        return FALSE;
  783. +    }
  784. +
  785. +    int bytes_written_name = WideCharToMultiByte(CP_UTF8,
  786. +        0,
  787. +        nameW,
  788. +        nameSizeW+1,
  789. +        pNameUTF8,
  790. +        *pNameSize,
  791. +        NULL,
  792. +        NULL);
  793. +    if (bytes_written_name == 0) {
  794. +        if (GetLastError() == ERROR_SUCCESS) {
  795. +            SetLastError(ERROR_INVALID_DATA);
  796. +        }
  797. +        return FALSE;
  798. +    }
  799. +
  800. +    int bytes_written_domain = WideCharToMultiByte(CP_UTF8,
  801. +        0,
  802. +        referencedDomainNameW,
  803. +        referencedDomainNameSizeW+1,
  804. +        pReferencedDomainNameUTF8,
  805. +        *pReferencedDomainNameUTF8Size,
  806. +        NULL,
  807. +        NULL);
  808. +    if (bytes_written_domain == 0) {
  809. +        if (GetLastError() == ERROR_SUCCESS) {
  810. +            SetLastError(ERROR_INVALID_DATA);
  811. +        }
  812. +        return FALSE;
  813. +    }
  814. +
  815. +    *pReferencedDomainNameUTF8Size = (DWORD)bytes_written_domain-1;
  816. +    *pNameSize = (DWORD)bytes_written_name-1;
  817. +
  818. +    return TRUE;
  819. +#endif /* NO_UTF8_ACCOUNT_CONV */
  820. +}
  821. diff --git a/daemon/sid.h b/daemon/sid.h
  822. index 70fc910..c19b3d9 100644
  823. --- a/daemon/sid.h
  824. +++ b/daemon/sid.h
  825. @@ -1,6 +1,7 @@
  826.  
  827.  /* NFSv4.1 client for Windows
  828. - * Copyright (C) 2012 The Regents of the University of Michigan
  829. + * Copyright (C) 2012 The Regents of the University of Michigan
  830. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  831.   *
  832.   * Olga Kornievskaia <aglo@umich.edu>
  833.   * Casey Bodley <cbodley@umich.edu>
  834. @@ -64,4 +65,23 @@ bool sidcache_getcached_bysid(sidcache *cache, PSID sid, char *out_win32name);
  835.  
  836.  int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *sid_len, PSID *sid, LPCSTR name);
  837.  
  838. +/* UTF-8 version of |LookupAccountNameA()| */
  839. +BOOL lookupaccountnameutf8(
  840. +    const char *restrict pSystemNameUTF8,
  841. +    const char *restrict pAccountNameUTF8,
  842. +    PSID restrict pSid,
  843. +    LPDWORD restrict pSidSize,
  844. +    char *restrict pReferencedDomainNameUTF8,
  845. +    LPDWORD restrict pReferencedDomainNameUTF8size,
  846. +    PSID_NAME_USE restrict peUse);
  847. +/* UTF-8 version of |LookupAccountSidA()| */
  848. +BOOL lookupaccountsidutf8(
  849. +    const char *restrict pSystemNameUTF8,
  850. +    PSID restrict Sid,
  851. +    char *restrict pNameUTF8,
  852. +    LPDWORD restrict pNameSize,
  853. +    char *restrict pReferencedDomainNameUTF8,
  854. +    LPDWORD restrict pReferencedDomainNameSize,
  855. +    PSID_NAME_USE restrict peUse);
  856. +
  857.  #endif /* !__NFS41_DAEMON_SID_H */
  858. --
  859. 2.45.1

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