pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


msnfs41client: Prototype for supporting non-ASCII user+group names
Posted by Anonymous on Fri 13th Jun 2025 16:04
raw | new post

  1. diff --git a/daemon/accesstoken.c b/daemon/accesstoken.c
  2. index 6432bdb..eae34c6 100644
  3. --- a/daemon/accesstoken.c
  4. +++ b/daemon/accesstoken.c
  5. @@ -72,10 +72,10 @@ bool get_token_user_name(HANDLE tok, char *out_buffer)
  6.      }
  7.  #endif /* NFS41_DRIVER_SID_CACHE */
  8.  
  9. -    if (!LookupAccountSidA(NULL, pusid, out_buffer, &namesize,
  10. +    if (!lookupaccountsidutf8(NULL, pusid, out_buffer, &namesize,
  11.          domainbuffer, &domainbuffer_size, &name_use)) {
  12.          eprintf("get_token_user_name: "
  13. -            "LookupAccountSidA() failed, status=%d\n",
  14. +            "lookupaccountsidutf8() failed, status=%d\n",
  15.              (int)GetLastError());
  16.          return false;
  17.      }
  18. @@ -116,10 +116,10 @@ bool get_token_primarygroup_name(HANDLE tok, char *out_buffer)
  19.      }
  20.  #endif /* NFS41_DRIVER_SID_CACHE */
  21.  
  22. -    if (!LookupAccountSidA(NULL, pgsid, out_buffer, &namesize,
  23. +    if (!lookupaccountsidutf8(NULL, pgsid, out_buffer, &namesize,
  24.          domainbuffer, &domainbuffer_size, &name_use)) {
  25.          eprintf("get_token_primarygroup_name: "
  26. -            "LookupAccountSidA() failed, status=%d\n",
  27. +            "lookupaccountsidutf8() failed, status=%d\n",
  28.              (int)GetLastError());
  29.          return false;
  30.      }
  31. @@ -241,10 +241,14 @@ bool get_token_groups_names(HANDLE tok,
  32.          namesize = sizeof(namebuffer)-1;
  33.          domainbuffer_size = sizeof(domainbuffer)-1;
  34.  
  35. -        if (!LookupAccountSidA(NULL, ptgroups->Groups[i].Sid,
  36. -            namebuffer, &namesize, domainbuffer, &domainbuffer_size, &name_use)) {
  37. +        if (!lookupaccountsidutf8(NULL, ptgroups->Groups[i].Sid,
  38. +            namebuffer,
  39. +            &namesize,
  40. +            domainbuffer,
  41. +            &domainbuffer_size,
  42. +            &name_use)) {
  43.              DPRINTF(0, ("get_token_groups_names: "
  44. -                "LookupAccountSidA() failed, status=%d.\n",
  45. +                "lookupaccountsidutf8() failed, status=%d.\n",
  46.                  (int)GetLastError()));
  47.              continue;
  48.          }
  49. diff --git a/daemon/acl.c b/daemon/acl.c
  50. index ecf6156..45dda26 100644
  51. --- a/daemon/acl.c
  52. +++ b/daemon/acl.c
  53. @@ -1,5 +1,6 @@
  54.  /* NFSv4.1 client for Windows
  55. - * Copyright (C) 2012 The Regents of the University of Michigan
  56. + * Copyright (C) 2012 The Regents of the University of Michigan
  57. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  58.   *
  59.   * Olga Kornievskaia <aglo@umich.edu>
  60.   * Casey Bodley <cbodley@umich.edu>
  61. @@ -987,7 +988,7 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  62.          goto out;
  63.      }
  64.  
  65. -    status = LookupAccountSidA(NULL, sid, who_buf, &who_size, domain_buf,
  66. +    status = lookupaccountsidutf8(NULL, sid, who_buf, &who_size, domain_buf,
  67.          &domain_size, &sid_type);
  68.      lasterr = GetLastError();
  69.  
  70. @@ -1074,14 +1075,15 @@ int map_sid2nfs4ace_who(PSID sid, PSID owner_sid, PSID group_sid,
  71.                      goto err_none_mapped;
  72.                  }
  73.  
  74. -                eprintf("map_sid2nfs4ace_who: LookupAccountSidA() "
  75. +                eprintf("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  76.                      "returned ERROR_NONE_MAPPED+no "
  77.                      "Unix_@(User|Group)+ mapping for sidstr='%s'\n",
  78.                      sidstr);
  79.  err_none_mapped:
  80.                  status = ERROR_NONE_MAPPED;
  81.  #else
  82. -                DPRINTF(ACLLVL2, ("map_sid2nfs4ace_who: LookupAccountSidA() "
  83. +                DPRINTF(ACLLVL2,
  84. +                    ("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  85.                      "returned ERROR_NONE_MAPPED for sidstr='%s'\n",
  86.                      sidstr));
  87.                  status = lasterr;
  88. @@ -1091,7 +1093,7 @@ err_none_mapped:
  89.              /* Catch other cases */
  90.              case ERROR_NO_SUCH_USER:
  91.              case ERROR_NO_SUCH_GROUP:
  92. -                eprintf("map_sid2nfs4ace_who: LookupAccountSidA() "
  93. +                eprintf("map_sid2nfs4ace_who: lookupaccountsidutf8() "
  94.                      "returned ERROR_NO_SUCH_@(USER|GROUP) for "
  95.                      "sidstr='%s'\n",
  96.                      sidstr);
  97. @@ -1099,7 +1101,7 @@ err_none_mapped:
  98.                  goto out;
  99.              default:
  100.                  eprintf("map_sid2nfs4ace_who: Internal error, "
  101. -                    "LookupAccountSidA() returned unexpected ERROR_%d "
  102. +                    "lookupaccountsidutf8() returned unexpected ERROR_%d "
  103.                      "for sidstr='%s'\n",
  104.                      status, sidstr);
  105.                  status = ERROR_INTERNAL_ERROR;
  106. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  107. index 93d66b2..0fd2255 100644
  108. --- a/daemon/nfs41_daemon.c
  109. +++ b/daemon/nfs41_daemon.c
  110. @@ -792,6 +792,10 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  111.      DPRINTF(0, ("SID cache disabled\n"));
  112.  #endif /* NFS41_DRIVER_SID_CACHE */
  113.  
  114. +#if 1
  115. +    DPRINTF(0, ("wmain: GetACP()=%d\n", (int)GetACP()));
  116. +#endif
  117. +
  118.  #ifdef _DEBUG
  119.      logprintf("NFS client daemon (DEBUG build) %s starting...\n",
  120.          GIT_COMMIT_ID);
  121. diff --git a/daemon/sid.c b/daemon/sid.c
  122. index 0ea20ee..0ce84f8 100644
  123. --- a/daemon/sid.c
  124. +++ b/daemon/sid.c
  125. @@ -1,5 +1,6 @@
  126.  /* NFSv4.1 client for Windows
  127. - * Copyright (C) 2012 The Regents of the University of Michigan
  128. + * Copyright (C) 2012 The Regents of the University of Michigan
  129. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  130.   *
  131.   * Olga Kornievskaia <aglo@umich.edu>
  132.   * Casey Bodley <cbodley@umich.edu>
  133. @@ -327,7 +328,8 @@ void sidcache_addwithalias(sidcache *cache, const char *win32name, const char *a
  134.      /* Replace the cache entry */
  135.      sidcache_entry *e = &cache->entries[freeEntryIndex];
  136.      DWORD sid_len = GetLengthSid(value);
  137. -    EASSERT(sid_len <= SECURITY_MAX_SID_SIZE);
  138. +    EASSERT_MSG((sid_len <= SECURITY_MAX_SID_SIZE),
  139. +        ("sid_len=%ld\n", (long)sid_len));
  140.      e->sid = (PSID)e->sid_buffer;
  141.      if (!CopySid(sid_len, e->sid, value)) {
  142.          e->sid = NULL;
  143. @@ -506,15 +508,15 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  144.      *sid_len = SECURITY_MAX_SID_SIZE;
  145.      domain_len = sizeof(domain_buff);
  146.  
  147. -    status = LookupAccountNameA(NULL, nfsname, *sid, sid_len,
  148. +    status = lookupaccountnameutf8(NULL, nfsname, *sid, sid_len,
  149.          domain_buff, &domain_len, &sid_type);
  150.  
  151.      if (status) {
  152. -        /* |LookupAccountNameA()| success */
  153. +        /* |lookupaccountnameutf8()| success */
  154.  
  155.          DPRINTF(ACLLVL,
  156.              ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  157. -            "LookupAccountNameA() returned status=%d "
  158. +            "lookupaccountnameutf8() returned status=%d "
  159.              "GetLastError=%d *sid_len=%d domain_buff='%s' domain_len=%d\n",
  160.              query, nfsname, status, GetLastError(), *sid_len, domain_buff,
  161.              domain_len));
  162. @@ -524,10 +526,10 @@ int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *si
  163.          goto out_cache;
  164.      }
  165.  
  166. -    /* |LookupAccountNameA()| failed... */
  167. +    /* |lookupaccountnameutf8()| failed... */
  168.      DPRINTF(ACLLVL,
  169.          ("map_nfs4servername_2_sid(query=0x%x,nfsname='%s'): "
  170. -        "LookupAccountNameA() returned status=%d "
  171. +        "lookupaccountnameutf8() returned status=%d "
  172.          "GetLastError=%d\n",
  173.          query, nfsname, status, GetLastError()));
  174.  
  175. @@ -648,7 +650,7 @@ out_cache:
  176.              /*
  177.               * Treat |SidTypeAlias| as (local) group
  178.               *
  179. -             * It seems that |LookupAccountNameA()| will always return
  180. +             * It seems that |lookupaccountnameutf8()| will always return
  181.               * |SidTypeAlias| for local groups created with
  182.               * $ net localgroup cygwingrp1 /add #
  183.               *
  184. @@ -743,3 +745,341 @@ out_free_sid:
  185.      *sid = NULL;
  186.      goto out;
  187.  }
  188. +
  189. +
  190. +/* Maximum number of bytes required to store one |wchar_t| as UTF-8 */
  191. +#define MAX_UTF8_BYTES_PER_WCHAR_T (5)
  192. +
  193. +/*
  194. + * |lookupaccountnameutf8()| - UTF-8 version of |LookupAccountNameA()|
  195. + *
  196. + * We need this because Windows user+group names can contain Unicode
  197. + * characters, and |*A()| functions depend on the current code page,
  198. + * which might not cover all code points needed
  199. + */
  200. +BOOL lookupaccountnameutf8(
  201. +    const char *restrict pSystemNameUTF8,
  202. +    const char *restrict pAccountNameUTF8,
  203. +    PSID restrict pSid,
  204. +    LPDWORD restrict pSidSize,
  205. +    char *restrict pReferencedDomainNameUTF8,
  206. +    LPDWORD restrict pReferencedDomainNameUTF8size,
  207. +    PSID_NAME_USE restrict peUse)
  208. +{
  209. +#ifdef NO_UTF8_ACCOUNT_CONV
  210. +    return LookupAccountNameA(
  211. +        pSystemNameUTF8,
  212. +        pAccountNameUTF8,
  213. +        pSid,
  214. +        pSidSize,
  215. +        pReferencedDomainNameUTF8,
  216. +        pReferencedDomainNameUTF8size,
  217. +        peUse);
  218. +#else
  219. +    if ((pAccountNameUTF8 == NULL) ||
  220. +        (pReferencedDomainNameUTF8size == NULL) ||
  221. +        (pSidSize == NULL) || (peUse == NULL)) {
  222. +        SetLastError(ERROR_INVALID_PARAMETER);
  223. +        return FALSE;
  224. +    }
  225. +
  226. +    LPWSTR pSystemNameW;
  227. +
  228. +    if (pSystemNameUTF8) {
  229. +        DWORD systemNameWsize;
  230. +
  231. +        /*
  232. +         * Use |strlen()| here as optimisation, saving one around of
  233. +         * |MultiByteToWideChar()|
  234. +         */
  235. +        systemNameWsize = (DWORD)strlen(pSystemNameUTF8)+1;
  236. +        pSystemNameW = (LPWSTR)_alloca(systemNameWsize * sizeof(wchar_t));
  237. +
  238. +        if (MultiByteToWideChar(CP_UTF8,
  239. +            0,
  240. +            pSystemNameUTF8,
  241. +            -1,
  242. +            pSystemNameW,
  243. +            systemNameWsize) == 0) {
  244. +            if (GetLastError() == ERROR_SUCCESS) {
  245. +                SetLastError(ERROR_INVALID_DATA);
  246. +            }
  247. +            return FALSE;
  248. +        }
  249. +    }
  250. +    else {
  251. +        pSystemNameW = NULL;
  252. +    }
  253. +
  254. +    LPWSTR pAccountNameW;
  255. +    DWORD accountNameWsize;
  256. +
  257. +    /*
  258. +     * Use |strlen()| here as optimisation, saving one around of
  259. +     * |MultiByteToWideChar()|
  260. +     */
  261. +    accountNameWsize = (DWORD)strlen(pAccountNameUTF8)+1;
  262. +    pAccountNameW = (LPWSTR)_alloca(accountNameWsize * sizeof(wchar_t));
  263. +
  264. +    if (MultiByteToWideChar(CP_UTF8,
  265. +        0,
  266. +        pAccountNameUTF8,
  267. +        -1,
  268. +        pAccountNameW,
  269. +        accountNameWsize) == 0) {
  270. +        if (GetLastError() == ERROR_SUCCESS) {
  271. +            SetLastError(ERROR_INVALID_DATA);
  272. +        }
  273. +        return FALSE;
  274. +    }
  275. +
  276. +    DWORD referencedDomainNameWsize =
  277. +        (DWORD)*pReferencedDomainNameUTF8size / sizeof(wchar_t);
  278. +    LPWSTR pReferencedDomainNameW = NULL;
  279. +
  280. +    if ((pReferencedDomainNameUTF8 == NULL) ||
  281. +        (*pReferencedDomainNameUTF8size == 0)) {
  282. +        referencedDomainNameWsize = 256;
  283. +    }
  284. +
  285. +    pReferencedDomainNameW =
  286. +        (LPWSTR)_alloca(referencedDomainNameWsize * sizeof(wchar_t));
  287. +
  288. +    BOOL success = LookupAccountNameW(
  289. +        pSystemNameW,
  290. +        pAccountNameW,
  291. +        pSid,
  292. +        pSidSize,
  293. +        pReferencedDomainNameW,
  294. +        &referencedDomainNameWsize,
  295. +        peUse);
  296. +
  297. +    if (!success) {
  298. +        DWORD lastError = GetLastError();
  299. +
  300. +        if (lastError == ERROR_INSUFFICIENT_BUFFER) {
  301. +            int requiredDomainNameUTF8Size = WideCharToMultiByte(CP_UTF8,
  302. +                0,
  303. +                pReferencedDomainNameW,
  304. +                referencedDomainNameWsize+1,
  305. +                NULL,
  306. +                0,
  307. +                NULL,
  308. +                NULL);
  309. +            if (requiredDomainNameUTF8Size == 0) {
  310. +                if (GetLastError() == ERROR_SUCCESS) {
  311. +                    SetLastError(ERROR_INVALID_DATA);
  312. +                }
  313. +                return FALSE;
  314. +            }
  315. +
  316. +            *pReferencedDomainNameUTF8size =
  317. +                (size_t)requiredDomainNameUTF8Size+1;
  318. +        } else if (lastError == ERROR_NONE_MAPPED) {
  319. +            *pReferencedDomainNameUTF8size = 0;
  320. +            *pSidSize = 0;
  321. +            *peUse = SidTypeUnknown;
  322. +        } else {
  323. +            *pReferencedDomainNameUTF8size = 0;
  324. +            *pSidSize = 0;
  325. +            *peUse = SidTypeUnknown;
  326. +        }
  327. +
  328. +        return FALSE;
  329. +    }
  330. +
  331. +    int domainNameUTF8size = WideCharToMultiByte(CP_UTF8,
  332. +        0,
  333. +        pReferencedDomainNameW,
  334. +        referencedDomainNameWsize+1,
  335. +        NULL,
  336. +        0,
  337. +        NULL,
  338. +        NULL);
  339. +    if (domainNameUTF8size == 0) {
  340. +        if (GetLastError() == ERROR_SUCCESS) {
  341. +            SetLastError(ERROR_INVALID_DATA);
  342. +        }
  343. +        return FALSE;
  344. +    }
  345. +
  346. +    if (*pReferencedDomainNameUTF8size < (size_t)domainNameUTF8size) {
  347. +        *pReferencedDomainNameUTF8size = (size_t)domainNameUTF8size;
  348. +        SetLastError(ERROR_INSUFFICIENT_BUFFER);
  349. +        return FALSE;
  350. +    }
  351. +
  352. +    (void)WideCharToMultiByte(CP_UTF8,
  353. +        0,
  354. +        pReferencedDomainNameW,
  355. +        referencedDomainNameWsize+1,
  356. +        pReferencedDomainNameUTF8,
  357. +        domainNameUTF8size,
  358. +        NULL,
  359. +        NULL);
  360. +    *pReferencedDomainNameUTF8size = (size_t)domainNameUTF8size-1;
  361. +
  362. +    SetLastError(ERROR_SUCCESS);
  363. +    return TRUE;
  364. +#endif /* NO_UTF8_ACCOUNT_CONV */
  365. +}
  366. +
  367. +
  368. +/*
  369. + * |lookupaccountsidutf8()| - UTF-8 version of |LookupAccountSidA()|
  370. + *
  371. + * We need this because Windows user+group names can contain Unicode
  372. + * characters, and |*A()| functions depend on the current code page,
  373. + * which might not cover all code points needed
  374. + */
  375. +BOOL lookupaccountsidutf8(
  376. +    const char *restrict pSystemNameUTF8,
  377. +    PSID restrict Sid,
  378. +    char *restrict pNameUTF8,
  379. +    LPDWORD restrict pNameSize,
  380. +    char *restrict pReferencedDomainNameUTF8,
  381. +    LPDWORD restrict pReferencedDomainNameUTF8Size,
  382. +    PSID_NAME_USE restrict peUse)
  383. +{
  384. +#ifdef NO_UTF8_ACCOUNT_CONV
  385. +    return LookupAccountSidA(pSystemNameUTF8,
  386. +        Sid, pNameUTF8, pNameSize,
  387. +        pReferencedDomainNameUTF8, pReferencedDomainNameUTF8Size,
  388. +        peUse);
  389. +#else
  390. +    if ((Sid == NULL) ||
  391. +        (pNameUTF8 == NULL) ||
  392. +        (pNameSize == NULL) ||
  393. +        (pReferencedDomainNameUTF8 == NULL) ||
  394. +        (pReferencedDomainNameUTF8Size == NULL) ||
  395. +        (peUse == NULL)) {
  396. +        SetLastError(ERROR_INVALID_PARAMETER);
  397. +        return FALSE;
  398. +    }
  399. +
  400. +    wchar_t *systemNameW;
  401. +    wchar_t *nameW;
  402. +    wchar_t *referencedDomainNameW;
  403. +
  404. +    if (pSystemNameUTF8) {
  405. +        DWORD wide_len = (DWORD)strlen(pSystemNameUTF8)+1;
  406. +
  407. +        systemNameW = (wchar_t *)_alloca(wide_len * sizeof(wchar_t));
  408. +
  409. +        if (MultiByteToWideChar(CP_UTF8,
  410. +            0,
  411. +            pSystemNameUTF8,
  412. +            -1,
  413. +            systemNameW,
  414. +            wide_len) == 0) {
  415. +            if (GetLastError() == ERROR_SUCCESS) {
  416. +                SetLastError(ERROR_INVALID_DATA);
  417. +            }
  418. +            return FALSE;
  419. +        }
  420. +    }
  421. +    else {
  422. +        systemNameW = NULL;
  423. +    }
  424. +
  425. +    nameW = (wchar_t *)_alloca(((size_t)*pNameSize+1) * sizeof(wchar_t));
  426. +    referencedDomainNameW =
  427. +        (wchar_t *)_alloca(((size_t)*pReferencedDomainNameUTF8Size+1) *
  428. +            sizeof(wchar_t));
  429. +
  430. +    DWORD nameSizeW = *pNameSize;
  431. +    DWORD referencedDomainNameSizeW =
  432. +        *pReferencedDomainNameUTF8Size;
  433. +
  434. +    if (!LookupAccountSidW(
  435. +        systemNameW,
  436. +        Sid,
  437. +        nameW,
  438. +        &nameSizeW,
  439. +        referencedDomainNameW,
  440. +        &referencedDomainNameSizeW,
  441. +        peUse))
  442. +    {
  443. +        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
  444. +            /* Assume that each |wchar_t| needs a maximum of 5 bytes */
  445. +            *pNameSize = nameSizeW * MAX_UTF8_BYTES_PER_WCHAR_T;
  446. +            *pReferencedDomainNameUTF8Size =
  447. +                referencedDomainNameSizeW * MAX_UTF8_BYTES_PER_WCHAR_T;
  448. +        }
  449. +        return FALSE;
  450. +    }
  451. +
  452. +    int required_name_utf8_bytes = WideCharToMultiByte(CP_UTF8,
  453. +        0,
  454. +        nameW,
  455. +        nameSizeW+1,
  456. +        NULL,
  457. +        0,
  458. +        NULL,
  459. +        NULL);
  460. +    if (required_name_utf8_bytes == 0) {
  461. +        if (GetLastError() == ERROR_SUCCESS) {
  462. +            SetLastError(ERROR_INVALID_DATA);
  463. +        }
  464. +        return FALSE;
  465. +    }
  466. +
  467. +    int required_domain_utf8_bytes = WideCharToMultiByte(CP_UTF8,
  468. +        0,
  469. +        referencedDomainNameW,
  470. +        referencedDomainNameSizeW+1,
  471. +        NULL,
  472. +        0,
  473. +        NULL,
  474. +        NULL);
  475. +    if (required_domain_utf8_bytes == 0) {
  476. +        if (GetLastError() == ERROR_SUCCESS) {
  477. +            SetLastError(ERROR_INVALID_DATA);
  478. +        }
  479. +        return FALSE;
  480. +    }
  481. +
  482. +    if ((*pNameSize < (DWORD)required_name_utf8_bytes) ||
  483. +        (*pReferencedDomainNameUTF8Size < (DWORD)required_domain_utf8_bytes)) {
  484. +        *pNameSize = (DWORD)required_name_utf8_bytes;
  485. +        *pReferencedDomainNameUTF8Size = (DWORD)required_domain_utf8_bytes;
  486. +        SetLastError(ERROR_INSUFFICIENT_BUFFER);
  487. +        return FALSE;
  488. +    }
  489. +
  490. +    int bytes_written_name = WideCharToMultiByte(CP_UTF8,
  491. +        0,
  492. +        nameW,
  493. +        nameSizeW+1,
  494. +        pNameUTF8,
  495. +        *pNameSize,
  496. +        NULL,
  497. +        NULL);
  498. +    if (bytes_written_name == 0) {
  499. +        if (GetLastError() == ERROR_SUCCESS) {
  500. +            SetLastError(ERROR_INVALID_DATA);
  501. +        }
  502. +        return FALSE;
  503. +    }
  504. +
  505. +    int bytes_written_domain = WideCharToMultiByte(CP_UTF8,
  506. +        0,
  507. +        referencedDomainNameW,
  508. +        referencedDomainNameSizeW+1,
  509. +        pReferencedDomainNameUTF8,
  510. +        *pReferencedDomainNameUTF8Size,
  511. +        NULL,
  512. +        NULL);
  513. +    if (bytes_written_domain == 0) {
  514. +        if (GetLastError() == ERROR_SUCCESS) {
  515. +            SetLastError(ERROR_INVALID_DATA);
  516. +        }
  517. +        return FALSE;
  518. +    }
  519. +
  520. +    *pReferencedDomainNameUTF8Size = (DWORD)bytes_written_domain-1;
  521. +    *pNameSize = (DWORD)bytes_written_name-1;
  522. +
  523. +    return TRUE;
  524. +#endif /* NO_UTF8_ACCOUNT_CONV */
  525. +}
  526. diff --git a/daemon/sid.h b/daemon/sid.h
  527. index 70fc910..c19b3d9 100644
  528. --- a/daemon/sid.h
  529. +++ b/daemon/sid.h
  530. @@ -1,6 +1,7 @@
  531.  
  532.  /* NFSv4.1 client for Windows
  533. - * Copyright (C) 2012 The Regents of the University of Michigan
  534. + * Copyright (C) 2012 The Regents of the University of Michigan
  535. + * Copyright (C) 2023-2025 Roland Mainz <roland.mainz@nrubsig.org>
  536.   *
  537.   * Olga Kornievskaia <aglo@umich.edu>
  538.   * Casey Bodley <cbodley@umich.edu>
  539. @@ -64,4 +65,23 @@ bool sidcache_getcached_bysid(sidcache *cache, PSID sid, char *out_win32name);
  540.  
  541.  int map_nfs4servername_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *sid_len, PSID *sid, LPCSTR name);
  542.  
  543. +/* UTF-8 version of |LookupAccountNameA()| */
  544. +BOOL lookupaccountnameutf8(
  545. +    const char *restrict pSystemNameUTF8,
  546. +    const char *restrict pAccountNameUTF8,
  547. +    PSID restrict pSid,
  548. +    LPDWORD restrict pSidSize,
  549. +    char *restrict pReferencedDomainNameUTF8,
  550. +    LPDWORD restrict pReferencedDomainNameUTF8size,
  551. +    PSID_NAME_USE restrict peUse);
  552. +/* UTF-8 version of |LookupAccountSidA()| */
  553. +BOOL lookupaccountsidutf8(
  554. +    const char *restrict pSystemNameUTF8,
  555. +    PSID restrict Sid,
  556. +    char *restrict pNameUTF8,
  557. +    LPDWORD restrict pNameSize,
  558. +    char *restrict pReferencedDomainNameUTF8,
  559. +    LPDWORD restrict pReferencedDomainNameSize,
  560. +    PSID_NAME_USE restrict peUse);
  561. +
  562.  #endif /* !__NFS41_DAEMON_SID_H */
  563. diff --git a/daemon/util.c b/daemon/util.c
  564. index aa3883f..e3988e4 100644
  565. --- a/daemon/util.c
  566. +++ b/daemon/util.c
  567. @@ -424,7 +424,7 @@ out:
  568.  subcmd_popen_context *subcmd_popen(const char *command)
  569.  {
  570.      subcmd_popen_context *pinfo;
  571. -    STARTUPINFOA si;
  572. +    STARTUPINFOW si;
  573.      SECURITY_ATTRIBUTES sa = { 0 };
  574.  
  575.      if (!command) {
  576. @@ -483,8 +483,24 @@ subcmd_popen_context *subcmd_popen(const char *command)
  577.      si.hStdError = GetStdHandle(STD_ERROR_HANDLE);
  578.      si.dwFlags |= STARTF_USESTDHANDLES;
  579.  
  580. -    if (!CreateProcessA(NULL,
  581. -        (LPSTR)command, NULL, NULL, TRUE, 0, NULL, NULL, &si,
  582. +    size_t commandWSize = strlen(command)+1;
  583. +    wchar_t *commandW = _alloca(commandWSize * sizeof(wchar_t));
  584. +    
  585. +    if (MultiByteToWideChar(CP_UTF8,
  586. +        0,
  587. +        command,
  588. +        -1,
  589. +        commandW,
  590. +        (int)commandWSize) == 0) {
  591. +        if (GetLastError() == ERROR_SUCCESS) {
  592. +            SetLastError(ERROR_INVALID_DATA);
  593. +        }
  594. +        DPRINTF(0, ("subcmd_popen: cannot convert cmdline to widechar\n"));
  595. +        goto fail;
  596. +    }
  597. +
  598. +    if (!CreateProcessW(NULL,
  599. +        commandW, NULL, NULL, TRUE, 0, NULL, NULL, &si,
  600.          &pinfo->pi)) {
  601.          DPRINTF(0, ("subcmd_popen: cannot create process\n"));
  602.          goto fail;

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