pastebin - collaborative debugging tool
nrubsig.kpaste.net RSS


ACL work backup 2024-06-27
Posted by Anonymous on Sat 29th Jun 2024 15:18
raw | new post
modification of post by Anonymous (view diff)

  1. diff --git a/daemon/acl.c b/daemon/acl.c
  2. index 331fc8e..22cc33f 100644
  3. --- a/daemon/acl.c
  4. +++ b/daemon/acl.c
  5. @@ -117,7 +117,7 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  6.      bool named_attr_support)
  7.  {
  8.      int status = ERROR_NOT_SUPPORTED, size = 0;
  9. -    uint32_t i;
  10. +    uint32_t nfs_i = 0, win_i = 0;
  11.      DWORD sid_len;
  12.      PSID *sids;
  13.      PACL dacl;
  14. @@ -129,42 +129,71 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  15.          acl, map_nfs_ftype2str(file_type), file_type,
  16.          (int)named_attr_support));
  17.  
  18. -    sids = malloc(acl->count * sizeof(PSID));
  19. +    bool *skip_aces = _alloca(acl->count * sizeof(bool));
  20. +
  21. +    /*
  22. +     * We use |calloc()| here to get |NULL| pointer for unallocated
  23. +     * slots in case of error codepaths below...
  24. +     */
  25. +    sids = calloc(acl->count, sizeof(PSID));
  26.      if (sids == NULL) {
  27.          status = GetLastError();
  28.          goto out;
  29.      }
  30. -    for (i = 0; i < acl->count; i++) {
  31. -        convert_nfs4name_2_user_domain(acl->aces[i].who, &domain);
  32. +    for (nfs_i = win_i = 0; nfs_i < acl->count; nfs_i++) {
  33. +        nfsace4 *curr_nfsace = &acl->aces[nfs_i];
  34. +
  35. +        skip_aces[nfs_i] = false;
  36. +
  37. +        convert_nfs4name_2_user_domain(curr_nfsace->who, &domain);
  38.          DPRINTF(ACLLVL2, ("convert_nfs4acl_2_dacl: for user='%s' domain='%s'\n",
  39. -                acl->aces[i].who, domain?domain:"<null>"));
  40. -        status = check_4_special_identifiers(acl->aces[i].who, &sids[i],
  41. +                curr_nfsace->who, domain?domain:"<null>"));
  42. +
  43. +#ifdef NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES
  44. +        /*
  45. +         * Skip "nobody" ACEs - Cygwin uses |WinNullSid| ACEs (mapped
  46. +         * to NFS user "nobody") to store special data.
  47. +         * We skip these here, because we cannot use them, as Linux nfsd
  48. +         * only supports POSIX ACLs translated to NFSv4 ACLs, which
  49. +         * corrupts the Cygwin data.
  50. +         */
  51. +        if (!strcmp(curr_nfsace->who, ACE4_NOBODY)) {
  52. +            DPRINTF(ACLLVL3, ("Skipping 'nobody' ACE, "
  53. +                "win_i=%d nfs_i=%d\n", (int)win_i, (int)nfs_i));
  54. +            skip_aces[nfs_i] = true;
  55. +            continue;
  56. +        }
  57. +#endif /* NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES */
  58. +
  59. +        status = check_4_special_identifiers(curr_nfsace->who, &sids[win_i],
  60.                                               &sid_len, &flag);
  61.          if (status) {
  62. -            free_sids(sids, i);
  63. +            free_sids(sids, win_i);
  64.              goto out;
  65.          }
  66.          if (!flag) {
  67. -            bool isgroupacl = (acl->aces[i].aceflag & ACE4_IDENTIFIER_GROUP)?true:false;
  68. +            bool isgroupacl = (curr_nfsace->aceflag & ACE4_IDENTIFIER_GROUP)?true:false;
  69.  
  70.              if (isgroupacl) {
  71.                  DPRINTF(ACLLVL2,
  72.                      ("convert_nfs4acl_2_dacl: aces[%d].who='%s': "
  73.                      "Setting group flag\n",
  74. -                    i, acl->aces[i].who));
  75. +                    nfs_i, curr_nfsace->who));
  76.              }
  77.  
  78.              status = map_nfs4servername_2_sid(nfs41dg,
  79.                  (isgroupacl?GROUP_SECURITY_INFORMATION:OWNER_SECURITY_INFORMATION),
  80. -                &sid_len, &sids[i], acl->aces[i].who);
  81. +                &sid_len, &sids[win_i], curr_nfsace->who);
  82.              if (status) {
  83. -                free_sids(sids, i);
  84. +                free_sids(sids, win_i);
  85.                  goto out;
  86.              }
  87.          }
  88.          size += sid_len - sizeof(DWORD);
  89. +
  90. +        win_i++;
  91.      }
  92. -    size += sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)*acl->count);
  93. +    size += sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)*win_i);
  94.      size = align8(size); // align size on |DWORD| boundry
  95.      dacl = malloc(size);
  96.      if (dacl == NULL)
  97. @@ -174,10 +203,15 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  98.          ACCESS_MASK mask;
  99.          DWORD win_aceflags;
  100.  
  101. -        for (i = 0; i < acl->count; i++) {
  102. -            map_nfs4aceflags2winaceflags(acl->aces[i].aceflag,
  103. +        for (nfs_i = win_i = 0; nfs_i < acl->count; nfs_i++) {
  104. +            nfsace4 *curr_nfsace = &acl->aces[nfs_i];
  105. +
  106. +            if (skip_aces[nfs_i])
  107. +                continue;
  108. +
  109. +            map_nfs4aceflags2winaceflags(curr_nfsace->aceflag,
  110.                  &win_aceflags);
  111. -            map_nfs4acemask2winaccessmask(acl->aces[i].acemask,
  112. +            map_nfs4acemask2winaccessmask(curr_nfsace->acemask,
  113.                  file_type, named_attr_support, &mask);
  114.  
  115.              if (DPRINTF_LEVEL_ENABLED(ACLLVL1)) {
  116. @@ -185,19 +219,20 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  117.                      "acetype='%s', "
  118.                      "nfs_acemask=0x%lx, win_mask=0x%lx, "
  119.                      "win_aceflags=0x%lx\n",
  120. -                    i, acl->aces[i].who,
  121. -                    map_nfs_acetype2str(acl->aces[i].acetype),
  122. -                    (long)acl->aces[i].acemask,
  123. +                    nfs_i, curr_nfsace->who,
  124. +                    map_nfs_acetype2str(curr_nfsace->acetype),
  125. +                    (long)curr_nfsace->acemask,
  126.                      (long)mask,
  127.                      (long)win_aceflags);
  128.  
  129. -                print_nfs_access_mask(acl->aces[i].who,
  130. -                    acl->aces[i].acemask);
  131. -                print_windows_access_mask(acl->aces[i].who, mask);
  132. +                print_nfs_access_mask(curr_nfsace->who,
  133. +                    curr_nfsace->acemask);
  134. +                print_windows_access_mask(curr_nfsace->who, mask);
  135.              }
  136.  
  137. -            if (acl->aces[i].acetype == ACE4_ACCESS_ALLOWED_ACE_TYPE) {
  138. -                status = AddAccessAllowedAceEx(dacl, ACL_REVISION, win_aceflags, mask, sids[i]);
  139. +            if (curr_nfsace->acetype == ACE4_ACCESS_ALLOWED_ACE_TYPE) {
  140. +                status = AddAccessAllowedAceEx(dacl, ACL_REVISION,
  141. +                    win_aceflags, mask, sids[win_i]);
  142.                  if (!status) {
  143.                      eprintf("convert_nfs4acl_2_dacl: "
  144.                          "AddAccessAllowedAceEx(dacl=0x%p,win_aceflags=0x%x,mask=0x%x) failed "
  145. @@ -206,8 +241,9 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  146.                      goto out_free_dacl;
  147.                  }
  148.                  else status = ERROR_SUCCESS;
  149. -            } else if (acl->aces[i].acetype == ACE4_ACCESS_DENIED_ACE_TYPE) {
  150. -                status = AddAccessDeniedAceEx(dacl, ACL_REVISION, win_aceflags, mask, sids[i]);
  151. +            } else if (curr_nfsace->acetype == ACE4_ACCESS_DENIED_ACE_TYPE) {
  152. +                status = AddAccessDeniedAceEx(dacl, ACL_REVISION,
  153. +                    win_aceflags, mask, sids[win_i]);
  154.                  if (!status) {
  155.                      eprintf("convert_nfs4acl_2_dacl: "
  156.                          "AddAccessDeniedAceEx(dacl=0x%p,win_aceflags=0x%x,mask=0x%x) failed "
  157. @@ -218,12 +254,14 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg,
  158.                  else status = ERROR_SUCCESS;
  159.              } else {
  160.                  eprintf("convert_nfs4acl_2_dacl: unknown acetype %d\n",
  161. -                        acl->aces[i].acetype);
  162. +                        curr_nfsace->acetype);
  163.                  status = ERROR_INTERNAL_ERROR;
  164.                  free(dacl);
  165. -                free_sids(sids, acl->count);
  166. +                free_sids(sids, win_i);
  167.                  goto out;
  168.              }
  169. +
  170. +            win_i++;
  171.          }
  172.      } else {
  173.          eprintf("convert_nfs4acl_2_dacl: InitializeAcl failed with %d\n", status);
  174. @@ -240,7 +278,7 @@ out:
  175.  out_free_dacl:
  176.      free(dacl);
  177.  out_free_sids:
  178. -    free_sids(sids, acl->count);
  179. +    free_sids(sids, win_i);
  180.      status = GetLastError();
  181.      goto out;
  182.  }
  183. @@ -1026,7 +1064,7 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  184.          }
  185.          nfs4_acl->aces->aceflag = 0;
  186.      } else {
  187. -        int i;
  188. +        int win_i, nfs_i;
  189.          PACE_HEADER ace;
  190.          PBYTE tmp_pointer;
  191.          SID_NAME_USE who_sid_type = 0;
  192. @@ -1037,15 +1075,18 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  193.              print_hexbuf_no_asci("ACL\n",
  194.                  (const unsigned char *)acl, acl->AclSize);
  195.          }
  196. -        nfs4_acl->count = acl->AceCount;
  197. -        nfs4_acl->aces = calloc(nfs4_acl->count, sizeof(nfsace4));
  198. +
  199. +        nfs4_acl->aces = calloc(acl->AceCount, sizeof(nfsace4));
  200.          if (nfs4_acl->aces == NULL) {
  201.              status = GetLastError();
  202.              goto out;
  203.          }
  204.          nfs4_acl->flag = 0;
  205. -        for (i = 0; i < acl->AceCount; i++) {
  206. -            status = GetAce(acl, i, &ace);
  207. +        for (win_i = nfs_i = 0; win_i < acl->AceCount; win_i++) {
  208. +            nfsace4 *curr_nfsace = &nfs4_acl->aces[nfs_i];
  209. +            PSID ace_sid;
  210. +
  211. +            status = GetAce(acl, win_i, &ace);
  212.              if (!status) {
  213.                  status = GetLastError();
  214.                  eprintf("map_dacl_2_nfs4acl: GetAce failed with %d\n", status);
  215. @@ -1058,9 +1099,9 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  216.              }
  217.              DPRINTF(ACLLVL3, ("ACE TYPE: %x\n", ace->AceType));
  218.              if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE)
  219. -                nfs4_acl->aces[i].acetype = ACE4_ACCESS_ALLOWED_ACE_TYPE;
  220. +                curr_nfsace->acetype = ACE4_ACCESS_ALLOWED_ACE_TYPE;
  221.              else if (ace->AceType == ACCESS_DENIED_ACE_TYPE)
  222. -                nfs4_acl->aces[i].acetype = ACE4_ACCESS_DENIED_ACE_TYPE;
  223. +                curr_nfsace->acetype = ACE4_ACCESS_DENIED_ACE_TYPE;
  224.              else {
  225.                  eprintf("map_dacl_2_nfs4acl: unsupported ACE type %d\n",
  226.                      ace->AceType);
  227. @@ -1069,8 +1110,40 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  228.              }
  229.  
  230.              tmp_pointer += sizeof(ACCESS_MASK) + sizeof(ACE_HEADER);
  231. +            ace_sid = tmp_pointer;
  232.  
  233. -            status = map_nfs4ace_who(tmp_pointer, sid, gsid, nfs4_acl->aces[i].who,
  234. +#ifdef NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES
  235. +            if (IsWellKnownSid(ace_sid, WinNullSid)) {
  236. +                /*
  237. +                 * Skip ACEs with SID==|WinNullSid|
  238. +                 *
  239. +                 * Cygwin generates artificial ACEs with SID user
  240. +                 * |WinNullSid| to encode permission information
  241. +                 * (see |CYG_ACE_ISBITS_TO_POSIX()| in
  242. +                 * Cygwin newlib-cygwin/winsup/cygwin/sec/acl.cc
  243. +                 *
  244. +                 * This assumes that the filesystem which stores
  245. +                 * the ACL data leaves them 1:1 intact - which is
  246. +                 * not the case for the Linux NFSv4.1 server
  247. +                 * (tested with Linux 6.6.32), which transforms the
  248. +                 * NFSv4.1 ACLs into POSIX ACLs at setacl time,
  249. +                 * and the POSIX ACLs back to NFSv4 ACLs at getacl
  250. +                 * time.
  251. +                 * And this lossy transformation screws-up Cygwin
  252. +                 * completly.
  253. +                 * The best we can do for now is to skip such
  254. +                 * ACEs, as we have no way to detect whether
  255. +                 * the NFS server supports full NFSv4 ACLs, or
  256. +                 * only POSIX ACLs disguised as NFSv4 ACLs.
  257. +                 */
  258. +                DPRINTF(ACLLVL3, ("Skipping WinNullSid ACE, "
  259. +                    "win_i=%d nfs_i=%d\n", (int)win_i, (int)nfs_i));
  260. +                continue;
  261. +            }
  262. +#endif /* NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES */
  263. +
  264. +            status = map_nfs4ace_who(ace_sid, sid, gsid,
  265. +                curr_nfsace->who,
  266.                  domain, &who_sid_type);
  267.              if (status)
  268.                  goto out_free;
  269. @@ -1078,10 +1151,10 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  270.              win_mask = *(PACCESS_MASK)(ace + 1);
  271.  
  272.              map_winace2nfs4aceflags(ace->AceFlags,
  273. -                &nfs4_acl->aces[i].aceflag);
  274. +                &curr_nfsace->aceflag);
  275.              map_winaccessmask2nfs4acemask(win_mask,
  276.                  file_type, named_attr_support,
  277. -                &nfs4_acl->aces[i].acemask);
  278. +                &curr_nfsace->acemask);
  279.  
  280.              /*
  281.               * Clear |ACE4_INHERITED_ACE|
  282. @@ -1104,8 +1177,8 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  283.               * icacls(1win) if the parent directory has inheritance
  284.               * ACLs.
  285.               */
  286. -            if (nfs4_acl->aces[i].aceflag & ACE4_INHERITED_ACE) {
  287. -                nfs4_acl->aces[i].aceflag &= ~ACE4_INHERITED_ACE;
  288. +            if (curr_nfsace->aceflag & ACE4_INHERITED_ACE) {
  289. +                curr_nfsace->aceflag &= ~ACE4_INHERITED_ACE;
  290.                  DPRINTF(ACLLVL3, ("clearning ACE4_INHERITED_ACE\n"));
  291.              }
  292.  
  293. @@ -1125,8 +1198,8 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  294.                      "aces[%d].who='%s': "
  295.                      "setting group flag\n",
  296.                      map_SID_NAME_USE2str(who_sid_type),
  297. -                    i, nfs4_acl->aces[i].who));
  298. -                nfs4_acl->aces[i].aceflag |= ACE4_IDENTIFIER_GROUP;
  299. +                    nfs_i, curr_nfsace->who));
  300. +                curr_nfsace->aceflag |= ACE4_IDENTIFIER_GROUP;
  301.              }
  302.  
  303.              if (DPRINTF_LEVEL_ENABLED(ACLLVL1)) {
  304. @@ -1134,24 +1207,30 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl,
  305.                      "acetype='%s', "
  306.                      "aceflag='%s'/0x%lx, "
  307.                      "acemask='%s'/0x%lx(=win_mask=0x%lx)), "
  308. -                    "who_sid_type='%s'\n",
  309. -                    i,
  310. -                    nfs4_acl->aces[i].who,
  311. -                    map_nfs_acetype2str(nfs4_acl->aces[i].acetype),
  312. -                    nfs_aceflag2shortname(nfs4_acl->aces[i].aceflag),
  313. -                    nfs4_acl->aces[i].aceflag,
  314. -                    nfs_mask2shortname(nfs4_acl->aces[i].acemask),
  315. -                    (long)nfs4_acl->aces[i].acemask,
  316. +                    "who_sid_type='%s', "
  317. +                    "win_i=%d\n",
  318. +                    nfs_i,
  319. +                    curr_nfsace->who,
  320. +                    map_nfs_acetype2str(curr_nfsace->acetype),
  321. +                    nfs_aceflag2shortname(curr_nfsace->aceflag),
  322. +                    curr_nfsace->aceflag,
  323. +                    nfs_mask2shortname(curr_nfsace->acemask),
  324. +                    (long)curr_nfsace->acemask,
  325.                      (long)win_mask,
  326. -                    map_SID_NAME_USE2str(who_sid_type));
  327. +                    map_SID_NAME_USE2str(who_sid_type),
  328. +                    (int)win_i);
  329.                  if (DPRINTF_LEVEL_ENABLED(ACLLVL2)) {
  330. -                    print_windows_access_mask(nfs4_acl->aces[i].who,
  331. +                    print_windows_access_mask(curr_nfsace->who,
  332.                          win_mask);
  333. -                    print_nfs_access_mask(nfs4_acl->aces[i].who,
  334. -                        nfs4_acl->aces[i].acemask);
  335. +                    print_nfs_access_mask(curr_nfsace->who,
  336. +                        curr_nfsace->acemask);
  337.                  }
  338.              }
  339. +
  340. +            nfs_i++;
  341.          }
  342. +
  343. +        nfs4_acl->count = nfs_i;
  344.      }
  345.      status = ERROR_SUCCESS;
  346.  out:
  347. diff --git a/daemon/nfs41_session.c b/daemon/nfs41_session.c
  348. index 98a2ccb..92741e7 100644
  349. --- a/daemon/nfs41_session.c
  350. +++ b/daemon/nfs41_session.c
  351. @@ -117,6 +117,9 @@ void nfs41_session_free_slot(
  352.      }
  353.      /* update highest_used if necessary */
  354.      if (slotid == table->highest_used) {
  355. +        EASSERT_MSG((table->highest_used < NFS41_MAX_NUM_SLOTS),
  356. +            ("table->highest_used=%lu\n",
  357. +            (unsigned long)table->highest_used));
  358.          while (table->highest_used && !table->used_slots[table->highest_used])
  359.              table->highest_used--;
  360.      }
  361. diff --git a/nfs41_build_features.h b/nfs41_build_features.h
  362. index 0fb2882..37c5995 100644
  363. --- a/nfs41_build_features.h
  364. +++ b/nfs41_build_features.h
  365. @@ -133,4 +133,24 @@
  366.   */
  367.  #define NFS41_DRIVER_DEBUG_FS_NAME 1
  368.  
  369. +/*
  370. + * NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES - Skip ACEs
  371. + * with SID==|WinNullSid|
  372. + *
  373. + * Cygwin generates artificial ACEs with SID user |WinNullSid| to
  374. + * encode permission information (follow |CYG_ACE_ISBITS_TO_POSIX()|
  375. + * in Cygwin newlib-cygwin/winsup/cygwin/sec/acl.cc
  376. + *
  377. + * This assumes that the filesystem which storesthe ACL data leaves
  378. + * them 1:1 intact - which is not the case for the Linux NFSv4.1
  379. + * server (tested with Linux 6.6.32), which transforms the NFSv4.1
  380. + * ACLs into POSIX ACLs at setacl time, and the POSIX ACLs back to
  381. + * NFSv4 ACLs at getacl time.
  382. + * And this lossy transformation screws-up Cygwin completly.
  383. + * The best we can do for now is to skip such ACEs, as we have no
  384. + * way to detect whether the NFS server supports full NFSv4 ACLs,
  385. + * or only POSIX ACLs disguised as NFSv4 ACLs.
  386. + */
  387. +#define NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES 1
  388. +
  389.  #endif /* !_NFS41_DRIVER_BUILDFEATURES_ */

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