All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Wilck <martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
To: linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org,
	sfrench-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org,
	Martin Wilck
	<martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
Subject: [RFC/PATCH] cifs.upcall: use kernel.provided principal name if available
Date: Tue,  6 Sep 2011 17:26:34 +0200	[thread overview]
Message-ID: <1315322794-10725-1-git-send-email-martin.wilck@ts.fujitsu.com> (raw)
In-Reply-To: <1315322512-10652-1-git-send-email-martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>

This patch complements the kernel patch
"cifs: add server-provided principal name in upcall". When cifs.upcall
is started with -p, the kernel-provided principal name from the initial
negotiation with the server will be used to obtain a ticket. If this fails,
"cifs/<hostname>" and "host/hostname" fallbacks will be tried as fallback.

This will enable kerberos-based CIFS mounts on more servers, and make
mount.cifs work more similar to smbclient.

Note that the "-p" option must be added in the cifs.upcall line in
/etc/request-key.conf to activate this.

Signed-off-by: Martin Wilck <martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
---
 cifs.upcall.8.in |    6 ++++++
 cifs.upcall.c    |   38 +++++++++++++++++++++++++++++++-------
 cifs_spnego.h    |    2 +-
 3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/cifs.upcall.8.in b/cifs.upcall.8.in
index 03842b7..7d90d1e 100644
--- a/cifs.upcall.8.in
+++ b/cifs.upcall.8.in
@@ -52,6 +52,12 @@ Traditionally, the kernel has sent only a single uid= parameter to the upcall fo
 Newer kernels send a creduid= option as well, which contains what uid it thinks actually owns the credentials that it\'s looking for\&. At mount time, this is generally set to the real uid of the user doing the mount. For multisession mounts, it's set to the fsuid of the mount user. Set this option if you want cifs.upcall to use the older uid= parameter instead of the creduid= parameter\&.
 .RE
 .PP
+\-\-principal\-from\-kernel|\-p
+.RS 4
+When this option is used, the principal name obtained by the kernel from the CIFS server is used rather than a principal name derived from the host name. If this fails, the host name is used as fallback.
+This makes it possible to obtain credentials for CIFS servers using nonstandard principal names, and makes cifs mounts behave more similar to smbclient, which also uses the server-provided principal name.
+.RE
+.PP
 \-\-version|\-v
 .RS 4
 Print version number and exit\&.
diff --git a/cifs.upcall.c b/cifs.upcall.c
index de92092..2adac1d 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -518,11 +518,13 @@ handle_krb5_mech(const char *oid, const char *principal, DATA_BLOB * secblob,
 #define DKD_HAVE_PID		0x20
 #define DKD_HAVE_CREDUID	0x40
 #define DKD_HAVE_USERNAME	0x80
+#define DKD_HAVE_PRINCIPAL	0x100
 #define DKD_MUSTHAVE_SET (DKD_HAVE_HOSTNAME|DKD_HAVE_VERSION|DKD_HAVE_SEC)
 
 struct decoded_args {
 	int ver;
 	char *hostname;
+	char *principal;
 	char *ip;
 	char *username;
 	uid_t uid;
@@ -557,6 +559,21 @@ decode_key_description(const char *desc, struct decoded_args *arg)
 			}
 			retval |= DKD_HAVE_HOSTNAME;
 			syslog(LOG_DEBUG, "host=%s", arg->hostname);
+		} else if (!strncmp(tkn, "pri=", 4)) {
+			if (pos == NULL)
+				len = strlen(tkn);
+			else
+				len = pos - tkn;
+
+			len -= 4;
+			SAFE_FREE(arg->principal);
+			arg->principal = strndup(tkn + 4, len);
+			if (arg->principal == NULL) {
+				syslog(LOG_ERR, "Unable to allocate memory");
+				return 1;
+			}
+			retval |= DKD_HAVE_PRINCIPAL;
+			syslog(LOG_DEBUG, "pri=%s", arg->principal);
 		} else if (!strncmp(tkn, "ip4=", 4) || !strncmp(tkn, "ip6=", 4)) {
 			if (pos == NULL)
 				len = strlen(tkn);
@@ -755,6 +772,7 @@ static void usage(void)
 const struct option long_options[] = {
 	{"trust-dns", 0, NULL, 't'},
 	{"legacy-uid", 0, NULL, 'l'},
+	{"principal-from-kernel", 0, NULL, 'p'},
 	{"version", 0, NULL, 'v'},
 	{NULL, 0, NULL, 0}
 };
@@ -768,7 +786,7 @@ int main(const int argc, char *const argv[])
 	size_t datalen;
 	unsigned int have;
 	long rc = 1;
-	int c, try_dns = 0, legacy_uid = 0;
+	int c, try_dns = 0, legacy_uid = 0, use_principal = 0;
 	char *buf, *princ = NULL, *ccname = NULL;
 	char hostbuf[NI_MAXHOST], *host;
 	struct decoded_args arg;
@@ -781,7 +799,7 @@ int main(const int argc, char *const argv[])
 
 	openlog(prog, 0, LOG_DAEMON);
 
-	while ((c = getopt_long(argc, argv, "cltv", long_options, NULL)) != -1) {
+	while ((c = getopt_long(argc, argv, "cltpv", long_options, NULL)) != -1) {
 		switch (c) {
 		case 'c':
 			/* legacy option -- skip it */
@@ -792,6 +810,9 @@ int main(const int argc, char *const argv[])
 		case 'l':
 			legacy_uid++;
 			break;
+		case 'p':
+			use_principal++;
+			break;
 		case 'v':
 			printf("version: %s\n", VERSION);
 			goto out;
@@ -873,9 +894,16 @@ int main(const int argc, char *const argv[])
 	host = arg.hostname;
 
 	// do mech specific authorization
+	oid = OID_KERBEROS5;
 	switch (arg.sec) {
 	case MS_KRB5:
+		oid = OID_KERBEROS5_OLD;
 	case KRB5:
+		if (use_principal && have & DKD_HAVE_PRINCIPAL) {
+			rc = handle_krb5_mech(oid, arg.principal, &secblob, &sess_key, ccname);
+			if (!rc)
+				break;
+		}
 retry_new_hostname:
 		/* for "cifs/" service name + terminating 0 */
 		datalen = strlen(host) + 5 + 1;
@@ -885,11 +913,6 @@ retry_new_hostname:
 			break;
 		}
 
-		if (arg.sec == MS_KRB5)
-			oid = OID_KERBEROS5_OLD;
-		else
-			oid = OID_KERBEROS5;
-
 		/*
 		 * try getting a cifs/ principal first and then fall back to
 		 * getting a host/ principal if that doesn't work.
@@ -965,6 +988,7 @@ out:
 	data_blob_free(&sess_key);
 	SAFE_FREE(ccname);
 	SAFE_FREE(arg.hostname);
+	SAFE_FREE(arg.principal);
 	SAFE_FREE(arg.ip);
 	SAFE_FREE(arg.username);
 	SAFE_FREE(keydata);
diff --git a/cifs_spnego.h b/cifs_spnego.h
index f8753a7..d43f965 100644
--- a/cifs_spnego.h
+++ b/cifs_spnego.h
@@ -23,7 +23,7 @@
 #ifndef _CIFS_SPNEGO_H
 #define _CIFS_SPNEGO_H
 
-#define CIFS_SPNEGO_UPCALL_VERSION 2
+#define CIFS_SPNEGO_UPCALL_VERSION 3
 
 /*
  * The version field should always be set to CIFS_SPNEGO_UPCALL_VERSION.
-- 
1.7.6

  parent reply	other threads:[~2011-09-06 15:26 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-09-06 15:21 [RFC/PATCH] cifs: add server-provided principal name in upcall Martin Wilck
     [not found] ` <1315322512-10652-1-git-send-email-martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-06 15:26   ` Martin Wilck [this message]
     [not found]     ` <1315322794-10725-1-git-send-email-martin.wilck-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-06 16:10       ` [RFC/PATCH] cifs.upcall: use kernel.provided principal name if available Jeff Layton
     [not found]         ` <4E673D6F.90606@ts.fujitsu.com>
2011-09-07 13:03           ` Jeff Layton
2011-09-07 21:42             ` Andrew Bartlett
2011-09-08  7:23               ` Martin Wilck
     [not found]                 ` <4E686D69.9090503-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-08  7:39                   ` Andrew Bartlett
2011-09-08 12:53                     ` Martin Wilck
     [not found]                       ` <4E68BACD.2020403-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-08 12:59                         ` simo
2011-09-08 13:01                         ` Andrew Bartlett
2011-09-08 13:13                           ` Martin Wilck
     [not found]                             ` <4E68BF73.2090707-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-08 13:23                               ` simo
2011-09-08 13:23                               ` Andrew Bartlett
2011-09-08 14:54                                 ` Jeff Layton
     [not found]                                 ` <4E68EEAE.2090102@ts.fujitsu.com>
     [not found]                                   ` <4E68EEAE.2090102-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-09 13:37                                     ` Jeff Layton
2011-09-12  9:01                                       ` Martin Wilck
     [not found]                                         ` <4E6DCA86.8020707-RJz4owOZxyXQFUHtdCDX3A@public.gmane.org>
2011-09-12 13:41                                           ` Jeff Layton
     [not found]                                             ` <20110912094114.4e7f2b8e-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org>
2011-09-12 14:00                                               ` simo
2011-09-12 23:23                                           ` Andrew Bartlett
2011-09-13 11:01                                             ` Martin Wilck
2011-09-08 13:31                               ` Jeff Layton
2011-09-07 22:18       ` Steve French
2011-09-06 16:16   ` [RFC/PATCH] cifs: add server-provided principal name in upcall Jeff Layton

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=1315322794-10725-1-git-send-email-martin.wilck@ts.fujitsu.com \
    --to=martin.wilck-rjz4owozxyxqfuhtdcdx3a@public.gmane.org \
    --cc=jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org \
    --cc=linux-cifs-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=sfrench-eUNUBHrolfbYtjvyW6yDsg@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.