From: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Steve French <smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Steve French <steve.french-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
Subject: Re: [PATCH 2/2] Retrieve uid and gid from special sid if enabled
Date: Fri, 14 Oct 2016 14:26:10 -0400 [thread overview]
Message-ID: <1476469570.2727.0.camel@redhat.com> (raw)
In-Reply-To: <1476457807-22055-2-git-send-email-smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
On Fri, 2016-10-14 at 10:10 -0500, Steve French wrote:
> 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-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org>
> Reviewed-by: Shirish Pargaonkar <shirishpargaonkar-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> 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
Nice! Good idea:
Reviewed-by: Jeff Layton <jlayton-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
next prev parent reply other threads:[~2016-10-14 18:26 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-10-14 15:10 [PATCH 1/2] Add new mount option to set owner uid and gid from special sids in acl Steve French
[not found] ` <1476457807-22055-1-git-send-email-smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-14 15:10 ` [PATCH 2/2] Retrieve uid and gid from special sid if enabled Steve French
[not found] ` <1476457807-22055-2-git-send-email-smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-14 18:26 ` Jeff Layton [this message]
2016-10-14 19:12 ` Pavel Shilovsky
[not found] ` <CAKywueTJt+GG9TpxEfU464HREF=ia3wAs7Pf1D6g8aRt=KRQEA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-14 19:15 ` Steve French
2016-10-14 18:34 ` [PATCH 1/2] Add new mount option to set owner uid and gid from special sids in acl Jeff Layton
[not found] ` <1476470077.2727.6.camel-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2016-10-14 18:36 ` Steve French
[not found] ` <CAH2r5muStgeA6QJxRFJ3mZPbLbFVnQ8xpcOn+3QtWvx+3HGs0Q-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-10-14 18:41 ` Steve French
2016-10-14 19:09 ` Pavel Shilovsky
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1476469570.2727.0.camel@redhat.com \
--to=jlayton-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=smfrench-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
--cc=steve.french-7I+n7zu2hftEKMMhf/gKZA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox