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

Commit 86ed5a93 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* git://git.kernel.org/pub/scm/linux/kernel/git/sfrench/cifs-2.6:
  [CIFS] Check that last search entry resume key is valid
  [CIFS] make sure we have the right resume info before calling CIFSFindNext
  [CIFS]  clean up error handling in cifs_unlink
  [CIFS] fix some settings of cifsAttrs after calling SetFileInfo and SetPathInfo
  cifs: explicitly revoke SPNEGO key after session setup
  cifs: Convert cifs to new aops.
  [CIFS] update DOS attributes in cifsInode if we successfully changed them
  cifs: remove NULL termination from rename target in CIFSSMBRenameOpenFIle
  cifs: work around samba returning -ENOENT on SetFileDisposition call
  cifs: fix inverted NULL check after kmalloc
  [CIFS] clean up upcall handling for dns_resolver keys
  [CIFS]  fix busy-file renames and refactor cifs_rename logic
  cifs: add function to set file disposition
  [CIFS] add constants for string lengths of keynames in SPNEGO upcall string
  cifs: move rename and delete-on-close logic into helper function
  cifs: have find_writeable_file prefer filehandles opened by same task
  cifs: don't use GFP_KERNEL with GFP_NOFS
  [CIFS] use common code for turning off ATTR_READONLY in cifs_unlink
  cifs: clean up variables in cifs_unlink
parents 835a1c09 b77d753c
Loading
Loading
Loading
Loading
+26 −9
Original line number Diff line number Diff line
@@ -66,11 +66,28 @@ struct key_type cifs_spnego_key_type = {
	.describe	= user_describe,
};

#define MAX_VER_STR_LEN   8 /* length of longest version string e.g.
				strlen("ver=0xFF") */
#define MAX_MECH_STR_LEN 13 /* length of longest security mechanism name, eg
			       in future could have strlen(";sec=ntlmsspi") */
#define MAX_IPV6_ADDR_LEN 42 /* eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
/* length of longest version string e.g.  strlen("ver=0xFF") */
#define MAX_VER_STR_LEN		8

/* length of longest security mechanism name, eg in future could have
 * strlen(";sec=ntlmsspi") */
#define MAX_MECH_STR_LEN	13

/* max possible addr len eg FEDC:BA98:7654:3210:FEDC:BA98:7654:3210/60 */
#define MAX_IPV6_ADDR_LEN	42

/* strlen of "host=" */
#define HOST_KEY_LEN		5

/* strlen of ";ip4=" or ";ip6=" */
#define IP_KEY_LEN		5

/* strlen of ";uid=0x" */
#define UID_KEY_LEN		7

/* strlen of ";user=" */
#define USER_KEY_LEN		6

/* get a key struct with a SPNEGO security blob, suitable for session setup */
struct key *
cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
@@ -84,11 +101,11 @@ cifs_get_spnego_key(struct cifsSesInfo *sesInfo)
	/* length of fields (with semicolons): ver=0xyz ip4=ipaddress
	   host=hostname sec=mechanism uid=0xFF user=username */
	desc_len = MAX_VER_STR_LEN +
		   6 /* len of "host=" */ + strlen(hostname) +
		   5 /* len of ";ipv4=" */ + MAX_IPV6_ADDR_LEN +
		   HOST_KEY_LEN + strlen(hostname) +
		   IP_KEY_LEN + MAX_IPV6_ADDR_LEN +
		   MAX_MECH_STR_LEN +
		   7 /* len of ";uid=0x" */ + (sizeof(uid_t) * 2) +
		   6 /* len of ";user=" */ + strlen(sesInfo->userName) + 1;
		   UID_KEY_LEN + (sizeof(uid_t) * 2) +
		   USER_KEY_LEN + strlen(sesInfo->userName) + 1;

	spnego_key = ERR_PTR(-ENOMEM);
	description = kzalloc(desc_len, GFP_KERNEL);
+1 −1
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@ extern int cifs_create(struct inode *, struct dentry *, int,
		       struct nameidata *);
extern struct dentry *cifs_lookup(struct inode *, struct dentry *,
				  struct nameidata *);
extern int cifs_unlink(struct inode *, struct dentry *);
extern int cifs_unlink(struct inode *dir, struct dentry *dentry);
extern int cifs_hardlink(struct dentry *, struct inode *, struct dentry *);
extern int cifs_mknod(struct inode *, struct dentry *, int, dev_t);
extern int cifs_mkdir(struct inode *, struct dentry *, int);
+1 −0
Original line number Diff line number Diff line
@@ -309,6 +309,7 @@ struct cifs_search_info {
	__u32 resume_key;
	char *ntwrk_buf_start;
	char *srch_entries_start;
	char *last_entry;
	char *presume_name;
	unsigned int resume_name_len;
	bool endOfSearch:1;
+3 −1
Original line number Diff line number Diff line
@@ -179,6 +179,8 @@ extern int CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
extern int CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
			const FILE_BASIC_INFO *data, __u16 fid,
			__u32 pid_of_opener);
extern int CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
			bool delete_file, __u16 fid, __u32 pid_of_opener);
#if 0
extern int CIFSSMBSetAttrLegacy(int xid, struct cifsTconInfo *tcon,
			char *fileName, __u16 dos_attributes,
@@ -229,7 +231,7 @@ extern int CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
			const struct nls_table *nls_codepage,
			int remap_special_chars);
extern int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
			int netfid, char *target_name,
			int netfid, const char *target_name,
			const struct nls_table *nls_codepage,
			int remap_special_chars);
extern int CIFSCreateHardLink(const int xid,
+82 −2
Original line number Diff line number Diff line
@@ -2017,7 +2017,7 @@ CIFSSMBRename(const int xid, struct cifsTconInfo *tcon,
}

int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
		int netfid, char *target_name,
		int netfid, const char *target_name,
		const struct nls_table *nls_codepage, int remap)
{
	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
@@ -2071,7 +2071,7 @@ int CIFSSMBRenameOpenFile(const int xid, struct cifsTconInfo *pTcon,
					remap);
	}
	rename_info->target_name_len = cpu_to_le32(2 * len_of_str);
	count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str) + 2;
	count = 12 /* sizeof(struct set_file_rename) */ + (2 * len_of_str);
	byte_count += count;
	pSMB->DataCount = cpu_to_le16(count);
	pSMB->TotalDataCount = pSMB->DataCount;
@@ -3614,6 +3614,8 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
		/* BB remember to free buffer if error BB */
		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
		if (rc == 0) {
			unsigned int lnoff;

			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
				psrch_inf->unicode = true;
			else
@@ -3636,6 +3638,17 @@ CIFSFindFirst(const int xid, struct cifsTconInfo *tcon,
					le16_to_cpu(parms->SearchCount);
			psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
				psrch_inf->entries_in_buffer;
			lnoff = le16_to_cpu(parms->LastNameOffset);
			if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
			      lnoff) {
				cERROR(1, ("ignoring corrupt resume name"));
				psrch_inf->last_entry = NULL;
				return rc;
			}

			psrch_inf->last_entry = psrch_inf->srch_entries_start +
							lnoff;

			*pnetfid = parms->SearchHandle;
		} else {
			cifs_buf_release(pSMB);
@@ -3725,6 +3738,8 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
		rc = validate_t2((struct smb_t2_rsp *)pSMBr);

		if (rc == 0) {
			unsigned int lnoff;

			/* BB fixme add lock for file (srch_info) struct here */
			if (pSMBr->hdr.Flags2 & SMBFLG2_UNICODE)
				psrch_inf->unicode = true;
@@ -3751,6 +3766,16 @@ int CIFSFindNext(const int xid, struct cifsTconInfo *tcon,
						le16_to_cpu(parms->SearchCount);
			psrch_inf->index_of_last_entry +=
				psrch_inf->entries_in_buffer;
			lnoff = le16_to_cpu(parms->LastNameOffset);
			if (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE <
			      lnoff) {
				cERROR(1, ("ignoring corrupt resume name"));
				psrch_inf->last_entry = NULL;
				return rc;
			} else
				psrch_inf->last_entry =
					psrch_inf->srch_entries_start + lnoff;

/*  cFYI(1,("fnxt2 entries in buf %d index_of_last %d",
	    psrch_inf->entries_in_buffer, psrch_inf->index_of_last_entry)); */

@@ -4876,6 +4901,61 @@ CIFSSMBSetFileInfo(const int xid, struct cifsTconInfo *tcon,
	return rc;
}

int
CIFSSMBSetFileDisposition(const int xid, struct cifsTconInfo *tcon,
			  bool delete_file, __u16 fid, __u32 pid_of_opener)
{
	struct smb_com_transaction2_sfi_req *pSMB  = NULL;
	char *data_offset;
	int rc = 0;
	__u16 params, param_offset, offset, byte_count, count;

	cFYI(1, ("Set File Disposition (via SetFileInfo)"));
	rc = small_smb_init(SMB_COM_TRANSACTION2, 15, tcon, (void **) &pSMB);

	if (rc)
		return rc;

	pSMB->hdr.Pid = cpu_to_le16((__u16)pid_of_opener);
	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid_of_opener >> 16));

	params = 6;
	pSMB->MaxSetupCount = 0;
	pSMB->Reserved = 0;
	pSMB->Flags = 0;
	pSMB->Timeout = 0;
	pSMB->Reserved2 = 0;
	param_offset = offsetof(struct smb_com_transaction2_sfi_req, Fid) - 4;
	offset = param_offset + params;

	data_offset = (char *) (&pSMB->hdr.Protocol) + offset;

	count = 1;
	pSMB->MaxParameterCount = cpu_to_le16(2);
	/* BB find max SMB PDU from sess */
	pSMB->MaxDataCount = cpu_to_le16(1000);
	pSMB->SetupCount = 1;
	pSMB->Reserved3 = 0;
	pSMB->SubCommand = cpu_to_le16(TRANS2_SET_FILE_INFORMATION);
	byte_count = 3 /* pad */  + params + count;
	pSMB->DataCount = cpu_to_le16(count);
	pSMB->ParameterCount = cpu_to_le16(params);
	pSMB->TotalDataCount = pSMB->DataCount;
	pSMB->TotalParameterCount = pSMB->ParameterCount;
	pSMB->ParameterOffset = cpu_to_le16(param_offset);
	pSMB->DataOffset = cpu_to_le16(offset);
	pSMB->Fid = fid;
	pSMB->InformationLevel = cpu_to_le16(SMB_SET_FILE_DISPOSITION_INFO);
	pSMB->Reserved4 = 0;
	pSMB->hdr.smb_buf_length += byte_count;
	pSMB->ByteCount = cpu_to_le16(byte_count);
	*data_offset = delete_file ? 1 : 0;
	rc = SendReceiveNoRsp(xid, tcon->ses, (struct smb_hdr *) pSMB, 0);
	if (rc)
		cFYI(1, ("Send error in SetFileDisposition = %d", rc));

	return rc;
}

int
CIFSSMBSetPathInfo(const int xid, struct cifsTconInfo *tcon,
Loading