Difference between
modified post c9d5a1 by Anonymous on Sat 29th Jun 2024 15:18
original post fa143 by Anonymous on Thu 27th Jun 2024 15:48
Download diff
Show
old version |
new version |
both versions
| 1 | 1 | diff --git a/daemon/acl.c b/daemon/acl.c | |
| 2 | - | index 331fc8e..474a170 100644 | |
| 2 | + | index 331fc8e..22cc33f 100644 | |
| 3 | 3 | --- a/daemon/acl.c | |
| 4 | 4 | +++ b/daemon/acl.c | |
| 5 | - | @@ -1026,7 +1026,7 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 5 | + | @@ -117,7 +117,7 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 6 | - | } | |
| 6 | + | bool named_attr_support) | |
| 7 | - | nfs4_acl->aces->aceflag = 0; | |
| 7 | + | { | |
| 8 | - | } else { | |
| 8 | + | int status = ERROR_NOT_SUPPORTED, size = 0; | |
| 9 | - | - int i; | |
| 9 | + | - uint32_t i; | |
| 10 | - | + int win_i, nfs_i; | |
| 10 | + | + uint32_t nfs_i = 0, win_i = 0; | |
| 11 | - | PACE_HEADER ace; | |
| 11 | + | DWORD sid_len; | |
| 12 | - | PBYTE tmp_pointer; | |
| 12 | + | PSID *sids; | |
| 13 | - | SID_NAME_USE who_sid_type = 0; | |
| 13 | + | PACL dacl; | |
| 14 | - | @@ -1037,15 +1037,18 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 14 | + | @@ -129,42 +129,71 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 15 | - | print_hexbuf_no_asci("ACL\n", | |
| 15 | + | acl, map_nfs_ftype2str(file_type), file_type, | |
| 16 | - | (const unsigned char *)acl, acl->AclSize); | |
| 16 | + | (int)named_attr_support)); | |
| 17 | - | } | |
| 17 | + | ||
| 18 | - | - nfs4_acl->count = acl->AceCount; | |
| 18 | + | - sids = malloc(acl->count * sizeof(PSID)); | |
| 19 | - | - nfs4_acl->aces = calloc(nfs4_acl->count, sizeof(nfsace4)); | |
| 19 | + | + bool *skip_aces = _alloca(acl->count * sizeof(bool)); | |
| 20 | 20 | + | |
| 21 | - | + nfs4_acl->aces = calloc(acl->AceCount, sizeof(nfsace4)); | |
| 21 | + | + /* | |
| 22 | - | if (nfs4_acl->aces == NULL) { | |
| 22 | + | + * We use |calloc()| here to get |NULL| pointer for unallocated | |
| 23 | + | + * slots in case of error codepaths below... | |
| 23 | 27 | status = GetLastError(); | |
| 24 | 28 | goto out; | |
| 25 | 29 | } | |
| 26 | - | nfs4_acl->flag = 0; | |
| 30 | + | - for (i = 0; i < acl->count; i++) { | |
| 27 | - | - for (i = 0; i < acl->AceCount; i++) { | |
| 31 | + | - convert_nfs4name_2_user_domain(acl->aces[i].who, &domain); | |
| 28 | - | - status = GetAce(acl, i, &ace); | |
| 32 | + | + for (nfs_i = win_i = 0; nfs_i < acl->count; nfs_i++) { | |
| 29 | - | + for (win_i = nfs_i = 0; win_i < acl->AceCount; win_i++) { | |
| 33 | + | + nfsace4 *curr_nfsace = &acl->aces[nfs_i]; | |
| 32 | 34 | + | |
| 33 | - | + status = GetAce(acl, win_i, &ace); | |
| 35 | + | + skip_aces[nfs_i] = false; | |
| 34 | - | if (!status) { | |
| 36 | + | + | |
| 35 | - | status = GetLastError(); | |
| 37 | + | + convert_nfs4name_2_user_domain(curr_nfsace->who, &domain); | |
| 36 | - | eprintf("map_dacl_2_nfs4acl: GetAce failed with %d\n", status); | |
| 38 | + | DPRINTF(ACLLVL2, ("convert_nfs4acl_2_dacl: for user='%s' domain='%s'\n", | |
| 37 | - | @@ -1058,9 +1061,9 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 39 | + | - acl->aces[i].who, domain?domain:"<null>")); | |
| 38 | - | } | |
| 40 | + | - status = check_4_special_identifiers(acl->aces[i].who, &sids[i], | |
| 39 | - | DPRINTF(ACLLVL3, ("ACE TYPE: %x\n", ace->AceType)); | |
| 41 | + | + curr_nfsace->who, domain?domain:"<null>")); | |
| 40 | - | if (ace->AceType == ACCESS_ALLOWED_ACE_TYPE) | |
| 42 | + | + | |
| 41 | - | - nfs4_acl->aces[i].acetype = ACE4_ACCESS_ALLOWED_ACE_TYPE; | |
| 43 | + | +#ifdef NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES | |
| 42 | - | + curr_nfsace->acetype = ACE4_ACCESS_ALLOWED_ACE_TYPE; | |
| 44 | + | + /* | |
| 43 | - | else if (ace->AceType == ACCESS_DENIED_ACE_TYPE) | |
| 45 | + | + * Skip "nobody" ACEs - Cygwin uses |WinNullSid| ACEs (mapped | |
| 44 | - | - nfs4_acl->aces[i].acetype = ACE4_ACCESS_DENIED_ACE_TYPE; | |
| 46 | + | + * to NFS user "nobody") to store special data. | |
| 45 | - | + curr_nfsace->acetype = ACE4_ACCESS_DENIED_ACE_TYPE; | |
| 47 | + | + * We skip these here, because we cannot use them, as Linux nfsd | |
| 46 | - | else { | |
| 48 | + | + * only supports POSIX ACLs translated to NFSv4 ACLs, which | |
| 47 | - | eprintf("map_dacl_2_nfs4acl: unsupported ACE type %d\n", | |
| 49 | + | + * corrupts the Cygwin data. | |
| 48 | - | ace->AceType); | |
| 50 | + | + */ | |
| 49 | - | @@ -1069,8 +1072,40 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 51 | + | + if (!strcmp(curr_nfsace->who, ACE4_NOBODY)) { | |
| 50 | - | } | |
| 52 | + | + DPRINTF(ACLLVL3, ("Skipping 'nobody' ACE, " | |
| 51 | - | ||
| 53 | + | + "win_i=%d nfs_i=%d\n", (int)win_i, (int)nfs_i)); | |
| 52 | - | tmp_pointer += sizeof(ACCESS_MASK) + sizeof(ACE_HEADER); | |
| 54 | + | + skip_aces[nfs_i] = true; | |
| 53 | - | + ace_sid = tmp_pointer; | |
| 55 | + | + continue; | |
| 56 | + | + } | |
| 54 | 58 | + | |
| 55 | - | +#ifdef NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES | |
| 59 | + | + status = check_4_special_identifiers(curr_nfsace->who, &sids[win_i], | |
| 56 | - | + if (IsWellKnownSid(ace_sid, WinNullSid)) { | |
| 60 | + | &sid_len, &flag); | |
| 57 | - | + /* | |
| 61 | + | if (status) { | |
| 58 | - | + * Skip ACEs with SID==|WinNullSid| | |
| 62 | + | - free_sids(sids, i); | |
| 59 | - | + * | |
| 63 | + | + free_sids(sids, win_i); | |
| 60 | - | + * Cygwin generates artificial ACEs with SID user | |
| 64 | + | goto out; | |
| 61 | - | + * |WinNullSid| to encode permission information | |
| 65 | + | } | |
| 62 | - | + * (see |CYG_ACE_ISBITS_TO_POSIX()| in | |
| 66 | + | if (!flag) { | |
| 63 | - | + * Cygwin newlib-cygwin/winsup/cygwin/sec/acl.cc | |
| 67 | + | - bool isgroupacl = (acl->aces[i].aceflag & ACE4_IDENTIFIER_GROUP)?true:false; | |
| 64 | - | + * | |
| 68 | + | + bool isgroupacl = (curr_nfsace->aceflag & ACE4_IDENTIFIER_GROUP)?true:false; | |
| 65 | - | + * This assumes that the filesystem which stores | |
| 69 | + | ||
| 66 | - | + * the ACL data leaves them 1:1 intact - which is | |
| 70 | + | if (isgroupacl) { | |
| 67 | - | + * not the case for the Linux NFSv4.1 server | |
| 71 | + | DPRINTF(ACLLVL2, | |
| 68 | - | + * (tested with Linux 6.6.32), which transforms the | |
| 72 | + | ("convert_nfs4acl_2_dacl: aces[%d].who='%s': " | |
| 69 | - | + * NFSv4.1 ACLs into POSIX ACLs at setacl time, | |
| 73 | + | "Setting group flag\n", | |
| 70 | - | + * and the POSIX ACLs back to NFSv4 ACLs at getacl | |
| 74 | + | - i, acl->aces[i].who)); | |
| 71 | - | + * time. | |
| 75 | + | + nfs_i, curr_nfsace->who)); | |
| 72 | - | + * And this lossy transformation screws-up Cygwin | |
| 76 | + | } | |
| 73 | - | + * completly. | |
| 77 | + | ||
| 74 | - | + * The best we can do for now is to skip such | |
| 78 | + | status = map_nfs4servername_2_sid(nfs41dg, | |
| 75 | - | + * ACEs, as we have no way to detect whether | |
| 79 | + | (isgroupacl?GROUP_SECURITY_INFORMATION:OWNER_SECURITY_INFORMATION), | |
| 76 | - | + * the NFS server supports full NFSv4 ACLs, or | |
| 80 | + | - &sid_len, &sids[i], acl->aces[i].who); | |
| 77 | - | + * only POSIX ACLs disguised as NFSv4 ACLs. | |
| 81 | + | + &sid_len, &sids[win_i], curr_nfsace->who); | |
| 78 | - | + */ | |
| 82 | + | if (status) { | |
| 79 | - | + DPRINTF(ACLLVL3, ("Skipping WinNullSid ACE, " | |
| 83 | + | - free_sids(sids, i); | |
| 80 | - | + "win_i=%d nfs_i=%d\n", (int)win_i, (int)nfs_i)); | |
| 84 | + | + free_sids(sids, win_i); | |
| 81 | - | + continue; | |
| 85 | + | goto out; | |
| 82 | - | + } | |
| 86 | + | } | |
| 83 | - | +#endif /* NFS41_DRIVER_ACLS_SETACL_SKIP_WINNULLSID_ACES */ | |
| 87 | + | } | |
| 84 | - | ||
| 88 | + | size += sid_len - sizeof(DWORD); | |
| 85 | - | - status = map_nfs4ace_who(tmp_pointer, sid, gsid, nfs4_acl->aces[i].who, | |
| 89 | + | + | |
| 86 | - | + status = map_nfs4ace_who(ace_sid, sid, gsid, | |
| 90 | + | + win_i++; | |
| 87 | - | + curr_nfsace->who, | |
| 91 | + | } | |
| 88 | - | domain, &who_sid_type); | |
| 92 | + | - size += sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)*acl->count); | |
| 89 | - | if (status) | |
| 93 | + | + size += sizeof(ACL) + (sizeof(ACCESS_ALLOWED_ACE)*win_i); | |
| 90 | - | goto out_free; | |
| 94 | + | size = align8(size); // align size on |DWORD| boundry | |
| 91 | - | @@ -1078,10 +1113,10 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 95 | + | dacl = malloc(size); | |
| 92 | - | win_mask = *(PACCESS_MASK)(ace + 1); | |
| 96 | + | if (dacl == NULL) | |
| 97 | + | @@ -174,10 +203,15 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 93 | 100 | ||
| 94 | - | map_winace2nfs4aceflags(ace->AceFlags, | |
| 101 | + | - for (i = 0; i < acl->count; i++) { | |
| 95 | - | - &nfs4_acl->aces[i].aceflag); | |
| 102 | + | - map_nfs4aceflags2winaceflags(acl->aces[i].aceflag, | |
| 96 | - | + &curr_nfsace->aceflag); | |
| 103 | + | + for (nfs_i = win_i = 0; nfs_i < acl->count; nfs_i++) { | |
| 97 | - | map_winaccessmask2nfs4acemask(win_mask, | |
| 104 | + | + nfsace4 *curr_nfsace = &acl->aces[nfs_i]; | |
| 98 | - | file_type, named_attr_support, | |
| 105 | + | + | |
| 99 | - | - &nfs4_acl->aces[i].acemask); | |
| 106 | + | + if (skip_aces[nfs_i]) | |
| 100 | - | + &curr_nfsace->acemask); | |
| 107 | + | + continue; | |
| 108 | + | + | |
| 101 | 114 | ||
| 102 | - | /* | |
| 115 | + | if (DPRINTF_LEVEL_ENABLED(ACLLVL1)) { | |
| 103 | - | * Clear |ACE4_INHERITED_ACE| | |
| 116 | + | @@ -185,19 +219,20 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 104 | - | @@ -1104,8 +1139,8 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 117 | + | "acetype='%s', " | |
| 105 | - | * icacls(1win) if the parent directory has inheritance | |
| 118 | + | "nfs_acemask=0x%lx, win_mask=0x%lx, " | |
| 106 | - | * ACLs. | |
| 119 | + | "win_aceflags=0x%lx\n", | |
| 107 | - | */ | |
| 120 | + | - i, acl->aces[i].who, | |
| 108 | - | - if (nfs4_acl->aces[i].aceflag & ACE4_INHERITED_ACE) { | |
| 121 | + | - map_nfs_acetype2str(acl->aces[i].acetype), | |
| 109 | - | - nfs4_acl->aces[i].aceflag &= ~ACE4_INHERITED_ACE; | |
| 122 | + | - (long)acl->aces[i].acemask, | |
| 110 | - | + if (curr_nfsace->aceflag & ACE4_INHERITED_ACE) { | |
| 123 | + | + nfs_i, curr_nfsace->who, | |
| 111 | - | + curr_nfsace->aceflag &= ~ACE4_INHERITED_ACE; | |
| 124 | + | + map_nfs_acetype2str(curr_nfsace->acetype), | |
| 112 | - | DPRINTF(ACLLVL3, ("clearning ACE4_INHERITED_ACE\n")); | |
| 125 | + | + (long)curr_nfsace->acemask, | |
| 126 | + | (long)mask, | |
| 114 | 128 | ||
| 115 | - | @@ -1125,8 +1160,8 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 129 | + | - print_nfs_access_mask(acl->aces[i].who, | |
| 116 | - | "aces[%d].who='%s': " | |
| 130 | + | - acl->aces[i].acemask); | |
| 117 | - | "setting group flag\n", | |
| 131 | + | - print_windows_access_mask(acl->aces[i].who, mask); | |
| 118 | - | map_SID_NAME_USE2str(who_sid_type), | |
| 132 | + | + print_nfs_access_mask(curr_nfsace->who, | |
| 119 | - | - i, nfs4_acl->aces[i].who)); | |
| 133 | + | + curr_nfsace->acemask); | |
| 120 | - | - nfs4_acl->aces[i].aceflag |= ACE4_IDENTIFIER_GROUP; | |
| 134 | + | + print_windows_access_mask(curr_nfsace->who, mask); | |
| 123 | 135 | } | |
| 124 | 136 | ||
| 125 | - | if (DPRINTF_LEVEL_ENABLED(ACLLVL1)) { | |
| 137 | + | - if (acl->aces[i].acetype == ACE4_ACCESS_ALLOWED_ACE_TYPE) { | |
| 126 | - | @@ -1134,24 +1169,30 @@ static int map_dacl_2_nfs4acl(PACL acl, PSID sid, PSID gsid, nfsacl41 *nfs4_acl, | |
| 138 | + | - status = AddAccessAllowedAceEx(dacl, ACL_REVISION, win_aceflags, mask, sids[i]); | |
| 127 | - | "acetype='%s', " | |
| 139 | + | + if (curr_nfsace->acetype == ACE4_ACCESS_ALLOWED_ACE_TYPE) { | |
| 128 | - | "aceflag='%s'/0x%lx, " | |
| 140 | + | + status = AddAccessAllowedAceEx(dacl, ACL_REVISION, | |
| 129 | - | "acemask='%s'/0x%lx(=win_mask=0x%lx)), " | |
| 141 | + | + win_aceflags, mask, sids[win_i]); | |
| 130 | - | - "who_sid_type='%s'\n", | |
| 142 | + | if (!status) { | |
| 131 | - | - i, | |
| 143 | + | eprintf("convert_nfs4acl_2_dacl: " | |
| 132 | - | - nfs4_acl->aces[i].who, | |
| 144 | + | "AddAccessAllowedAceEx(dacl=0x%p,win_aceflags=0x%x,mask=0x%x) failed " | |
| 133 | - | - map_nfs_acetype2str(nfs4_acl->aces[i].acetype), | |
| 145 | + | @@ -206,8 +241,9 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 134 | - | - nfs_aceflag2shortname(nfs4_acl->aces[i].aceflag), | |
| 146 | + | goto out_free_dacl; | |
| 135 | - | - nfs4_acl->aces[i].aceflag, | |
| 147 | + | } | |
| 136 | - | - nfs_mask2shortname(nfs4_acl->aces[i].acemask), | |
| 148 | + | else status = ERROR_SUCCESS; | |
| 137 | - | - (long)nfs4_acl->aces[i].acemask, | |
| 149 | + | - } else if (acl->aces[i].acetype == ACE4_ACCESS_DENIED_ACE_TYPE) { | |
| 138 | - | + "who_sid_type='%s', " | |
| 150 | + | - status = AddAccessDeniedAceEx(dacl, ACL_REVISION, win_aceflags, mask, sids[i]); | |
| 139 | - | + "win_i=%d\n", | |
| 151 | + | + } else if (curr_nfsace->acetype == ACE4_ACCESS_DENIED_ACE_TYPE) { | |
| 140 | - | + nfs_i, | |
| 152 | + | + status = AddAccessDeniedAceEx(dacl, ACL_REVISION, | |
| 141 | - | + curr_nfsace->who, | |
| 153 | + | + win_aceflags, mask, sids[win_i]); | |
| 142 | - | + map_nfs_acetype2str(curr_nfsace->acetype), | |
| 154 | + | if (!status) { | |
| 143 | - | + nfs_aceflag2shortname(curr_nfsace->aceflag), | |
| 155 | + | eprintf("convert_nfs4acl_2_dacl: " | |
| 144 | - | + curr_nfsace->aceflag, | |
| 156 | + | "AddAccessDeniedAceEx(dacl=0x%p,win_aceflags=0x%x,mask=0x%x) failed " | |
| 145 | - | + nfs_mask2shortname(curr_nfsace->acemask), | |
| 157 | + | @@ -218,12 +254,14 @@ static int convert_nfs4acl_2_dacl(nfs41_daemon_globals *nfs41dg, | |
| 146 | - | + (long)curr_nfsace->acemask, | |
| 158 | + | else status = ERROR_SUCCESS; | |
| 147 | - | (long)win_mask, | |
| 159 | + | } else { | |
| 148 | - | - map_SID_NAME_USE2str(who_sid_type)); | |
| 160 | + | eprintf("convert_nfs4acl_2_dacl: unknown acetype %d\n", | |
| 149 | - | + map_SID_NAME_USE2str(who_sid_type), | |
| 161 | + | - acl->aces[i].acetype); | |
| 150 | - | + (int)win_i); | |
| 162 | + | + curr_nfsace->acetype); | |
| 151 | - | if (DPRINTF_LEVEL_ENABLED(ACLLVL2)) { | |
| 163 | + | status = ERROR_INTERNAL_ERROR; | |
| 152 | - | - print_windows_access_mask(nfs4_acl->aces[i].who, | |
| 164 | + | free(dacl); | |
| 153 | - | + print_windows_access_mask(curr_nfsace->who, | |
| 165 | + | - free_sids(sids, acl->count); | |
| 154 | - | win_mask); | |
| 166 | + | + free_sids(sids, win_i); | |
| 155 | - | - print_nfs_access_mask(nfs4_acl->aces[i].who, | |
| 167 | + | goto out; | |
| 159 | 168 | } | |
| 169 | + | + |
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.
nrubsig.kpaste.net RSS