Re: [PATCH 2/2] scan /run/user/${UID} for ccaches, too

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 21 Aug 2012 18:56:48 -0400
Nalin Dahyabhai <nalin@xxxxxxxxxx> wrote:

> When scanning for credential caches, check the user's directory under
> /run/user first, then fall back to /tmp as we have previously.  Because
> we now call find_krb5_cc() twice (once for each directory), we move its
> state to be outside of the function.  We also add a substitution
> mechanism to make the process of resolving the location of the user's
> home directory before searching it a bit more explicable.
> ---
>  cifs.upcall.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++++-----------
>  1 file changed, 51 insertions(+), 11 deletions(-)
> 
> diff --git a/cifs.upcall.c b/cifs.upcall.c
> index 6f95c1c..598a999 100644
> --- a/cifs.upcall.c
> +++ b/cifs.upcall.c
> @@ -53,7 +53,8 @@
>  #include "cifs_spnego.h"
>  
>  #define	CIFS_DEFAULT_KRB5_DIR		"/tmp"
> -#define	CIFS_DEFAULT_KRB5_PREFIX	"krb5cc_"
> +#define	CIFS_DEFAULT_KRB5_USER_DIR	"/run/user/%U"
> +#define	CIFS_DEFAULT_KRB5_PREFIX	"krb5cc"
>  #define CIFS_DEFAULT_KRB5_KEYTAB	"/etc/krb5.keytab"
>  
>  #define	MAX_CCNAME_LEN			PATH_MAX + 5
> @@ -258,14 +259,47 @@ 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)
> +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, *best_cache = NULL;
> +	char ccname[MAX_CCNAME_LEN], *credpath;
>  	int i, n;
> -	time_t cred_time, best_time = 0;
> +	time_t cred_time;
>  
>  	n = scandir(dirname, &namelist, krb5cc_filter, NULL);
>  	if (n < 0) {
> @@ -310,7 +344,7 @@ static char *find_krb5_cc(const char *dirname, uid_t uid)
>  			continue;
>  		}
>  
> -		if (cred_time <= best_time) {
> +		if (cred_time <= *best_time) {
>  			syslog(LOG_DEBUG, "%s: %s expires sooner than current "
>  			       "best.", __func__, ccname);
>  			free(namelist[i]);
> @@ -318,14 +352,14 @@ static char *find_krb5_cc(const char *dirname, uid_t uid)
>  		}
>  
>  		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(*best_cache);
> +		*best_cache = strndup(ccname, MAX_CCNAME_LEN);
> +		*best_time = cred_time;
>  		free(namelist[i]);
>  	}
>  	free(namelist);
>  
> -	return best_cache;
> +	return *best_cache;
>  }
>  
>  static int
> @@ -793,12 +827,13 @@ int main(const int argc, char *const argv[])
>  	unsigned int have;
>  	long rc = 1;
>  	int c, try_dns = 0, legacy_uid = 0;
> -	char *buf, *ccname = NULL;
> +	char *buf, *ccdir = NULL, *ccname = NULL, *best_cache = NULL;
>  	char hostbuf[NI_MAXHOST], *host;
>  	struct decoded_args arg;
>  	const char *oid;
>  	uid_t uid;
>  	char *keytab_name = CIFS_DEFAULT_KRB5_KEYTAB;
> +	time_t best_time = 0;
>  
>  	hostbuf[0] = '\0';
>  	memset(&arg, 0, sizeof(arg));
> @@ -901,7 +936,12 @@ int main(const int argc, char *const argv[])
>  		syslog(LOG_ERR, "setuid: %s", strerror(errno));
>  		goto out;
>  	}
> -	ccname = find_krb5_cc(CIFS_DEFAULT_KRB5_DIR, uid);
> +	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);
>  
>  	/* Couldn't find credcache? Try to use keytab */
>  	if (ccname == NULL && arg.username != NULL)

Committed...
-- 
Jeff Layton <jlayton@xxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux