Skip to content

Commit

Permalink
3223 SMB FindFirst/FindNext don't fill in Last Name Offset
Browse files Browse the repository at this point in the history
Reviewed by: Bayard Bell <[email protected]>
Reviewed by: Dan McDonald <[email protected]>
Reviewed by: Kevin Crowe <[email protected]>
Reviewed by: Yakov Zaytsev <[email protected]>
Approved by: Richard Lowe <[email protected]>
  • Loading branch information
gwr committed Feb 12, 2013
1 parent 42c141d commit bfbce3c
Show file tree
Hide file tree
Showing 5 changed files with 243 additions and 119 deletions.
13 changes: 7 additions & 6 deletions usr/src/uts/common/fs/smbsrv/smb_find.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2012 Nexenta Systems, Inc. All rights reserved.
*/

#include <smbsrv/smb_kproto.h>
Expand Down Expand Up @@ -230,7 +231,7 @@ smb_com_search(smb_request_t *sr)
smb_odir_t *od;
smb_fileinfo_t fileinfo;
smb_odir_resume_t odir_resume;
boolean_t eos;
uint16_t eos;

to_upper = B_FALSE;
if ((sr->session->dialect <= LANMAN1_0) ||
Expand Down Expand Up @@ -328,7 +329,7 @@ smb_com_search(smb_request_t *sr)

while (count < maxcount) {
rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
if ((rc != 0 || (eos == B_TRUE)))
if (rc != 0 || eos != 0)
break;

if (*fileinfo.fi_shortname == '\0') {
Expand Down Expand Up @@ -407,7 +408,7 @@ smb_com_find(smb_request_t *sr)
char name83[SMB_SHORTNAMELEN];
smb_odir_t *od;
smb_fileinfo_t fileinfo;
boolean_t eos;
uint16_t eos;

smb_pathname_t *pn;
unsigned char resume_char;
Expand Down Expand Up @@ -474,7 +475,7 @@ smb_com_find(smb_request_t *sr)

while (count < maxcount) {
rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
if ((rc != 0 || (eos == B_TRUE)))
if (rc != 0 || eos != 0)
break;

if (*fileinfo.fi_shortname == '\0') {
Expand Down Expand Up @@ -618,7 +619,7 @@ smb_com_find_unique(struct smb_request *sr)
char name83[SMB_SHORTNAMELEN];
smb_odir_t *od;
smb_fileinfo_t fileinfo;
boolean_t eos;
uint16_t eos;
smb_vdb_t *vdb;

if (smbsr_decode_vwv(sr, "ww", &maxcount, &sattr) != 0)
Expand Down Expand Up @@ -660,7 +661,7 @@ smb_com_find_unique(struct smb_request *sr)

while (count < maxcount) {
rc = smb_odir_read_fileinfo(sr, od, &fileinfo, &eos);
if ((rc != 0 || (eos == B_TRUE)))
if (rc != 0 || eos != 0)
break;

if (*fileinfo.fi_shortname == '\0') {
Expand Down
84 changes: 64 additions & 20 deletions usr/src/uts/common/fs/smbsrv/smb_odir.c
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ smb_odir_read(smb_request_t *sr, smb_odir_t *od,
*/
int
smb_odir_read_fileinfo(smb_request_t *sr, smb_odir_t *od,
smb_fileinfo_t *fileinfo, boolean_t *eof)
smb_fileinfo_t *fileinfo, uint16_t *eof)
{
int rc, errnum;
smb_odirent_t *odirent;
Expand All @@ -584,7 +584,7 @@ smb_odir_read_fileinfo(smb_request_t *sr, smb_odir_t *od,
return (-1);
}

if (!(od->d_flags & SMB_ODIR_FLAG_WILDCARDS)) {
if ((od->d_flags & SMB_ODIR_FLAG_WILDCARDS) == 0) {
if (od->d_eof)
rc = ENOENT;
else
Expand Down Expand Up @@ -617,10 +617,10 @@ smb_odir_read_fileinfo(smb_request_t *sr, smb_odir_t *od,

switch (rc) {
case 0:
*eof = B_FALSE;
*eof = 0;
return (0);
case ENOENT:
*eof = B_TRUE;
*eof = 1; /* per. FindFirst, FindNext spec. */
return (0);
default:
smbsr_errno(sr, rc);
Expand Down Expand Up @@ -742,6 +742,28 @@ smb_odir_save_cookie(smb_odir_t *od, int idx, uint32_t cookie)
mutex_exit(&od->d_mutex);
}

/*
* smb_odir_save_fname
*
* Save a filename / offset pair, which are basically a
* one entry cache. See smb_com_trans2_find_next2.
*/
void
smb_odir_save_fname(smb_odir_t *od, uint32_t cookie, const char *fname)
{
ASSERT(od);
ASSERT(od->d_magic == SMB_ODIR_MAGIC);

mutex_enter(&od->d_mutex);

od->d_last_cookie = cookie;
bzero(od->d_last_name, MAXNAMELEN);
if (fname != NULL)
(void) strlcpy(od->d_last_name, fname, MAXNAMELEN);

mutex_exit(&od->d_mutex);
}

/*
* smb_odir_resume_at
*
Expand Down Expand Up @@ -775,23 +797,45 @@ smb_odir_resume_at(smb_odir_t *od, smb_odir_resume_t *resume)
}

switch (resume->or_type) {
case SMB_ODIR_RESUME_IDX:
ASSERT(resume->or_idx >= 0);
ASSERT(resume->or_idx < SMB_MAX_SEARCH);

if ((resume->or_idx < 0) ||
(resume->or_idx >= SMB_MAX_SEARCH)) {
resume->or_idx = 0;
}
od->d_offset = od->d_cookies[resume->or_idx];
break;
case SMB_ODIR_RESUME_COOKIE:

default:
case SMB_ODIR_RESUME_CONT:
/* Continue where we left off. */
break;

case SMB_ODIR_RESUME_IDX:
/*
* This is used only by the (ancient) SMB_SEARCH.
* Modern clients use trans2 FindFirst, FindNext.
*/
ASSERT(resume->or_idx >= 0);
ASSERT(resume->or_idx < SMB_MAX_SEARCH);

if ((resume->or_idx < 0) ||
(resume->or_idx >= SMB_MAX_SEARCH)) {
resume->or_idx = 0;
}
od->d_offset = od->d_cookies[resume->or_idx];
break;

case SMB_ODIR_RESUME_COOKIE:
od->d_offset = resume->or_cookie;
break;

case SMB_ODIR_RESUME_FNAME:
/*
* If the name matches the last one saved,
* use the offset that was saved with it in
* the odir. Otherwise use the cookie value
* in the resume data from the client.
*/
if (strcmp(resume->or_fname, od->d_last_name) &&
od->d_last_cookie != 0) {
od->d_offset = od->d_last_cookie;
} else if (resume->or_cookie != 0) {
od->d_offset = resume->or_cookie;
break;
case SMB_ODIR_RESUME_FNAME:
default:
od->d_offset = od->d_cookies[0];
break;
} /* else continue where we left off */
break;
}

/* Force a vop_readdir to refresh d_buf */
Expand Down
Loading

0 comments on commit bfbce3c

Please sign in to comment.