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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.