[cifs-utils/f18] Update to 5.8-pre1

Jeff Layton jlayton at fedoraproject.org
Sun Nov 4 15:11:22 UTC 2012


commit 911bbd2790ec6293105e085851d604ecf8c9c108
Author: Jeff Layton <jlayton at redhat.com>
Date:   Sun Nov 4 10:10:50 2012 -0500

    Update to 5.8-pre1

 cifs-utils-5.8-pre1.patch |  973 +++++++++++++++++++++++++++++++++++++++++++++
 cifs-utils.spec           |    7 +-
 2 files changed, 979 insertions(+), 1 deletions(-)
---
diff --git a/cifs-utils-5.8-pre1.patch b/cifs-utils-5.8-pre1.patch
new file mode 100644
index 0000000..113345b
--- /dev/null
+++ b/cifs-utils-5.8-pre1.patch
@@ -0,0 +1,973 @@
+diff --git a/cifs.idmap.8.in b/cifs.idmap.8.in
+index efec7b6..c022402 100644
+--- a/cifs.idmap.8.in
++++ b/cifs.idmap.8.in
+@@ -22,7 +22,7 @@
+ cifs.idmap \- Userspace helper for mapping ids for Common Internet File System (CIFS)
+ .SH "SYNOPSIS"
+ .HP \w'\ 'u
+-cifs\&.idmap [\-\-version|\-v] {keyid}
++cifs.idmap [--help|-h] [--timeout|-t] [--version|-v] {keyid}
+ .SH "DESCRIPTION"
+ .PP
+ This tool is part of the cifs-utils suite\&.
+@@ -46,6 +46,16 @@ cifs\&.idmap works in conjuction with winbind facility of Samba suite to map own
+ In case winbind and cifs.idmap facilities are unavailable, file objects in a mounted share are assigned uid and gid of the credentials of the process that mounted the share\&. So it is strongly recomemended to use mount options of uid and gid to specify a default uid and gid to map owner SIDs and group SIDs respectively in case services of winbind and cifs.idmap facility are unavailable\&.
+ .SH "OPTIONS"
+ .PP
++--help|-h
++.RS
++Print the usage message and exit.
++.RE
++.PP
++--timeout|-t
++.RS 4
++Set the expiration timer, in seconds on the key. The default is 600 seconds (10 minutes). Setting this to 0 will cause the key to never expire.
++.RE
++.PP
+ \-\-version|\-v
+ .RS 4
+ Print version number and exit\&.
+diff --git a/cifs.idmap.c b/cifs.idmap.c
+index 80802d7..4109ca0 100644
+--- a/cifs.idmap.c
++++ b/cifs.idmap.c
+@@ -42,35 +42,76 @@
+ #include <limits.h>
+ #include <wbclient.h>
+ 
++#include "cifsacl.h"
++
+ static const char *prog = "cifs.idmap";
+ 
++static const struct option long_options[] = {
++	{"help", 0, NULL, 'h'},
++	{"timeout", 1, NULL, 't'},
++	{"version", 0, NULL, 'v'},
++	{NULL, 0, NULL, 0}
++};
++
+ static void usage(void)
+ {
+-	fprintf(stderr, "Usage: %s key_serial\n", prog);
++	fprintf(stderr, "Usage: %s [-h] [-v] [-t timeout] key_serial\n", prog);
+ }
+ 
+-char *strget(const char *str, char *substr)
++char *strget(const char *str, const char *substr)
+ {
+ 	int len, sublen, retlen;
+-	char *retstr, *substrptr;
++	char *substrptr;
+ 
+-	sublen = strlen(substr);
++	/* find the prefix */
+ 	substrptr = strstr(str, substr);
+-	if (substrptr) {
+-		len = strlen(substrptr);
+-		substrptr += sublen;
+-
+-		retlen = len - sublen;
+-		if (retlen > 0) {
+-			retstr = malloc(retlen + 1);
+-			if (retstr) {
+-				strncpy(retstr, substrptr, retlen);
+-				return retstr;
+-			}
+-		}
+-	}
++	if (!substrptr)
++		return substrptr;
++
++	/* skip over it */
++	sublen = strlen(substr);
++	substrptr += sublen;
++
++	/* if there's nothing after the prefix, return NULL */
++	if (*substrptr == '\0')
++		return NULL;
+ 
+-	return NULL;
++	return substrptr;
++}
++
++/*
++ * Convert a string representation of unsigned int into a numeric one. Also
++ * check for incomplete string conversion and overflow.
++ */
++static int
++str_to_uint(const char *src, unsigned int *dst)
++{
++	unsigned long tmp;
++	char *end;
++
++	errno = 0;
++	tmp = strtoul(src, &end, 0);
++
++	if (*end != '\0')
++		return EINVAL;
++	if (tmp > UINT_MAX)
++		return EOVERFLOW;
++
++	*dst = (unsigned int)tmp;
++	return 0;
++}
++
++/*
++ * Winbind keeps wbcDomainSid fields in host-endian. So, we must convert it
++ * to little endian since the kernel will expect that.
++ */
++static void
++convert_sid_endianness(struct cifs_sid *sid)
++{
++	int i;
++
++	for (i = 0; i < sid->num_subauth; i++)
++		sid->sub_auth[i] = htole32(sid->sub_auth[i]);
+ }
+ 
+ static int
+@@ -136,12 +177,20 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
+ 
+ 	sidstr = strget(key_descr, "oi:");
+ 	if (sidstr) {
+-		uid = atoi(sidstr);
+-		syslog(LOG_DEBUG, "SID: %s, uid: %d", sidstr, uid);
++		rc = str_to_uint(sidstr, (unsigned int *)&uid);
++		if (rc) {
++			syslog(LOG_ERR, "Unable to convert %s to uid: %s",
++				sidstr, strerror(rc));
++			goto cifs_idmap_ret;
++		}
++
++		syslog(LOG_DEBUG, "SID: %s, uid: %u", sidstr, uid);
+ 		rc = wbcUidToSid(uid, &sid);
+ 		if (rc)
+-			syslog(LOG_DEBUG, "uid %d to SID  error: %d", uid, rc);
+-		if (!rc) { /* SID has been mapped to a uid */
++			syslog(LOG_DEBUG, "uid %u to SID  error: %d", uid, rc);
++		if (!rc) {
++			/* SID has been mapped to a uid */
++			convert_sid_endianness((struct cifs_sid *)&sid);
+ 			rc = keyctl_instantiate(key, &sid,
+ 					sizeof(struct wbcDomainSid), 0);
+ 			if (rc)
+@@ -154,12 +203,20 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
+ 
+ 	sidstr = strget(key_descr, "gi:");
+ 	if (sidstr) {
+-		gid = atoi(sidstr);
+-		syslog(LOG_DEBUG, "SID: %s, gid: %d", sidstr, gid);
++		rc = str_to_uint(sidstr, (unsigned int *)&gid);
++		if (rc) {
++			syslog(LOG_ERR, "Unable to convert %s to gid: %s",
++				sidstr, strerror(rc));
++			goto cifs_idmap_ret;
++		}
++
++		syslog(LOG_DEBUG, "SID: %s, gid: %u", sidstr, gid);
+ 		rc = wbcGidToSid(gid, &sid);
+ 		if (rc)
+-			syslog(LOG_DEBUG, "gid %d to SID error: %d", gid, rc);
+-		if (!rc) { /* SID has been mapped to a gid */
++			syslog(LOG_DEBUG, "gid %u to SID error: %d", gid, rc);
++		if (!rc) {
++			/* SID has been mapped to a gid */
++			convert_sid_endianness((struct cifs_sid *)&sid);
+ 			rc = keyctl_instantiate(key, &sid,
+ 					sizeof(struct wbcDomainSid), 0);
+ 			if (rc)
+@@ -174,32 +231,46 @@ cifs_idmap(const key_serial_t key, const char *key_descr)
+ 	syslog(LOG_DEBUG, "Invalid key: %s", key_descr);
+ 
+ cifs_idmap_ret:
+-	if (sidstr)
+-		free(sidstr);
+-
+ 	return rc;
+ }
+ 
+ int main(const int argc, char *const argv[])
+ {
+ 	int c;
+-	long rc = 1;
++	long rc;
+ 	key_serial_t key = 0;
+ 	char *buf;
++	unsigned int timeout = 600; /* default idmap cache timeout */
+ 
+ 	openlog(prog, 0, LOG_DAEMON);
+ 
+-	while ((c = getopt_long(argc, argv, "v", NULL, NULL)) != -1) {
++	while ((c = getopt_long(argc, argv, "ht:v",
++					long_options, NULL)) != -1) {
+ 		switch (c) {
++		case 'h':
++			rc = 0;
++			usage();
++			goto out;
++		case 't':
++			rc = str_to_uint(optarg, &timeout);
++			if (rc) {
++				syslog(LOG_ERR, "bad timeout value %s: %s",
++					optarg, strerror(rc));
++				goto out;
++			}
++			break;
+ 		case 'v':
++			rc = 0;
+ 			printf("version: %s\n", VERSION);
+ 			goto out;
+ 		default:
++			rc = EINVAL;
+ 			syslog(LOG_ERR, "unknown option: %c", c);
+ 			goto out;
+ 		}
+ 	}
+ 
++	rc = 1;
+ 	/* is there a key? */
+ 	if (argc <= optind) {
+ 		usage();
+@@ -215,6 +286,14 @@ int main(const int argc, char *const argv[])
+ 		goto out;
+ 	}
+ 
++	/* set timeout on key */
++	rc = keyctl_set_timeout(key, timeout);
++	if (rc == -1) {
++		syslog(LOG_ERR, "unable to set key timeout: %s",
++			strerror(errno));
++		goto out;
++	}
++
+ 	rc = keyctl_describe_alloc(key, &buf);
+ 	if (rc == -1) {
+ 		syslog(LOG_ERR, "keyctl_describe_alloc failed: %s",
+@@ -225,8 +304,7 @@ int main(const int argc, char *const argv[])
+ 
+ 	syslog(LOG_DEBUG, "key description: %s", buf);
+ 
+-	if ((strncmp(buf, "cifs.idmap", sizeof("cifs.idmap") - 1) == 0))
+-		rc = cifs_idmap(key, buf);
++	rc = cifs_idmap(key, buf);
+ out:
+ 	return rc;
+ }
+diff --git a/cifsacl.h b/cifsacl.h
+index 4ea7fd4..68fe0fd 100644
+--- a/cifsacl.h
++++ b/cifsacl.h
+@@ -83,7 +83,7 @@
+ #define NO_PROPAGATE_INHERIT_FLAG 0x04	/* NP */
+ #define INHERIT_ONLY_FLAG 0x08		/* IO */
+ #define INHERITED_ACE_FLAG 0x10		/* I */
+-#define VFLAGS 0x1f
++#define VFLAGS (OBJECT_INHERIT_FLAG|CONTAINER_INHERIT_FLAG|NO_PROPAGATE_INHERIT_FLAG|INHERIT_ONLY_FLAG|INHERITED_ACE_FLAG)
+ 
+ #define ACCESS_ALLOWED	0		/* ALLOWED */
+ #define ACCESS_DENIED	1		/* DENIED */
+@@ -94,15 +94,17 @@
+ #define COMPTYPE 0x2
+ #define COMPFLAG 0x4
+ #define COMPMASK 0x8
+-#define COMPALL 0xf /* COMPSID | COMPTYPE | COMPFLAG | COMPMASK */
++#define COMPALL (COMPSID|COMPTYPE|COMPFLAG|COMPMASK)
+ 
+-enum ace_action {
+-	acedelete = 0,
+-	acemodify,
+-	aceadd,
+-	aceset
+-};
++#define NUM_AUTHS (6)			/* number of authority fields */
++#define SID_MAX_SUB_AUTHORITIES (15)	/* max number of sub authority fields */
+ 
++/*
++ * While not indicated here, the structs below represent on-the-wire data
++ * structures. Any multi-byte values are expected to be little-endian!
++ *
++ * FIXME: should we change these to use endianness annotations?
++ */
+ struct cifs_ntsd {
+ 	uint16_t revision; /* revision level */
+ 	uint16_t type;
+@@ -110,20 +112,20 @@ struct cifs_ntsd {
+ 	uint32_t gsidoffset;
+ 	uint32_t sacloffset;
+ 	uint32_t dacloffset;
+-};
++} __attribute__((packed));
+ 
+ struct cifs_sid {
+ 	uint8_t revision; /* revision level */
+ 	uint8_t num_subauth;
+-	uint8_t authority[6];
+-	uint32_t sub_auth[5]; /* sub_auth[num_subauth] */
+-};
++	uint8_t authority[NUM_AUTHS];
++	uint32_t sub_auth[SID_MAX_SUB_AUTHORITIES];
++} __attribute__((packed));
+ 
+ struct cifs_ctrl_acl {
+ 	uint16_t revision; /* revision level */
+ 	uint16_t size;
+ 	uint32_t num_aces;
+-};
++} __attribute__((packed));
+ 
+ struct cifs_ace {
+ 	uint8_t type;
+@@ -131,6 +133,6 @@ struct cifs_ace {
+ 	uint16_t size;
+ 	uint32_t access_req;
+ 	struct cifs_sid sid; /* ie UUID of user or group who gets these perms */
+-};
++} __attribute__((packed));
+ 
+ #endif /* CIFSACL_H */
+diff --git a/configure.ac b/configure.ac
+index f969b37..07df3be 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.7], [linux-cifs at vger.kernel.org], [cifs-utils], [https://wiki.samba.org/index.php/LinuxCIFS_utils])
++AC_INIT([cifs-utils], [5.7.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 8cbdb1d..b832c50 100644
+--- a/getcifsacl.c
++++ b/getcifsacl.c
+@@ -38,7 +38,7 @@
+ #include <sys/xattr.h>
+ #include "cifsacl.h"
+ 
+-static const char *prog = "getcifsacl";
++static const char *prog;
+ 
+ static void
+ print_each_ace_mask(uint32_t mask)
+@@ -171,22 +171,37 @@ print_ace_type(uint8_t acetype, int raw)
+ 	}
+ }
+ 
++/*
++ * Winbind keeps wbcDomainSid fields in host-endian. So, we must convert from
++ * little endian here so that winbind will understand correctly.
++ */
++static void
++convert_sid_endianness(struct cifs_sid *sid)
++{
++	int i;
++
++	for (i = 0; i < sid->num_subauth; i++)
++		sid->sub_auth[i] = le32toh(sid->sub_auth[i]);
++}
++
+ static void
+-print_sid(struct wbcDomainSid *sidptr, int raw)
++print_sid(struct cifs_sid *sidptr, int raw)
+ {
+ 	int i;
+-	int num_auths;
+-	int num_auth = MAX_NUM_AUTHS;
+ 	wbcErr rc;
+ 	char *domain_name = NULL;
+ 	char *sidname = NULL;
+ 	enum wbcSidType sntype;
++	unsigned long long id_auth_val;
++
++	convert_sid_endianness(sidptr);
+ 
+ 	if (raw)
+ 		goto print_sid_raw;
+ 
+-	rc = wbcLookupSid(sidptr, &domain_name, &sidname, &sntype);
+-	if (!rc) {
++	rc = wbcLookupSid((struct wbcDomainSid *)sidptr, &domain_name,
++				&sidname, &sntype);
++	if (WBC_ERROR_IS_OK(rc)) {
+ 		printf("%s", domain_name);
+ 		if (strlen(domain_name))
+ 			printf("%c", '\\');
+@@ -195,29 +210,41 @@ print_sid(struct wbcDomainSid *sidptr, int raw)
+ 	}
+ 
+ print_sid_raw:
+-	num_auths = sidptr->num_auths;
+-	printf("S");
+-	printf("-%d", sidptr->sid_rev_num);
+-	for (i = 0; i < num_auth; ++i)
+-		if (sidptr->id_auth[i])
+-			printf("-%d", sidptr->id_auth[i]);
+-	for (i = 0; i < num_auths; i++)
+-		printf("-%u", le32toh(sidptr->sub_auths[i]));
++	printf("S-%hhu", sidptr->revision);
++
++	id_auth_val = (unsigned long long)sidptr->authority[5];
++	id_auth_val += (unsigned long long)sidptr->authority[4] << 8;
++	id_auth_val += (unsigned long long)sidptr->authority[3] << 16;
++	id_auth_val += (unsigned long long)sidptr->authority[2] << 24;
++	id_auth_val += (unsigned long long)sidptr->authority[1] << 32;
++	id_auth_val += (unsigned long long)sidptr->authority[0] << 48;
++
++	/*
++	 * MS-DTYP states that if the authority is >= 2^32, then it should be
++	 * expressed as a hex value.
++	 */
++	if (id_auth_val <= UINT_MAX)
++		printf("-%llu", id_auth_val);
++	else
++		printf("-0x%llx", id_auth_val);
++
++	for (i = 0; i < sidptr->num_subauth; i++)
++		printf("-%u", sidptr->sub_auth[i]);
+ }
+ 
+ static void
+ print_ace(struct cifs_ace *pace, char *end_of_acl, int raw)
+ {
+-	/* validate that we do not go past end of acl */
+-
++	/* 16 == size of cifs_ace sans the cifs_sid */
+ 	if (le16toh(pace->size) < 16)
+ 		return;
+ 
++	/* validate that we do not go past end of acl */
+ 	if (end_of_acl < (char *)pace + le16toh(pace->size))
+ 		return;
+ 
+ 	printf("ACL:");
+-	print_sid((struct wbcDomainSid *)&pace->sid, raw);
++	print_sid((struct cifs_sid *)&pace->sid, raw);
+ 	printf(":");
+ 	print_ace_type(pace->type, raw);
+ 	printf("/");
+@@ -261,14 +288,14 @@ parse_dacl(struct cifs_ctrl_acl *pdacl, char *end_of_acl, int raw)
+ }
+ 
+ static int
+-parse_sid(struct wbcDomainSid *psid, char *end_of_acl, char *title, int raw)
++parse_sid(struct cifs_sid *psid, char *end_of_acl, char *title, int raw)
+ {
+ 	if (end_of_acl < (char *)psid + 8)
+ 		return -EINVAL;
+ 
+ 	if (title)
+ 		printf("%s:", title);
+-	print_sid((struct wbcDomainSid *)psid, raw);
++	print_sid((struct cifs_sid *)psid, raw);
+ 	printf("\n");
+ 
+ 	return 0;
+@@ -280,15 +307,15 @@ parse_sec_desc(struct cifs_ntsd *pntsd, ssize_t acl_len, int raw)
+ 	int rc;
+ 	uint32_t dacloffset;
+ 	char *end_of_acl = ((char *)pntsd) + acl_len;
+-	struct wbcDomainSid *owner_sid_ptr, *group_sid_ptr;
++	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+ 	struct cifs_ctrl_acl *dacl_ptr; /* no need for SACL ptr */
+ 
+ 	if (pntsd == NULL)
+ 		return -EIO;
+ 
+-	owner_sid_ptr = (struct wbcDomainSid *)((char *)pntsd +
++	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ 				le32toh(pntsd->osidoffset));
+-	group_sid_ptr = (struct wbcDomainSid *)((char *)pntsd +
++	group_sid_ptr = (struct cifs_sid *)((char *)pntsd +
+ 				le32toh(pntsd->gsidoffset));
+ 	dacloffset = le32toh(pntsd->dacloffset);
+ 	dacl_ptr = (struct cifs_ctrl_acl *)((char *)pntsd + dacloffset);
+@@ -333,6 +360,7 @@ main(const int argc, char *const argv[])
+ 	size_t bufsize = BUFSIZE;
+ 	char *filename, *attrval;
+ 
++	prog = basename(argv[0]);
+ 	openlog(prog, 0, LOG_DAEMON);
+ 
+ 	while ((c = getopt_long(argc, argv, "r:v", NULL, NULL)) != -1) {
+diff --git a/mount.cifs.c b/mount.cifs.c
+index 756fce2..9cf58a5 100644
+--- a/mount.cifs.c
++++ b/mount.cifs.c
+@@ -1335,6 +1335,7 @@ static int parse_unc(const char *unc_name, struct parsed_mount_info *parsed_info
+ 	}
+ 
+ 	/* Set up "host" and "share" pointers based on UNC format. */
++	/* TODO: Remove support for NFS syntax as of cifs-utils-6.0. */
+ 	if (strncmp(unc_name, "//", 2) && strncmp(unc_name, "\\\\", 2)) {
+ 		/*
+ 		 * check for nfs syntax (server:/share/prepath)
+@@ -1351,6 +1352,9 @@ static int parse_unc(const char *unc_name, struct parsed_mount_info *parsed_info
+ 		share++;
+ 		if (*share == '/')
+ 			++share;
++		fprintf(stderr, "WARNING: using NFS syntax for mounting CIFS "
++			"shares is deprecated and will be removed in cifs-utils"
++			"-6.0. Please migrate to UNC syntax.\n");
+ 	} else {
+ 		host = unc_name + 2;
+ 		hostlen = strcspn(host, "/\\");
+diff --git a/setcifsacl.1 b/setcifsacl.1
+index 550d23d..3dd755c 100644
+--- a/setcifsacl.1
++++ b/setcifsacl.1
+@@ -30,6 +30,10 @@ This tool is part of the cifs-utils suite\&.
+ setcifsacl is a userspace helper program for the Linux CIFS client file system.  It is intended to alter an ACL of a security descriptor for a file system object.  It is best utilized when an option of cifsacl is specified when mounting a cifs share in conjunction with winbind facility of Samba suite.  Whether a security descriptor to be set is applied or not is determined by the CIFS/SMB server.
+ .SH "OPTIONS"
+ .PP
++-h
++.RS 4
++Print usage message and exit.
++.RE
+ \-v
+ .RS 4
+ Print version number and exit\&.
+diff --git a/setcifsacl.c b/setcifsacl.c
+index 29b7b93..5016264 100644
+--- a/setcifsacl.c
++++ b/setcifsacl.c
+@@ -39,23 +39,42 @@
+ #include <sys/xattr.h>
+ #include "cifsacl.h"
+ 
+-static const char *prog = "setcifsacl";
++static const char *prog;
++
++enum setcifsacl_actions {
++	ActUnknown = -1,
++	ActDelete,
++	ActModify,
++	ActAdd,
++	ActSet
++};
+ 
+ static void
+-copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+-		int numaces, int acessize)
++copy_cifs_sid(struct cifs_sid *dst, const struct cifs_sid *src)
+ {
+ 	int i;
+ 
++	dst->revision = src->revision;
++	dst->num_subauth = src->num_subauth;
++	for (i = 0; i < NUM_AUTHS; i++)
++		dst->authority[i] = src->authority[i];
++	for (i = 0; i < src->num_subauth; i++)
++		dst->sub_auth[i] = src->sub_auth[i];
++}
++
++static void
++copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
++		int numaces, int acessize)
++{
+ 	int osidsoffset, gsidsoffset, dacloffset;
+ 	struct cifs_sid *owner_sid_ptr, *group_sid_ptr;
+ 	struct cifs_sid *nowner_sid_ptr, *ngroup_sid_ptr;
+ 	struct cifs_ctrl_acl *dacl_ptr, *ndacl_ptr;
+ 
+ 	/* copy security descriptor control portion */
+-	osidsoffset = htole32(pntsd->osidoffset);
+-	gsidsoffset = htole32(pntsd->gsidoffset);
+-	dacloffset = htole32(pntsd->dacloffset);
++	osidsoffset = le32toh(pntsd->osidoffset);
++	gsidsoffset = le32toh(pntsd->gsidoffset);
++	dacloffset = le32toh(pntsd->dacloffset);
+ 
+ 	pnntsd->revision = pntsd->revision;
+ 	pnntsd->type = pntsd->type;
+@@ -73,24 +92,12 @@ copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ 	/* copy owner sid */
+ 	owner_sid_ptr = (struct cifs_sid *)((char *)pntsd + osidsoffset);
+ 	nowner_sid_ptr = (struct cifs_sid *)((char *)pnntsd + osidsoffset);
+-
+-	nowner_sid_ptr->revision = owner_sid_ptr->revision;
+-	nowner_sid_ptr->num_subauth = owner_sid_ptr->num_subauth;
+-	for (i = 0; i < 6; i++)
+-		nowner_sid_ptr->authority[i] = owner_sid_ptr->authority[i];
+-	for (i = 0; i < 5; i++)
+-		nowner_sid_ptr->sub_auth[i] = owner_sid_ptr->sub_auth[i];
++	copy_cifs_sid(nowner_sid_ptr, owner_sid_ptr);
+ 
+ 	/* copy group sid */
+ 	group_sid_ptr = (struct cifs_sid *)((char *)pntsd + gsidsoffset);
+ 	ngroup_sid_ptr = (struct cifs_sid *)((char *)pnntsd + gsidsoffset);
+-
+-	ngroup_sid_ptr->revision = group_sid_ptr->revision;
+-	ngroup_sid_ptr->num_subauth = group_sid_ptr->num_subauth;
+-	for (i = 0; i < 6; i++)
+-		ngroup_sid_ptr->authority[i] = group_sid_ptr->authority[i];
+-	for (i = 0; i < 5; i++)
+-		ngroup_sid_ptr->sub_auth[i] = group_sid_ptr->sub_auth[i];
++	copy_cifs_sid(ngroup_sid_ptr, group_sid_ptr);
+ 
+ 	return;
+ }
+@@ -98,20 +105,13 @@ copy_sec_desc(const struct cifs_ntsd *pntsd, struct cifs_ntsd *pnntsd,
+ static int
+ copy_ace(struct cifs_ace *dace, struct cifs_ace *sace)
+ {
+-	int i;
+-
+ 	dace->type = sace->type;
+ 	dace->flags = sace->flags;
+-	dace->access_req = htole32(sace->access_req);
++	dace->access_req = sace->access_req;
+ 
+-	dace->sid.revision = sace->sid.revision;
+-	dace->sid.num_subauth = sace->sid.num_subauth;
+-	for (i = 0; i < 6; i++)
+-		dace->sid.authority[i] = sace->sid.authority[i];
+-	for (i = 0; i < sace->sid.num_subauth; i++)
+-		dace->sid.sub_auth[i] = sace->sid.sub_auth[i];
++	copy_cifs_sid(&dace->sid, &sace->sid);
+ 
+-	dace->size = htole16(sace->size);
++	dace->size = sace->size;
+ 
+ 	return dace->size;
+ }
+@@ -126,7 +126,7 @@ compare_aces(struct cifs_ace *sace, struct cifs_ace *dace, int compflags)
+ 			return 0;
+ 		if (dace->sid.num_subauth != sace->sid.num_subauth)
+ 			return 0;
+-		for (i = 0; i < 6; i++) {
++		for (i = 0; i < NUM_AUTHS; i++) {
+ 			if (dace->sid.authority[i] != sace->sid.authority[i])
+ 				return 0;
+ 		}
+@@ -147,7 +147,7 @@ compare_aces(struct cifs_ace *sace, struct cifs_ace *dace, int compflags)
+ 	}
+ 
+ 	if (compflags & COMPMASK) {
+-		if (dace->access_req != htole32(sace->access_req))
++		if (dace->access_req != sace->access_req)
+ 			return 0;
+ 	}
+ 
+@@ -329,19 +329,16 @@ get_numfaces(struct cifs_ntsd *pntsd, ssize_t acl_len,
+ 	struct cifs_ctrl_acl *ldaclptr;
+ 	char *end_of_acl = ((char *)pntsd) + acl_len;
+ 
+-	if (pntsd == NULL)
+-		return 0;
+-
+ 	dacloffset = le32toh(pntsd->dacloffset);
+ 	if (!dacloffset)
+ 		return 0;
+-	else {
+-		ldaclptr = (struct cifs_ctrl_acl *)((char *)pntsd + dacloffset);
+-		/* validate that we do not go past end of acl */
+-		if (end_of_acl >= (char *)ldaclptr + le16toh(ldaclptr->size)) {
+-			numfaces = le32toh(ldaclptr->num_aces);
+-			*daclptr = ldaclptr;
+-		}
++
++	ldaclptr = (struct cifs_ctrl_acl *)((char *)pntsd + dacloffset);
++
++	/* validate that we do not go past end of acl */
++	if (end_of_acl >= (char *)ldaclptr + le16toh(ldaclptr->size)) {
++		numfaces = le32toh(ldaclptr->num_aces);
++		*daclptr = ldaclptr;
+ 	}
+ 
+ 	return numfaces;
+@@ -391,33 +388,40 @@ build_fetched_aces_ret:
+ static int
+ verify_ace_sid(char *sidstr, struct cifs_sid *sid)
+ {
+-	int rc;
+-	char *lstr;
+-	struct passwd *winpswdptr;
+-
+-	lstr = strstr(sidstr, "\\"); /* everything before | */
+-	if (lstr)
+-		++lstr;
+-	else
+-		lstr = sidstr;
+-
+-	/* Check if it is a (raw) SID (string) */
+-	rc = wbcStringToSid(lstr, (struct wbcDomainSid *)sid);
+-	if (!rc)
+-		return rc;
+-
+-	/* Check if it a name (string) which can be resolved to a SID*/
+-	rc = wbcGetpwnam(lstr, &winpswdptr);
+-	if (rc) {
+-		printf("%s: Invalid user name: %s\n", __func__, sidstr);
+-		return rc;
+-	}
+-	rc = wbcUidToSid(winpswdptr->pw_uid, (struct wbcDomainSid *)sid);
+-	if (rc) {
+-		printf("%s: Invalid user: %s\n", __func__, sidstr);
++	int i;
++	wbcErr rc;
++	char *name, *domain;
++	enum wbcSidType type;
++
++	name = strchr(sidstr, '\\');
++	if (!name) {
++		/* might be a raw string representation of SID */
++		rc = wbcStringToSid(sidstr, (struct wbcDomainSid *)sid);
++		if (WBC_ERROR_IS_OK(rc))
++			goto fix_endianness;
++
++		domain = "";
++		name = sidstr;
++	} else {
++		domain = sidstr;
++		*name = '\0';
++		++name;
++	}
++
++	rc = wbcLookupName(domain, name, (struct wbcDomainSid *)sid, &type);
++	if (!WBC_ERROR_IS_OK(rc)) {
++		printf("%s: Error converting %s\\%s to SID: %s\n",
++			__func__, domain, name, wbcErrorString(rc));
+ 		return rc;
+ 	}
+ 
++fix_endianness:
++	/*
++	 * Winbind keeps wbcDomainSid fields in host-endian. So, we must
++	 * convert that to little endian since the server will expect that.
++	 */
++	for (i = 0; i < sid->num_subauth; i++)
++		sid->sub_auth[i] = htole32(sid->sub_auth[i]);
+ 	return 0;
+ }
+ 
+@@ -643,92 +647,77 @@ build_cmdline_aces_ret:
+ }
+ 
+ static char **
+-parse_cmdline_aces(char *optarg, int numcaces)
++parse_cmdline_aces(char *acelist, int numcaces)
+ {
+ 	int i = 0, len;
+ 	char *acestr, *vacestr, **arrptr = NULL;
+ 
+-	errno = EINVAL;
+ 	arrptr = (char **)malloc(numcaces * sizeof(char *));
+ 	if (!arrptr) {
+-		printf("%s: Error %d allocating char array\n", __func__, errno);
++		printf("%s: Unable to allocate char array\n", __func__);
+ 		return NULL;
+ 	}
+ 
+ 	while (i < numcaces) {
+-		acestr = strtok(optarg, ","); /* everything before , */
+-		if (acestr) {
+-			vacestr = strstr(acestr, "ACL:"); /* ace as ACL:*" */
+-			if (vacestr) {
+-				vacestr = strchr(vacestr, ':');
+-				if (vacestr)
+-					++vacestr; /* go past : */
+-				if (vacestr) {
+-					len = strlen(vacestr);
+-					arrptr[i] = malloc(len + 1);
+-					if (!arrptr[i])
+-						goto parse_cmdline_aces_ret;
+-					strcpy(arrptr[i], vacestr);
+-					++i;
+-				} else
+-					goto parse_cmdline_aces_ret;
+-			} else
+-				goto parse_cmdline_aces_ret;
+-		} else
+-			goto parse_cmdline_aces_ret;
+-		optarg = NULL;
+-	}
+-	errno = 0;
++		acestr = strtok(acelist, ","); /* everything before , */
++		if (!acestr)
++			goto parse_cmdline_aces_err;
++
++		vacestr = strstr(acestr, "ACL:"); /* ace as ACL:*" */
++		if (!vacestr)
++			goto parse_cmdline_aces_err;
++		vacestr += 4; /* skip past "ACL:" */
++		if (*vacestr) {
++			arrptr[i] = vacestr;
++			++i;
++		}
++		acelist = NULL;
++	}
+ 	return arrptr;
+ 
+-parse_cmdline_aces_ret:
+-	printf("%s: Error %d parsing ACEs\n", __func__, errno);
+-	for (;  i >= 0; --i)
+-		free(arrptr[i]);
++parse_cmdline_aces_err:
++	printf("%s: Error parsing ACEs\n", __func__);
+ 	free(arrptr);
+ 	return NULL;
+ }
+ 
++/* How many aces were provided on the command-line? Count the commas. */
+ static unsigned int
+-get_numcaces(const char *optarg)
++get_numcaces(const char *aces)
+ {
+ 	int i, len;
+-	unsigned int numcaces = 1;
++	unsigned int num = 1;
++	const char *current;
+ 
+-	if (!optarg)
+-		return 0;
++	current = aces;
++	while((current = strchr(current, ',')))
++		++num;
+ 
+-	len = strlen(optarg);
+-	for (i = 0; i < len; ++i) {
+-		if (*(optarg + i) == ',')
+-			++numcaces;
+-	}
+-
+-	return numcaces;
++	return num;
+ }
+ 
+ static int
+ setacl_action(struct cifs_ntsd *pntsd, struct cifs_ntsd **npntsd,
+ 		ssize_t *bufsize, struct cifs_ace **facesptr, int numfaces,
+ 		struct cifs_ace **cacesptr, int numcaces,
+-		int maction)
++		enum setcifsacl_actions maction)
+ {
+ 	int rc = 1;
+ 
+ 	switch (maction) {
+-	case 0:
++	case ActDelete:
+ 		rc = ace_delete(pntsd, npntsd, bufsize, facesptr,
+ 				numfaces, cacesptr, numcaces);
+ 		break;
+-	case 1:
++	case ActModify:
+ 		rc = ace_modify(pntsd, npntsd, bufsize, facesptr,
+ 				numfaces, cacesptr, numcaces);
+ 		break;
+-	case 2:
++	case ActAdd:
+ 		rc = ace_add(pntsd, npntsd, bufsize, facesptr,
+ 				numfaces, cacesptr, numcaces);
+ 		break;
+-	case 3:
++	case ActSet:
+ 		rc = ace_set(pntsd, npntsd, bufsize, cacesptr, numcaces);
+ 		break;
+ 	default:
+@@ -771,52 +760,62 @@ setcifsacl_usage(void)
+ int
+ main(const int argc, char *const argv[])
+ {
+-	int i, rc, c, numcaces, numfaces, maction = -1;
++	int i, rc, c, numcaces, numfaces;
++	enum setcifsacl_actions maction = ActUnknown;
+ 	ssize_t attrlen, bufsize = BUFSIZE;
+-	char *filename, *attrval, **arrptr = NULL;
++	char *ace_list, *filename, *attrval, **arrptr = NULL;
+ 	struct cifs_ctrl_acl *daclptr = NULL;
+ 	struct cifs_ace **cacesptr = NULL, **facesptr = NULL;
+ 	struct cifs_ntsd *ntsdptr = NULL;
+ 
++	prog = basename(argv[0]);
++
+ 	openlog(prog, 0, LOG_DAEMON);
+ 
+-	c = getopt(argc, argv, "v:D:M:a:S:?");
++	c = getopt(argc, argv, "hvD:M:a:S:");
+ 	switch (c) {
+-	case 'v':
+-		printf("Version: %s\n", VERSION);
+-		goto out;
+ 	case 'D':
+-		maction = 0;
++		maction = ActDelete;
++		ace_list = optarg;
+ 		break;
+ 	case 'M':
+-		maction = 1;
++		maction = ActModify;
++		ace_list = optarg;
+ 		break;
+ 	case 'a':
+-		maction = 2;
++		maction = ActAdd;
++		ace_list = optarg;
+ 		break;
+ 	case 'S':
+-		maction = 3;
++		maction = ActSet;
++		ace_list = optarg;
+ 		break;
+-	case '?':
++	case 'h':
+ 		setcifsacl_usage();
+ 		return 0;
++	case 'v':
++		printf("Version: %s\n", VERSION);
++		return 0;
+ 	default:
+-		break;
++		setcifsacl_usage();
++		return -1;
+ 	}
+ 
++	/* We expect 1 argument in addition to the option */
+ 	if (argc != 4) {
+ 		setcifsacl_usage();
+ 		return -1;
+ 	}
+ 	filename = argv[3];
+ 
+-	numcaces = get_numcaces(optarg);
+-	if (!numcaces) {
++	if (!ace_list) {
+ 		printf("%s: No valid ACEs specified\n", __func__);
+ 		return -1;
+ 	}
+ 
+-	arrptr = parse_cmdline_aces(optarg, numcaces);
++	numcaces = get_numcaces(ace_list);
++
++	arrptr = parse_cmdline_aces(ace_list, numcaces);
+ 	if (!arrptr)
+ 		goto setcifsacl_numcaces_ret;
+ 
+@@ -850,7 +849,7 @@ cifsacl:
+ 	}
+ 
+ 	numfaces = get_numfaces((struct cifs_ntsd *)attrval, attrlen, &daclptr);
+-	if (!numfaces && maction != 2) { /* if we are not adding aces */
++	if (!numfaces && maction != ActAdd) { /* if we are not adding aces */
+ 		printf("%s: Empty DACL\n", __func__);
+ 		goto setcifsacl_facenum_ret;
+ 	}
+@@ -870,7 +869,6 @@ cifsacl:
+ 		printf("%s: setxattr error: %s\n", __func__, strerror(errno));
+ 	goto setcifsacl_facenum_ret;
+ 
+-out:
+ 	return 0;
+ 
+ setcifsacl_action_ret:
+@@ -890,8 +888,6 @@ setcifsacl_cmdlineverify_ret:
+ 	free(cacesptr);
+ 
+ setcifsacl_cmdlineparse_ret:
+-	for (i = 0; i < numcaces; ++i)
+-		free(arrptr[i]);
+ 	free(arrptr);
+ 
+ setcifsacl_numcaces_ret:
diff --git a/cifs-utils.spec b/cifs-utils.spec
index 5350087..8bebab1 100644
--- a/cifs-utils.spec
+++ b/cifs-utils.spec
@@ -3,7 +3,7 @@
 
 Name:           cifs-utils
 Version:        5.7
-Release:        1%{pre_release}%{?dist}
+Release:        2%{pre_release}%{?dist}
 Summary:        Utilities for mounting and managing CIFS mounts
 
 Group:          System Environment/Daemons
@@ -13,6 +13,7 @@ BuildRoot:      %{_tmppath}/%{name}-%{version}%{pre_release}-%{release}-root-%(%
 
 Source0:        ftp://ftp.samba.org/pub/linux-cifs/cifs-utils/%{name}-%{version}%{pre_release}.tar.bz2
 
+Patch1:         cifs-utils-5.8-pre1.patch
 BuildRequires:  libcap-ng-devel libtalloc-devel krb5-devel keyutils-libs-devel autoconf automake libwbclient-devel
 Requires:       keyutils
 
@@ -26,6 +27,7 @@ file system.
 
 %prep
 %setup -q -n %{name}-%{version}%{pre_release}
+%patch1 -p1
 
 %build
 %configure --prefix=/usr
@@ -60,6 +62,9 @@ rm -rf %{buildroot}
 %config(noreplace) %{_sysconfdir}/request-key.d/cifs.spnego.conf
 
 %changelog
+* Sun Nov 04 2012 Jeff Layton <jlayton at redhat.com> 5.7-2
+- update to latest patches queued for 5.8. Mostly idmapping and ACL tool fixes.
+
 * Tue Oct 09 2012 Jeff Layton <jlayton at redhat.com> 5.7-1
 - update to 5.7
 


More information about the scm-commits mailing list