1
diff -uNr samba-3.0.14a.orig/source/libsmb/clilist.c samba-3.0.14a/source/libsmb/clilist.c
2
--- samba-3.0.14a.orig/source/libsmb/clilist.c 2005-06-02 08:26:15.000000000 -0700
3
+++ samba-3.0.14a/source/libsmb/clilist.c 2005-06-02 08:48:04.000000000 -0700
5
by NT and 2 is used by OS/2
6
****************************************************************************/
8
-static size_t interpret_long_filename(struct cli_state *cli,
9
- int level,char *p,file_info *finfo, uint32 *p_resume_key)
10
+static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo,
11
+ uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len)
13
extern file_info def_finfo;
17
if (!finfo) finfo = &finfo2;
23
memcpy(finfo,&def_finfo,sizeof(*finfo));
28
p += 4; /* next entry offset */
30
- *p_resume_key = IVAL(p,0);
32
+ *p_resume_key = IVAL(p,0);
34
p += 4; /* fileindex */
36
/* these dates appear to arrive in a
38
clistr_pull(cli, finfo->name, p,
42
+ /* To be robust in the face of unicode conversion failures
43
+ we need to copy the raw bytes of the last name seen here.
44
+ Namelen doesn't include the terminating unicode null, so
47
+ if (p_last_name_raw && p_last_name_raw_len) {
48
+ if (namelen + 2 > p_last_name_raw->length) {
49
+ memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length));
50
+ *p_last_name_raw_len = 0;
52
+ memcpy(p_last_name_raw->data, p, namelen);
53
+ SSVAL(p_last_name_raw->data, namelen, 0);
54
+ *p_last_name_raw_len = namelen + 2;
57
return (size_t)IVAL(base, 0);
63
uint32 resume_key = 0;
64
+ uint32 last_name_raw_len = 0;
65
+ DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring));
67
/* NT uses 260, OS/2 uses 2. Both accept 1. */
68
info_level = (cli->capabilities&CAP_NT_SMBS)?260:1;
70
can miss filenames. Use last filename continue instead. JRA */
71
SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */
73
- p += clistr_push(cli, param+12, mask, sizeof(param)-12,
75
+ if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) {
76
+ memcpy(p, last_name_raw.data, last_name_raw_len);
77
+ p += last_name_raw_len;
79
+ p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE);
83
param_len = PTR_DIFF(p, param);
85
/* Last entry - fixup the last offset length. */
86
SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2));
88
- p2 += interpret_long_filename(cli,info_level,p2,&finfo,&resume_key);
89
+ p2 += interpret_long_filename(cli,info_level,p2,&finfo,
90
+ &resume_key,&last_name_raw,&last_name_raw_len);
93
if (ff_lastname > 0) {
95
mnt = cli_cm_get_mntpoint( cli );
97
for (p=dirlist,i=0;i<total_received;i++) {
98
- p += interpret_long_filename(cli,info_level,p,&finfo,&resume_key);
99
+ p += interpret_long_filename(cli,info_level,p,&finfo,NULL,NULL,NULL);
100
fn( mnt,&finfo, Mask, state );
103
- /* free up the dirlist buffer */
104
+ /* free up the dirlist buffer and last name raw blob */
106
+ data_blob_free(&last_name_raw);
107
return(total_received);