I planned to use the NFS mode in the future (since apparently it can be set in ACL in Windows case - not sure about Mac) but I didn't have time to test it yet, and in any case want to get the SMB3 cifsacl enablement in first. On Fri, Oct 14, 2016 at 2:12 PM, Pavel Shilovsky <piastryyy@xxxxxxxxx> wrote: > 2016-10-14 8:10 GMT-07:00 Steve French <smfrench@xxxxxxxxx>: >> New mount option "idsfromsid" indicates to cifs.ko that >> it should try to retrieve the uid and gid owner fields >> from special sids. This patch adds the code to parse the owner >> sids in the ACL to see if they match, and if so populate the >> uid and/or gid from them. This is faster than upcalling for >> them and asking winbind, and is a fairly common case, and is >> also helpful when cifs.upcall and idmapping is not configured. >> >> Signed-off-by: Steve French <steve.french@xxxxxxxxxxxxxxx> >> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> >> --- >> fs/cifs/cifsacl.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ >> 1 file changed, 123 insertions(+) >> >> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c >> index 71e8a56..15bac39 100644 >> --- a/fs/cifs/cifsacl.c >> +++ b/fs/cifs/cifsacl.c >> @@ -42,6 +42,35 @@ >> /* group users */ >> static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; >> >> +/* S-1-22-1 Unmapped Unix users */ >> +static const struct cifs_sid sid_unix_users = {1, 1, {0, 0, 0, 0, 0, 22}, >> + {cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; >> + >> +/* S-1-22-2 Unmapped Unix groups */ >> +static const struct cifs_sid sid_unix_groups = { 1, 1, {0, 0, 0, 0, 0, 22}, >> + {cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; >> + >> +/* >> + * See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx >> + */ >> + >> +/* S-1-5-88 MS NFS and Apple style UID/GID/mode */ >> + >> +/* S-1-5-88-1 Unix uid */ >> +static const struct cifs_sid sid_unix_NFS_users = { 1, 2, {0, 0, 0, 0, 0, 5}, >> + {cpu_to_le32(88), >> + cpu_to_le32(1), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; >> + >> +/* S-1-5-88-2 Unix gid */ >> +static const struct cifs_sid sid_unix_NFS_groups = { 1, 2, {0, 0, 0, 0, 0, 5}, >> + {cpu_to_le32(88), >> + cpu_to_le32(2), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; >> + >> +/* S-1-5-88-3 Unix mode */ >> +static const struct cifs_sid sid_unix_NFS_mode = { 1, 2, {0, 0, 0, 0, 0, 5}, >> + {cpu_to_le32(88), >> + cpu_to_le32(3), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} }; >> + >> static const struct cred *root_cred; >> >> static int >> @@ -183,6 +212,62 @@ >> return 0; /* sids compare/match */ >> } >> >> +static bool >> +is_well_known_sid(const struct cifs_sid *psid, uint32_t *puid, bool is_group) >> +{ >> + int i; >> + int num_subauth; >> + const struct cifs_sid *pwell_known_sid; >> + >> + if (!psid || (puid == NULL)) >> + return false; >> + >> + num_subauth = psid->num_subauth; >> + >> + /* check if Mac (or Windows NFS) vs. Samba format for Unix owner SID */ >> + if (num_subauth == 2) { >> + if (is_group) >> + pwell_known_sid = &sid_unix_groups; >> + else >> + pwell_known_sid = &sid_unix_users; >> + } else if (num_subauth == 3) { >> + if (is_group) >> + pwell_known_sid = &sid_unix_NFS_groups; >> + else >> + pwell_known_sid = &sid_unix_NFS_users; >> + } else >> + return false; >> + >> + /* compare the revision */ >> + if (psid->revision != pwell_known_sid->revision) >> + return false; >> + >> + /* compare all of the six auth values */ >> + for (i = 0; i < NUM_AUTHS; ++i) { >> + if (psid->authority[i] != pwell_known_sid->authority[i]) { >> + cifs_dbg(FYI, "auth %d did not match\n", i); >> + return false; >> + } >> + } >> + >> + if (num_subauth == 2) { >> + if (psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) >> + return false; >> + >> + *puid = le32_to_cpu(psid->sub_auth[1]); >> + } else /* 3 subauths, ie Windows/Mac style */ { >> + *puid = le32_to_cpu(psid->sub_auth[0]); >> + if ((psid->sub_auth[0] != pwell_known_sid->sub_auth[0]) || >> + (psid->sub_auth[1] != pwell_known_sid->sub_auth[1])) >> + return false; >> + >> + *puid = le32_to_cpu(psid->sub_auth[2]); >> + } >> + >> + cifs_dbg(FYI, "Unix UID %d returned from SID\n", *puid); >> + return true; /* well known sid found, uid returned */ >> +} >> + >> static void >> cifs_copy_sid(struct cifs_sid *dst, const struct cifs_sid *src) >> { >> @@ -276,6 +361,43 @@ >> return -EIO; >> } >> >> + if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_UID_FROM_ACL) { >> + uint32_t unix_id; >> + bool is_group; >> + >> + if (sidtype != SIDOWNER) >> + is_group = true; >> + else >> + is_group = false; >> + >> + if (is_well_known_sid(psid, &unix_id, is_group) == false) >> + goto try_upcall_to_get_id; >> + >> + if (is_group) { >> + kgid_t gid; >> + gid_t id; >> + >> + id = (gid_t)unix_id; >> + gid = make_kgid(&init_user_ns, id); >> + if (gid_valid(gid)) { >> + fgid = gid; >> + goto got_valid_id; >> + } >> + } else { >> + kuid_t uid; >> + uid_t id; >> + >> + id = (uid_t)unix_id; >> + uid = make_kuid(&init_user_ns, id); >> + if (uid_valid(uid)) { >> + fuid = uid; >> + goto got_valid_id; >> + } >> + } >> + /* If unable to find uid/gid easily from SID try via upcall */ >> + } >> + >> +try_upcall_to_get_id: >> sidstr = sid_to_key_str(psid, sidtype); >> if (!sidstr) >> return -ENOMEM; >> @@ -329,6 +451,7 @@ >> * Note that we return 0 here unconditionally. If the mapping >> * fails then we just fall back to using the mnt_uid/mnt_gid. >> */ >> +got_valid_id: >> if (sidtype == SIDOWNER) >> fattr->cf_uid = fuid; >> else >> -- >> 1.9.1 >> >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-cifs" in >> the body of a message to majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > It seems like sid_unix_NFS_mode variable is not used. > > Other than the notice above, the patch looks good: > > Reviewed-by: Pavel Shilovsky <pshilov@xxxxxxxxxxxxx> > > -- > Best regards, > Pavel Shilovsky -- Thanks, Steve -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html