pastebin - collaborative debugging tool
rovema.kpaste.net RSS


daemon/idmap: Add support for using Cygwin as idmapping service
Posted by Anonymous on Sat 14th Oct 2023 14:03
raw | new post

  1. From 10045684053b8b9e130712c6bd1e177bcb85090e Mon Sep 17 00:00:00 2001
  2. From: Roland Mainz <roland.mainz@nrubsig.org>
  3. Date: Sat, 14 Oct 2023 14:32:39 +0200
  4. Subject: [PATCH 1/2] daemon/idmap: Add support for using Cygwin as idmapping
  5.  service
  6.  
  7. Adding support for using Cygwin as idmapping service via Cygwin
  8. /usr/bin/getent, including the option that numeric uid and gid values
  9. differ between NFS server and NFS client (this is actually
  10. a design feature of NFSv4).
  11.  
  12. The code is currently disabled (set
  13. |NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN| to |1| in
  14. sys/nfs41_build_features.h to enable it), until the feature is
  15. complete and fully tested.
  16.  
  17. ToDo:
  18. - Command line option to select { LDAP, Cygwin } as idmap service
  19. - Autodetection Cygwin idmap service via testing for
  20. "C:\cygwin64\bin\getent.exe
  21.  
  22. Signed-off-by: Cedric Blancher <cedric.blancher@gmail.com>
  23. ---
  24. daemon/acl.c               | 650 ++++++++++++++++++-------------------
  25.  daemon/ea.c                |   4 +-
  26.  daemon/getattr.c           |   2 +-
  27.  daemon/idmap.c             | 395 +++++++++++++++++++++-
  28.  daemon/lock.c              |   4 +-
  29.  daemon/mount.c             |   4 +-
  30.  daemon/nfs41_const.h       |   3 +
  31.  daemon/nfs41_daemon.c      |  61 ++--
  32.  daemon/nfs41_daemon.h      |  39 +++
  33.  daemon/open.c              | 324 +++++++++---------
  34.  daemon/readdir.c           |  16 +-
  35.  daemon/readwrite.c         |   6 +-
  36.  daemon/setattr.c           |  24 +-
  37.  daemon/symlink.c           |   2 +-
  38.  daemon/upcall.c            |   3 +-
  39.  daemon/upcall.h            |  37 ++-
  40.  daemon/volume.c            |   2 +-
  41.  libtirpc/src/auth_unix.c   |   7 +-
  42.  sys/nfs41_build_features.h |   7 +-
  43.  19 files changed, 1000 insertions(+), 590 deletions(-)
  44.  create mode 100644 daemon/nfs41_daemon.h
  45.  
  46. diff --git a/daemon/acl.c b/daemon/acl.c
  47. index e65548e..401fcd6 100644
  48. --- a/daemon/acl.c
  49. +++ b/daemon/acl.c
  50. @@ -20,22 +20,23 @@
  51.   */
  52.  
  53.  #include <Windows.h>
  54. +#include <stdio.h>
  55.  #include <strsafe.h>
  56. -#include <sddl.h>
  57. -
  58. -#include "nfs41_ops.h"
  59. -#include "nfs41_build_features.h"
  60. -#include "delegation.h"
  61. -#include "daemon_debug.h"
  62. -#include "util.h"
  63. +#include <sddl.h>
  64. +
  65. +#include "nfs41_ops.h"
  66. +#include "nfs41_build_features.h"
  67. +#include "nfs41_daemon.h"
  68. +#include "delegation.h"
  69. +#include "daemon_debug.h"
  70. +#include "util.h"
  71.  #include "upcall.h"
  72.  #include "nfs41_xdr.h"
  73. +#include "idmap.h"
  74.  
  75.  //#define DEBUG_ACLS
  76.  #define ACLLVL 2 /* dprintf level for acl logging */
  77.  
  78. -extern char localdomain_name[NFS41_HOSTNAME_LEN];
  79. -
  80.  static int parse_getacl(unsigned char *buffer, uint32_t length,
  81.                          nfs41_upcall *upcall)
  82.  {
  83. @@ -58,32 +59,32 @@ static int create_unknownsid(WELL_KNOWN_SID_TYPE type, PSID *sid,
  84.      *sid = NULL;
  85.  
  86.      status = CreateWellKnownSid(type, NULL, *sid, sid_len);
  87. -    dprintf(ACLLVL, "create_unknownsid: CreateWellKnownSid type %d returned %d "
  88. -            "GetLastError %d sid len %d needed\n", type, status,
  89. -            GetLastError(), *sid_len);
  90. -    if (status) {
  91. -        status = ERROR_INTERNAL_ERROR;
  92. -        goto err;
  93. -    }
  94. -    status = GetLastError();
  95. -    if (status != ERROR_INSUFFICIENT_BUFFER)
  96. -        goto err;
  97. -
  98. -    *sid = malloc(*sid_len);
  99. -    if (*sid == NULL) {
  100. -        status = ERROR_INSUFFICIENT_BUFFER;
  101. -        goto err;
  102. -    }
  103. -    status = CreateWellKnownSid(type, NULL, *sid, sid_len);
  104. -    if (status)
  105. -        return ERROR_SUCCESS;
  106. -    free(*sid);
  107. -    *sid = NULL;
  108. -    status = GetLastError();
  109. -err:
  110. -    eprintf("create_unknownsid: CreateWellKnownSid failed with %d\n", status);
  111. -    return status;
  112. -}
  113. +    dprintf(ACLLVL, "create_unknownsid: CreateWellKnownSid type %d returned %d "
  114. +            "GetLastError %d sid len %d needed\n", type, status,
  115. +            GetLastError(), *sid_len);
  116. +    if (status) {
  117. +        status = ERROR_INTERNAL_ERROR;
  118. +        goto err;
  119. +    }
  120. +    status = GetLastError();
  121. +    if (status != ERROR_INSUFFICIENT_BUFFER)
  122. +        goto err;
  123. +
  124. +    *sid = malloc(*sid_len);
  125. +    if (*sid == NULL) {
  126. +        status = ERROR_INSUFFICIENT_BUFFER;
  127. +        goto err;
  128. +    }
  129. +    status = CreateWellKnownSid(type, NULL, *sid, sid_len);
  130. +    if (status)
  131. +        return ERROR_SUCCESS;
  132. +    free(*sid);
  133. +    *sid = NULL;
  134. +    status = GetLastError();
  135. +err:
  136. +    eprintf("create_unknownsid: CreateWellKnownSid failed with %d\n", status);
  137. +    return status;
  138. +}
  139.  
  140.  static void convert_nfs4name_2_user_domain(LPSTR nfs4name,
  141.                                             LPSTR *domain)
  142. @@ -92,145 +93,146 @@ static void convert_nfs4name_2_user_domain(LPSTR nfs4name,
  143.      for(; p[0] != '\0'; p++) {
  144.          if (p[0] == '@') {
  145.              p[0] = '\0';
  146. +
  147.              *domain = &p[1];
  148.              break;
  149.          }
  150. -    }
  151. -}
  152. -
  153. -#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  154. -/*
  155. - * Allocate a SID from SECURITY_SAMBA_UNIX_AUTHORITY, which encodes an
  156. - * UNIX/POSIX uid directly into a SID.
  157. - *
  158. - * Examples:
  159. - * UID 1616 gets mapped to "Unix_User+1616", encoding the UID into the
  160. - * SID as "S-1-22-1-1616":
  161. - * $ getent passwd Unix_User+1616
  162. - * Unix_User+1616:*:4278191696:4278191696:U-Unix_User616,S-1-22-1-1616:/:/sbin/nologin
  163. - *
  164. - * GID 1984 gets mapped to "Unix_Group+1984", encoding the GID into the
  165. - * SID as "S-1-22-2-1984":
  166. - * $ getent group Unix_Group+1984
  167. - * Unix_Group+1984:S-1-22-2-1984:4278192064:
  168. - *
  169. - */
  170. -
  171. -#define SECURITY_SAMBA_UNIX_AUTHORITY { { 0,0,0,0,0,22 } }
  172. -SID_IDENTIFIER_AUTHORITY sid_id_auth = SECURITY_SAMBA_UNIX_AUTHORITY;
  173. -
  174. -static
  175. -BOOL allocate_unixuser_sid(unsigned long uid, PSID *pSid)
  176. -{
  177. -    PSID sid = NULL;
  178. -    PSID malloced_sid = NULL;
  179. -    DWORD sid_len;
  180. -
  181. -    if (AllocateAndInitializeSid(&sid_id_auth, 2, 1, (DWORD)uid,
  182. -        0, 0, 0, 0, 0, 0, &sid)) {
  183. -        sid_len = GetLengthSid(sid);
  184. -
  185. -        malloced_sid = malloc(sid_len);
  186. -
  187. -        if (malloced_sid) {
  188. -            /*
  189. -             * |AllocateAndInitializeSid()| has an own memory
  190. -             * allocator, but we need the sid in memory from
  191. -             * |malloc()|
  192. -             */
  193. -            if (CopySid(sid_len, malloced_sid, sid)) {
  194. -                FreeSid(sid);
  195. -                *pSid = malloced_sid;
  196. -                dprintf(ACLLVL, "allocate_unixuser_sid(): Allocated "
  197. -                    "Unix_User+%lu: success, len=%ld\n",
  198. -                    uid, (long)sid_len);
  199. -                return TRUE;
  200. -            }
  201. -        }
  202. -    }
  203. -
  204. -    FreeSid(sid);
  205. -    free(malloced_sid);
  206. -    dprintf(ACLLVL, "allocate_unixuser_sid(): Failed to allocate "
  207. -        "SID for Unix_User+%lu: error code %d\n",
  208. -        uid, GetLastError());
  209. -    return FALSE;
  210. -}
  211. -
  212. -static
  213. -BOOL allocate_unixgroup_sid(unsigned long gid, PSID *pSid)
  214. -{
  215. -    PSID sid = NULL;
  216. -    PSID malloced_sid = NULL;
  217. -    DWORD sid_len;
  218. -
  219. -    if (AllocateAndInitializeSid(&sid_id_auth, 2, 2, (DWORD)gid,
  220. -        0, 0, 0, 0, 0, 0, &sid)) {
  221. -        sid_len = GetLengthSid(sid);
  222. -
  223. -        malloced_sid = malloc(sid_len);
  224. -
  225. -        if (malloced_sid) {
  226. -            /*
  227. -             * |AllocateAndInitializeSid()| has an own memory
  228. -             * allocator, but we need the sid in memory from
  229. -             * |malloc()|
  230. -             */
  231. -            if (CopySid(sid_len, malloced_sid, sid)) {
  232. -                FreeSid(sid);
  233. -                *pSid = malloced_sid;
  234. -                dprintf(ACLLVL, "allocate_unixgroup_sid(): Allocated "
  235. -                    "Unix_Group+%lu: success, len=%ld\n",
  236. -                    gid, (long)sid_len);
  237. -                return TRUE;
  238. -            }
  239. -        }
  240. -    }
  241. -
  242. -    FreeSid(sid);
  243. -    free(malloced_sid);
  244. -    dprintf(ACLLVL, "allocate_unixgroup_sid(): Failed to allocate "
  245. -        "SID for Unix_Group+%lu: error code %d\n",
  246. -        gid, GetLastError());
  247. -    return FALSE;
  248. -}
  249. -#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  250. -
  251. -static int map_name_2_sid(int query, DWORD *sid_len, PSID *sid, LPCSTR name)
  252. -{
  253. -    int status = ERROR_INTERNAL_ERROR;
  254. -    SID_NAME_USE sid_type;
  255. -    LPSTR tmp_buf = NULL;
  256. -    DWORD tmp = 0;
  257. -#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  258. -    signed long user_uid = -1;
  259. -    signed long group_gid = -1;
  260. -#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  261. -
  262. -#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  263. -    if (query & OWNER_SECURITY_INFORMATION) {
  264. -        if (!strcmp(name, "rmainz")) {
  265. -            name = "roland_mainz";
  266. -            dprintf(ACLLVL, "map_name_2_sid: remap rmainz --> roland_mainz\n");
  267. -        }
  268. -        else if (!strcmp(name, "197608")) {
  269. -            name = "roland_mainz";
  270. -            dprintf(ACLLVL, "map_name_2_sid: remap 197608 --> roland_mainz\n");
  271. -        }
  272. -        else if (!strcmp(name, "1616")) {
  273. -            name = "roland_mainz";
  274. -            dprintf(ACLLVL, "map_name_2_sid: remap 1616 --> roland_mainz\n");
  275. -        }
  276. -    }
  277. -#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  278. -
  279. -    status = LookupAccountName(NULL, name, NULL, sid_len, NULL, &tmp, &sid_type);
  280. -    dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): LookupAccountName returned %d "
  281. -            "GetLastError %d name len %d domain len %d\n",
  282. -            query, name, status, GetLastError(), *sid_len, tmp);
  283. -    if (status)
  284. -        return ERROR_INTERNAL_ERROR;
  285. -
  286. +    }
  287. +}
  288. +
  289. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  290. +/*
  291. + * Allocate a SID from SECURITY_SAMBA_UNIX_AUTHORITY, which encodes an
  292. + * UNIX/POSIX uid directly into a SID.
  293. + *
  294. + * Examples:
  295. + * UID 1616 gets mapped to "Unix_User+1616", encoding the UID into the
  296. + * SID as "S-1-22-1-1616":
  297. + * $ getent passwd Unix_User+1616
  298. + * Unix_User+1616:*:4278191696:4278191696:U-Unix_User616,S-1-22-1-1616:/:/sbin/nologin
  299. + *
  300. + * GID 1984 gets mapped to "Unix_Group+1984", encoding the GID into the
  301. + * SID as "S-1-22-2-1984":
  302. + * $ getent group Unix_Group+1984
  303. + * Unix_Group+1984:S-1-22-2-1984:4278192064:
  304. + *
  305. + */
  306. +
  307. +#define SECURITY_SAMBA_UNIX_AUTHORITY { { 0,0,0,0,0,22 } }
  308. +SID_IDENTIFIER_AUTHORITY sid_id_auth = SECURITY_SAMBA_UNIX_AUTHORITY;
  309. +
  310. +static
  311. +BOOL allocate_unixuser_sid(unsigned long uid, PSID *pSid)
  312. +{
  313. +    PSID sid = NULL;
  314. +    PSID malloced_sid = NULL;
  315. +    DWORD sid_len;
  316. +
  317. +    if (AllocateAndInitializeSid(&sid_id_auth, 2, 1, (DWORD)uid,
  318. +        0, 0, 0, 0, 0, 0, &sid)) {
  319. +        sid_len = GetLengthSid(sid);
  320. +
  321. +        malloced_sid = malloc(sid_len);
  322. +
  323. +        if (malloced_sid) {
  324. +            /*
  325. +             * |AllocateAndInitializeSid()| has an own memory
  326. +             * allocator, but we need the sid in memory from
  327. +             * |malloc()|
  328. +             */
  329. +            if (CopySid(sid_len, malloced_sid, sid)) {
  330. +                FreeSid(sid);
  331. +                *pSid = malloced_sid;
  332. +                dprintf(ACLLVL, "allocate_unixuser_sid(): Allocated "
  333. +                    "Unix_User+%lu: success, len=%ld\n",
  334. +                    uid, (long)sid_len);
  335. +                return TRUE;
  336. +            }
  337. +        }
  338. +    }
  339. +
  340. +    FreeSid(sid);
  341. +    free(malloced_sid);
  342. +    dprintf(ACLLVL, "allocate_unixuser_sid(): Failed to allocate "
  343. +        "SID for Unix_User+%lu: error code %d\n",
  344. +        uid, GetLastError());
  345. +    return FALSE;
  346. +}
  347. +
  348. +static
  349. +BOOL allocate_unixgroup_sid(unsigned long gid, PSID *pSid)
  350. +{
  351. +    PSID sid = NULL;
  352. +    PSID malloced_sid = NULL;
  353. +    DWORD sid_len;
  354. +
  355. +    if (AllocateAndInitializeSid(&sid_id_auth, 2, 2, (DWORD)gid,
  356. +        0, 0, 0, 0, 0, 0, &sid)) {
  357. +        sid_len = GetLengthSid(sid);
  358. +
  359. +        malloced_sid = malloc(sid_len);
  360. +
  361. +        if (malloced_sid) {
  362. +            /*
  363. +             * |AllocateAndInitializeSid()| has an own memory
  364. +             * allocator, but we need the sid in memory from
  365. +             * |malloc()|
  366. +             */
  367. +            if (CopySid(sid_len, malloced_sid, sid)) {
  368. +                FreeSid(sid);
  369. +                *pSid = malloced_sid;
  370. +                dprintf(ACLLVL, "allocate_unixgroup_sid(): Allocated "
  371. +                    "Unix_Group+%lu: success, len=%ld\n",
  372. +                    gid, (long)sid_len);
  373. +                return TRUE;
  374. +            }
  375. +        }
  376. +    }
  377. +
  378. +    FreeSid(sid);
  379. +    free(malloced_sid);
  380. +    dprintf(ACLLVL, "allocate_unixgroup_sid(): Failed to allocate "
  381. +        "SID for Unix_Group+%lu: error code %d\n",
  382. +        gid, GetLastError());
  383. +    return FALSE;
  384. +}
  385. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  386. +
  387. +static int map_name_2_sid(nfs41_daemon_globals *nfs41dg, int query, DWORD *sid_len, PSID *sid, LPCSTR name)
  388. +{
  389. +    int status = ERROR_INTERNAL_ERROR;
  390. +    SID_NAME_USE sid_type;
  391. +    LPSTR tmp_buf = NULL;
  392. +    DWORD tmp = 0;
  393. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  394. +    signed long user_uid = -1;
  395. +    signed long group_gid = -1;
  396. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  397. +
  398. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  399. +    if (query & OWNER_SECURITY_INFORMATION) {
  400. +        if (!strcmp(name, "rmainz")) {
  401. +            name = "roland_mainz";
  402. +            dprintf(ACLLVL, "map_name_2_sid: remap rmainz --> roland_mainz\n");
  403. +        }
  404. +        else if (!strcmp(name, "197608")) {
  405. +            name = "roland_mainz";
  406. +            dprintf(ACLLVL, "map_name_2_sid: remap 197608 --> roland_mainz\n");
  407. +        }
  408. +        else if (!strcmp(name, "1616")) {
  409. +            name = "roland_mainz";
  410. +            dprintf(ACLLVL, "map_name_2_sid: remap 1616 --> roland_mainz\n");
  411. +        }
  412. +    }
  413. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  414. +
  415. +    status = LookupAccountName(NULL, name, NULL, sid_len, NULL, &tmp, &sid_type);
  416. +    dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): LookupAccountName returned %d "
  417. +            "GetLastError %d name len %d domain len %d\n",
  418. +            query, name, status, GetLastError(), *sid_len, tmp);
  419. +    if (status)
  420. +        return ERROR_INTERNAL_ERROR;
  421. +
  422.      status = GetLastError();
  423.      switch(status) {
  424.      case ERROR_INSUFFICIENT_BUFFER:
  425. @@ -243,14 +245,14 @@ static int map_name_2_sid(int query, DWORD *sid_len, PSID *sid, LPCSTR name)
  426.          if (tmp_buf == NULL)
  427.              goto out_free_sid;
  428.          status = LookupAccountName(NULL, name, *sid, sid_len, tmp_buf,
  429. -                                    &tmp, &sid_type);
  430. -        free(tmp_buf);
  431. -        if (!status) {
  432. -            eprintf("map_name_2_sid(query=%x,name='%s'): LookupAccountName failed "
  433. -                    "with %d\n", query, name, GetLastError());
  434. -            goto out_free_sid;
  435. -        } else {
  436. -#ifdef DEBUG_ACLS
  437. +                                    &tmp, &sid_type);
  438. +        free(tmp_buf);
  439. +        if (!status) {
  440. +            eprintf("map_name_2_sid(query=%x,name='%s'): LookupAccountName failed "
  441. +                    "with %d\n", query, name, GetLastError());
  442. +            goto out_free_sid;
  443. +        } else {
  444. +#ifdef DEBUG_ACLS
  445.              LPSTR ssid = NULL;
  446.              if (IsValidSid(*sid))
  447.                  if (ConvertSidToStringSidA(*sid, &ssid))
  448. @@ -264,115 +266,101 @@ static int map_name_2_sid(int query, DWORD *sid_len, PSID *sid, LPCSTR name)
  449.              if (ssid) LocalFree(ssid);
  450.  #endif
  451.          }
  452. -        status = ERROR_SUCCESS;
  453. -        break;
  454. -    case ERROR_NONE_MAPPED:
  455. -#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  456. -        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  457. -            "trying Unix_User+/Unix_Group+ mapping\n",
  458. -            query, name);
  459. -
  460. -        if ((user_uid == -1) && (query & OWNER_SECURITY_INFORMATION)) {
  461. -            if (isdigit(name[0])) {
  462. -                user_uid = atol(name);
  463. -            }
  464. -            else if(!strcmp(name, "nobody")) {
  465. -                user_uid = 65534;
  466. -            }
  467. -            else if(!strcmp(name, "root")) {
  468. -                user_uid = 0;
  469. -            }
  470. -            else if(!strcmp(name, "rmainz")) {
  471. -                user_uid = 1616;
  472. -            }
  473. -            else if(!strcmp(name, "swulsch")) {
  474. -                user_uid = 1818;
  475. -            }
  476. -            else if(!strcmp(name, "mwenzel")) {
  477. -                user_uid = 8239;
  478. -            }
  479. -            else if(!strcmp(name, "test001")) {
  480. -                user_uid = 1000;
  481. -            }
  482. -        }
  483. -
  484. -        if ((group_gid == -1) && (query & GROUP_SECURITY_INFORMATION)) {
  485. -            if (isdigit(name[0])) {
  486. -                group_gid = atol(name);
  487. -            }
  488. -            else if(!strcmp(name, "nobody")) {
  489. -                group_gid = 65534;
  490. -            }
  491. -            else if(!strcmp(name, "root")) {
  492. -                group_gid = 0;
  493. -            }
  494. -            else if(!strcmp(name, "rmainz")) {
  495. -                group_gid = 1616;
  496. -            }
  497. -            else if(!strcmp(name, "swulsch")) {
  498. -                group_gid = 1818;
  499. -            }
  500. -            else if(!strcmp(name, "mwenzel")) {
  501. -                group_gid = 8239;
  502. -            }
  503. -            else if(!strcmp(name, "test001")) {
  504. -                group_gid = 1000;
  505. -            }
  506. -        }
  507. -
  508. -        if (user_uid != -1) {
  509. -            if (allocate_unixuser_sid(user_uid, sid)) {
  510. -                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  511. -                    "allocate_unixuser_sid(uid=%ld) success\n",
  512. -                    query, name, user_uid);
  513. -                return ERROR_SUCCESS;
  514. -            }
  515. -
  516. -            status = GetLastError();
  517. -            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  518. -                "allocate_unixuser_sid(uid=%ld) failed, error=%d\n",
  519. -                query, name, user_uid, status);
  520. -            return status;
  521. -        }
  522. -
  523. -        if (group_gid != -1) {
  524. -            if (allocate_unixgroup_sid(group_gid, sid)) {
  525. -                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  526. -                    "allocate_unixgroup_sid(gid=%ld) success\n",
  527. -                    query, name, group_gid);
  528. -                return ERROR_SUCCESS;
  529. -            }
  530. -
  531. -            status = GetLastError();
  532. -            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  533. -                "allocate_unixgroup_sid(gid=%ld) failed, error=%d\n",
  534. -                query, name, group_gid, status);
  535. -            return status;
  536. -        }
  537. -#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  538. -
  539. -        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  540. -            "using WinNullSid mapping\n",
  541. -            query, name);
  542. -
  543. -        status = create_unknownsid(WinNullSid, sid, sid_len);
  544. -        if (status)
  545. -            goto out_free_sid;
  546. -        break;
  547. -    default:
  548. -        dprintf(1, "map_name_2_sid(query=%x,name='%s'): error %d not handled\n",
  549. -            query, name, GetLastError());
  550. -        break;
  551. -    }
  552. -out:
  553. -    return status;
  554. -out_free_sid:
  555. -    status = GetLastError();
  556. -    free(*sid);
  557. -    *sid = NULL;
  558. -    goto out;
  559. -}
  560. -
  561. +        status = ERROR_SUCCESS;
  562. +        break;
  563. +    case ERROR_NONE_MAPPED:
  564. +#ifdef NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID
  565. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  566. +            "trying Unix_User+/Unix_Group+ mapping\n",
  567. +            query, name);
  568. +
  569. +        if ((user_uid == -1) && (query & OWNER_SECURITY_INFORMATION)) {
  570. +            uid_t map_uid = -1;
  571. +            gid_t gid_dummy = -1;
  572. +
  573. +            if (nfs41_idmap_name_to_ids(
  574. +                nfs41dg->idmapper,
  575. +                name,
  576. +                &map_uid,
  577. +                &gid_dummy) == 0) {
  578. +                user_uid = map_uid;
  579. +            }
  580. +            else {
  581. +                dprintf(1, "map_name_2_sid(query=%x,name='%s'): nfs41_idmap_name_to_ids() failed\n",
  582. +                    query, name);
  583. +                /* fixme: try harder here, "1234" should to to |atol()| */
  584. +            }
  585. +        }
  586. +
  587. +        if ((group_gid == -1) && (query & GROUP_SECURITY_INFORMATION)) {
  588. +            gid_t map_gid = -1;
  589. +
  590. +            if (nfs41_idmap_group_to_gid(
  591. +                nfs41dg->idmapper,
  592. +                name,
  593. +                &map_gid) == 0) {
  594. +                group_gid = map_gid;
  595. +            }
  596. +            else {
  597. +                dprintf(1, "map_name_2_sid(query=%x,name='%s'): nfs41_idmap_group_to_gid() failed\n",
  598. +                    query, name);
  599. +                /* fixme: try harder here, "1234" should to to |atol()| */
  600. +            }
  601. +        }
  602. +
  603. +        if (user_uid != -1) {
  604. +            if (allocate_unixuser_sid(user_uid, sid)) {
  605. +                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  606. +                    "allocate_unixuser_sid(uid=%ld) success\n",
  607. +                    query, name, user_uid);
  608. +                return ERROR_SUCCESS;
  609. +            }
  610. +
  611. +            status = GetLastError();
  612. +            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  613. +                "allocate_unixuser_sid(uid=%ld) failed, error=%d\n",
  614. +                query, name, user_uid, status);
  615. +            return status;
  616. +        }
  617. +
  618. +        if (group_gid != -1) {
  619. +            if (allocate_unixgroup_sid(group_gid, sid)) {
  620. +                dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  621. +                    "allocate_unixgroup_sid(gid=%ld) success\n",
  622. +                    query, name, group_gid);
  623. +                return ERROR_SUCCESS;
  624. +            }
  625. +
  626. +            status = GetLastError();
  627. +            dprintf(ACLLVL, "map_name_2_sid(query=%x,name='%s'): "
  628. +                "allocate_unixgroup_sid(gid=%ld) failed, error=%d\n",
  629. +                query, name, group_gid, status);
  630. +            return status;
  631. +        }
  632. +#endif /* NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID */
  633. +
  634. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): none mapped, "
  635. +            "using WinNullSid mapping\n",
  636. +            query, name);
  637. +
  638. +        status = create_unknownsid(WinNullSid, sid, sid_len);
  639. +        if (status)
  640. +            goto out_free_sid;
  641. +        break;
  642. +    default:
  643. +        dprintf(1, "map_name_2_sid(query=%x,name='%s'): error %d not handled\n",
  644. +            query, name, GetLastError());
  645. +        break;
  646. +    }
  647. +out:
  648. +    return status;
  649. +out_free_sid:
  650. +    status = GetLastError();
  651. +    free(*sid);
  652. +    *sid = NULL;
  653. +    goto out;
  654. +}
  655. +
  656.  static void free_sids(PSID *sids, int count)
  657.  {
  658.      int i;
  659. @@ -402,8 +390,8 @@ static int check_4_special_identifiers(char *who, PSID *sid, DWORD *sid_len,
  660.      return status;
  661.  }
  662.  
  663. -static int convert_nfs4acl_2_dacl(nfsacl41 *acl, int file_type,
  664. -                                  PACL *dacl_out, PSID **sids_out)
  665. +static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  666. +    nfsacl41 *acl, int file_type, PACL *dacl_out, PSID **sids_out)
  667.  {
  668.      int status = ERROR_NOT_SUPPORTED, size = 0;
  669.      uint32_t i;
  670. @@ -426,14 +414,15 @@ static int convert_nfs4acl_2_dacl(nfsacl41 *acl, int file_type,
  671.                                               &sid_len, &flag);
  672.          if (status) {
  673.              free_sids(sids, i);
  674. -            goto out;
  675. -        }
  676. -        if (!flag) {
  677. -            status = map_name_2_sid(0xFFFF /* fixme: Unknown whether user or group */,
  678. -                &sid_len, &sids[i], acl->aces[i].who);
  679. -            if (status) {
  680. -                free_sids(sids, i);
  681. -                goto out;
  682. +            goto out;
  683. +        }
  684. +        if (!flag) {
  685. +            status = map_name_2_sid(nfs41dg,
  686. +                0xFFFF /* fixme: Unknown whether user or group */,
  687. +                &sid_len, &sids[i], acl->aces[i].who);
  688. +            if (status) {
  689. +                free_sids(sids, i);
  690. +                goto out;
  691.              }
  692.          }
  693.          size += sid_len - sizeof(DWORD);
  694. @@ -493,9 +482,10 @@ out_free_sids:
  695.      goto out;
  696.  }
  697.  
  698. -static int handle_getacl(nfs41_upcall *upcall)
  699. +static int handle_getacl(void *daemon_context, nfs41_upcall *upcall)
  700.  {
  701.      int status = ERROR_NOT_SUPPORTED;
  702. +    nfs41_daemon_globals *nfs41dg = daemon_context;
  703.      getacl_upcall_args *args = &upcall->args.getacl;
  704.      nfs41_open_state *state = upcall->state_ref;
  705.      nfs41_file_info info = { 0 };
  706. @@ -541,30 +531,32 @@ static int handle_getacl(nfs41_upcall *upcall)
  707.      if (args->query & OWNER_SECURITY_INFORMATION) {
  708.          // parse user@domain. currently ignoring domain part XX
  709.          convert_nfs4name_2_user_domain(info.owner, &domain);
  710. -        dprintf(ACLLVL, "handle_getacl: OWNER_SECURITY_INFORMATION: for user=%s "
  711. -                "domain=%s\n", info.owner, domain?domain:"<null>");
  712. -        sid_len = 0;
  713. -        status = map_name_2_sid(OWNER_SECURITY_INFORMATION, &sid_len, &osid, info.owner);
  714. -        if (status)
  715. -            goto out;
  716. -        status = SetSecurityDescriptorOwner(&sec_desc, osid, TRUE);
  717. +        dprintf(ACLLVL, "handle_getacl: OWNER_SECURITY_INFORMATION: for user=%s "
  718. +                "domain=%s\n", info.owner, domain?domain:"<null>");
  719. +        sid_len = 0;
  720. +        status = map_name_2_sid(nfs41dg,
  721. +            OWNER_SECURITY_INFORMATION, &sid_len, &osid, info.owner);
  722. +        if (status)
  723. +            goto out;
  724. +        status = SetSecurityDescriptorOwner(&sec_desc, osid, TRUE);
  725.          if (!status) {
  726.              status = GetLastError();
  727.              eprintf("handle_getacl: SetSecurityDescriptorOwner failed with "
  728.                      "%d\n", status);
  729. -            goto out;
  730. -        }
  731. -    }
  732. -
  733. -    if (args->query & GROUP_SECURITY_INFORMATION) {
  734. -        convert_nfs4name_2_user_domain(info.owner_group, &domain);
  735. -        dprintf(ACLLVL, "handle_getacl: GROUP_SECURITY_INFORMATION: for %s "
  736. -                "domain=%s\n", info.owner_group, domain?domain:"<null>");
  737. -        sid_len = 0;
  738. -        status = map_name_2_sid(GROUP_SECURITY_INFORMATION, &sid_len, &gsid, info.owner_group);
  739. -        if (status)
  740. -            goto out;
  741. -        status = SetSecurityDescriptorGroup(&sec_desc, gsid, TRUE);
  742. +            goto out;
  743. +        }
  744. +    }
  745. +
  746. +    if (args->query & GROUP_SECURITY_INFORMATION) {
  747. +        convert_nfs4name_2_user_domain(info.owner_group, &domain);
  748. +        dprintf(ACLLVL, "handle_getacl: GROUP_SECURITY_INFORMATION: for %s "
  749. +                "domain=%s\n", info.owner_group, domain?domain:"<null>");
  750. +        sid_len = 0;
  751. +        status = map_name_2_sid(nfs41dg,
  752. +            GROUP_SECURITY_INFORMATION, &sid_len, &gsid, info.owner_group);
  753. +        if (status)
  754. +            goto out;
  755. +        status = SetSecurityDescriptorGroup(&sec_desc, gsid, TRUE);
  756.          if (!status) {
  757.              status = GetLastError();
  758.              eprintf("handle_getacl: SetSecurityDescriptorGroup failed with "
  759. @@ -574,7 +566,8 @@ static int handle_getacl(nfs41_upcall *upcall)
  760.      }
  761.      if (args->query & DACL_SECURITY_INFORMATION) {
  762.          dprintf(ACLLVL, "handle_getacl: DACL_SECURITY_INFORMATION\n");
  763. -        status = convert_nfs4acl_2_dacl(info.acl, state->type, &dacl, &sids);
  764. +        status = convert_nfs4acl_2_dacl(nfs41dg,
  765. +            info.acl, state->type, &dacl, &sids);
  766.          if (status)
  767.              goto out;
  768.          status = SetSecurityDescriptorDacl(&sec_desc, TRUE, dacl, TRUE);
  769. @@ -910,9 +903,10 @@ out_free:
  770.      goto out;
  771.  }
  772.  
  773. -static int handle_setacl(nfs41_upcall *upcall)
  774. +static int handle_setacl(void *daemon_context, nfs41_upcall *upcall)
  775.  {
  776.      int status = ERROR_NOT_SUPPORTED;
  777. +    nfs41_daemon_globals *nfs41dg = daemon_context;
  778.      setacl_upcall_args *args = &upcall->args.setacl;
  779.      nfs41_open_state *state = upcall->state_ref;
  780.      nfs41_file_info info = { 0 };
  781. @@ -931,7 +925,7 @@ static int handle_setacl(nfs41_upcall *upcall)
  782.              goto out;
  783.          }
  784.          info.owner = owner;
  785. -        status = map_nfs4ace_who(sid, NULL, NULL, info.owner, localdomain_name);
  786. +        status = map_nfs4ace_who(sid, NULL, NULL, info.owner, nfs41dg->localdomain_name);
  787.          if (status)
  788.              goto out;
  789.          else {
  790. @@ -950,7 +944,7 @@ static int handle_setacl(nfs41_upcall *upcall)
  791.          }
  792.          info.owner_group = group;
  793.          status = map_nfs4ace_who(sid, NULL, NULL, info.owner_group,
  794. -                                 localdomain_name);
  795. +                                 nfs41dg->localdomain_name);
  796.          if (status)
  797.              goto out;
  798.          else {
  799. @@ -982,7 +976,7 @@ static int handle_setacl(nfs41_upcall *upcall)
  800.              goto out;
  801.          }
  802.          status = map_dacl_2_nfs4acl(acl, sid, gsid, &nfs4_acl, state->type,
  803. -                                    localdomain_name);
  804. +                                    nfs41dg->localdomain_name);
  805.          if (status)
  806.              goto out;
  807.          else {
  808. @@ -1018,7 +1012,7 @@ static int marshall_setacl(unsigned char *buffer, uint32_t *length, nfs41_upcall
  809.  }
  810.  
  811.  const nfs41_upcall_op nfs41_op_setacl = {
  812. -    parse_setacl,
  813. -    handle_setacl,
  814. -    marshall_setacl
  815. -};
  816. +    parse_setacl,
  817. +    handle_setacl,
  818. +    marshall_setacl
  819. +};
  820. diff --git a/daemon/ea.c b/daemon/ea.c
  821. index 4909ad5..0cba5f8 100644
  822. --- a/daemon/ea.c
  823. +++ b/daemon/ea.c
  824. @@ -159,7 +159,7 @@ out:
  825.      return status;
  826.  }
  827.  
  828. -static int handle_setexattr(nfs41_upcall *upcall)
  829. +static int handle_setexattr(void *daemon_context, nfs41_upcall *upcall)
  830.  {
  831.      int status;
  832.      setexattr_upcall_args *args = &upcall->args.setexattr;
  833. @@ -527,7 +527,7 @@ static int overflow_error(
  834.      return NO_ERROR;
  835.  }
  836.  
  837. -static int handle_getexattr(nfs41_upcall *upcall)
  838. +static int handle_getexattr(void *daemon_context, nfs41_upcall *upcall)
  839.  {
  840.      getexattr_upcall_args *args = &upcall->args.getexattr;
  841.      PFILE_GET_EA_INFORMATION query = (PFILE_GET_EA_INFORMATION)args->ealist;
  842. diff --git a/daemon/getattr.c b/daemon/getattr.c
  843. index e9249a4..fa853a3 100644
  844. --- a/daemon/getattr.c
  845. +++ b/daemon/getattr.c
  846. @@ -73,7 +73,7 @@ out:
  847.      return status;
  848.  }
  849.  
  850. -static int handle_getattr(nfs41_upcall *upcall)
  851. +static int handle_getattr(void *daemon_context, nfs41_upcall *upcall)
  852.  {
  853.      int status;
  854.      getattr_upcall_args *args = &upcall->args.getattr;
  855. diff --git a/daemon/idmap.c b/daemon/idmap.c
  856. index 0dfa8ef..7662393 100644
  857. --- a/daemon/idmap.c
  858. +++ b/daemon/idmap.c
  859. @@ -26,13 +26,14 @@
  860.  #include <errno.h>
  861.  #include <time.h>
  862.  
  863. +#include "nfs41_build_features.h"
  864.  #include "idmap.h"
  865.  #include "nfs41_const.h"
  866.  #include "list.h"
  867.  #include "daemon_debug.h"
  868.  
  869. -
  870. -#define IDLVL 2 /* dprintf level for idmap logging */
  871. +#define IDLVL 2         /* dprintf level for idmap logging */
  872. +#define CYGWINIDLVL 2   /* dprintf level for idmap logging */
  873.  
  874.  #define FILTER_LEN 1024
  875.  #define NAME_LEN 32
  876. @@ -375,6 +376,246 @@ out:
  877.      return status;
  878.  }
  879.  
  880. +#ifdef NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN
  881. +int cygwin_getent_passwd(const char *name, char *res_loginname, uid_t *res_uid, gid_t *res_gid)
  882. +{
  883. +    char cmdbuff[1024];
  884. +    char passwd_line[1024];
  885. +    FILE* getent_pipe = NULL;
  886. +    int res = 1;
  887. +    unsigned long uid = -1;
  888. +    unsigned long gid = -1;
  889. +    struct _cypwent {
  890. +        char* loginname;
  891. +        char* passwd;
  892. +        char* uidstr;
  893. +        char* gidstr;
  894. +        char* comment;
  895. +        char* homedir;
  896. +        char* shell;
  897. +    } pwent = { 0 };
  898. +#define PWENT_ENTRY(var, prevvar) \
  899. +    (((var) = strchr((prevvar), ':'))?(*(var)++ = '\0',(var)):(NULL))
  900. +
  901. +    dprintf(CYGWINIDLVL, "--> cygwin_getent_passwd('%s')\n", name);
  902. +
  903. +#if 1
  904. +    /* hack for testing, map "roland_mainz" to rmainz account */
  905. +    if ((!strcmp(name, "rmainz")) || (!strcmp(name, "1616"))) {
  906. +        uid = 1616;
  907. +        gid = 1616;
  908. +        pwent.loginname = "rmainz";
  909. +        goto found;
  910. +    }
  911. +    if ((!strcmp(name, "nobody")) || (!strcmp(name, "no+body")) ||
  912. +        (!strcmp(name, "65534"))) {
  913. +        uid = 65534;
  914. +        gid = 65534;
  915. +        pwent.loginname = "no+body"; /* Cygwin-specific */
  916. +        goto found;
  917. +    }
  918. +    if ((!strcmp(name, "root")) || (!strcmp(name, "0"))) {
  919. +        uid = 0;
  920. +        gid = 0;
  921. +        pwent.loginname = "root";
  922. +        goto found;
  923. +    }
  924. +    if ((!strcmp(name, "iam")) || (!strcmp(name, "2010"))) {
  925. +        uid = 2010;
  926. +        gid = 2010;
  927. +        pwent.loginname = "iam";
  928. +        goto found;
  929. +    }
  930. +    if ((!strcmp(name, "swulsch")) || (!strcmp(name, "1818"))) {
  931. +        uid = 1818;
  932. +        gid = 1818;
  933. +        pwent.loginname = "swulsch";
  934. +        goto found;
  935. +    }
  936. +    if ((!strcmp(name, "mwenzel")) || (!strcmp(name, "8239"))) {
  937. +        uid = 8239;
  938. +        gid = 8239;
  939. +        pwent.loginname = "mwenzel";
  940. +        goto found;
  941. +    }
  942. +#endif
  943. +
  944. +    /* fixme: better quoting for |name| needed */
  945. +    (void)snprintf(cmdbuff, sizeof(cmdbuff), "%s passwd \"%s\"",
  946. +        "C:\\cygwin64\\bin\\getent.exe",
  947. +        name);
  948. +    if ((getent_pipe = _popen(cmdbuff, "rt")) == NULL) {
  949. +        dprintf(CYGWINIDLVL, "cygwin_getent_passwd: /usr/bin/getent failed, errno='%s'\n",
  950. +            strerror(errno));
  951. +        goto fail;
  952. +    }
  953. +
  954. +    if (fgets(passwd_line, sizeof(passwd_line), getent_pipe)) {
  955. +        pwent.loginname = passwd_line;
  956. +        if (!PWENT_ENTRY(pwent.passwd, pwent.loginname)) goto fail;
  957. +        if (!PWENT_ENTRY(pwent.uidstr, pwent.passwd)) goto fail;
  958. +        if (!PWENT_ENTRY(pwent.gidstr, pwent.uidstr)) goto fail;
  959. +        if (!PWENT_ENTRY(pwent.comment, pwent.gidstr)) goto fail;
  960. +        if (!PWENT_ENTRY(pwent.homedir, pwent.comment)) goto fail;
  961. +        PWENT_ENTRY(pwent.shell, pwent.homedir);
  962. +
  963. +        errno = 0;
  964. +        uid = strtol(pwent.uidstr, NULL, 10);
  965. +        if (errno != 0)
  966. +            goto fail;
  967. +
  968. +        errno = 0;
  969. +        gid = strtol(pwent.gidstr, NULL, 10);
  970. +        if (errno != 0)
  971. +            goto fail;
  972. +
  973. +#if 0
  974. +        dprintf(CYGWINIDLVL, "cygwin_getent_passwd(): name='%s'\n", name);
  975. +        dprintf(CYGWINIDLVL, "loginname\t='%s'\n", pwent.loginname);
  976. +        dprintf(CYGWINIDLVL, "passwd\t='%s'\n", pwent.passwd);
  977. +        dprintf(CYGWINIDLVL, "uidstr\t='%s' (%lu)\n", pwent.uidstr, (unsigned long)uid);
  978. +        dprintf(CYGWINIDLVL, "gidstr\t='%s' (%lu)\n", pwent.gidstr, (unsigned long)gid);
  979. +        dprintf(CYGWINIDLVL, "comment\t='%s'\n", pwent.comment);
  980. +        dprintf(CYGWINIDLVL, "homedir\t='%s'\n", pwent.homedir);
  981. +        dprintf(CYGWINIDLVL, "shell\t='%s'\n", pwent.shell);
  982. +#endif
  983. +
  984. +found:
  985. +        if (res_loginname)
  986. +            (void)strcpy_s(res_loginname, VAL_LEN, pwent.loginname);
  987. +        *res_uid = uid;
  988. +        *res_gid = gid;
  989. +        res = 0;
  990. +    }
  991. +
  992. +fail:
  993. +    if (getent_pipe)
  994. +        (void)_pclose(getent_pipe);
  995. +
  996. +    if (res == 0) {
  997. +        dprintf(CYGWINIDLVL, "<-- cygwin_getent_passwd('%s'): "
  998. +            "returning res_uid=%lu, res_gid=%lu, res_loginname='%s'\n",
  999. +            name,
  1000. +            (unsigned long)(*res_uid),
  1001. +            (unsigned long)(*res_gid),
  1002. +            res_loginname?res_loginname:"<NULL>");
  1003. +    }
  1004. +    else {
  1005. +        dprintf(CYGWINIDLVL, "<-- cygwin_getent_passwd('%s'): no match found\n",
  1006. +            name);
  1007. +    }
  1008. +
  1009. +    return res;
  1010. +}
  1011. +
  1012. +int cygwin_getent_group(const char* name, char* res_group_name, gid_t* res_gid)
  1013. +{
  1014. +    char cmdbuff[1024];
  1015. +    char group_line[1024];
  1016. +    FILE* getent_pipe = NULL;
  1017. +    int res = 1;
  1018. +    unsigned long gid = -1;
  1019. +    struct _cygrent
  1020. +    {
  1021. +        char* group_name;
  1022. +        char* passwd;
  1023. +        char* gidstr;
  1024. +        char* userlist;
  1025. +    } grent = { 0 };
  1026. +
  1027. +    dprintf(CYGWINIDLVL, "--> cygwin_getent_group('%s')\n", name);
  1028. +
  1029. +#if 1
  1030. +    if ((!strcmp(name, "rmainz")) || (!strcmp(name, "1616"))) {
  1031. +        gid = 1616;
  1032. +        grent.group_name = "rmainz";
  1033. +        goto found;
  1034. +    }
  1035. +    if ((!strcmp(name, "nogroup")) || (!strcmp(name, "no+body")) ||
  1036. +        (!strcmp(name, "65534"))) {
  1037. +        gid = 65534;
  1038. +        grent.group_name = "no+body"; /* Cygwin-specific */
  1039. +        goto found;
  1040. +    }
  1041. +    if ((!strcmp(name, "root")) || (!strcmp(name, "0"))) {
  1042. +        gid = 0;
  1043. +        grent.group_name = "root";
  1044. +        goto found;
  1045. +    }
  1046. +    if ((!strcmp(name, "iam")) || (!strcmp(name, "2010"))) {
  1047. +        gid = 2010;
  1048. +        grent.group_name = "iam";
  1049. +        goto found;
  1050. +    }
  1051. +    if ((!strcmp(name, "swulsch")) || (!strcmp(name, "1818"))) {
  1052. +        gid = 1818;
  1053. +        grent.group_name = "swulsch";
  1054. +        goto found;
  1055. +    }
  1056. +    if ((!strcmp(name, "mwenzel")) || (!strcmp(name, "8239"))) {
  1057. +        gid = 8239;
  1058. +        grent.group_name = "mwenzel";
  1059. +        goto found;
  1060. +    }
  1061. +#endif
  1062. +
  1063. +    /* fixme: better quoting for |name| needed */
  1064. +    (void)snprintf(cmdbuff, sizeof(cmdbuff), "%s group \"%s\"",
  1065. +        "C:\\cygwin64\\bin\\getent.exe",
  1066. +        name);
  1067. +    if ((getent_pipe = _popen(cmdbuff, "rt")) == NULL) {
  1068. +        dprintf(CYGWINIDLVL,
  1069. +            "cygwin_getent_group: /usr/bin/getent failed, errno='%s'\n",
  1070. +            strerror(errno));
  1071. +        goto fail;
  1072. +    }
  1073. +
  1074. +    if (fgets(group_line, sizeof(group_line), getent_pipe))
  1075. +    {
  1076. +        grent.group_name = group_line;
  1077. +        if (!PWENT_ENTRY(grent.passwd, grent.group_name)) goto fail;
  1078. +        if (!PWENT_ENTRY(grent.gidstr, grent.passwd)) goto fail;
  1079. +        PWENT_ENTRY(grent.userlist, grent.gidstr);
  1080. +
  1081. +        errno = 0;
  1082. +        gid = strtol(grent.gidstr, NULL, 10);
  1083. +        if (errno != 0)
  1084. +            goto fail;
  1085. +
  1086. +#if 0
  1087. +        dprintf(CYGWINIDLVL, "cygwin_getent_group(): name='%s'\n", name);
  1088. +        dprintf(CYGWINIDLVL, "group_name\t='%s'\n", grent.group_name);
  1089. +        dprintf(CYGWINIDLVL, "passwd\t='%s'\n", grent.passwd);
  1090. +        dprintf(CYGWINIDLVL, "gidstr\t='%s' (%lu)\n", grent.gidstr, (unsigned long)gid);
  1091. +        dprintf(CYGWINIDLVL, "userlist\t='%s'\n", grent.userlist);
  1092. +#endif
  1093. +
  1094. +found:
  1095. +        if (res_group_name)
  1096. +            (void)strcpy_s(res_group_name, VAL_LEN, grent.group_name);
  1097. +        *res_gid = gid;
  1098. +        res = 0;
  1099. +    }
  1100. +
  1101. +fail:
  1102. +    if (getent_pipe)
  1103. +        (void)_pclose(getent_pipe);
  1104. +
  1105. +    if (res == 0) {
  1106. +        dprintf(CYGWINIDLVL, "<-- cygwin_getent_group('%s'): "
  1107. +            "returning res_gid=%lu, res_group_name='%s'\n",
  1108. +            name, (unsigned long)(*res_gid),
  1109. +            res_group_name?res_group_name:"<NULL>");
  1110. +    }
  1111. +    else {
  1112. +        dprintf(CYGWINIDLVL,
  1113. +            "<-- cygwin_getent_group('%s'): no match found\n",
  1114. +            name);
  1115. +    }
  1116. +
  1117. +    return res;
  1118. +}
  1119. +#endif /* NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN */
  1120.  
  1121.  /* generic cache */
  1122.  typedef struct list_entry* (*entry_alloc_fn)();
  1123. @@ -665,10 +906,10 @@ static int idmap_lookup_user(
  1124.      if (status == NO_ERROR) {
  1125.          /* don't return expired entries; query new attributes
  1126.           * and overwrite the entry with cache_insert() */
  1127. -        if (time(NULL) - user->last_updated < context->config.cache_ttl)
  1128. +        if ((time(NULL) - user->last_updated) < context->config.cache_ttl)
  1129.              goto out;
  1130.      }
  1131. -
  1132. +#ifndef NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN
  1133.      /* send the query to the ldap server */
  1134.      status = idmap_query_attrs(context, lookup,
  1135.          attributes, optional, values, NUM_ATTRIBUTES);
  1136. @@ -705,7 +946,94 @@ static int idmap_lookup_user(
  1137.          goto out_free_values;
  1138.      }
  1139.      user->last_updated = time(NULL);
  1140. +#else
  1141. +    if (lookup->attr == ATTR_USER_NAME) {
  1142. +        char principal_name[VAL_LEN];
  1143. +        uid_t cy_uid = 0;
  1144. +        gid_t cy_gid = 0;
  1145. +
  1146. +        status = ERROR_NOT_FOUND;
  1147. +
  1148. +        if (!cygwin_getent_passwd(lookup->value, NULL, &cy_uid, &cy_gid)) {
  1149. +            dprintf(CYGWINIDLVL, "# ATTR_USER_NAME: cygwin_getent_passwd: returned '%s', uid=%d, gid=%d\n", lookup->value, (int)cy_uid, (int)cy_gid);
  1150. +            (void)snprintf(principal_name, sizeof(principal_name),
  1151. +                "%s@%s", (const char *)lookup->value, "GLOBAL.LOC");
  1152. +            StringCchCopyA(user->username, VAL_LEN, lookup->value);
  1153. +            StringCchCopyA(user->principal, VAL_LEN, principal_name);
  1154. +            user->uid = cy_uid;
  1155. +            user->gid = cy_gid;
  1156. +            status = 0;
  1157. +        }
  1158. +    }
  1159. +    else if (lookup->attr == ATTR_PRINCIPAL) {
  1160. +        char search_name[VAL_LEN];
  1161. +        char principal_name[VAL_LEN];
  1162. +        char *s;
  1163. +        uid_t cy_uid = 0;
  1164. +        gid_t cy_gid = 0;
  1165. +
  1166. +        status = ERROR_NOT_FOUND;
  1167. +
  1168. +        /*
  1169. +         * strip '@' from principal name and use that for getent
  1170. +         * fixme: This does not work with multiple domains
  1171. +         */
  1172. +        (void)strcpy_s(search_name, sizeof(search_name), lookup->value);
  1173. +        if (s = strchr(search_name, '@'))
  1174. +            *s = '\0';
  1175. +
  1176. +        if (!cygwin_getent_passwd(search_name, NULL, &cy_uid, &cy_gid)) {
  1177. +            dprintf(CYGWINIDLVL, "# ATTR_PRINCIPAL: cygwin_getent_passwd: returned '%s', uid=%d, gid=%d\n", lookup->value, (int)cy_uid, (int)cy_gid);
  1178. +            (void)snprintf(principal_name, sizeof(principal_name),
  1179. +                "%s@%s", (const char *)lookup->value, "GLOBAL.LOC");
  1180. +
  1181. +            if (!strcmp(principal_name, lookup->value)) {
  1182. +                StringCchCopyA(user->username, VAL_LEN, search_name);
  1183. +                StringCchCopyA(user->principal, VAL_LEN, principal_name);
  1184. +                user->uid = cy_uid;
  1185. +                user->gid = cy_gid;
  1186. +                status = 0;
  1187. +            }
  1188. +        }
  1189. +    }
  1190. +    else if (lookup->attr == ATTR_UID) {
  1191. +        uid_t search_uid = (uid_t)(lookup->value);
  1192. +        char search_name[VAL_LEN];
  1193. +        char res_username[VAL_LEN];
  1194. +        char principal_name[VAL_LEN];
  1195. +        uid_t cy_uid = 0;
  1196. +        gid_t cy_gid = 0;
  1197. +
  1198. +        status = ERROR_NOT_FOUND;
  1199. +
  1200. +        (void)snprintf(search_name, sizeof(search_name), "%lu", (unsigned long)search_uid);
  1201. +
  1202. +        if (!cygwin_getent_passwd(search_name, res_username, &cy_uid, &cy_gid)) {
  1203. +            dprintf(CYGWINIDLVL, "# ATTR_UID: cygwin_getent_passwd: returned '%s', uid=%d, gid=%d\n", res_username, (int)cy_uid, (int)cy_gid);
  1204. +            (void)snprintf(principal_name, sizeof(principal_name), "%s@%s", res_username, "GLOBAL.LOC");
  1205. +
  1206. +            StringCchCopyA(user->username, VAL_LEN, res_username);
  1207. +            StringCchCopyA(user->principal, VAL_LEN, principal_name);
  1208. +            user->uid = cy_uid;
  1209. +            user->gid = cy_gid;
  1210. +            status = 0;
  1211. +        }
  1212. +    }
  1213. +    else
  1214. +    {
  1215. +        status = ERROR_NOT_FOUND;
  1216. +    }
  1217.  
  1218. +    if (status == 0) {
  1219. +        user->last_updated = time(NULL);
  1220. +        dprintf(CYGWINIDLVL, "## idmap_lookup_user: "
  1221. +            "found username='%s', principal='%s', uid=%lu, gid=%lu\n",
  1222. +            user->username,
  1223. +            user->principal,
  1224. +            (unsigned long)user->uid,
  1225. +            (unsigned long)user->gid);
  1226. +    }
  1227. +#endif /* !NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN */
  1228.      if (context->config.cache_ttl) {
  1229.          /* insert the entry into the cache */
  1230.          cache_insert(&context->users, lookup, &user->entry);
  1231. @@ -732,10 +1060,10 @@ static int idmap_lookup_group(
  1232.      if (status == NO_ERROR) {
  1233.          /* don't return expired entries; query new attributes
  1234.           * and overwrite the entry with cache_insert() */
  1235. -        if (time(NULL) - group->last_updated < context->config.cache_ttl)
  1236. +        if ((time(NULL) - group->last_updated) < context->config.cache_ttl)
  1237.              goto out;
  1238.      }
  1239. -
  1240. +#ifndef NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN
  1241.      /* send the query to the ldap server */
  1242.      status = idmap_query_attrs(context, lookup,
  1243.          attributes, 0, values, NUM_ATTRIBUTES);
  1244. @@ -758,7 +1086,55 @@ static int idmap_lookup_group(
  1245.          goto out_free_values;
  1246.      }
  1247.      group->last_updated = time(NULL);
  1248. +#else
  1249. +    if (lookup->attr == ATTR_GROUP_NAME) {
  1250. +        gid_t cy_gid = 0;
  1251. +
  1252. +        status = ERROR_NOT_FOUND;
  1253. +
  1254. +        if (!cygwin_getent_group(lookup->value, NULL, &cy_gid)) {
  1255. +            dprintf(CYGWINIDLVL,
  1256. +                "# ATTR_GROUP_NAME: cygwin_getent_group: "
  1257. +                "returned '%s', gid=%d\n",
  1258. +                lookup->value, (int)cy_gid);
  1259. +            StringCchCopyA(group->name, VAL_LEN, lookup->value);
  1260. +            group->gid = cy_gid;
  1261. +            status = 0;
  1262. +        }
  1263. +    }
  1264. +    else if (lookup->attr == ATTR_GID) {
  1265. +        gid_t search_gid = (gid_t)(lookup->value);
  1266. +        char search_name[VAL_LEN];
  1267. +        char res_groupname[VAL_LEN];
  1268. +        gid_t cy_gid = 0;
  1269. +
  1270. +        status = ERROR_NOT_FOUND;
  1271. +
  1272. +        (void)snprintf(search_name, sizeof(search_name),
  1273. +            "%lu", (unsigned long)search_gid);
  1274. +
  1275. +        if (!cygwin_getent_group(search_name, res_groupname, &cy_gid)) {
  1276. +            dprintf(CYGWINIDLVL,
  1277. +                "# ATTR_GID: cygwin_getent_group: returned '%s', gid=%d\n",
  1278. +                res_groupname, (int)cy_gid);
  1279. +            StringCchCopyA(group->name, VAL_LEN, res_groupname);
  1280. +            group->gid = cy_gid;
  1281. +            status = 0;
  1282. +        }
  1283. +    }
  1284. +    else
  1285. +    {
  1286. +        status = ERROR_NOT_FOUND;
  1287. +    }
  1288.  
  1289. +    if (status == 0) {
  1290. +        group->last_updated = time(NULL);
  1291. +        dprintf(CYGWINIDLVL,
  1292. +            "## idmap_lookup_group: found name='%s', gid=%lu\n",
  1293. +            group->name,
  1294. +            (unsigned long)group->gid);
  1295. +    }
  1296. +#endif /* !NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN */
  1297.      if (context->config.cache_ttl) {
  1298.          /* insert the entry into the cache */
  1299.          cache_insert(&context->groups, lookup, &group->entry);
  1300. @@ -770,7 +1146,6 @@ out:
  1301.      return status;
  1302.  }
  1303.  
  1304. -
  1305.  /* public idmap interface */
  1306.  int nfs41_idmap_create(
  1307.      struct idmap_context **context_out)
  1308. @@ -795,6 +1170,7 @@ int nfs41_idmap_create(
  1309.          goto out_err_free;
  1310.      }
  1311.  
  1312. +#ifndef NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN
  1313.      /* initialize ldap and configure options */
  1314.      context->ldap = ldap_init(context->config.hostname, context->config.port);
  1315.      if (context->ldap == NULL) {
  1316. @@ -824,8 +1200,13 @@ int nfs41_idmap_create(
  1317.              goto out_err_free;
  1318.          }
  1319.      }
  1320. +#else
  1321. +    dprintf(CYGWINIDLVL, "nfs41_idmap_create: Force context->config.timeout = 6000;\n");
  1322. +    context->config.timeout = 6000;
  1323. +#endif
  1324.  
  1325.      *context_out = context;
  1326. +
  1327.  out:
  1328.      return status;
  1329.  
  1330. diff --git a/daemon/lock.c b/daemon/lock.c
  1331. index c1ac146..4d5294d 100644
  1332. --- a/daemon/lock.c
  1333. +++ b/daemon/lock.c
  1334. @@ -194,7 +194,7 @@ static __inline uint32_t get_lock_type(BOOLEAN exclusive, BOOLEAN blocking)
  1335.          : ( exclusive == 0 ? READW_LT : WRITEW_LT );
  1336.  }
  1337.  
  1338. -static int handle_lock(nfs41_upcall *upcall)
  1339. +static int handle_lock(void *deamon_context, nfs41_upcall *upcall)
  1340.  {
  1341.      stateid_arg stateid;
  1342.      lock_upcall_args *args = &upcall->args.lock;
  1343. @@ -318,7 +318,7 @@ out:
  1344.      return status;
  1345.  }
  1346.  
  1347. -static int handle_unlock(nfs41_upcall *upcall)
  1348. +static int handle_unlock(void *daemon_context, nfs41_upcall *upcall)
  1349.  {
  1350.      nfs41_lock_state input;
  1351.      stateid_arg stateid;
  1352. diff --git a/daemon/mount.c b/daemon/mount.c
  1353. index fc6ec47..8d51020 100644
  1354. --- a/daemon/mount.c
  1355. +++ b/daemon/mount.c
  1356. @@ -56,7 +56,7 @@ out:
  1357.      return status;
  1358.  }
  1359.  
  1360. -static int handle_mount(nfs41_upcall *upcall)
  1361. +static int handle_mount(void *daemon_context, nfs41_upcall *upcall)
  1362.  {
  1363.      int status;
  1364.      mount_upcall_args *args = &upcall->args.mount;
  1365. @@ -192,7 +192,7 @@ static int parse_unmount(unsigned char *buffer, uint32_t length, nfs41_upcall *u
  1366.      return ERROR_SUCCESS;
  1367.  }
  1368.  
  1369. -static int handle_unmount(nfs41_upcall *upcall)
  1370. +static int handle_unmount(void *daemon_context, nfs41_upcall *upcall)
  1371.  {
  1372.      /* release the original reference from nfs41_root_create() */
  1373.      nfs41_root_deref(upcall->root_ref);
  1374. diff --git a/daemon/nfs41_const.h b/daemon/nfs41_const.h
  1375. index f1e6177..0e96586 100644
  1376. --- a/daemon/nfs41_const.h
  1377. +++ b/daemon/nfs41_const.h
  1378. @@ -395,5 +395,8 @@ enum nfs_ftype4 {
  1379.  #define ACL4_PROTECTED            0x00000002
  1380.  #define ACL4_DEFAULTED            0x00000004
  1381.  
  1382. +/* Common user and group names */
  1383. +#define NFS_USER_NOBODY_UID     65534
  1384. +#define NFS_GROUP_NOGROUP_GID   65534
  1385.  
  1386.  #endif /* !__NFS41_NFS_CONST_H__ */
  1387. diff --git a/daemon/nfs41_daemon.c b/daemon/nfs41_daemon.c
  1388. index bb485cb..04086ea 100644
  1389. --- a/daemon/nfs41_daemon.c
  1390. +++ b/daemon/nfs41_daemon.c
  1391. @@ -30,7 +30,7 @@
  1392.  #include "nfs41_driver.h" /* for NFS41_USER_DEVICE_NAME_A */
  1393.  #include "nfs41_np.h" /* for NFS41NP_SHARED_MEMORY */
  1394.  
  1395. -#include "idmap.h"
  1396. +#include "nfs41_daemon.h"
  1397.  #include "daemon_debug.h"
  1398.  #include "upcall.h"
  1399.  #include "util.h"
  1400. @@ -41,9 +41,11 @@ DWORD NFS41D_VERSION = 0;
  1401.  static const char FILE_NETCONFIG[] = "C:\\etc\\netconfig";
  1402.  
  1403.  /* Globals */
  1404. -char localdomain_name[NFS41_HOSTNAME_LEN];
  1405. -int default_uid = 666;
  1406. -int default_gid = 777;
  1407. +nfs41_daemon_globals nfs41_dg = {
  1408. +    .default_uid = NFS_USER_NOBODY_UID,
  1409. +    .default_gid = NFS_GROUP_NOGROUP_GID,
  1410. +};
  1411. +
  1412.  
  1413.  #ifndef STANDALONE_NFSD //make sure to define it in "sources" not here
  1414.  #include "service.h"
  1415. @@ -54,7 +56,7 @@ typedef struct _nfs41_process_thread {
  1416.      uint32_t tid;
  1417.  } nfs41_process_thread;
  1418.  
  1419. -static int map_user_to_ids(nfs41_idmapper *idmapper, uid_t *uid, gid_t *gid)
  1420. +static int map_current_user_to_ids(nfs41_idmapper *idmapper, uid_t *uid, gid_t *gid)
  1421.  {
  1422.      char username[UNLEN + 1];
  1423.      DWORD len = UNLEN + 1;
  1424. @@ -62,15 +64,15 @@ static int map_user_to_ids(nfs41_idmapper *idmapper, uid_t *uid, gid_t *gid)
  1425.  
  1426.      if (!GetUserNameA(username, &len)) {
  1427.          status = GetLastError();
  1428. -        eprintf("GetUserName() failed with %d\n", status);
  1429. +        eprintf("map_current_user_to_ids: GetUserName() failed with %d\n", status);
  1430.          goto out;
  1431.      }
  1432. -    dprintf(1, "map_user_to_ids: mapping user %s\n", username);
  1433. +    dprintf(1, "map_current_user_to_ids: mapping user %s\n", username);
  1434.  
  1435.      if (nfs41_idmap_name_to_ids(idmapper, username, uid, gid)) {
  1436.          /* instead of failing for auth_sys, fall back to 'nobody' uid/gid */
  1437. -        *uid = default_uid;
  1438. -        *gid = default_gid;
  1439. +        *uid = nfs41_dg.default_uid;
  1440. +        *gid = nfs41_dg.default_gid;
  1441.      }
  1442.  out:
  1443.      return status;
  1444. @@ -78,7 +80,7 @@ out:
  1445.  
  1446.  static unsigned int WINAPI thread_main(void *args)
  1447.  {
  1448. -    nfs41_idmapper *idmapper = (nfs41_idmapper*)args;
  1449. +    nfs41_daemon_globals *nfs41dg = (nfs41_daemon_globals *)args;
  1450.      DWORD status = 0;
  1451.      HANDLE pipe;
  1452.      // buffer used to process upcall, assumed to be fixed size.
  1453. @@ -110,8 +112,12 @@ static unsigned int WINAPI thread_main(void *args)
  1454.              goto write_downcall;
  1455.          }
  1456.  
  1457. -        /* map username to uid/gid */
  1458. -        status = map_user_to_ids(idmapper, &upcall.uid, &upcall.gid);
  1459. +        /*
  1460. +         * Map current username to uid/gid
  1461. +         * Each thread can handle a different user
  1462. +         */
  1463. +        status = map_current_user_to_ids(nfs41dg->idmapper,
  1464. +            &upcall.uid, &upcall.gid);
  1465.          if (status) {
  1466.              upcall.status = status;
  1467.              goto write_downcall;
  1468. @@ -122,7 +128,7 @@ static unsigned int WINAPI thread_main(void *args)
  1469.              exit(0);
  1470.          }
  1471.  
  1472. -        status = upcall_handle(&upcall);
  1473. +        status = upcall_handle(&nfs41_dg, &upcall);
  1474.  
  1475.  write_downcall:
  1476.          dprintf(1, "writing downcall: xid=%lld opcode=%s status=%d "
  1477. @@ -212,10 +218,10 @@ static bool_t parse_cmdlineargs(int argc, TCHAR *argv[], nfsd_args *out)
  1478.                      PrintUsage();
  1479.                      return FALSE;
  1480.                  }
  1481. -                default_uid = _ttoi(argv[i]);
  1482. -                if (!default_uid) {
  1483. +                nfs41_dg.default_uid = _ttoi(argv[i]);
  1484. +                if (!nfs41_dg.default_uid) {
  1485.                      fprintf(stderr, "Invalid (or missing) anonymous uid value of %d\n",
  1486. -                        default_uid);
  1487. +                        nfs41_dg.default_uid);
  1488.                      return FALSE;
  1489.                  }
  1490.              }
  1491. @@ -226,7 +232,7 @@ static bool_t parse_cmdlineargs(int argc, TCHAR *argv[], nfsd_args *out)
  1492.                      PrintUsage();
  1493.                      return FALSE;
  1494.                  }
  1495. -                default_gid = _ttoi(argv[i]);
  1496. +                nfs41_dg.default_gid = _ttoi(argv[i]);
  1497.              }
  1498.              else
  1499.                  fprintf(stderr, "Unrecognized option '%s', disregarding.\n", argv[i]);
  1500. @@ -320,9 +326,9 @@ static int getdomainname()
  1501.                      if (i == len)
  1502.                          break;
  1503.                      flag = TRUE;
  1504. -                    memcpy(localdomain_name, &hostname[i+1], len-i);
  1505. +                    memcpy(nfs41_dg.localdomain_name, &hostname[i+1], len-i);
  1506.                      dprintf(1, "getdomainname: domainname %s %d\n",
  1507. -                            localdomain_name, strlen(localdomain_name));
  1508. +                            nfs41_dg.localdomain_name, strlen(nfs41_dg.localdomain_name));
  1509.                      goto out_loop;
  1510.                  }
  1511.                  break;
  1512. @@ -340,9 +346,9 @@ out_loop:
  1513.          freeaddrinfo(result);
  1514.      } else {
  1515.          dprintf(1, "domain name is %s\n", net_info->DomainName);
  1516. -        memcpy(localdomain_name, net_info->DomainName,
  1517. +        memcpy(nfs41_dg.localdomain_name, net_info->DomainName,
  1518.                  strlen(net_info->DomainName));
  1519. -        localdomain_name[strlen(net_info->DomainName)] = '\0';
  1520. +        nfs41_dg.localdomain_name[strlen(net_info->DomainName)] = '\0';
  1521.      }
  1522.  out_free:
  1523.      free(net_info);
  1524. @@ -360,7 +366,6 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  1525.      // handle to our drivers
  1526.      HANDLE pipe;
  1527.      nfs41_process_thread tids[MAX_NUM_THREADS];
  1528. -    nfs41_idmapper *idmapper = NULL;
  1529.      int i;
  1530.      nfsd_args cmd_args;
  1531.  
  1532. @@ -389,10 +394,15 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  1533.          exit(1);
  1534.      }
  1535.  
  1536. +#ifdef NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN
  1537. +    /* force enable for cygwin getent passwd/group testing */
  1538. +    cmd_args.ldap_enable = TRUE;
  1539. +#endif /* NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN */
  1540. +
  1541.      nfs41_server_list_init();
  1542.  
  1543.      if (cmd_args.ldap_enable) {
  1544. -        status = nfs41_idmap_create(&idmapper);
  1545. +        status = nfs41_idmap_create(&(nfs41_dg.idmapper));
  1546.          if (status) {
  1547.              eprintf("id mapping initialization failed with %d\n", status);
  1548.              goto out_logs;
  1549. @@ -428,7 +438,7 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  1550.  
  1551.      for (i = 0; i < MAX_NUM_THREADS; i++) {
  1552.          tids[i].handle = (HANDLE)_beginthreadex(NULL, 0, thread_main,
  1553. -                idmapper, 0, &tids[i].tid);
  1554. +                &nfs41_dg, 0, &tids[i].tid);
  1555.          if (tids[i].handle == INVALID_HANDLE_VALUE) {
  1556.              status = GetLastError();
  1557.              eprintf("_beginthreadex failed %d\n", status);
  1558. @@ -451,7 +461,8 @@ VOID ServiceStart(DWORD argc, LPTSTR *argv)
  1559.  out_pipe:
  1560.      CloseHandle(pipe);
  1561.  out_idmap:
  1562. -    if (idmapper) nfs41_idmap_free(idmapper);
  1563. +    if (nfs41_dg.idmapper)
  1564. +        nfs41_idmap_free(nfs41_dg.idmapper);
  1565.  out_logs:
  1566.  #ifndef STANDALONE_NFSD
  1567.      close_log_files();
  1568. diff --git a/daemon/nfs41_daemon.h b/daemon/nfs41_daemon.h
  1569. new file mode 100644
  1570. index 0000000..6c91e41
  1571. --- /dev/null
  1572. +++ b/daemon/nfs41_daemon.h
  1573. @@ -0,0 +1,39 @@
  1574. +/* NFSv4.1 client for Windows
  1575. + * Copyright © 2012 The Regents of the University of Michigan
  1576. + *
  1577. + * Olga Kornievskaia <aglo@umich.edu>
  1578. + * Casey Bodley <cbodley@umich.edu>
  1579. + * Roland Mainz <roland.mainz@nrubsig.org>
  1580. + *
  1581. + * This library is free software; you can redistribute it and/or modify it
  1582. + * under the terms of the GNU Lesser General Public License as published by
  1583. + * the Free Software Foundation; either version 2.1 of the License, or (at
  1584. + * your option) any later version.
  1585. + *
  1586. + * This library is distributed in the hope that it will be useful, but
  1587. + * without any warranty; without even the implied warranty of merchantability
  1588. + * or fitness for a particular purpose.  See the GNU Lesser General Public
  1589. + * License for more details.
  1590. + *
  1591. + * You should have received a copy of the GNU Lesser General Public License
  1592. + * along with this library; if not, write to the Free Software Foundation,
  1593. + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  1594. + */
  1595. +
  1596. +#ifndef __NFS41_DAEMON_H_
  1597. +#define __NFS41_DAEMON_H_ 1
  1598. +
  1599. +#include "nfs41_build_features.h"
  1600. +#include "idmap.h"
  1601. +
  1602. +/*
  1603. + * Global data of the daemon process
  1604. + */
  1605. +typedef struct __nfs41_daemon_globals {
  1606. +    struct idmap_context *idmapper;
  1607. +    char localdomain_name[NFS41_HOSTNAME_LEN];
  1608. +    int default_uid;
  1609. +    int default_gid;
  1610. +} nfs41_daemon_globals;
  1611. +
  1612. +#endif /* !__NFS41_DAEMON_H_ */
  1613. diff --git a/daemon/open.c b/daemon/open.c
  1614. index e59939b..87b71cd 100644
  1615. --- a/daemon/open.c
  1616. +++ b/daemon/open.c
  1617. @@ -18,23 +18,25 @@
  1618.   * along with this library; if not, write to the Free Software Foundation,
  1619.   * Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  1620.   */
  1621. -
  1622. -#include <Windows.h>
  1623. -#include <stdio.h>
  1624. -#include <ctype.h>
  1625. -#include <strsafe.h>
  1626. -
  1627. -#include "nfs41_ops.h"
  1628. -#include "nfs41_build_features.h"
  1629. -#include "delegation.h"
  1630. -#include "from_kernel.h"
  1631. -#include "daemon_debug.h"
  1632. -#include "upcall.h"
  1633. -#include "util.h"
  1634. -
  1635. -static int create_open_state(
  1636. -    IN const char *path,
  1637. -    IN uint32_t open_owner_id,
  1638. +
  1639. +#include <Windows.h>
  1640. +#include <stdio.h>
  1641. +#include <ctype.h>
  1642. +#include <strsafe.h>
  1643. +
  1644. +#include "nfs41_ops.h"
  1645. +#include "nfs41_build_features.h"
  1646. +#include "nfs41_daemon.h"
  1647. +#include "delegation.h"
  1648. +#include "from_kernel.h"
  1649. +#include "daemon_debug.h"
  1650. +#include "upcall.h"
  1651. +#include "util.h"
  1652. +#include "idmap.h"
  1653. +
  1654. +static int create_open_state(
  1655. +    IN const char *path,
  1656. +    IN uint32_t open_owner_id,
  1657.      OUT nfs41_open_state **state_out)
  1658.  {
  1659.      int status;
  1660. @@ -293,38 +295,38 @@ static int parse_open(unsigned char *buffer, uint32_t length, nfs41_upcall *upca
  1661.      status = safe_read(&buffer, &length, &args->disposition, sizeof(ULONG));
  1662.      if (status) goto out;
  1663.      status = safe_read(&buffer, &length, &args->open_owner_id, sizeof(LONG));
  1664. -    if (status) goto out;
  1665. -    status = safe_read(&buffer, &length, &args->mode, sizeof(DWORD));
  1666. -    if (status) goto out;
  1667. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1668. -    status = safe_read(&buffer, &length, &args->owner_local_uid, sizeof(DWORD));
  1669. -    if (status) goto out;
  1670. -    status = safe_read(&buffer, &length, &args->owner_group_local_gid, sizeof(DWORD));
  1671. -    if (status) goto out;
  1672. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1673. -    status = safe_read(&buffer, &length, &args->srv_open, sizeof(HANDLE));
  1674. -    if (status) goto out;
  1675. -    status = parse_abs_path(&buffer, &length, &args->symlink);
  1676. +    if (status) goto out;
  1677. +    status = safe_read(&buffer, &length, &args->mode, sizeof(DWORD));
  1678. +    if (status) goto out;
  1679. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1680. +    status = safe_read(&buffer, &length, &args->owner_local_uid, sizeof(DWORD));
  1681. +    if (status) goto out;
  1682. +    status = safe_read(&buffer, &length, &args->owner_group_local_gid, sizeof(DWORD));
  1683. +    if (status) goto out;
  1684. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1685. +    status = safe_read(&buffer, &length, &args->srv_open, sizeof(HANDLE));
  1686. +    if (status) goto out;
  1687. +    status = parse_abs_path(&buffer, &length, &args->symlink);
  1688.      if (status) goto out;
  1689.      status = safe_read(&buffer, &length, &args->ea, sizeof(HANDLE));
  1690.      if (status) goto out;
  1691.  
  1692. -    dprintf(1, "parsing NFS41_OPEN: filename='%s' access mask=%d "
  1693. -        "access mode=%d\n\tfile attrs=0x%x create attrs=0x%x "
  1694. -        "(kernel) disposition=%d\n\topen_owner_id=%d mode=%o "
  1695. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1696. -        "owner_local_uid=%u owner_group_local_gid=%u "
  1697. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1698. -        "srv_open=%p symlink=%s ea=%p\n", args->path, args->access_mask,
  1699. -        args->access_mode, args->file_attrs, args->create_opts,
  1700. -        args->disposition, args->open_owner_id, args->mode,
  1701. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1702. -        (unsigned int)args->owner_local_uid, (unsigned int)args->owner_group_local_gid,
  1703. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1704. -        args->srv_open,
  1705. -        args->symlink.path, args->ea);
  1706. -    print_disposition(2, args->disposition);
  1707. -    print_access_mask(2, args->access_mask);
  1708. +    dprintf(1, "parsing NFS41_OPEN: filename='%s' access mask=%d "
  1709. +        "access mode=%d\n\tfile attrs=0x%x create attrs=0x%x "
  1710. +        "(kernel) disposition=%d\n\topen_owner_id=%d mode=%o "
  1711. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1712. +        "owner_local_uid=%u owner_group_local_gid=%u "
  1713. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1714. +        "srv_open=%p symlink=%s ea=%p\n", args->path, args->access_mask,
  1715. +        args->access_mode, args->file_attrs, args->create_opts,
  1716. +        args->disposition, args->open_owner_id, args->mode,
  1717. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1718. +        (unsigned int)args->owner_local_uid, (unsigned int)args->owner_group_local_gid,
  1719. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1720. +        args->srv_open,
  1721. +        args->symlink.path, args->ea);
  1722. +    print_disposition(2, args->disposition);
  1723. +    print_access_mask(2, args->access_mask);
  1724.      print_share_mode(2, args->access_mode);
  1725.      print_create_attributes(2, args->create_opts);
  1726.  out:
  1727. @@ -491,9 +493,10 @@ static int create_with_ea(
  1728.          || (disposition == FILE_OPEN_IF && lookup_status == NFS4ERR_NOENT);
  1729.  }
  1730.  
  1731. -static int handle_open(nfs41_upcall *upcall)
  1732. +static int handle_open(void *daemon_context, nfs41_upcall *upcall)
  1733.  {
  1734.      int status = 0;
  1735. +    nfs41_daemon_globals *nfs41dg = daemon_context;
  1736.      open_upcall_args *args = &upcall->args.open;
  1737.      nfs41_open_state *state;
  1738.      nfs41_file_info info = { 0 };
  1739. @@ -655,123 +658,92 @@ static int handle_open(nfs41_upcall *upcall)
  1740.          }
  1741.  
  1742.          nfs_to_basic_info(&info, &args->basic_info);
  1743. -        nfs_to_standard_info(&info, &args->std_info);
  1744. -        args->mode = info.mode;
  1745. -        args->changeattr = info.change;
  1746. -
  1747. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1748. -        bitmap4 og_attr_request = { 0 };
  1749. -        nfs41_file_info og_info = { 0 };
  1750. -        char owner[NFS4_OPAQUE_LIMIT], group[NFS4_OPAQUE_LIMIT];
  1751. -        nfsacl41 acl = { 0 };
  1752. -
  1753. -        /*
  1754. -         * gisburn:
  1755. -         * 1. We should cache owner/group information
  1756. -         * 2. We should always ask for
  1757. -         * FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP with the other
  1758. -         * attributes
  1759. -         */
  1760. -        og_attr_request.count = 2;
  1761. -        og_attr_request.arr[1] = FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP;
  1762. -        og_info.owner = owner;
  1763. -        og_info.owner_group = group;
  1764. -        status = nfs41_getattr(state->session, &state->file, &og_attr_request, &og_info);
  1765. -        if (status) {
  1766. -            eprintf("get_stat_data: nfs41_cached_getattr() failed with %d\n",
  1767. -            status);
  1768. -        }
  1769. -
  1770. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_TESTMAPPING
  1771. -        /*
  1772. -         * Map owner to local uid
  1773. -         *
  1774. -         * |owner| can be numeric string ("1616"), plain username
  1775. -         *  ("gisburn") or username@domain ("gisburn@sun.com")
  1776. -         */
  1777. -        /* stomp over '@' */
  1778. -        char *at_ch; /* pointer to '@' */
  1779. -        if (at_ch = strchr(og_info.owner, '@'))
  1780. -            *at_ch = '\0';
  1781. -
  1782. -        if (isdigit(og_info.owner[0])) {
  1783. -            args->owner_local_uid = atol(og_info.owner);
  1784. -        }
  1785. -        else if(!strcmp(og_info.owner, "nobody")) {
  1786. -            args->owner_local_uid = 65534;
  1787. -        }
  1788. -        else if(!strcmp(og_info.owner, "root")) {
  1789. -            args->owner_local_uid = 0;
  1790. -        }
  1791. -        else if(!strcmp(og_info.owner, "rmainz")) {
  1792. -            args->owner_local_uid = 1616;
  1793. -        }
  1794. -        else if(!strcmp(og_info.owner, "roland_mainz")) {
  1795. -            args->owner_local_uid = 197608;
  1796. -        }
  1797. -        else if(!strcmp(og_info.owner, "swulsch")) {
  1798. -            args->owner_local_uid = 1818;
  1799. -        }
  1800. -        else if(!strcmp(og_info.owner, "iam")) {
  1801. -            args->owner_local_uid = 2010;
  1802. -        }
  1803. -        else if(!strcmp(og_info.owner, "mwenzel")) {
  1804. -            args->owner_local_uid = 8239;
  1805. -        }
  1806. -        else if(!strcmp(og_info.owner, "test001")) {
  1807. -            args->owner_local_uid = 1000;
  1808. -        }
  1809. -        else {
  1810. -            args->owner_local_uid = 666; /* debug: number of the beast */
  1811. -        }
  1812. -
  1813. -        /*
  1814. -         * Map owner_group to local gid
  1815. -         *
  1816. -         * |owner_group| can be numeric string ("1616"), plain username
  1817. -         * ("gisgrp") or username@domain ("gisgrp@sun.com")
  1818. -         */
  1819. -        if (at_ch = strchr(og_info.owner_group, '@'))
  1820. -            *at_ch = '\0';
  1821. -        if (isdigit(og_info.owner_group[0])) {
  1822. -            args->owner_group_local_gid = atol(og_info.owner_group);
  1823. -        }
  1824. -        else if(!strcmp(og_info.owner_group, "nogroup")) {
  1825. -            args->owner_group_local_gid = 65534;
  1826. -        }
  1827. -        else if(!strcmp(og_info.owner_group, "root")) {
  1828. -            args->owner_group_local_gid = 0;
  1829. -        }
  1830. -        else if(!strcmp(og_info.owner_group, "Kein")) {
  1831. -            args->owner_group_local_gid = 197121;
  1832. -        }
  1833. -        else if(!strcmp(og_info.owner_group, "rmainz")) {
  1834. -            args->owner_group_local_gid = 1616;
  1835. -        }
  1836. -        else if(!strcmp(og_info.owner, "iam")) {
  1837. -            args->owner_group_local_gid = 2010;
  1838. -        }
  1839. -        else if(!strcmp(og_info.owner_group, "swulsch")) {
  1840. -            args->owner_group_local_gid = 1818;
  1841. -        }
  1842. -        else if(!strcmp(og_info.owner_group, "mwenzel")) {
  1843. -            args->owner_group_local_gid = 8239;
  1844. -        }
  1845. -        else if(!strcmp(og_info.owner_group, "test001")) {
  1846. -            args->owner_group_local_gid = 1000;
  1847. -        }
  1848. -        else {
  1849. -            args->owner_group_local_gid = 666; /* debug: number of the beast */
  1850. -        }
  1851. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_TESTMAPPING */
  1852. -
  1853. -        dprintf(1, "handle_open: stat: owner=%u/'%s', owner_group=%u/'%s'\n",
  1854. -            (unsigned int)args->owner_local_uid, og_info.owner,
  1855. -            (unsigned int)args->owner_group_local_gid, og_info.owner_group);
  1856. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1857. -    } else {
  1858. -        nfs41_file_info createattrs = { 0 };
  1859. -        uint32_t create = 0, createhowmode = 0, lookup_status = status;
  1860. +        nfs_to_standard_info(&info, &args->std_info);
  1861. +        args->mode = info.mode;
  1862. +        args->changeattr = info.change;
  1863. +
  1864. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1865. +        bitmap4 og_attr_request = { 0 };
  1866. +        nfs41_file_info og_info = { 0 };
  1867. +        char owner[NFS4_OPAQUE_LIMIT], group[NFS4_OPAQUE_LIMIT];
  1868. +        nfsacl41 acl = { 0 };
  1869. +
  1870. +        /*
  1871. +         * gisburn:
  1872. +         * 1. We should cache owner/group information
  1873. +         * 2. We should always ask for
  1874. +         * FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP with the other
  1875. +         * attributes
  1876. +         */
  1877. +        og_attr_request.count = 2;
  1878. +        og_attr_request.arr[1] = FATTR4_WORD1_OWNER | FATTR4_WORD1_OWNER_GROUP;
  1879. +        og_info.owner = owner;
  1880. +        og_info.owner_group = group;
  1881. +        status = nfs41_getattr(state->session, &state->file, &og_attr_request, &og_info);
  1882. +        if (status) {
  1883. +            eprintf("get_stat_data: nfs41_cached_getattr() failed with %d\n",
  1884. +            status);
  1885. +        }
  1886. +
  1887. +        uid_t map_uid = -1;
  1888. +        gid_t gid_dummy = -1;
  1889. +        gid_t map_gid = -1;
  1890. +        char *at_ch; /* pointer to '@' */
  1891. +
  1892. +        /*
  1893. +         * Map owner to local uid
  1894. +         *
  1895. +         * |owner| can be numeric string ("1616"), plain username
  1896. +         *  ("gisburn") or username@domain ("gisburn@sun.com")
  1897. +         */
  1898. +        /* stomp over '@' */
  1899. +        if (at_ch = strchr(og_info.owner, '@'))
  1900. +            *at_ch = '\0';
  1901. +
  1902. +        if (nfs41_idmap_name_to_ids(
  1903. +            nfs41dg->idmapper,
  1904. +            og_info.owner,
  1905. +            &map_uid,
  1906. +            &gid_dummy) == 0) {
  1907. +             args->owner_local_uid = map_uid;
  1908. +        }
  1909. +        else {
  1910. +            args->owner_local_uid = NFS_USER_NOBODY_UID;
  1911. +            eprintf("get_stat_data: "
  1912. +                "no username mapping for '%s', fake uid=%d\n",
  1913. +                og_info.owner, args->owner_local_uid);
  1914. +        }
  1915. +
  1916. +        /*
  1917. +         * Map owner_group to local gid
  1918. +         *
  1919. +         * |owner_group| can be numeric string ("1616"), plain username
  1920. +         * ("gisgrp") or username@domain ("gisgrp@sun.com")
  1921. +         */
  1922. +        /* stomp over '@' */
  1923. +        if (at_ch = strchr(og_info.owner_group, '@'))
  1924. +            *at_ch = '\0';
  1925. +
  1926. +        if (nfs41_idmap_group_to_gid(
  1927. +            nfs41dg->idmapper,
  1928. +            og_info.owner_group,
  1929. +            &map_gid) == 0) {
  1930. +            args->owner_group_local_gid = map_gid;
  1931. +        }
  1932. +        else {
  1933. +            args->owner_group_local_gid = NFS_GROUP_NOGROUP_GID;
  1934. +            eprintf("get_stat_data: "
  1935. +                "no group mapping for '%s', fake gid=%d\n",
  1936. +                og_info.owner_group, args->owner_group_local_gid);
  1937. +        }
  1938. +
  1939. +        dprintf(1, "handle_open: stat: owner=%u/'%s', owner_group=%u/'%s'\n",
  1940. +            (unsigned int)args->owner_local_uid, og_info.owner,
  1941. +            (unsigned int)args->owner_group_local_gid, og_info.owner_group);
  1942. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1943. +    } else {
  1944. +        nfs41_file_info createattrs = { 0 };
  1945. +        uint32_t create = 0, createhowmode = 0, lookup_status = status;
  1946.  
  1947.          if (!lookup_status && (args->disposition == FILE_OVERWRITE ||
  1948.                  args->disposition == FILE_OVERWRITE_IF ||
  1949. @@ -875,18 +847,18 @@ static int marshall_open(unsigned char *buffer, uint32_t *length, nfs41_upcall *
  1950.      status = safe_write(&buffer, length, &args->std_info, sizeof(args->std_info));
  1951.      if (status) goto out;
  1952.      status = safe_write(&buffer, length, &upcall->state_ref, sizeof(HANDLE));
  1953. -    if (status) goto out;
  1954. -    status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
  1955. -    if (status) goto out;
  1956. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1957. -    status = safe_write(&buffer, length, &args->owner_local_uid, sizeof(args->owner_local_uid));
  1958. -    if (status) goto out;
  1959. -    status = safe_write(&buffer, length, &args->owner_group_local_gid, sizeof(args->owner_group_local_gid));
  1960. -    if (status) goto out;
  1961. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1962. -    status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
  1963. -    if (status) goto out;
  1964. -    status = safe_write(&buffer, length, &args->deleg_type, sizeof(args->deleg_type));
  1965. +    if (status) goto out;
  1966. +    status = safe_write(&buffer, length, &args->mode, sizeof(args->mode));
  1967. +    if (status) goto out;
  1968. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  1969. +    status = safe_write(&buffer, length, &args->owner_local_uid, sizeof(args->owner_local_uid));
  1970. +    if (status) goto out;
  1971. +    status = safe_write(&buffer, length, &args->owner_group_local_gid, sizeof(args->owner_group_local_gid));
  1972. +    if (status) goto out;
  1973. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  1974. +    status = safe_write(&buffer, length, &args->changeattr, sizeof(args->changeattr));
  1975. +    if (status) goto out;
  1976. +    status = safe_write(&buffer, length, &args->deleg_type, sizeof(args->deleg_type));
  1977.      if (status) goto out;
  1978.      if (upcall->last_error == ERROR_REPARSE) {
  1979.          unsigned short len = (args->symlink.len + 1) * sizeof(WCHAR);
  1980. @@ -996,7 +968,7 @@ static int do_nfs41_close(nfs41_open_state *state)
  1981.      return status;
  1982.  }
  1983.  
  1984. -static int handle_close(nfs41_upcall *upcall)
  1985. +static int handle_close(void *deamon_context, nfs41_upcall *upcall)
  1986.  {
  1987.      int status = NFS4_OK, rm_status = NFS4_OK;
  1988.      close_upcall_args *args = &upcall->args.close;
  1989. diff --git a/daemon/readdir.c b/daemon/readdir.c
  1990. index 3742ffd..ab15539 100644
  1991. --- a/daemon/readdir.c
  1992. +++ b/daemon/readdir.c
  1993. @@ -162,13 +162,13 @@ static void readdir_copy_shortname(
  1994.      OUT LPWSTR name_out,
  1995.      OUT CCHAR *name_size_out)
  1996.  {
  1997. -    /* GetShortPathName returns number of characters, not including \0 */
  1998. -    *name_size_out = (CCHAR)GetShortPathNameW(name, name_out, 12);
  1999. -    if (*name_size_out) {
  2000. -        (*name_size_out)++;
  2001. -        *name_size_out *= sizeof(WCHAR);
  2002. -    }
  2003. -}
  2004. +    /* GetShortPathName returns number of characters, not including \0 */
  2005. +    *name_size_out = (CCHAR)GetShortPathNameW(name, name_out, 12);
  2006. +    if (*name_size_out) {
  2007. +        (*name_size_out)++;
  2008. +        *name_size_out *= sizeof(WCHAR);
  2009. +    }
  2010. +}
  2011.  
  2012.  static void readdir_copy_full_dir_info(
  2013.      IN nfs41_readdir_entry *entry,
  2014. @@ -448,7 +448,7 @@ out:
  2015.      return status;
  2016.  }
  2017.  
  2018. -static int handle_readdir(nfs41_upcall *upcall)
  2019. +static int handle_readdir(void *deamon_context, nfs41_upcall *upcall)
  2020.  {
  2021.      int status;
  2022.      readdir_upcall_args *args = &upcall->args.readdir;
  2023. diff --git a/daemon/readwrite.c b/daemon/readwrite.c
  2024. index 6a8f0c0..b35f9c0 100644
  2025. --- a/daemon/readwrite.c
  2026. +++ b/daemon/readwrite.c
  2027. @@ -135,7 +135,7 @@ out:
  2028.      return status;
  2029.  }
  2030.  
  2031. -static int handle_read(nfs41_upcall *upcall)
  2032. +static int handle_read(void *daemon_context, nfs41_upcall *upcall)
  2033.  {
  2034.      readwrite_upcall_args *args = &upcall->args.rw;
  2035.      stateid_arg stateid;
  2036. @@ -271,7 +271,7 @@ out:
  2037.      return status;
  2038.  }
  2039.  
  2040. -static int handle_write(nfs41_upcall *upcall)
  2041. +static int handle_write(void *daemon_context, nfs41_upcall *upcall)
  2042.  {
  2043.      readwrite_upcall_args *args = &upcall->args.rw;
  2044.      stateid_arg stateid;
  2045. @@ -322,4 +322,4 @@ const nfs41_upcall_op nfs41_op_write = {
  2046.      parse_rw,
  2047.      handle_write,
  2048.      marshall_rw
  2049. -};
  2050. \ No newline at end of file
  2051. +};
  2052. diff --git a/daemon/setattr.c b/daemon/setattr.c
  2053. index 23c2703..8cb8e3a 100644
  2054. --- a/daemon/setattr.c
  2055. +++ b/daemon/setattr.c
  2056. @@ -55,7 +55,7 @@ out:
  2057.      return status;
  2058.  }
  2059.  
  2060. -static int handle_nfs41_setattr(setattr_upcall_args *args)
  2061. +static int handle_nfs41_setattr(void *daemon_context, setattr_upcall_args *args)
  2062.  {
  2063.      PFILE_BASIC_INFO basic_info = (PFILE_BASIC_INFO)args->buf;
  2064.      nfs41_open_state *state = args->state;
  2065. @@ -149,7 +149,7 @@ out:
  2066.      return status;
  2067.  }
  2068.  
  2069. -static int handle_nfs41_remove(setattr_upcall_args *args)
  2070. +static int handle_nfs41_remove(void *daemon_context, setattr_upcall_args *args)
  2071.  {
  2072.      nfs41_open_state *state = args->state;
  2073.      int status;
  2074. @@ -208,7 +208,7 @@ static int is_dst_name_opened(nfs41_abs_path *dst_path, nfs41_session *dst_sessi
  2075.  
  2076.      return status;
  2077.  }
  2078. -static int handle_nfs41_rename(setattr_upcall_args *args)
  2079. +static int handle_nfs41_rename(void *daemon_context, setattr_upcall_args *args)
  2080.  {
  2081.      nfs41_open_state *state = args->state;
  2082.      nfs41_session *dst_session;
  2083. @@ -341,7 +341,7 @@ out:
  2084.      return status;
  2085.  }
  2086.  
  2087. -static int handle_nfs41_set_size(setattr_upcall_args *args)
  2088. +static int handle_nfs41_set_size(void *daemon_context, setattr_upcall_args *args)
  2089.  {
  2090.      nfs41_file_info info = { 0 };
  2091.      stateid_arg stateid;
  2092. @@ -378,7 +378,7 @@ out:
  2093.      return status = nfs_to_windows_error(status, ERROR_NOT_SUPPORTED);
  2094.  }
  2095.  
  2096. -static int handle_nfs41_link(setattr_upcall_args *args)
  2097. +static int handle_nfs41_link(void *daemon_context, setattr_upcall_args *args)
  2098.  {
  2099.      nfs41_open_state *state = args->state;
  2100.      PFILE_LINK_INFORMATION link = (PFILE_LINK_INFORMATION)args->buf;
  2101. @@ -480,30 +480,30 @@ out:
  2102.      return status;
  2103.  }
  2104.  
  2105. -static int handle_setattr(nfs41_upcall *upcall)
  2106. +static int handle_setattr(void *daemon_context, nfs41_upcall *upcall)
  2107.  {
  2108.      setattr_upcall_args *args = &upcall->args.setattr;
  2109.      int status;
  2110.  
  2111.      switch (args->set_class) {
  2112.      case FileBasicInformation:
  2113. -        status = handle_nfs41_setattr(args);
  2114. +        status = handle_nfs41_setattr(daemon_context, args);
  2115.          break;
  2116.      case FileDispositionInformation:
  2117. -        status = handle_nfs41_remove(args);
  2118. +        status = handle_nfs41_remove(daemon_context, args);
  2119.          break;
  2120.      case FileRenameInformation:
  2121. -        status = handle_nfs41_rename(args);
  2122. +        status = handle_nfs41_rename(daemon_context, args);
  2123.          break;
  2124.      case FileAllocationInformation:
  2125.      case FileEndOfFileInformation:
  2126. -        status = handle_nfs41_set_size(args);
  2127. +        status = handle_nfs41_set_size(daemon_context, args);
  2128.          break;
  2129.      case FileLinkInformation:
  2130. -        status = handle_nfs41_link(args);
  2131. +        status = handle_nfs41_link(daemon_context, args);
  2132.          break;
  2133.      default:
  2134. -        eprintf("unknown set_file information class %d\n",
  2135. +        eprintf("handle_setattr: unknown set_file information class %d\n",
  2136.              args->set_class);
  2137.          status = ERROR_NOT_SUPPORTED;
  2138.          break;
  2139. diff --git a/daemon/symlink.c b/daemon/symlink.c
  2140. index 9709e4f..f27d0a4 100644
  2141. --- a/daemon/symlink.c
  2142. +++ b/daemon/symlink.c
  2143. @@ -208,7 +208,7 @@ out:
  2144.      return status;
  2145.  }
  2146.  
  2147. -static int handle_symlink(nfs41_upcall *upcall)
  2148. +static int handle_symlink(void *daemon_context, nfs41_upcall *upcall)
  2149.  {
  2150.      symlink_upcall_args *args = &upcall->args.symlink;
  2151.      nfs41_open_state *state = upcall->state_ref;
  2152. diff --git a/daemon/upcall.c b/daemon/upcall.c
  2153. index 16fa4a4..e2ead20 100644
  2154. --- a/daemon/upcall.c
  2155. +++ b/daemon/upcall.c
  2156. @@ -133,6 +133,7 @@ out:
  2157.  }
  2158.  
  2159.  int upcall_handle(
  2160. +    IN void *daemon_context,
  2161.      IN nfs41_upcall *upcall)
  2162.  {
  2163.      int status = NO_ERROR;
  2164. @@ -146,7 +147,7 @@ int upcall_handle(
  2165.          goto out;
  2166.      }
  2167.  
  2168. -    upcall->status = op->handle(upcall);
  2169. +    upcall->status = op->handle(daemon_context, upcall);
  2170.  out:
  2171.      return status;
  2172.  }
  2173. diff --git a/daemon/upcall.h b/daemon/upcall.h
  2174. index 8c72cbb..8340497 100644
  2175. --- a/daemon/upcall.h
  2176. +++ b/daemon/upcall.h
  2177. @@ -20,13 +20,13 @@
  2178.   */
  2179.  
  2180.  #ifndef __NFS41_DAEMON_UPCALL_H__
  2181. -#define __NFS41_DAEMON_UPCALL_H__
  2182. -
  2183. -#include "nfs41_ops.h"
  2184. -#include "nfs41_build_features.h"
  2185. -#include "from_kernel.h"
  2186. -
  2187. -#define NFSD_VERSION_MISMATCH 116
  2188. +#define __NFS41_DAEMON_UPCALL_H__
  2189. +
  2190. +#include "nfs41_ops.h"
  2191. +#include "nfs41_build_features.h"
  2192. +#include "from_kernel.h"
  2193. +
  2194. +#define NFSD_VERSION_MISMATCH 116
  2195.  
  2196.  /* structures for upcall arguments */
  2197.  typedef struct __mount_upcall_args {
  2198. @@ -48,16 +48,16 @@ typedef struct __open_upcall_args {
  2199.      ULONG access_mode;
  2200.      ULONG file_attrs;
  2201.      ULONG disposition;
  2202. -    ULONG create_opts;
  2203. -    LONG open_owner_id;
  2204. -    DWORD mode;
  2205. -#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  2206. -    DWORD owner_local_uid;         /* owner mapped into local uid */
  2207. -    DWORD owner_group_local_gid;   /* owner group mapped into local gid */
  2208. -#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  2209. -    ULONGLONG changeattr;
  2210. -    HANDLE srv_open;
  2211. -    DWORD deleg_type;
  2212. +    ULONG create_opts;
  2213. +    LONG open_owner_id;
  2214. +    DWORD mode;
  2215. +#ifdef NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES
  2216. +    DWORD owner_local_uid;         /* owner mapped into local uid */
  2217. +    DWORD owner_group_local_gid;   /* owner group mapped into local gid */
  2218. +#endif /* NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES */
  2219. +    ULONGLONG changeattr;
  2220. +    HANDLE srv_open;
  2221. +    DWORD deleg_type;
  2222.      PFILE_FULL_EA_INFORMATION ea;
  2223.      BOOLEAN created;
  2224.      BOOLEAN symlink_embedded;
  2225. @@ -215,7 +215,7 @@ typedef struct __nfs41_upcall {
  2226.  
  2227.  /* upcall operation interface */
  2228.  typedef int (*upcall_parse_proc)(unsigned char*, uint32_t, nfs41_upcall*);
  2229. -typedef int (*upcall_handle_proc)(nfs41_upcall*);
  2230. +typedef int (*upcall_handle_proc)(void*, nfs41_upcall*);
  2231.  typedef int (*upcall_marshall_proc)(unsigned char*, uint32_t*, nfs41_upcall*);
  2232.  typedef void (*upcall_cancel_proc)(nfs41_upcall*);
  2233.  typedef void (*upcall_cleanup_proc)(nfs41_upcall*);
  2234. @@ -236,6 +236,7 @@ int upcall_parse(
  2235.      OUT nfs41_upcall *upcall);
  2236.  
  2237.  int upcall_handle(
  2238. +    IN void *daemon_context,
  2239.      IN nfs41_upcall *upcall);
  2240.  
  2241.  void upcall_marshall(
  2242. diff --git a/daemon/volume.c b/daemon/volume.c
  2243. index 3c6381f..d23c68a 100644
  2244. --- a/daemon/volume.c
  2245. +++ b/daemon/volume.c
  2246. @@ -112,7 +112,7 @@ out:
  2247.      return status;
  2248.  }
  2249.  
  2250. -static int handle_volume(nfs41_upcall *upcall)
  2251. +static int handle_volume(void *daemon_context, nfs41_upcall *upcall)
  2252.  {
  2253.      volume_upcall_args *args = &upcall->args.volume;
  2254.      int status = NO_ERROR;
  2255. diff --git a/libtirpc/src/auth_unix.c b/libtirpc/src/auth_unix.c
  2256. index ca8c908..8261b9e 100644
  2257. --- a/libtirpc/src/auth_unix.c
  2258. +++ b/libtirpc/src/auth_unix.c
  2259. @@ -213,10 +213,13 @@ authunix_create_default()
  2260.                 abort();
  2261.  #else
  2262.         // XXX Need to figure out what to do here!
  2263. -       uid = 666;
  2264. -       gid = 777;
  2265. +       uid = 10666;
  2266. +       gid = 10777;
  2267.         gids[0] = 0;
  2268.         len = 0;
  2269. +        (void)fprintf(stderr, "authunix_create_default(): fixme, "
  2270. +            "do not know what do to, returning fake uid=%d/gid=%d",
  2271. +            (int)uid, (int)gid);
  2272.  #endif
  2273.         /* XXX: interface problem; those should all have been unsigned */
  2274.         return (authunix_create(machname, uid, gid, len, gids));
  2275. diff --git a/sys/nfs41_build_features.h b/sys/nfs41_build_features.h
  2276. index f8ea548..93ee7a9 100644
  2277. --- a/sys/nfs41_build_features.h
  2278. +++ b/sys/nfs41_build_features.h
  2279. @@ -33,7 +33,6 @@
  2280.   * NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES - return local uid/gid values
  2281.   */
  2282.  // #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_IN_NFSV3ATTRIBUTES 1
  2283. -// #define NFS41_DRIVER_FEATURE_LOCAL_UIDGID_TESTMAPPING 1
  2284.  
  2285.  /*
  2286.   * NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID - give NFS
  2287. @@ -42,4 +41,10 @@
  2288.   */
  2289.  // #define NFS41_DRIVER_FEATURE_MAP_UNMAPPED_USER_TO_UNIXUSER_SID 1
  2290.  
  2291. +/*
  2292. + * NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN - use Cygwin /usr/bin/getent
  2293. + * as "name service"
  2294. + */
  2295. +// #define NFS41_DRIVER_FEATURE_NAMESERVICE_CYGWIN 1
  2296. +
  2297.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */
  2298. --
  2299. 2.39.0

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