[cifs-utils/f17] Update to current upstream head (5.7-pre)

Jeff Layton jlayton at fedoraproject.org
Wed Oct 10 01:10:19 UTC 2012


commit b607505324b7fb06e88b0fc3b64c668319f28cfb
Author: Jeff Layton <jlayton at redhat.com>
Date:   Tue Oct 9 21:09:15 2012 -0400

    Update to current upstream head (5.7-pre)
    
    Includes patches to make cifs.upcall search for krb5 credcaches under
    /run/user, and fixes to make mount.cifs treat usernames differently
    when sec=krb5 is in use. Plus some other random fixes...

 cifs-utils-5.7-pre.patch |  411 ++++++++++++++++++++++++++++++++++++++++++++++
 cifs-utils.spec          |    6 +
 2 files changed, 417 insertions(+), 0 deletions(-)
---
diff --git a/cifs-utils-5.7-pre.patch b/cifs-utils-5.7-pre.patch
new file mode 100644
index 0000000..3cbecc5
--- /dev/null
+++ b/cifs-utils-5.7-pre.patch
@@ -0,0 +1,411 @@
+diff --git a/Makefile.am b/Makefile.am
+index 0d0b599..73f756f 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -10,7 +10,7 @@ man_MANS = mount.cifs.8
+ 
+ bin_PROGRAMS =
+ sbin_PROGRAMS =
+-clean-local: clean-local-upcall clean-local-idmap clean-local-aclprogs
++clean-local: clean-local-upcall clean-local-idmap
+ 
+ if CONFIG_CIFSUPCALL
+ sbin_PROGRAMS += cifs.upcall
+@@ -66,12 +66,6 @@ setcifsacl_SOURCES = setcifsacl.c
+ setcifsacl_LDADD = $(WBCLIENT_LIBS)
+ setcifsacl_CFLAGS = $(WBCLIENT_CFLAGS)
+ man_MANS += setcifsacl.1
+-
+-endif
+-
+-clean-local-aclprogs:
+-if CONFIG_CIFSACL
+-	rm -f getcifsacl.8 getcifsacl.8-t setcifsacl.8 setcifsacl.8-t
+ endif
+ 
+ SUBDIRS = contrib
+diff --git a/cifs.upcall.c b/cifs.upcall.c
+index eef461d..12d5900 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
+@@ -180,10 +181,9 @@ err_cache:
+ 
+ static int krb5cc_filter(const struct dirent *dirent)
+ {
+-	if (strstr(dirent->d_name, CIFS_DEFAULT_KRB5_PREFIX))
+-		return 1;
+-	else
+-		return 0;
++	/* subtract 1 for the null terminator */
++	return !strncmp(dirent->d_name, CIFS_DEFAULT_KRB5_PREFIX,
++			sizeof(CIFS_DEFAULT_KRB5_PREFIX) - 1);
+ }
+ 
+ static char *
+@@ -258,14 +258,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) {
+@@ -292,6 +325,11 @@ static char *find_krb5_cc(const char *dirname, uid_t 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);
+@@ -305,7 +343,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]);
+@@ -313,14 +351,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
+@@ -788,12 +826,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));
+@@ -896,7 +935,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)
+diff --git a/configure.ac b/configure.ac
+index e2bed44..993208a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ #                                               -*- Autoconf -*-
+ # Process this file with autoconf to produce a configure script.
+ 
+-AC_INIT([cifs-utils], [5.6], [linux-cifs at vger.kernel.org], [cifs-utils], [https://wiki.samba.org/index.php/LinuxCIFS_utils])
++AC_INIT([cifs-utils], [5.6.1], [linux-cifs at vger.kernel.org], [cifs-utils], [https://wiki.samba.org/index.php/LinuxCIFS_utils])
+ AC_CONFIG_SRCDIR([replace.h])
+ AC_CONFIG_HEADERS([config.h])
+ AC_CONFIG_FILES([Makefile contrib/Makefile contrib/request-key.d/Makefile])
+diff --git a/getcifsacl.c b/getcifsacl.c
+index 19b1fec..8cbdb1d 100644
+--- a/getcifsacl.c
++++ b/getcifsacl.c
+@@ -322,7 +322,7 @@ getcifsacl_usage(void)
+ 	fprintf(stderr, "\t-v	Version of the program\n");
+ 	fprintf(stderr, "\n");
+ 	fprintf(stderr, "\t-r	Display raw values of the ACE fields\n");
+-	fprintf(stderr, "\nRefer to getcifsacl(8) manpage for details\n");
++	fprintf(stderr, "\nRefer to getcifsacl(1) manpage for details\n");
+ }
+ 
+ int
+diff --git a/mount.cifs.8 b/mount.cifs.8
+index f6a66bf..cca6048 100644
+--- a/mount.cifs.8
++++ b/mount.cifs.8
+@@ -56,7 +56,9 @@ user=\fIarg\fR
+ .RS 4
+ specifies the username to connect as\&. If this is not given, then the environment variable
+ \fIUSER\fR
+-is used\&. This option can also take the form "user%password" or "workgroup/user" or "workgroup/user%password" to allow the password and workgroup to be specified as part of the username\&.
++is used\&.
++.PP
++Earlier versions of mount.cifs also allowed one to specify the username in a "user%password" or "workgroup/user" or "workgroup/user%password" to allow the password and workgroup to be specified as part of the username. Support for those alternate username formats is now deprecated and should no longer be used. Users should use the discrete "pass=" and "dom=" to specify the username.
+ .if n \{\
+ .sp
+ .\}
+@@ -675,7 +677,7 @@ winbind support configured via nsswitch.conf(5) and smb.conf(5)
+ .RE
+ Please refer to the respective manpages of cifs.idmap(8) and winbindd(8) for more information.
+ 
+-Security descriptors for a file object can be retrieved and set directly using extended attribute named system.cifs_acl. The security descriptors presented via this interface are "raw" blobs of data and need a userspace utility to either parse and format or to assemble it such as getcifsacl(8) and setcifsacl(8) respectively.
++Security descriptors for a file object can be retrieved and set directly using extended attribute named system.cifs_acl. The security descriptors presented via this interface are "raw" blobs of data and need a userspace utility to either parse and format or to assemble it such as \fBgetcifsacl\fR(1) and \fBsetcifsacl\fR(1) respectively.
+ 
+ Some of the things to consider while using this mount option:
+ .sp
+@@ -783,9 +785,9 @@ Note that the typical response to a bug report is a suggestion to try the latest
+ This man page is correct for version 1\&.74 of the cifs vfs filesystem (roughly Linux kernel 3\&.0)\&.
+ .SH "SEE ALSO"
+ .PP
+-Documentation/filesystems/cifs\&.txt and fs/cifs/README in the linux kernel source tree may contain additional options and information\&.
++\fBcifs.upcall\fR(8), \fBgetcifsacl\fR(1), \fBsetcifsacl\fR(1)
+ .PP
+-\fBcifs.upcall\fR(8)
++Documentation/filesystems/cifs\&.txt and fs/cifs/README in the linux kernel source tree may contain additional options and information\&.
+ .SH "AUTHOR"
+ .PP
+ Steve French
+diff --git a/mount.cifs.c b/mount.cifs.c
+index 330e528..3fd472a 100644
+--- a/mount.cifs.c
++++ b/mount.cifs.c
+@@ -45,6 +45,7 @@
+ #include <libgen.h>
+ #include <sys/mman.h>
+ #include <sys/wait.h>
++#include <stdbool.h>
+ #ifdef HAVE_SYS_FSUID_H
+ #include <sys/fsuid.h>
+ #endif /* HAVE_SYS_FSUID_H */
+@@ -320,15 +321,22 @@ static int set_password(struct parsed_mount_info *parsed_info, const char *src)
+  *
+  * ...obviously the only required component is "username". The source string
+  * is modified in the process, but it should remain unchanged at the end.
++ *
++ * NOTE: the above syntax does not allow for usernames that have slashes in
++ * them, as some krb5 usernames do. Support for the above syntax will be
++ * removed in a later version of cifs-utils. Users should use separate options
++ * instead of overloading this info into the username.
+  */
+ static int parse_username(char *rawuser, struct parsed_mount_info *parsed_info)
+ {
+ 	char *user, *password, slash;
+ 	int rc = 0;
++	bool warn = false;
+ 
+ 	/* everything after first % sign is a password */
+ 	password = strchr(rawuser, '%');
+ 	if (password) {
++		warn = true;
+ 		rc = set_password(parsed_info, password + 1);
+ 		if (rc)
+ 			return rc;
+@@ -342,6 +350,7 @@ static int parse_username(char *rawuser, struct parsed_mount_info *parsed_info)
+ 
+ 	/* everything before that slash is a domain */
+ 	if (user) {
++		warn = true;
+ 		slash = *user;
+ 		*user = '\0';
+ 		strlcpy(parsed_info->domain, rawuser,
+@@ -356,6 +365,11 @@ static int parse_username(char *rawuser, struct parsed_mount_info *parsed_info)
+ 	if (password)
+ 		*password = '%';
+ 
++	if (warn)
++		fprintf(stderr, "WARNING: The DOMAIN/username%%password syntax "
++				"for usernames is deprecated and will be "
++				"removed in version 5.9 of cifs-utils.\n");
++
+ 	return 0;
+ }
+ 
+@@ -574,7 +588,8 @@ parsing_err:
+ }
+ 
+ static int open_cred_file(char *file_name,
+-			struct parsed_mount_info *parsed_info)
++			struct parsed_mount_info *parsed_info,
++			char **saved_username)
+ {
+ 	char *line_buf = NULL;
+ 	char *temp_val = NULL;
+@@ -623,9 +638,11 @@ static int open_cred_file(char *file_name,
+ 		/* parse next token */
+ 		switch (parse_cred_line(line_buf + i, &temp_val)) {
+ 		case CRED_USER:
+-			i = parse_username(temp_val, parsed_info);
+-			if (i)
++			*saved_username = strdup(temp_val);
++			if (!*saved_username) {
++				i = EX_SYSERR;
+ 				goto return_i;
++			}
+ 			break;
+ 		case CRED_PASS:
+ 			i = set_password(parsed_info, temp_val);
+@@ -813,6 +830,8 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info)
+ 	char *ep;
+ 	struct passwd *pw;
+ 	struct group *gr;
++	char *saved_username = NULL;
++	bool krb5_auth = false;
+ 	/*
+ 	 * max 32-bit uint in decimal is 4294967295 which is 10 chars wide
+ 	 * +1 for NULL, and +1 for good measure
+@@ -880,11 +899,10 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info)
+ 					fprintf(stderr, "username too long\n");
+ 					return EX_USAGE;
+ 				}
+-				rc = parse_username(value, parsed_info);
+-				if (rc) {
+-					fprintf(stderr,
+-						"problem parsing username\n");
+-					return rc;
++				saved_username = strdup(value);
++				if (!saved_username) {
++					fprintf(stderr, "Unable to allocate memory!\n");
++					return EX_SYSERR;
+ 				}
+ 				goto nocopy;
+ 			}
+@@ -906,9 +924,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;
++				} else if (!strncmp(value, "krb5", 4)) {
++					parsed_info->got_password = 1;
++					krb5_auth = true;
++				}
+ 			}
+ 			break;
+ 
+@@ -964,7 +985,7 @@ parse_options(const char *data, struct parsed_mount_info *parsed_info)
+ 					"invalid credential file name specified\n");
+ 				return EX_USAGE;
+ 			}
+-			rc = open_cred_file(value, parsed_info);
++			rc = open_cred_file(value, parsed_info, &saved_username);
+ 			if (rc) {
+ 				fprintf(stderr,
+ 					"error %d (%s) opening credential file %s\n",
+@@ -1183,6 +1204,22 @@ nocopy:
+ 		data = next_keyword;
+ 	}
+ 
++	if (saved_username) {
++		if (krb5_auth) {
++			strlcpy(parsed_info->username, saved_username,
++				sizeof(parsed_info->username));
++			parsed_info->got_user = 1;
++		} else {
++			rc = parse_username(saved_username, parsed_info);
++			free(saved_username);
++			if (rc) {
++				fprintf(stderr, "Unable to parse username!\n");
++				return rc;
++			}
++		}
++	}
++
++
+ 	/* special-case the uid and gid */
+ 	if (got_uid) {
+ 		word_len = snprintf(txtbuf, sizeof(txtbuf), "%u", uid);
+@@ -1927,8 +1964,8 @@ restore_privs:
+ 		if (dacrc)
+ 			rc = rc ? rc : dacrc;
+ 	} else {
+-		setfsuid(oldfsuid);
+-		setfsgid(oldfsgid);
++		uid_t __attribute__((unused)) uignore = setfsuid(oldfsuid);
++		gid_t __attribute__((unused)) gignore = setfsgid(oldfsgid);
+ 	}
+ 
+ 	return rc;
+diff --git a/setcifsacl.c b/setcifsacl.c
+index 502c839..29b7b93 100644
+--- a/setcifsacl.c
++++ b/setcifsacl.c
+@@ -765,7 +765,7 @@ setcifsacl_usage(void)
+ 	"\n\t-S	Replace existing ACL with ACE(s), separated by a comma\n");
+ 	fprintf(stderr,
+ 	"\tsetcifsacl -S \"ACL:Administrator:ALLOWED/0x0/D\" <file_name>\n");
+-	fprintf(stderr, "\nRefer to setcifsacl(8) manpage for details\n");
++	fprintf(stderr, "\nRefer to setcifsacl(1) manpage for details\n");
+ }
+ 
+ int
diff --git a/cifs-utils.spec b/cifs-utils.spec
index d312967..36b006b 100644
--- a/cifs-utils.spec
+++ b/cifs-utils.spec
@@ -16,6 +16,8 @@ Source0:        ftp://ftp.samba.org/pub/linux-cifs/cifs-utils/%{name}-%{version}
 BuildRequires:  libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel
 Requires:       keyutils
 
+Patch0:         cifs-utils-5.7-pre.patch
+
 %description
 The SMB/CIFS protocol is a standard file sharing protocol widely deployed
 on Microsoft Windows machines. This package contains tools for mounting
@@ -26,6 +28,7 @@ file system.
 
 %prep
 %setup -q -n %{name}-%{version}%{pre_release}
+%patch0 -p1
 
 %build
 %configure --prefix=/usr
@@ -60,6 +63,9 @@ rm -rf %{buildroot}
 %config(noreplace) %{_sysconfdir}/request-key.d/cifs.spnego.conf
 
 %changelog
+* Fri Aug 24 2012 Jeff Layton <jlayton at redhat.com> 5.6-2
+- update to current upstream head
+
 * Thu Jul 26 2012 Jeff Layton <jlayton at redhat.com> 5.6-1
 - update to 5.6
 


More information about the scm-commits mailing list