All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff Layton <jlayton@samba.org>
To: linux-cifs@vger.kernel.org
Cc: jfdey@fredhutch.org, samba-technical@lists.samba.org
Subject: [cifs-utils PATCHv2 2/6] cifs.upcall: use krb5 routines to get default ccname
Date: Thu, 25 Aug 2016 10:17:41 -0400	[thread overview]
Message-ID: <1472134665-4014-3-git-send-email-jlayton@samba.org> (raw)
In-Reply-To: <1472134665-4014-1-git-send-email-jlayton@samba.org>

Currently we end up groveling around in /tmp, trying to guess what the
credcache will be. Instead, just get the default ccname for the user,
and then see if it has a valid tgt. If it doesn't then we try to use
the keytab to init the credcache before proceeding.

Signed-off-by: Jeff Layton <jlayton@samba.org>
---
 cifs.upcall.c | 148 +++++++++++-----------------------------------------------
 1 file changed, 27 insertions(+), 121 deletions(-)

diff --git a/cifs.upcall.c b/cifs.upcall.c
index e8544c2b68ad..d0f6d089d8e1 100644
--- a/cifs.upcall.c
+++ b/cifs.upcall.c
@@ -52,12 +52,6 @@
 #include "spnego.h"
 #include "cifs_spnego.h"
 
-#define	CIFS_DEFAULT_KRB5_DIR		"/tmp"
-#define	CIFS_DEFAULT_KRB5_USER_DIR	"/run/user/%U"
-#define	CIFS_DEFAULT_KRB5_PREFIX	"krb5cc"
-
-#define	MAX_CCNAME_LEN			PATH_MAX + 5
-
 static const char *prog = "cifs.upcall";
 typedef enum _sectype {
 	NONE = 0,
@@ -178,13 +172,34 @@ err_cache:
 	return credtime;
 }
 
-static int krb5cc_filter(const struct dirent *dirent)
+static char *
+get_default_cc(void)
 {
-	/* subtract 1 for the null terminator */
-	return !strncmp(dirent->d_name, CIFS_DEFAULT_KRB5_PREFIX,
-			sizeof(CIFS_DEFAULT_KRB5_PREFIX) - 1);
+	krb5_error_code ret;
+	const char *ccname;
+	char *rcc = NULL;
+	krb5_context context = NULL;
+
+	ret = krb5_init_context(&context);
+	if (ret) {
+		syslog(LOG_DEBUG, "krb5_init_context: %d", (int)ret);
+		return NULL;
+	}
+
+	ccname = krb5_cc_default_name(context);
+	if (!ccname) {
+		syslog(LOG_DEBUG, "krb5_cc_default returned NULL.");
+		goto out_free_context;
+	}
+
+	if (get_tgt_time(ccname))
+		rcc = strdup(ccname);
+out_free_context:
+	krb5_free_context(context);
+	return rcc;
 }
 
+
 static char *
 init_cc_from_keytab(const char *keytab_name, const char *user)
 {
@@ -263,109 +278,6 @@ icfk_cleanup:
 	return ccname;
 }
 
-/* resolve a pattern to an actual directory path */
-static char *resolve_krb5_dir(const char *pattern, uid_t uid)
-{
-	char name[MAX_CCNAME_LEN];
-	int i;
-	size_t j;
-	for (i = 0, j = 0; (pattern[i] != '\0') && (j < sizeof(name)); i++) {
-		switch (pattern[i]) {
-		case '%':
-			switch (pattern[i + 1]) {
-			case '%':
-				name[j++] = pattern[i];
-				i++;
-				break;
-			case 'U':
-				j += snprintf(name + j, sizeof(name) - j,
-					      "%lu", (unsigned long) uid);
-				i++;
-				break;
-			}
-			break;
-		default:
-			name[j++] = pattern[i];
-			break;
-		}
-	}
-	if ((j > 0) && (j < sizeof(name)))
-		return strndup(name, MAX_CCNAME_LEN);
-	else
-		return NULL;
-}
-
-/* search for a credcache that looks like a likely candidate */
-static char *find_krb5_cc(const char *dirname, uid_t uid,
-			  char **best_cache, time_t *best_time)
-{
-	struct dirent **namelist;
-	struct stat sbuf;
-	char ccname[MAX_CCNAME_LEN], *credpath;
-	int i, n;
-	time_t cred_time;
-
-	n = scandir(dirname, &namelist, krb5cc_filter, NULL);
-	if (n < 0) {
-		syslog(LOG_DEBUG, "%s: scandir error on directory '%s': %s",
-		       __func__, dirname, strerror(errno));
-		return NULL;
-	}
-
-	for (i = 0; i < n; i++) {
-		snprintf(ccname, sizeof(ccname), "FILE:%s/%s", dirname,
-			 namelist[i]->d_name);
-		credpath = ccname + 5;
-		syslog(LOG_DEBUG, "%s: considering %s", __func__, credpath);
-
-		if (lstat(credpath, &sbuf)) {
-			syslog(LOG_DEBUG, "%s: stat error on '%s': %s",
-			       __func__, credpath, strerror(errno));
-			free(namelist[i]);
-			continue;
-		}
-		if (sbuf.st_uid != uid) {
-			syslog(LOG_DEBUG, "%s: %s is owned by %u, not %u",
-			       __func__, credpath, sbuf.st_uid, uid);
-			free(namelist[i]);
-			continue;
-		}
-		if (S_ISDIR(sbuf.st_mode)) {
-			snprintf(ccname, sizeof(ccname), "DIR:%s/%s", dirname,
-				 namelist[i]->d_name);
-			credpath = ccname + 4;
-		} else
-		if (!S_ISREG(sbuf.st_mode)) {
-			syslog(LOG_DEBUG, "%s: %s is not a regular file",
-			       __func__, credpath);
-			free(namelist[i]);
-			continue;
-		}
-		if (!(cred_time = get_tgt_time(ccname))) {
-			syslog(LOG_DEBUG, "%s: %s is not a valid credcache.",
-			       __func__, ccname);
-			free(namelist[i]);
-			continue;
-		}
-
-		if (cred_time <= *best_time) {
-			syslog(LOG_DEBUG, "%s: %s expires sooner than current "
-			       "best.", __func__, ccname);
-			free(namelist[i]);
-			continue;
-		}
-
-		syslog(LOG_DEBUG, "%s: %s is valid ccache", __func__, ccname);
-		free(*best_cache);
-		*best_cache = strndup(ccname, MAX_CCNAME_LEN);
-		*best_time = cred_time;
-		free(namelist[i]);
-	}
-	free(namelist);
-
-	return *best_cache;
-}
-
 static int
 cifs_krb5_get_req(const char *host, const char *ccname,
 		  DATA_BLOB * mechtoken, DATA_BLOB * sess_key)
@@ -841,13 +753,12 @@ int main(const int argc, char *const argv[])
 	unsigned int have;
 	long rc = 1;
 	int c, try_dns = 0, legacy_uid = 0;
-	char *buf, *ccdir = NULL, *ccname = NULL, *best_cache = NULL;
+	char *buf, *ccname = NULL;
 	char hostbuf[NI_MAXHOST], *host;
 	struct decoded_args arg;
 	const char *oid;
 	uid_t uid;
 	char *keytab_name = NULL;
-	time_t best_time = 0;
 
 	hostbuf[0] = '\0';
 	memset(&arg, 0, sizeof(arg));
@@ -954,13 +865,8 @@ int main(const int argc, char *const argv[])
 		syslog(LOG_ERR, "setuid: %s", strerror(errno));
 		goto out;
 	}
-	ccdir = resolve_krb5_dir(CIFS_DEFAULT_KRB5_USER_DIR, uid);
-	if (ccdir != NULL)
-		find_krb5_cc(ccdir, uid, &best_cache, &best_time);
-	ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, uid, &best_cache,
-			      &best_time);
-	SAFE_FREE(ccdir);
 
+	ccname = get_default_cc();
 	/* Couldn't find credcache? Try to use keytab */
 	if (ccname == NULL && arg.username != NULL)
 		ccname = init_cc_from_keytab(keytab_name, arg.username);
-- 
2.7.4

  parent reply	other threads:[~2016-08-25 14:17 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-08-25 14:17 [cifs-utils PATCHv2 0/6] cifs.upcall: cleanup and overhaul of the cifs.upcall krb5 handling code Jeff Layton
2016-08-25 14:17 ` [cifs-utils PATCHv2 1/6] aclocal: fix typo in idmap.m4 Jeff Layton
2016-08-25 14:17 ` Jeff Layton [this message]
     [not found] ` <1472134665-4014-1-git-send-email-jlayton-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2016-08-25 14:17   ` [cifs-utils PATCHv2 3/6] cifs.upcall: make the krb5_context a static global variable Jeff Layton
2016-08-25 14:17 ` [cifs-utils PATCHv2 4/6] cifs.upcall: remove KRB5_TC_OPENCLOSE Jeff Layton
2016-08-25 14:17 ` [cifs-utils PATCHv2 5/6] cifs.upcall: make get_tgt_time take a ccache arg Jeff Layton
2016-08-25 14:17 ` [cifs-utils PATCHv2 6/6] cifs.upcall: stop passing around ccache name strings Jeff Layton
2016-08-25 16:05 ` [cifs-utils PATCHv2 0/6] cifs.upcall: cleanup and overhaul of the cifs.upcall krb5 handling code Isaac Boukris
     [not found]   ` <CAC-fF8S_K49oDzNMQ8PrjWyWEokdsRo2gC5xUQobWe4TTBYaCA-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-25 16:44     ` Jeff Layton
     [not found]       ` <1472143488.3160.7.camel-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2016-08-25 19:59         ` Isaac Boukris
2016-08-25 20:51           ` Jeff Layton
2016-08-26 12:53             ` Simo
     [not found]               ` <1472216025.17759.9.camel-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2016-08-26 13:44                 ` Jeff Layton
2016-08-26 13:54                   ` Simo
2016-08-27 17:11         ` Isaac Boukris
2016-08-26 12:46       ` Simo
     [not found]         ` <1472215575.17759.3.camel-eUNUBHrolfbYtjvyW6yDsg@public.gmane.org>
2016-08-27 18:06           ` Isaac Boukris
     [not found]             ` <CAC-fF8TP8T_qzmLNjTcs-u+nG46WWsEVyEQMqRBdgscQno3L5g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2016-08-27 21:25               ` Simo

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=1472134665-4014-3-git-send-email-jlayton@samba.org \
    --to=jlayton@samba.org \
    --cc=jfdey@fredhutch.org \
    --cc=linux-cifs@vger.kernel.org \
    --cc=samba-technical@lists.samba.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.