Skip to content

Commit

Permalink
Merge tag '5.9-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/ci…
Browse files Browse the repository at this point in the history
…fs-2.6

Pull cifs updates from Steve French:
 "16 cifs/smb3 fixes, about half DFS related, two fixes for stable.

  Still working on and testing an additional set of fixes (including
  updates to mount, and some fallocate scenario improvements) for later
  in the merge window"

* tag '5.9-rc-smb3-fixes-part1' of git://git.samba.org/sfrench/cifs-2.6:
  cifs: document and cleanup dfs mount
  cifs: only update prefix path of DFS links in cifs_tree_connect()
  cifs: fix double free error on share and prefix
  cifs: handle RESP_GET_DFS_REFERRAL.PathConsumed in reconnect
  cifs: handle empty list of targets in cifs_reconnect()
  cifs: rename reconn_inval_dfs_target()
  cifs: reduce number of referral requests in DFS link lookups
  cifs: merge __{cifs,smb2}_reconnect[_tcon]() into cifs_tree_connect()
  cifs: convert to use be32_add_cpu()
  cifs: delete duplicated words in header files
  cifs: Remove the superfluous break
  cifs: smb1: Try failing back to SetFileInfo if SetPathInfo fails
  cifs`: handle ERRBaduid for SMB1
  cifs: remove unused variable 'server'
  smb3: warn on confusing error scenario with sec=krb5
  cifs: Fix leak when handling lease break for cached root fid
  • Loading branch information
Linus Torvalds committed Aug 7, 2020
2 parents 96e3f3c + 7efd081 commit 327a8d7
Show file tree
Hide file tree
Showing 16 changed files with 560 additions and 493 deletions.
4 changes: 2 additions & 2 deletions fs/cifs/cifsacl.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ struct cifs_ace {
/*
* The current SMB3 form of security descriptor is similar to what was used for
* cifs (see above) but some fields are split, and fields in the struct below
* matches names of fields to the the spec, MS-DTYP (see sections 2.4.5 and
* matches names of fields to the spec, MS-DTYP (see sections 2.4.5 and
* 2.4.6). Note that "CamelCase" fields are used in this struct in order to
* match the MS-DTYP and MS-SMB2 specs which define the wire format.
*/
Expand Down Expand Up @@ -178,7 +178,7 @@ struct smb3_acl {

/*
* Used to store the special 'NFS SIDs' used to persist the POSIX uid and gid
* See See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
* See http://technet.microsoft.com/en-us/library/hh509017(v=ws.10).aspx
*/
struct owner_sid {
u8 Revision;
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -1466,7 +1466,7 @@ struct cifsInodeInfo {
struct list_head llist; /* locks helb by this inode */
/*
* NOTE: Some code paths call down_read(lock_sem) twice, so
* we must always use use cifs_down_write() instead of down_write()
* we must always use cifs_down_write() instead of down_write()
* for this semaphore to avoid deadlocks.
*/
struct rw_semaphore lock_sem; /* protect the fields above */
Expand Down
9 changes: 6 additions & 3 deletions fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ extern int decode_negTokenInit(unsigned char *security_blob, int length,
extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
extern int map_smb_to_linux_error(char *buf, bool logErr);
extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifs_tcon *, int /* length of
fixed section (word count) in two byte units */);
Expand Down Expand Up @@ -271,6 +272,9 @@ extern void cifs_move_llist(struct list_head *source, struct list_head *dest);
extern void cifs_free_llist(struct list_head *llist);
extern void cifs_del_lock_waiters(struct cifsLockInfo *lock);

extern int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon,
const struct nls_table *nlsc);

extern int cifs_negotiate_protocol(const unsigned int xid,
struct cifs_ses *ses);
extern int cifs_setup_session(const unsigned int xid, struct cifs_ses *ses,
Expand Down Expand Up @@ -344,7 +348,7 @@ extern int CIFSSMBQFSPosixInfo(const unsigned int xid, struct cifs_tcon *tcon,
extern int CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage,
int remap_special_chars);
struct cifs_sb_info *cifs_sb);
extern int CIFSSMBSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon,
const FILE_BASIC_INFO *data, __u16 fid,
__u32 pid_of_opener);
Expand Down Expand Up @@ -613,8 +617,7 @@ int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov,

struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server);
void cifs_put_tcp_super(struct super_block *sb);
int update_super_prepath(struct cifs_tcon *tcon, const char *prefix,
size_t prefix_len);
int update_super_prepath(struct cifs_tcon *tcon, char *prefix);

#ifdef CONFIG_CIFS_DFS_UPCALL
static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
Expand Down
151 changes: 39 additions & 112 deletions fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -124,116 +124,6 @@ cifs_mark_open_files_invalid(struct cifs_tcon *tcon)
*/
}

#ifdef CONFIG_CIFS_DFS_UPCALL
static int __cifs_reconnect_tcon(const struct nls_table *nlsc,
struct cifs_tcon *tcon)
{
int rc;
struct TCP_Server_Info *server = tcon->ses->server;
struct dfs_cache_tgt_list tl;
struct dfs_cache_tgt_iterator *it = NULL;
char *tree;
const char *tcp_host;
size_t tcp_host_len;
const char *dfs_host;
size_t dfs_host_len;

tree = kzalloc(MAX_TREE_SIZE, GFP_KERNEL);
if (!tree)
return -ENOMEM;

if (!tcon->dfs_path) {
if (tcon->ipc) {
scnprintf(tree, MAX_TREE_SIZE, "\\\\%s\\IPC$",
server->hostname);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
} else {
rc = CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
}
goto out;
}

rc = dfs_cache_noreq_find(tcon->dfs_path + 1, NULL, &tl);
if (rc)
goto out;

extract_unc_hostname(server->hostname, &tcp_host, &tcp_host_len);

for (it = dfs_cache_get_tgt_iterator(&tl); it;
it = dfs_cache_get_next_tgt(&tl, it)) {
const char *share, *prefix;
size_t share_len, prefix_len;
bool target_match;

rc = dfs_cache_get_tgt_share(it, &share, &share_len, &prefix,
&prefix_len);
if (rc) {
cifs_dbg(VFS, "%s: failed to parse target share %d\n",
__func__, rc);
continue;
}

extract_unc_hostname(share, &dfs_host, &dfs_host_len);

if (dfs_host_len != tcp_host_len
|| strncasecmp(dfs_host, tcp_host, dfs_host_len) != 0) {
cifs_dbg(FYI, "%s: %.*s doesn't match %.*s\n",
__func__,
(int)dfs_host_len, dfs_host,
(int)tcp_host_len, tcp_host);

rc = match_target_ip(server, dfs_host, dfs_host_len,
&target_match);
if (rc) {
cifs_dbg(VFS, "%s: failed to match target ip: %d\n",
__func__, rc);
break;
}

if (!target_match) {
cifs_dbg(FYI, "%s: skipping target\n", __func__);
continue;
}
}

if (tcon->ipc) {
scnprintf(tree, MAX_TREE_SIZE, "\\\\%.*s\\IPC$",
(int)share_len, share);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
} else {
scnprintf(tree, MAX_TREE_SIZE, "\\%.*s", (int)share_len,
share);
rc = CIFSTCon(0, tcon->ses, tree, tcon, nlsc);
if (!rc) {
rc = update_super_prepath(tcon, prefix,
prefix_len);
break;
}
}
if (rc == -EREMOTE)
break;
}

if (!rc) {
if (it)
rc = dfs_cache_noreq_update_tgthint(tcon->dfs_path + 1,
it);
else
rc = -ENOENT;
}
dfs_cache_free_tgts(&tl);
out:
kfree(tree);
return rc;
}
#else
static inline int __cifs_reconnect_tcon(const struct nls_table *nlsc,
struct cifs_tcon *tcon)
{
return CIFSTCon(0, tcon->ses, tcon->treeName, tcon, nlsc);
}
#endif

/* reconnect the socket, tcon, and smb session if needed */
static int
cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
Expand Down Expand Up @@ -338,7 +228,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command)
}

cifs_mark_open_files_invalid(tcon);
rc = __cifs_reconnect_tcon(nls_codepage, tcon);
rc = cifs_tree_connect(0, tcon, nls_codepage);
mutex_unlock(&ses->session_mutex);
cifs_dbg(FYI, "reconnect tcon rc = %d\n", rc);

Expand Down Expand Up @@ -5913,10 +5803,42 @@ CIFSSMBSetFileDisposition(const unsigned int xid, struct cifs_tcon *tcon,
return rc;
}

static int
CIFSSMBSetPathInfoFB(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage,
struct cifs_sb_info *cifs_sb)
{
int oplock = 0;
struct cifs_open_parms oparms;
struct cifs_fid fid;
int rc;

oparms.tcon = tcon;
oparms.cifs_sb = cifs_sb;
oparms.desired_access = GENERIC_WRITE;
oparms.create_options = cifs_create_options(cifs_sb, 0);
oparms.disposition = FILE_OPEN;
oparms.path = fileName;
oparms.fid = &fid;
oparms.reconnect = false;

rc = CIFS_open(xid, &oparms, &oplock, NULL);
if (rc)
goto out;

rc = CIFSSMBSetFileInfo(xid, tcon, data, fid.netfid, current->tgid);
CIFSSMBClose(xid, tcon, fid.netfid);
out:

return rc;
}

int
CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
const char *fileName, const FILE_BASIC_INFO *data,
const struct nls_table *nls_codepage, int remap)
const struct nls_table *nls_codepage,
struct cifs_sb_info *cifs_sb)
{
TRANSACTION2_SPI_REQ *pSMB = NULL;
TRANSACTION2_SPI_RSP *pSMBr = NULL;
Expand All @@ -5925,6 +5847,7 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
int bytes_returned = 0;
char *data_offset;
__u16 params, param_offset, offset, byte_count, count;
int remap = cifs_remap(cifs_sb);

cifs_dbg(FYI, "In SetTimes\n");

Expand Down Expand Up @@ -5987,6 +5910,10 @@ CIFSSMBSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon,
if (rc == -EAGAIN)
goto SetTimesRetry;

if (rc == -EOPNOTSUPP)
return CIFSSMBSetPathInfoFB(xid, tcon, fileName, data,
nls_codepage, cifs_sb);

return rc;
}

Expand Down
Loading

0 comments on commit 327a8d7

Please sign in to comment.