Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aada1bc9 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] remove unknown mount option warning message
  [CIFS] remove bkl usage from umount begin
  cifs: Fix incorrect return code being printed in cFYI messages
  [CIFS] cleanup asn handling for ntlmssp
  [CIFS] Copy struct *after* setting the port, instead of before.
  cifs: remove rw/ro options
  cifs: fix problems with earlier patches
  cifs: have cifs parse scope_id out of IPv6 addresses and use it
  [CIFS] Do not send tree disconnect if session is already disconnected
  [CIFS] Fix build break
  cifs: display scopeid in /proc/mounts
  cifs: add new routine for converting AF_INET and AF_INET6 addrs
  cifs: have cifs_show_options show forceuid/forcegid options
  cifs: remove unneeded NULL checks from cifs_show_options
parents 7e0d8a83 71a394fa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@ client generated ones by default (mount option "serverino" turned
on by default if server supports it).  Add forceuid and forcegid
mount options (so that when negotiating unix extensions specifying
which uid mounted does not immediately force the server's reported
uids to be overridden).
uids to be overridden).  Add support for scope moutn parm.

Version 1.58
------------
+49 −6
Original line number Diff line number Diff line
@@ -49,6 +49,7 @@
#define ASN1_OJI	6	/* Object Identifier  */
#define ASN1_OJD	7	/* Object Description */
#define ASN1_EXT	8	/* External */
#define ASN1_ENUM	10	/* Enumerated */
#define ASN1_SEQ	16	/* Sequence */
#define ASN1_SET	17	/* Set */
#define ASN1_NUMSTR	18	/* Numerical String */
@@ -78,10 +79,12 @@
#define SPNEGO_OID_LEN 7
#define NTLMSSP_OID_LEN  10
#define KRB5_OID_LEN  7
#define KRB5U2U_OID_LEN  8
#define MSKRB5_OID_LEN  7
static unsigned long SPNEGO_OID[7] = { 1, 3, 6, 1, 5, 5, 2 };
static unsigned long NTLMSSP_OID[10] = { 1, 3, 6, 1, 4, 1, 311, 2, 2, 10 };
static unsigned long KRB5_OID[7] = { 1, 2, 840, 113554, 1, 2, 2 };
static unsigned long KRB5U2U_OID[8] = { 1, 2, 840, 113554, 1, 2, 2, 3 };
static unsigned long MSKRB5_OID[7] = { 1, 2, 840, 48018, 1, 2, 2 };

/*
@@ -122,6 +125,28 @@ asn1_octet_decode(struct asn1_ctx *ctx, unsigned char *ch)
	return 1;
}

#if 0 /* will be needed later by spnego decoding/encoding of ntlmssp */
static unsigned char
asn1_enum_decode(struct asn1_ctx *ctx, __le32 *val)
{
	unsigned char ch;

	if (ctx->pointer >= ctx->end) {
		ctx->error = ASN1_ERR_DEC_EMPTY;
		return 0;
	}

	ch = *(ctx->pointer)++; /* ch has 0xa, ptr points to lenght octet */
	if ((ch) == ASN1_ENUM)  /* if ch value is ENUM, 0xa */
		*val = *(++(ctx->pointer)); /* value has enum value */
	else
		return 0;

	ctx->pointer++;
	return 1;
}
#endif

static unsigned char
asn1_tag_decode(struct asn1_ctx *ctx, unsigned int *tag)
{
@@ -476,10 +501,9 @@ decode_negTokenInit(unsigned char *security_blob, int length,
	unsigned int cls, con, tag, oidlen, rc;
	bool use_ntlmssp = false;
	bool use_kerberos = false;
	bool use_kerberosu2u = false;
	bool use_mskerberos = false;

	*secType = NTLM; /* BB eventually make Kerberos or NLTMSSP the default*/

	/* cifs_dump_mem(" Received SecBlob ", security_blob, length); */

	asn1_open(&ctx, security_blob, length);
@@ -515,6 +539,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		return 0;
	}

	/* SPNEGO */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding negTokenInit"));
		return 0;
@@ -526,6 +551,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		return 0;
	}

	/* negTokenInit */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding negTokenInit"));
		return 0;
@@ -537,6 +563,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		return 0;
	}

	/* sequence */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding 2nd part of negTokenInit"));
		return 0;
@@ -548,6 +575,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		return 0;
	}

	/* sequence of */
	if (asn1_header_decode
	    (&ctx, &sequence_end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding 2nd part of negTokenInit"));
@@ -560,6 +588,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		return 0;
	}

	/* list of security mechanisms */
	while (!asn1_eoc_decode(&ctx, sequence_end)) {
		rc = asn1_header_decode(&ctx, &end, &cls, &con, &tag);
		if (!rc) {
@@ -576,11 +605,15 @@ decode_negTokenInit(unsigned char *security_blob, int length,

				if (compare_oid(oid, oidlen, MSKRB5_OID,
						MSKRB5_OID_LEN) &&
						!use_kerberos)
						!use_mskerberos)
					use_mskerberos = true;
				else if (compare_oid(oid, oidlen, KRB5U2U_OID,
						     KRB5U2U_OID_LEN) &&
						     !use_kerberosu2u)
					use_kerberosu2u = true;
				else if (compare_oid(oid, oidlen, KRB5_OID,
						     KRB5_OID_LEN) &&
						     !use_mskerberos)
						     !use_kerberos)
					use_kerberos = true;
				else if (compare_oid(oid, oidlen, NTLMSSP_OID,
						     NTLMSSP_OID_LEN))
@@ -593,7 +626,12 @@ decode_negTokenInit(unsigned char *security_blob, int length,
		}
	}

	/* mechlistMIC */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		/* Check if we have reached the end of the blob, but with
		   no mechListMic (e.g. NTLMSSP instead of KRB5) */
		if (ctx.error == ASN1_ERR_DEC_EMPTY)
			goto decode_negtoken_exit;
		cFYI(1, ("Error decoding last part negTokenInit exit3"));
		return 0;
	} else if ((cls != ASN1_CTX) || (con != ASN1_CON)) {
@@ -602,6 +640,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
			 cls, con, tag, end, *end));
		return 0;
	}

	/* sequence */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding last part negTokenInit exit5"));
		return 0;
@@ -611,6 +651,7 @@ decode_negTokenInit(unsigned char *security_blob, int length,
			cls, con, tag, end, *end));
	}

	/* sequence of */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding last part negTokenInit exit 7"));
		return 0;
@@ -619,6 +660,8 @@ decode_negTokenInit(unsigned char *security_blob, int length,
			 cls, con, tag, end, *end));
		return 0;
	}

	/* general string */
	if (asn1_header_decode(&ctx, &end, &cls, &con, &tag) == 0) {
		cFYI(1, ("Error decoding last part negTokenInit exit9"));
		return 0;
@@ -630,13 +673,13 @@ decode_negTokenInit(unsigned char *security_blob, int length,
	}
	cFYI(1, ("Need to call asn1_octets_decode() function for %s",
		 ctx.pointer));	/* is this UTF-8 or ASCII? */

decode_negtoken_exit:
	if (use_kerberos)
		*secType = Kerberos;
	else if (use_mskerberos)
		*secType = MSKerberos;
	else if (use_ntlmssp)
		*secType = NTLMSSP;
		*secType = RawNTLMSSP;

	return 1;
}
+81 −76
Original line number Diff line number Diff line
@@ -333,6 +333,27 @@ cifs_destroy_inode(struct inode *inode)
	kmem_cache_free(cifs_inode_cachep, CIFS_I(inode));
}

static void
cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)
{
	seq_printf(s, ",addr=");

	switch (server->addr.sockAddr.sin_family) {
	case AF_INET:
		seq_printf(s, "%pI4", &server->addr.sockAddr.sin_addr.s_addr);
		break;
	case AF_INET6:
		seq_printf(s, "%pI6",
			   &server->addr.sockAddr6.sin6_addr.s6_addr);
		if (server->addr.sockAddr6.sin6_scope_id)
			seq_printf(s, "%%%u",
				   server->addr.sockAddr6.sin6_scope_id);
		break;
	default:
		seq_printf(s, "(unknown)");
	}
}

/*
 * cifs_show_options() is for displaying mount options in /proc/mounts.
 * Not all settable options are displayed but most of the important
@@ -343,55 +364,36 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
{
	struct cifs_sb_info *cifs_sb;
	struct cifsTconInfo *tcon;
	struct TCP_Server_Info *server;

	cifs_sb = CIFS_SB(m->mnt_sb);

	if (cifs_sb) {
	tcon = cifs_sb->tcon;
		if (tcon) {

	seq_printf(s, ",unc=%s", cifs_sb->tcon->treeName);
			if (tcon->ses) {
	if (tcon->ses->userName)
					seq_printf(s, ",username=%s",
					   tcon->ses->userName);
		seq_printf(s, ",username=%s", tcon->ses->userName);
	if (tcon->ses->domainName)
					seq_printf(s, ",domain=%s",
					   tcon->ses->domainName);
				server = tcon->ses->server;
				if (server) {
					seq_printf(s, ",addr=");
					switch (server->addr.sockAddr6.
						sin6_family) {
					case AF_INET6:
						seq_printf(s, "%pI6",
							   &server->addr.sockAddr6.sin6_addr);
						break;
					case AF_INET:
						seq_printf(s, "%pI4",
							   &server->addr.sockAddr.sin_addr.s_addr);
						break;
					}
				}
			}
			if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID) ||
			   !(tcon->unix_ext))
		seq_printf(s, ",domain=%s", tcon->ses->domainName);

	seq_printf(s, ",uid=%d", cifs_sb->mnt_uid);
			if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID) ||
			   !(tcon->unix_ext))
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
		seq_printf(s, ",forceuid");

	seq_printf(s, ",gid=%d", cifs_sb->mnt_gid);
			if (!tcon->unix_ext) {
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
		seq_printf(s, ",forcegid");

	cifs_show_address(s, tcon->ses->server);

	if (!tcon->unix_ext)
		seq_printf(s, ",file_mode=0%o,dir_mode=0%o",
					   cifs_sb->mnt_file_mode,
					   cifs_sb->mnt_dir_mode);
			}
	if (tcon->seal)
		seq_printf(s, ",seal");
	if (tcon->nocase)
		seq_printf(s, ",nocase");
	if (tcon->retry)
		seq_printf(s, ",hard");
		}
	if (cifs_sb->prepath)
		seq_printf(s, ",prepath=%s", cifs_sb->prepath);
	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
@@ -419,7 +421,7 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)

	seq_printf(s, ",rsize=%d", cifs_sb->rsize);
	seq_printf(s, ",wsize=%d", cifs_sb->wsize);
	}

	return 0;
}

@@ -535,9 +537,14 @@ static void cifs_umount_begin(struct super_block *sb)
	if (tcon == NULL)
		return;

	lock_kernel();
	read_lock(&cifs_tcp_ses_lock);
	if (tcon->tc_count == 1)
	if ((tcon->tc_count > 1) || (tcon->tidStatus == CifsExiting)) {
		/* we have other mounts to same share or we have
		   already tried to force umount this and woken up
		   all waiting network requests, nothing to do */
		read_unlock(&cifs_tcp_ses_lock);
		return;
	} else if (tcon->tc_count == 1)
		tcon->tidStatus = CifsExiting;
	read_unlock(&cifs_tcp_ses_lock);

@@ -552,9 +559,7 @@ static void cifs_umount_begin(struct super_block *sb)
		wake_up_all(&tcon->ses->server->response_q);
		msleep(1);
	}
/* BB FIXME - finish add checks for tidStatus BB */

	unlock_kernel();
	return;
}

+1 −1
Original line number Diff line number Diff line
@@ -83,7 +83,7 @@ enum securityEnum {
	NTLM,			/* Legacy NTLM012 auth with NTLM hash */
	NTLMv2,			/* Legacy NTLM auth with NTLMv2 hash */
	RawNTLMSSP,		/* NTLMSSP without SPNEGO, NTLMv2 hash */
	NTLMSSP,		/* NTLMSSP via SPNEGO, NTLMv2 hash */
/*	NTLMSSP, */ /* can use rawNTLMSSP instead of NTLMSSP via SPNEGO */
	Kerberos,		/* Kerberos via SPNEGO */
	MSKerberos,		/* MS Kerberos via SPNEGO */
};
+1 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ extern unsigned int smbCalcSize(struct smb_hdr *ptr);
extern unsigned int smbCalcSize_LE(struct smb_hdr *ptr);
extern int decode_negTokenInit(unsigned char *security_blob, int length,
			enum securityEnum *secType);
extern int cifs_inet_pton(const int, const char *source, void *dst);
extern int cifs_convert_address(char *src, void *dst);
extern int map_smb_to_linux_error(struct smb_hdr *smb, int logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
			    const struct cifsTconInfo *, int /* length of
Loading