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

Commit 1213959d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-linus' of git://git.samba.org/sfrench/cifs-2.6

Pull CIFS fixes from Steve French:
 "A set of cifs fixes most important of which is Pavel's fix for some
  problems with handling Windows reparse points and also the security
  fix for setfacl over a cifs mount to Samba removing part of the ACL.
  Both of these fixes are for stable as well.

  Also added most of copychunk (copy offload) support to cifs although I
  expect a final patch in that series (to fix handling of larger files)
  in a few days (had to hold off on that in order to incorporate some
  additional code review feedback).

  Also added support for O_DIRECT on forcedirectio mounts (needed in
  order to run some of the server benchmarks over cifs and smb2/smb3
  mounts)"

* 'for-linus' of git://git.samba.org/sfrench/cifs-2.6:
  [CIFS] Warn if SMB3 encryption required by server
  setfacl removes part of ACL when setting POSIX ACLs to Samba
  [CIFS] Set copychunk defaults
  CIFS: SMB2/SMB3 Copy offload support (refcopy) phase 1
  cifs: Use data structures to compute NTLMv2 response offsets
  [CIFS] O_DIRECT opens should work on directio mounts
  cifs: don't spam the logs on unexpected lookup errors
  cifs: change ERRnomem error mapping from ENOMEM to EREMOTEIO
  CIFS: Fix symbolic links usage
parents 673fdfe3 0cbaa53c
Loading
Loading
Loading
Loading
+24 −16
Original line number Diff line number Diff line
@@ -548,7 +548,13 @@ static int
CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
{
	int rc;
	unsigned int offset = CIFS_SESS_KEY_SIZE + 8;
	struct ntlmv2_resp *ntlmv2 = (struct ntlmv2_resp *)
	    (ses->auth_key.response + CIFS_SESS_KEY_SIZE);
	unsigned int hash_len;

	/* The MD5 hash starts at challenge_key.key */
	hash_len = ses->auth_key.len - (CIFS_SESS_KEY_SIZE +
		offsetof(struct ntlmv2_resp, challenge.key[0]));

	if (!ses->server->secmech.sdeschmacmd5) {
		cifs_dbg(VFS, "%s: can't generate ntlmv2 hash\n", __func__);
@@ -570,20 +576,21 @@ CalcNTLMv2_response(const struct cifs_ses *ses, char *ntlmv2_hash)
	}

	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED)
		memcpy(ses->auth_key.response + offset,
		memcpy(ntlmv2->challenge.key,
		       ses->ntlmssp->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
	else
		memcpy(ses->auth_key.response + offset,
		memcpy(ntlmv2->challenge.key,
		       ses->server->cryptkey, CIFS_SERVER_CHALLENGE_SIZE);
	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
		ses->auth_key.response + offset, ses->auth_key.len - offset);
				 ntlmv2->challenge.key, hash_len);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
		return rc;
	}

	/* Note that the MD5 digest over writes anon.challenge_key.key */
	rc = crypto_shash_final(&ses->server->secmech.sdeschmacmd5->shash,
		ses->auth_key.response + CIFS_SESS_KEY_SIZE);
				ntlmv2->ntlmv2_hash);
	if (rc)
		cifs_dbg(VFS, "%s: Could not generate md5 hash\n", __func__);

@@ -627,7 +634,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
	int rc;
	int baselen;
	unsigned int tilen;
	struct ntlmv2_resp *buf;
	struct ntlmv2_resp *ntlmv2;
	char ntlmv2_hash[16];
	unsigned char *tiblob = NULL; /* target info blob */

@@ -660,13 +667,14 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
	}
	ses->auth_key.len += baselen;

	buf = (struct ntlmv2_resp *)
	ntlmv2 = (struct ntlmv2_resp *)
			(ses->auth_key.response + CIFS_SESS_KEY_SIZE);
	buf->blob_signature = cpu_to_le32(0x00000101);
	buf->reserved = 0;
	buf->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
	get_random_bytes(&buf->client_chal, sizeof(buf->client_chal));
	buf->reserved2 = 0;
	ntlmv2->blob_signature = cpu_to_le32(0x00000101);
	ntlmv2->reserved = 0;
	/* Must be within 5 minutes of the server */
	ntlmv2->time = cpu_to_le64(cifs_UnixTimeToNT(CURRENT_TIME));
	get_random_bytes(&ntlmv2->client_chal, sizeof(ntlmv2->client_chal));
	ntlmv2->reserved2 = 0;

	memcpy(ses->auth_key.response + baselen, tiblob, tilen);

@@ -706,7 +714,7 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
	}

	rc = crypto_shash_update(&ses->server->secmech.sdeschmacmd5->shash,
		ses->auth_key.response + CIFS_SESS_KEY_SIZE,
		ntlmv2->ntlmv2_hash,
		CIFS_HMAC_MD5_HASH_SIZE);
	if (rc) {
		cifs_dbg(VFS, "%s: Could not update with response\n", __func__);
+7 −1
Original line number Diff line number Diff line
@@ -261,7 +261,7 @@ struct smb_version_operations {
	/* query path data from the server */
	int (*query_path_info)(const unsigned int, struct cifs_tcon *,
			       struct cifs_sb_info *, const char *,
			       FILE_ALL_INFO *, bool *);
			       FILE_ALL_INFO *, bool *, bool *);
	/* query file data from the server */
	int (*query_file_info)(const unsigned int, struct cifs_tcon *,
			       struct cifs_fid *, FILE_ALL_INFO *);
@@ -381,6 +381,9 @@ struct smb_version_operations {
	char * (*create_lease_buf)(u8 *, u8);
	/* parse lease context buffer and return oplock/epoch info */
	__u8 (*parse_lease_buf)(void *, unsigned int *);
	int (*clone_range)(const unsigned int, struct cifsFileInfo *src_file,
			struct cifsFileInfo *target_file, u64 src_off, u64 len,
			u64 dest_off);
};

struct smb_version_values {
@@ -855,6 +858,9 @@ struct cifs_tcon {
	__le64 vol_create_time;
	__u32 ss_flags;		/* sector size flags */
	__u32 perf_sector_size; /* best sector size for perf */
	__u32 max_chunks;
	__u32 max_bytes_chunk;
	__u32 max_bytes_copy;
#endif /* CONFIG_CIFS_SMB2 */
#ifdef CONFIG_CIFS_FSCACHE
	u64 resource_id;		/* server resource id */
+7 −1
Original line number Diff line number Diff line
@@ -697,7 +697,13 @@ struct ntlmssp2_name {
} __attribute__((packed));

struct ntlmv2_resp {
	union {
	    char ntlmv2_hash[CIFS_ENCPWD_SIZE];
	    struct {
		__u8 reserved[8];
		__u8 key[CIFS_SERVER_CHALLENGE_SIZE];
	    } __attribute__((packed)) challenge;
	} __attribute__((packed));
	__le32 blob_signature;
	__u32  reserved;
	__le64  time;
+5 −3
Original line number Diff line number Diff line
@@ -3369,11 +3369,13 @@ static __u16 ACL_to_cifs_posix(char *parm_data, const char *pACL,
		return 0;
	}
	cifs_acl->version = cpu_to_le16(1);
	if (acl_type == ACL_TYPE_ACCESS)
	if (acl_type == ACL_TYPE_ACCESS) {
		cifs_acl->access_entry_count = cpu_to_le16(count);
	else if (acl_type == ACL_TYPE_DEFAULT)
		cifs_acl->default_entry_count = __constant_cpu_to_le16(0xFFFF);
	} else if (acl_type == ACL_TYPE_DEFAULT) {
		cifs_acl->default_entry_count = cpu_to_le16(count);
	else {
		cifs_acl->access_entry_count = __constant_cpu_to_le16(0xFFFF);
	} else {
		cifs_dbg(FYI, "unknown ACL type %d\n", acl_type);
		return 0;
	}
+1 −1
Original line number Diff line number Diff line
@@ -756,7 +756,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
	/*	if it was once a directory (but how can we tell?) we could do
		shrink_dcache_parent(direntry); */
	} else if (rc != -EACCES) {
		cifs_dbg(VFS, "Unexpected lookup error %d\n", rc);
		cifs_dbg(FYI, "Unexpected lookup error %d\n", rc);
		/* We special case check for Access Denied - since that
		is a common return code */
	}
Loading