Linux CIFS filesystem development
 help / color / mirror / Atom feed
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>

  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