linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Shyam Prasad N <nspmangalore@gmail.com>
To: Pavel Shilovsky <piastryyy@gmail.com>
Cc: "Aurélien Aptel" <aaptel@suse.com>,
	"Steve French" <smfrench@gmail.com>,
	CIFS <linux-cifs@vger.kernel.org>,
	sribhat.msa@outlook.com
Subject: Re: [PATCH][SMB3] mount.cifs: use SUDO_UID env variable for cruid
Date: Fri, 27 Nov 2020 15:54:55 +0530	[thread overview]
Message-ID: <CANT5p=r2fwDd118_LTvB1PDDNbwzijdwXzF21O7AhpZpjxMU6w@mail.gmail.com> (raw)
In-Reply-To: <CAKywueRcmWYOJ748Tc4jmAD+8HRpNBUG9AtAKhKvm5OmmsT=pw@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 887 bytes --]

Hi Pavel,

Please consider the attached patch instead of the one I submitted earlier.
Contains the fix to the bug identified by Aurelien.

Regards,
Shyam

On Tue, Nov 10, 2020 at 5:13 AM Pavel Shilovsky <piastryyy@gmail.com> wrote:
>
> Merged. Thanks!
> --
> Best regards,
> Pavel Shilovsky
>
> пн, 21 сент. 2020 г. в 01:19, Aurélien Aptel <aaptel@suse.com>:
> >
> >
> > Thanks Shyam, looks good to me :)
> >
> > Shyam Prasad N <nspmangalore@gmail.com> writes:
> > > Here's the updated patch.
> >
> > Reviewed-by: Aurelien Aptel <aaptel@suse.com>
> >
> > Cheers,
> > --
> > Aurélien Aptel / SUSE Labs Samba Team
> > GPG: 1839 CB5F 9F5B FB9B AA97  8C99 03C8 A49B 521B D5D3
> > SUSE Software Solutions Germany GmbH, Maxfeldstr. 5, 90409 Nürnberg, DE
> > GF: Felix Imendörffer, Mary Higgins, Sri Rasiah HRB 247165 (AG München)



-- 
-Shyam

[-- Attachment #2: 0001-mount.cifs-use-SUDO_UID-env-variable-for-cruid.patch --]
[-- Type: application/octet-stream, Size: 6174 bytes --]

From 4933a08f59256bc9fde341d437f85780b1271849 Mon Sep 17 00:00:00 2001
From: Shyam Prasad N <sprasad@microsoft.com>
Date: Wed, 16 Sep 2020 00:18:44 -0700
Subject: [PATCH] mount.cifs: use SUDO_UID env variable for cruid

In the current mount.cifs logic, when sudo is used for mount,
uid=0, so the mount command searches for cruid=0 unless explicitly
specified by the user. The user may already have cred cache populated
but mount.cifs would end up searching cred cache for uid=0.

mount.cifs can avoid this confusion by reading the cruid from SUDO_UID
environment variable. If it is set to non-zero, we can make cruid=$SUDO_UID.

However, to maintain backward compatibility, keeping this as a fallback option.
If mount fails with ENOKEY, then retry with this option.
To enable this fallback, I had to make a few minor changes in the flow.

Signed-off-by: Shyam Prasad N <sprasad@microsoft.com>
Reviewed-by: Aurelien Aptel <aaptel@suse.com>

---
 mount.cifs.c | 83 ++++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 67 insertions(+), 16 deletions(-)

diff --git a/mount.cifs.c b/mount.cifs.c
index 4feb397..c0fb0e4 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -171,7 +171,11 @@
 
 #define NTFS_TIME_OFFSET ((unsigned long long)(369*365 + 89) * 24 * 3600 * 10000000)
 
-/* struct for holding parsed mount info for use by privileged process */
+/*
+* struct for holding parsed mount info for use by privileged process.
+* Please do not keep pointers in this struct.
+* That way, reinit of this struct is a simple memset.
+*/
 struct parsed_mount_info {
 	unsigned long flags;
 	char host[NI_MAXHOST + 1];
@@ -189,6 +193,8 @@ struct parsed_mount_info {
 	unsigned int verboseflag:1;
 	unsigned int nofail:1;
 	unsigned int got_domain:1;
+	unsigned int is_krb5:1;
+	uid_t sudo_uid;
 };
 
 static const char *thisprogram;
@@ -891,9 +897,12 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info)
 
 		case OPT_SEC:
 			if (value) {
-				if (!strncmp(value, "none", 4) ||
-				    !strncmp(value, "krb5", 4))
+				if (!strncmp(value, "none", 4))
+					parsed_info->got_password = 1;
+				if (!strncmp(value, "krb5", 4)) {
+					parsed_info->is_krb5 = 1;
 					parsed_info->got_password = 1;
+				}
 			}
 			break;
 
@@ -1199,6 +1208,10 @@ nocopy:
 		snprintf(out + out_len, word_len + 5, "uid=%s", txtbuf);
 		out_len = strlen(out);
 	}
+	if (parsed_info->is_krb5 && parsed_info->sudo_uid) {
+		cruid = parsed_info->sudo_uid;
+		got_cruid = 1;
+	}
 	if (got_cruid) {
 		word_len = snprintf(txtbuf, sizeof(txtbuf), "%u", cruid);
 
@@ -2012,12 +2025,17 @@ int main(int argc, char **argv)
 	char *options = NULL;
 	char *orig_dev = NULL;
 	char *currentaddress, *nextaddress;
+	char *value = NULL;
+	char *ep = NULL;
 	int rc = 0;
 	int already_uppercased = 0;
 	int sloppy = 0;
+	int fallback_sudo_uid = 0;
 	size_t options_size = MAX_OPTIONS_LEN;
 	struct parsed_mount_info *parsed_info = NULL;
+	struct parsed_mount_info *reinit_parsed_info = NULL;
 	pid_t pid;
+	uid_t sudo_uid = 0;
 
 	rc = check_setuid();
 	if (rc)
@@ -2053,7 +2071,23 @@ int main(int argc, char **argv)
 		parsed_info = NULL;
 		fprintf(stderr, "Unable to allocate memory: %s\n",
 				strerror(errno));
-		return EX_SYSERR;
+		rc = EX_SYSERR;
+		goto mount_exit;
+	}
+
+	reinit_parsed_info = malloc(sizeof(*reinit_parsed_info));
+	if (reinit_parsed_info == NULL) {
+		fprintf(stderr, "Unable to allocate memory: %s\n",
+				strerror(errno));
+		rc = EX_SYSERR;
+		goto mount_exit;
+	}
+
+	options = calloc(options_size, 1);
+	if (!options) {
+		fprintf(stderr, "Unable to allocate memory.\n");
+		rc = EX_SYSERR;
+		goto mount_exit;
 	}
 
 	/* add sharename in opts string as unc= parm */
@@ -2110,10 +2144,13 @@ int main(int argc, char **argv)
 	/* chdir into mountpoint as soon as possible */
 	rc = acquire_mountpoint(&mountpoint);
 	if (rc) {
-		free(orgoptions);
-		return rc;
+		goto mount_exit;
 	}
 
+	/* Before goto assemble_retry, reinitialize parsed_info with reinit_parsed_info */
+	memcpy(reinit_parsed_info, parsed_info,	sizeof(*reinit_parsed_info));
+
+assemble_retry:
 	/*
 	 * mount.cifs does privilege separation. Most of the code to handle
 	 * assembling the mount info is done in a child process that drops
@@ -2131,9 +2168,7 @@ int main(int argc, char **argv)
 		/* child */
 		rc = assemble_mountinfo(parsed_info, thisprogram, mountpoint,
 					orig_dev, orgoptions);
-		free(orgoptions);
-		free(mountpoint);
-		return rc;
+		goto mount_child_exit;
 	} else {
 		/* parent */
 		pid = wait(&rc);
@@ -2147,19 +2182,13 @@ int main(int argc, char **argv)
 			goto mount_exit;
 	}
 
-	options = calloc(options_size, 1);
-	if (!options) {
-		fprintf(stderr, "Unable to allocate memory.\n");
-		rc = EX_SYSERR;
-		goto mount_exit;
-	}
-
 	currentaddress = parsed_info->addrlist;
 	nextaddress = strchr(currentaddress, ',');
 	if (nextaddress)
 		*nextaddress++ = '\0';
 
 mount_retry:
+	options[0] = '\0';
 	if (!currentaddress) {
 		fprintf(stderr, "Unable to find suitable address.\n");
 		rc = parsed_info->nofail ? 0 : EX_FAIL;
@@ -2250,6 +2279,24 @@ mount_retry:
 				already_uppercased = 1;
 				goto mount_retry;
 			}
+			break;
+		case ENOKEY:
+			if (!fallback_sudo_uid && parsed_info->is_krb5) {
+				/* mount could have failed because cruid option was not passed when triggered with sudo */
+				value = getenv("SUDO_UID");
+				if (value) {
+					errno = 0;
+					sudo_uid = strtoul(value, &ep, 10);
+					if (errno == 0 && *ep == '\0' && sudo_uid) {
+						/* Reinitialize parsed_info and assemble options again with sudo_uid */
+						memcpy(parsed_info, reinit_parsed_info, sizeof(*parsed_info));
+						parsed_info->sudo_uid = sudo_uid;
+						fallback_sudo_uid = 1;
+						goto assemble_retry;
+					}
+				}
+			}
+			break;
 		}
 		fprintf(stderr, "mount error(%d): %s\n", errno,
 			strerror(errno));
@@ -2276,6 +2323,10 @@ mount_exit:
 		memset(parsed_info->password, 0, sizeof(parsed_info->password));
 		munmap(parsed_info, sizeof(*parsed_info));
 	}
+
+mount_child_exit:
+	/* Objects to be freed both in main process and child */
+	free(reinit_parsed_info);
 	free(options);
 	free(orgoptions);
 	free(mountpoint);
-- 
2.25.1


  reply	other threads:[~2020-11-27 10:25 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-16 10:00 [PATCH][SMB3] mount.cifs: use SUDO_UID env variable for cruid Shyam Prasad N
2020-09-16 10:56 ` Aurélien Aptel
2020-09-16 16:17   ` Shyam Prasad N
2020-09-17  8:57     ` Aurélien Aptel
2020-09-17  9:11       ` Shyam Prasad N
2020-09-17 10:13         ` Aurélien Aptel
2020-09-21  3:50           ` Shyam Prasad N
2020-09-21  8:19             ` Aurélien Aptel
2020-11-09 23:43               ` Pavel Shilovsky
2020-11-27 10:24                 ` Shyam Prasad N [this message]
2020-12-09 19:32                   ` 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='CANT5p=r2fwDd118_LTvB1PDDNbwzijdwXzF21O7AhpZpjxMU6w@mail.gmail.com' \
    --to=nspmangalore@gmail.com \
    --cc=aaptel@suse.com \
    --cc=linux-cifs@vger.kernel.org \
    --cc=piastryyy@gmail.com \
    --cc=smfrench@gmail.com \
    --cc=sribhat.msa@outlook.com \
    /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;
as well as URLs for NNTP newsgroup(s).