From 858e63cab3b6a23692678d6eb03f9e48c3c08603 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 25 Apr 2000 14:04:06 +0000 Subject: split clientgen.c into several parts the next step is splitting out the auth code, to make adding lukes NTLMSSP support easier (This used to be commit 10c5470835b43116ed48b3137c3b9cc867a20989) --- source3/libsmb/clilist.c | 303 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 303 insertions(+) create mode 100644 source3/libsmb/clilist.c (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c new file mode 100644 index 0000000000..4cb477961b --- /dev/null +++ b/source3/libsmb/clilist.c @@ -0,0 +1,303 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + client directory list routines + Copyright (C) Andrew Tridgell 1994-1998 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define NO_SYSLOG + +#include "includes.h" + + +/**************************************************************************** +interpret a long filename structure - this is mostly guesses at the moment +The length of the structure is returned +The structure of a long filename depends on the info level. 260 is used +by NT and 2 is used by OS/2 +****************************************************************************/ +static int interpret_long_filename(int level,char *p,file_info *finfo) +{ + extern file_info def_finfo; + + if (finfo) + memcpy(finfo,&def_finfo,sizeof(*finfo)); + + switch (level) + { + case 1: /* OS/2 understands this */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+27); + dos_to_unix(finfo->name,True); + } + return(28 + CVAL(p,26)); + + case 2: /* this is what OS/2 uses mostly */ + if (finfo) { + /* these dates are converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + pstrcpy(finfo->name,p+31); + dos_to_unix(finfo->name,True); + } + return(32 + CVAL(p,30)); + + /* levels 3 and 4 are untested */ + case 3: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+33); + dos_to_unix(finfo->name,True); + } + return(SVAL(p,4)+4); + + case 4: + if (finfo) { + /* these dates are probably like the other ones */ + finfo->ctime = make_unix_date2(p+8); + finfo->atime = make_unix_date2(p+12); + finfo->mtime = make_unix_date2(p+16); + finfo->size = IVAL(p,20); + finfo->mode = CVAL(p,28); + pstrcpy(finfo->name,p+37); + dos_to_unix(finfo->name,True); + } + return(SVAL(p,4)+4); + + case 260: /* NT uses this, but also accepts 2 */ + if (finfo) { + int ret = SVAL(p,0); + int namelen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ + + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + p += 2; /* short name len? */ + p += 24; /* short name? */ + StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); + dos_to_unix(finfo->name,True); + return(ret); + } + return(SVAL(p,0)); + } + + DEBUG(1,("Unknown long filename format %d\n",level)); + return(SVAL(p,0)); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + ****************************************************************************/ +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)) +{ + int max_matches = 512; + /* NT uses 260, OS/2 uses 2. Both accept 1. */ + int info_level = cli->protocol 200) { + DEBUG(0,("Error: Looping in FIND_NEXT??\n")); + break; + } + + param_len = 12+strlen(mask)+1; + + if (First) { + setup = TRANSACT2_FINDFIRST; + SSVAL(param,0,attribute); /* attribute */ + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,4+2); /* resume required + close on end */ + SSVAL(param,6,info_level); + SIVAL(param,8,0); + pstrcpy(param+12,mask); + } else { + setup = TRANSACT2_FINDNEXT; + SSVAL(param,0,ff_dir_handle); + SSVAL(param,2,max_matches); /* max count */ + SSVAL(param,4,info_level); + SIVAL(param,6,0); /* ff_resume_key */ + SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ + pstrcpy(param+12,mask); + + DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", + ff_dir_handle,ff_lastname,mask)); + } + + if (!cli_send_trans(cli, SMBtrans2, + NULL, 0, /* Name, length */ + -1, 0, /* fid, flags */ + &setup, 1, 0, /* setup, length, max */ + param, param_len, 10, /* param, length, max */ + NULL, 0, + cli->max_xmit /* data, length, max */ + )) { + break; + } + + if (!cli_receive_trans(cli, SMBtrans2, + &rparam, ¶m_len, + &rdata, &data_len)) { + /* we need to work around a Win95 bug - sometimes + it gives ERRSRV/ERRerror temprarily */ + uint8 eclass; + uint32 ecode; + cli_error(cli, &eclass, &ecode, NULL); + if (eclass != ERRSRV || ecode != ERRerror) break; + msleep(100); + continue; + } + + if (total_received == -1) total_received = 0; + + /* parse out some important return info */ + p = rparam; + if (First) { + ff_dir_handle = SVAL(p,0); + ff_searchcount = SVAL(p,2); + ff_eos = SVAL(p,4); + ff_lastname = SVAL(p,8); + } else { + ff_searchcount = SVAL(p,0); + ff_eos = SVAL(p,2); + ff_lastname = SVAL(p,6); + } + + if (ff_searchcount == 0) + break; + + /* point to the data bytes */ + p = rdata; + + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + switch(info_level) + { + case 260: + StrnCpy(mask,p+ff_lastname, + MIN(sizeof(mask)-1,data_len-ff_lastname)); + break; + case 1: + pstrcpy(mask,p + ff_lastname + 1); + break; + } + } else { + pstrcpy(mask,""); + } + + dos_to_unix(mask, True); + + /* and add them to the dirlist pool */ + dirlist = Realloc(dirlist,dirlist_len + data_len); + + if (!dirlist) { + DEBUG(0,("Failed to expand dirlist\n")); + break; + } + + /* put in a length for the last entry, to ensure we can chain entries + into the next packet */ + for (p2=p,i=0;i<(ff_searchcount-1);i++) + p2 += interpret_long_filename(info_level,p2,NULL); + SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + + /* grab the data for later use */ + memcpy(dirlist+dirlist_len,p,data_len); + dirlist_len += data_len; + + total_received += ff_searchcount; + + if (rdata) free(rdata); rdata = NULL; + if (rparam) free(rparam); rparam = NULL; + + DEBUG(3,("received %d entries (eos=%d)\n", + ff_searchcount,ff_eos)); + + if (ff_searchcount > 0) loop_count = 0; + + First = False; + } + + for (p=dirlist,i=0;i Date: Sun, 30 Apr 2000 04:45:16 +0000 Subject: YIPEE!!!!! We finally have a perfect emulation of Microsoft wildcard matching. The routine ms_fnmatch() does wildcard matching with all MS wildcards (including the unicode wildcards), and masktest against a NT4 workstation with hundreds of thousands of random exmaples has not found a single error. amazingly it is only about 60 lines of code, but it has taken us years to get it right. I didn't sleep much last night :) (This used to be commit cc9e007cdfdd300189f89e2a55e4234e47fa842d) --- source3/libsmb/clilist.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4cb477961b..f2e42be523 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -123,6 +123,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ p += 2; /* short name len? */ + unistr_to_ascii(finfo->short_name, p, 12); p += 24; /* short name? */ StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); dos_to_unix(finfo->name,True); -- cgit From 23c0cb01ca5b8bafb3ed9f31c3aa672957c2af86 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 12:34:26 +0000 Subject: added cli_list_old() to allow for old style directory listing from masktest (This used to be commit 8a5c8cfa0ede1d119bf9013e321a497beefd4dda) --- source3/libsmb/clilist.c | 146 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 144 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f2e42be523..74b908ae58 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -160,8 +160,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; - + int param_len, data_len; uint16 setup; pstring param; @@ -302,3 +301,146 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } + + +/**************************************************************************** +interpret a short filename structure +The length of the structure is returned +****************************************************************************/ +static int interpret_short_filename(char *p,file_info *finfo) +{ + extern file_info def_finfo; + + *finfo = def_finfo; + + finfo->mode = CVAL(p,21); + + /* this date is converted to GMT by make_unix_date */ + finfo->ctime = make_unix_date(p+22); + finfo->mtime = finfo->atime = finfo->ctime; + finfo->size = IVAL(p,26); + pstrcpy(finfo->name,p+30); + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) + fstrcpy(finfo->short_name,finfo->name); + + return(DIR_STRUCT_SIZE); +} + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used + ****************************************************************************/ +int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *)) +{ + char *p; + int received = 0; + BOOL first = True; + char status[21]; + int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; + int num_received = 0; + int i; + char *dirlist = NULL; + pstring mask; + + ZERO_ARRAY(status); + + pstrcpy(mask,Mask); + + while (1) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + if (first) + set_message(cli->outbuf,2,5 + strlen(mask),True); + else + set_message(cli->outbuf,2,5 + 21,True); + + CVAL(cli->outbuf,smb_com) = SMBffirst; + + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,num_asked); + SSVAL(cli->outbuf,smb_vwv1,attribute); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + if (first) + pstrcpy(p,mask); + else + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + if (first) { + SSVAL(p,0,0); + } else { + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + } + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) break; + + received = SVAL(cli->inbuf,smb_vwv0); + if (received <= 0) break; + + first = False; + + dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + + if (!dirlist) + return 0; + + p = smb_buf(cli->inbuf) + 3; + + memcpy(dirlist+num_received*DIR_STRUCT_SIZE, + p,received*DIR_STRUCT_SIZE); + + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); + + num_received += received; + + if (CVAL(cli->inbuf,smb_rcls) != 0) break; + } + + if (!first) { + memset(cli->outbuf,'\0',smb_size); + memset(cli->inbuf,'\0',smb_size); + + set_message(cli->outbuf,0,6,True); + CVAL(cli->outbuf,smb_com) = SMBfclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p++ = 4; + + pstrcpy(p,""); + p += strlen(p) + 1; + + *p++ = 5; + SSVAL(p,0,21); + p += 2; + memcpy(p,status,21); + + cli_send_smb(cli); + if (!cli_receive_smb(cli)) { + DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + } + } + + for (p=dirlist,i=0;i Date: Sun, 30 Apr 2000 14:26:59 +0000 Subject: - get the findclose code right - handle broken NT response to trans2 findfirst (This used to be commit 64f91a7a98fe9aaf176e665677e751e4e03d4c3d) --- source3/libsmb/clilist.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 74b908ae58..4374973fa9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -95,7 +95,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) case 260: /* NT uses this, but also accepts 2 */ if (finfo) { int ret = SVAL(p,0); - int namelen; + int namelen, slen; p += 4; /* next entry offset */ p += 4; /* fileindex */ @@ -122,8 +122,15 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; p += 4; /* EA size */ - p += 2; /* short name len? */ - unistr_to_ascii(finfo->short_name, p, 12); + slen = SVAL(p, 0); + p += 2; + if (p[1] == 0 && slen > 1) { + /* NT has stuffed up again */ + unistr_to_ascii(finfo->short_name, p, 24); + } else { + strncpy(finfo->short_name, p, 12); + finfo->short_name[12] = 0; + } p += 24; /* short name? */ StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); dos_to_unix(finfo->name,True); @@ -413,25 +420,26 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,0,6,True); + set_message(cli->outbuf,2,5 + 21,True); CVAL(cli->outbuf,smb_com) = SMBfclose; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); + SSVAL(cli->outbuf, smb_vwv0, 0); /* find count? */ + SSVAL(cli->outbuf, smb_vwv1, attribute); + p = smb_buf(cli->outbuf); *p++ = 4; - - pstrcpy(p,""); + fstrcpy(p, ""); p += strlen(p) + 1; - *p++ = 5; - SSVAL(p,0,21); + SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); } } -- cgit From 2fb2ae187d34adb7621608c82ea793e2d0bb41eb Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 30 Apr 2000 14:58:13 +0000 Subject: fixed parsing of broken NT short name (This used to be commit 9e4b3529455840f11940136dd55c641d89b46961) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4374973fa9..f3e4033539 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -126,7 +126,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 2; if (p[1] == 0 && slen > 1) { /* NT has stuffed up again */ - unistr_to_ascii(finfo->short_name, p, 24); + unistr_to_ascii(finfo->short_name, p, slen/2); } else { strncpy(finfo->short_name, p, 12); finfo->short_name[12] = 0; -- cgit From 612738a9e14b6fb6a2687993d6416bbe6c3ea94d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 10 May 2000 22:47:09 +0000 Subject: lib/util_unistr.c: libsmb/clilist.c: rpc_server/srv_spoolss_nt.c: smbd/trans2.c: Changed unistr_to_ascii to unistr_to_dos - do codepage conversion. msdfs/msdfs.c: Removed stub unistr_to_dos. libsmb/pwd_cache.c: Removed obfuscation functions as they don't do anything and don't add any security. Jeremy. (This used to be commit 1ed146467e764e6a81d8f78cd58fb5765ebf5d21) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f3e4033539..2e904e06b7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -126,7 +126,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 2; if (p[1] == 0 && slen > 1) { /* NT has stuffed up again */ - unistr_to_ascii(finfo->short_name, p, slen/2); + unistr_to_dos(finfo->short_name, p, slen/2); } else { strncpy(finfo->short_name, p, 12); finfo->short_name[12] = 0; -- cgit From dca808cbc4b52e38701f814f7aac043ddd1ca1c1 Mon Sep 17 00:00:00 2001 From: Richard Sharpe Date: Fri, 5 Jan 2001 13:11:29 +0000 Subject: Needed a callback arg on cli_list ... (This used to be commit d45e667a74fc2fcbf69c4819d480269c03dbfae4) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2e904e06b7..ae1607c1c4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -148,7 +148,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) do a directory listing, calling fn on each file found ****************************************************************************/ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) + void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -300,7 +300,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;i Date: Tue, 20 Feb 2001 10:11:40 +0000 Subject: pipe opening now works with unicode (This used to be commit ba3ce3404e1cd2e9da3ba1708f6fc8a12c085ef2) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index ae1607c1c4..d4c67fd9e4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -205,7 +205,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, } if (!cli_send_trans(cli, SMBtrans2, - NULL, 0, /* Name, length */ + NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ -- cgit From c7c3db2f16e572e14c5d881b641271b2ab9aa4be Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 20 Feb 2001 12:22:30 +0000 Subject: converted cli_list() (This used to be commit bdce09b77807c80281c1e169b7c4813c9238fbe3) --- source3/libsmb/clilist.c | 77 ++++++++++++++++++++++++++++-------------------- 1 file changed, 45 insertions(+), 32 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d4c67fd9e4..f7044b27e8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -30,7 +30,8 @@ The length of the structure is returned The structure of a long filename depends on the info level. 260 is used by NT and 2 is used by OS/2 ****************************************************************************/ -static int interpret_long_filename(int level,char *p,file_info *finfo) +static int interpret_long_filename(struct cli_state *cli, + int level,char *p,file_info *finfo) { extern file_info def_finfo; @@ -47,8 +48,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+27); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+27, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(28 + CVAL(p,26)); @@ -60,8 +63,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); - pstrcpy(finfo->name,p+31); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+31, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(32 + CVAL(p,30)); @@ -74,8 +79,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+33); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+33, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(SVAL(p,4)+4); @@ -87,8 +94,10 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) finfo->mtime = make_unix_date2(p+16); finfo->size = IVAL(p,20); finfo->mode = CVAL(p,28); - pstrcpy(finfo->name,p+37); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p+37, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } return(SVAL(p,4)+4); @@ -124,16 +133,15 @@ static int interpret_long_filename(int level,char *p,file_info *finfo) p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; - if (p[1] == 0 && slen > 1) { - /* NT has stuffed up again */ - unistr_to_dos(finfo->short_name, p, slen/2); - } else { - strncpy(finfo->short_name, p, 12); - finfo->short_name[12] = 0; - } + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); p += 24; /* short name? */ - StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen)); - dos_to_unix(finfo->name,True); + clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + -1, + CLISTR_TERMINATE | CLISTR_CONVERT); return(ret); } return(SVAL(p,0)); @@ -172,7 +180,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; pstrcpy(mask,Mask); - unix_to_dos(mask,True); while (ff_eos == 0) { loop_count++; @@ -181,7 +188,9 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param_len = 12+strlen(mask)+1; + param_len = 12+clistr_push_size(cli, NULL, mask, -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); if (First) { setup = TRANSACT2_FINDFIRST; @@ -190,7 +199,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); - pstrcpy(param+12,mask); + clistr_push(cli, param+12, mask, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -198,10 +208,8 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - pstrcpy(param+12,mask); - - DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n", - ff_dir_handle,ff_lastname,mask)); + clistr_push(cli, param+12, mask, -1, + CLISTR_TERMINATE | CLISTR_CONVERT); } if (!cli_send_trans(cli, SMBtrans2, @@ -254,19 +262,24 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, switch(info_level) { case 260: - StrnCpy(mask,p+ff_lastname, - MIN(sizeof(mask)-1,data_len-ff_lastname)); + clistr_pull(cli, mask, p+ff_lastname, + sizeof(mask), + data_len-ff_lastname, + CLISTR_TERMINATE | + CLISTR_CONVERT); break; case 1: - pstrcpy(mask,p + ff_lastname + 1); + clistr_pull(cli, mask, p+ff_lastname+1, + sizeof(mask), + -1, + CLISTR_TERMINATE | + CLISTR_CONVERT); break; } } else { pstrcpy(mask,""); } - dos_to_unix(mask, True); - /* and add them to the dirlist pool */ dirlist = Realloc(dirlist,dirlist_len + data_len); @@ -278,7 +291,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(info_level,p2,NULL); + p2 += interpret_long_filename(cli,info_level,p2,NULL); SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); /* grab the data for later use */ @@ -299,7 +312,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, } for (p=dirlist,i=0;i Date: Tue, 20 Feb 2001 23:52:27 +0000 Subject: yipee! client unicode now works well with nt (This used to be commit 5b2ef8a1b914265c6072c968d2dad7d26c2aeffc) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f7044b27e8..9348b65bad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -140,8 +140,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + namelen, + CLISTR_CONVERT); return(ret); } return(SVAL(p,0)); -- cgit From a8ab9840786b8376283743de8eef861d382b3171 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 21 Feb 2001 03:40:20 +0000 Subject: the unicode conversion of our client code is complete enough to be enabled by default you can disable it by setting the environment variable CLI_FORCE_ASCII (This used to be commit 4d59c08c5e6f54c0d6ced7650750cb987e77b6c9) --- source3/libsmb/clilist.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9348b65bad..d4cc00d9f3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -353,7 +353,7 @@ static int interpret_short_filename(char *p,file_info *finfo) but should otherwise not be used ****************************************************************************/ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *)) + void (*fn)(file_info *, const char *, void *), void *state) { char *p; int received = 0; @@ -373,12 +373,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - if (first) - set_message(cli->outbuf,2,5 + strlen(mask),True); - else - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBffirst; + CVAL(cli->outbuf,smb_com) = SMBsearch; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -389,21 +386,19 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - if (first) - pstrcpy(p,mask); - else - pstrcpy(p,""); - p += strlen(p) + 1; - + p += clistr_push(cli, p, first?mask:"", -1, CLISTR_TERMINATE|CLISTR_CONVERT); *p++ = 5; if (first) { SSVAL(p,0,0); + p += 2; } else { SSVAL(p,0,21); p += 2; memcpy(p,status,21); + p += 21; } + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) break; @@ -433,7 +428,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,5 + 21,True); + set_message(cli->outbuf,2,0,True); CVAL(cli->outbuf,smb_com) = SMBfclose; SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -449,7 +444,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(p, 0, 21); p += 2; memcpy(p,status,21); + p += 21; + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); @@ -459,7 +456,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;i Date: Sun, 25 Feb 2001 23:46:28 +0000 Subject: use cli_list_old() when negotiating the older protocols (This used to be commit 735f29319b8d81df203c8ddbcea5349b11f2195d) --- source3/libsmb/clilist.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d4cc00d9f3..c30f69a36c 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,6 +178,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, int param_len, data_len; uint16 setup; pstring param; + + if (cli->protocol <= PROTOCOL_LANMAN1) { + return cli_list_old(cli, Mask, attribute, fn, state); + } pstrcpy(mask,Mask); -- cgit From f9405ab8f921753f1de9490f37b18ccfcd3ab370 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2001 05:10:44 +0000 Subject: add cli_list_new() for forced new protocol listing (This used to be commit a5407366b77f2bec2c21e1f36dd007813d33f75e) --- source3/libsmb/clilist.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index c30f69a36c..eccf3c553a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -135,8 +135,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), - -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + 24, + CLISTR_CONVERT); p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), @@ -155,8 +155,8 @@ static int interpret_long_filename(struct cli_state *cli, /**************************************************************************** do a directory listing, calling fn on each file found ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state) +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -179,10 +179,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, uint16 setup; pstring param; - if (cli->protocol <= PROTOCOL_LANMAN1) { - return cli_list_old(cli, Mask, attribute, fn, state); - } - pstrcpy(mask,Mask); while (ff_eos == 0) { @@ -466,3 +462,17 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, if (dirlist) free(dirlist); return(num_received); } + + +/**************************************************************************** + do a directory listing, calling fn on each file found + this auto-switches between old and new style + ****************************************************************************/ +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, + void (*fn)(file_info *, const char *, void *), void *state) +{ + if (cli->protocol <= PROTOCOL_LANMAN1) { + return cli_list_old(cli, Mask, attribute, fn, state); + } + return cli_list_new(cli, Mask, attribute, fn, state); +} -- cgit From 0d54de536c03f941739359a121a337aa33a2dc84 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 26 Feb 2001 06:53:42 +0000 Subject: made some LANMAN1 wildcard progress it now handles -M LANMAN1 -f '.x' -m '?x' nicely (This used to be commit e7ccb9be6da9b1426eb136b4a0a1171232471768) --- source3/libsmb/clilist.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index eccf3c553a..175673d4fe 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -133,10 +133,14 @@ static int interpret_long_filename(struct cli_state *cli, p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; - clistr_pull(cli, finfo->short_name, p, - sizeof(finfo->short_name), - 24, - CLISTR_CONVERT); + { + /* stupid NT bugs. grr */ + int flags = CLISTR_CONVERT; + if (p[1] == 0 && namelen > 1) flags |= CLISTR_UNICODE; + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + 24, flags); + } p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), @@ -159,8 +163,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { int max_matches = 512; - /* NT uses 260, OS/2 uses 2. Both accept 1. */ - int info_level = cli->protocolcapabilities&CAP_NT_SMBS)?260:1; + pstrcpy(mask,Mask); while (ff_eos == 0) { -- cgit From 45c2ee3ff2d01fdd0a2db9fa90457cff4663c43d Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 10 Mar 2001 11:35:25 +0000 Subject: to use the same macros in the client and server rename the CLISTR_ macros to STR_ (This used to be commit 95c9e4e0ba8f37f565aaf136f41eb76489441ff7) --- source3/libsmb/clilist.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 175673d4fe..f0ca0d5f54 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -51,7 +51,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+27, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(28 + CVAL(p,26)); @@ -66,7 +66,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+31, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(32 + CVAL(p,30)); @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+33, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); @@ -97,7 +97,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+37, sizeof(finfo->name), -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } return(SVAL(p,4)+4); @@ -135,8 +135,8 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; { /* stupid NT bugs. grr */ - int flags = CLISTR_CONVERT; - if (p[1] == 0 && namelen > 1) flags |= CLISTR_UNICODE; + int flags = STR_CONVERT; + if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), 24, flags); @@ -145,7 +145,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, - CLISTR_CONVERT); + STR_CONVERT); return(ret); } return(SVAL(p,0)); @@ -195,8 +195,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } param_len = 12+clistr_push_size(cli, NULL, mask, -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); if (First) { setup = TRANSACT2_FINDFIRST; @@ -206,7 +206,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); clistr_push(cli, param+12, mask, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -215,7 +215,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ clistr_push(cli, param+12, mask, -1, - CLISTR_TERMINATE | CLISTR_CONVERT); + STR_TERMINATE | STR_CONVERT); } if (!cli_send_trans(cli, SMBtrans2, @@ -271,15 +271,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), data_len-ff_lastname, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); break; case 1: clistr_pull(cli, mask, p+ff_lastname+1, sizeof(mask), -1, - CLISTR_TERMINATE | - CLISTR_CONVERT); + STR_TERMINATE | + STR_CONVERT); break; } } else { @@ -392,7 +392,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, CLISTR_TERMINATE|CLISTR_CONVERT); + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT); *p++ = 5; if (first) { SSVAL(p,0,0); -- cgit From 9ea70bd00349bc391809bec374700c6d9ce2952b Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 14 Mar 2001 12:42:43 +0000 Subject: simpler clistr interface which handles individual packets having unicode bit set differently to capabilities (This used to be commit 34a0821e087810381996f5ff6cf3b4d7b9bb53a0) --- source3/libsmb/clilist.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index f0ca0d5f54..0033f05942 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -194,10 +194,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param_len = 12+clistr_push_size(cli, NULL, mask, -1, - STR_TERMINATE | - STR_CONVERT); - if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ @@ -205,8 +201,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,4+2); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); - clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -214,10 +211,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ - clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + p = param+12; + p += clistr_push(cli, param+12, mask, -1, + STR_TERMINATE | STR_CONVERT); } + param_len = PTR_DIFF(p, param); + if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ -- cgit From 871a4294043e2e74d906f63ad97a31e35abd0374 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 16 Mar 2001 03:25:13 +0000 Subject: added STR_ASCII support to clistr_pull() (This used to be commit 797293811ef0a79eecc460c471135c89090f8c06) --- source3/libsmb/clilist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0033f05942..9080a9c221 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -333,7 +333,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, interpret a short filename structure The length of the structure is returned ****************************************************************************/ -static int interpret_short_filename(char *p,file_info *finfo) +static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -345,7 +345,7 @@ static int interpret_short_filename(char *p,file_info *finfo) finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); - pstrcpy(finfo->name,p+30); + clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); @@ -461,7 +461,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, for (p=dirlist,i=0;i Date: Wed, 4 Jul 2001 07:15:53 +0000 Subject: The big character set handling changeover! This commit gets rid of all our old codepage handling and replaces it with iconv. All internal strings in Samba are now in "unix" charset, which may be multi-byte. See internals.doc and my posting to samba-technical for a more complete explanation. (This used to be commit debb471267960e56005a741817ebd227ecfc512a) --- source3/libsmb/clilist.c | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9080a9c221..b08cc08f01 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -51,7 +51,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+27, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(28 + CVAL(p,26)); @@ -66,7 +66,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+31, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(32 + CVAL(p,30)); @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+33, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(SVAL(p,4)+4); @@ -97,7 +97,7 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p+37, sizeof(finfo->name), -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } return(SVAL(p,4)+4); @@ -135,7 +135,7 @@ static int interpret_long_filename(struct cli_state *cli, p += 2; { /* stupid NT bugs. grr */ - int flags = STR_CONVERT; + int flags = 0; if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), @@ -144,8 +144,7 @@ static int interpret_long_filename(struct cli_state *cli, p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - namelen, - STR_CONVERT); + namelen, 0); return(ret); } return(SVAL(p,0)); @@ -203,7 +202,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,8,0); p = param+12; p += clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -213,7 +212,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, -1, - STR_TERMINATE | STR_CONVERT); + STR_TERMINATE); } param_len = PTR_DIFF(p, param); @@ -271,15 +270,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), data_len-ff_lastname, - STR_TERMINATE | - STR_CONVERT); + STR_TERMINATE); break; case 1: clistr_pull(cli, mask, p+ff_lastname+1, sizeof(mask), -1, - STR_TERMINATE | - STR_CONVERT); + STR_TERMINATE); break; } } else { @@ -345,7 +342,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); - clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_CONVERT|STR_ASCII); + clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); @@ -392,7 +389,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE|STR_CONVERT); + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); *p++ = 5; if (first) { SSVAL(p,0,0); -- cgit From 74e99216289956bef5d13f4a691b749933eadfa2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 7 Jul 2001 21:23:32 +0000 Subject: fixed some unicode and LANMAN2 bugs in trans2 find first (This used to be commit dc99b9ddf847c210c72921ba1dedcdc34fd32aab) --- source3/libsmb/clilist.c | 180 ++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 103 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b08cc08f01..e0287bf6c4 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -34,120 +34,94 @@ static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { extern file_info def_finfo; + file_info finfo2; + int len; + char *base = p; - if (finfo) - memcpy(finfo,&def_finfo,sizeof(*finfo)); + if (!finfo) finfo = &finfo2; + + memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { case 1: /* OS/2 understands this */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - clistr_pull(cli, finfo->name, p+27, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(28 + CVAL(p,26)); + /* these dates are converted to GMT by + make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + len = CVAL(p, 26); + p += 27; + p += clistr_align_in(cli, p, 0); + p += clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + len, + STR_TERMINATE); + return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ - if (finfo) { - /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); - finfo->mode = CVAL(p,24); - clistr_pull(cli, finfo->name, p+31, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(32 + CVAL(p,30)); - - /* levels 3 and 4 are untested */ - case 3: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - clistr_pull(cli, finfo->name, p+33, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(SVAL(p,4)+4); - - case 4: - if (finfo) { - /* these dates are probably like the other ones */ - finfo->ctime = make_unix_date2(p+8); - finfo->atime = make_unix_date2(p+12); - finfo->mtime = make_unix_date2(p+16); - finfo->size = IVAL(p,20); - finfo->mode = CVAL(p,28); - clistr_pull(cli, finfo->name, p+37, - sizeof(finfo->name), - -1, - STR_TERMINATE); - } - return(SVAL(p,4)+4); + /* these dates are converted to GMT by + make_unix_date */ + finfo->ctime = make_unix_date2(p+4); + finfo->atime = make_unix_date2(p+8); + finfo->mtime = make_unix_date2(p+12); + finfo->size = IVAL(p,16); + finfo->mode = CVAL(p,24); + len = CVAL(p, 30); + p += 31; + p += clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + len, + STR_NOALIGN); + return PTR_DIFF(p, base) + 1; case 260: /* NT uses this, but also accepts 2 */ - if (finfo) { - int ret = SVAL(p,0); - int namelen, slen; - p += 4; /* next entry offset */ - p += 4; /* fileindex */ + { + int namelen, slen; + p += 4; /* next entry offset */ + p += 4; /* fileindex */ - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; - p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; - p += 4; /* EA size */ - slen = SVAL(p, 0); - p += 2; - { - /* stupid NT bugs. grr */ - int flags = 0; - if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; - clistr_pull(cli, finfo->short_name, p, - sizeof(finfo->short_name), - 24, flags); - } - p += 24; /* short name? */ - clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - namelen, 0); - return(ret); + /* these dates appear to arrive in a + weird way. It seems to be localtime + plus the serverzone given in the + initial connect. This is GMT when + DST is not in effect and one hour + from GMT otherwise. Can this really + be right?? + + I suppose this could be called + kludge-GMT. Is is the GMT you get + by using the current DST setting on + a different localtime. It will be + cheap to calculate, I suppose, as + no DST tables will be needed */ + + finfo->ctime = interpret_long_date(p); p += 8; + finfo->atime = interpret_long_date(p); p += 8; + finfo->mtime = interpret_long_date(p); p += 8; p += 8; + finfo->size = IVAL(p,0); p += 8; + p += 8; /* alloc size */ + finfo->mode = CVAL(p,0); p += 4; + namelen = IVAL(p,0); p += 4; + p += 4; /* EA size */ + slen = SVAL(p, 0); + p += 2; + { + /* stupid NT bugs. grr */ + int flags = 0; + if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; + clistr_pull(cli, finfo->short_name, p, + sizeof(finfo->short_name), + 24, flags); } - return(SVAL(p,0)); + p += 24; /* short name? */ + clistr_pull(cli, finfo->name, p, + sizeof(finfo->name), + namelen, 0); + return SVAL(base, 0); + } } DEBUG(1,("Unknown long filename format %d\n",level)); -- cgit From 2ccfea3de7b2b7dc0be2438c3adb3f7be82a2dfc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Fri, 10 Aug 2001 06:00:33 +0000 Subject: A rewrite of the error handling in the libsmb client code. I've separated out the error handling into a bunch of separate functions rather than all being handled in one big function. Fetch error codes from the last received packet: void cli_dos_error(struct cli_state *cli, uint8 *eclass, uint32 *num); uint32 cli_nt_error(struct cli_state *); Convert errors to UNIX errno values: int cli_errno_from_dos(uint8 eclass, uint32 num); int cli_errno_from_nt(uint32 status); int cli_errno(struct cli_state *cli); Detect different kinds of errors: BOOL cli_is_dos_error(struct cli_state *cli); BOOL cli_is_nt_error(struct cli_state *cli); BOOL cli_is_error(struct cli_state *cli); This also means we now support CAP_STATUS32 as we can decode and understand NT errors instead of just DOS errors. Yay! Ported a whole bunch of files in libsmb to use this new API instead of the just the DOS error. (This used to be commit 6dbdb0d813f3c7ab20b38baa1223b0b479aadec9) --- source3/libsmb/clilist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e0287bf6c4..b7624486d6 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -204,12 +204,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, - &rdata, &data_len)) { + &rdata, &data_len) && + cli_is_dos_error(cli)) { /* we need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; - cli_error(cli, &eclass, &ecode, NULL); + cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; msleep(100); continue; -- cgit From 2e783a47076bd0994b6ce86df7ec967bc1c2da63 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sun, 12 Aug 2001 17:30:01 +0000 Subject: this is a big global fix for the ptr = Realloc(ptr, size) bug. many possible mem leaks, and segfaults fixed. someone should port this fix to 2.2 also. (This used to be commit fa8e55b8b465114ce209344965c1ca0333b84db9) --- source3/libsmb/clilist.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b7624486d6..609f5f2331 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -141,7 +141,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring mask; file_info finfo; int i; - char *dirlist = NULL; + char *tdl, *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; @@ -259,12 +259,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* and add them to the dirlist pool */ - dirlist = Realloc(dirlist,dirlist_len + data_len); + tdl = Realloc(dirlist,dirlist_len + data_len); - if (!dirlist) { - DEBUG(0,("Failed to expand dirlist\n")); + if (!tdl) { + DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); break; } + else dirlist = tdl; /* put in a length for the last entry, to ensure we can chain entries into the next packet */ @@ -340,7 +341,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; int i; - char *dirlist = NULL; + char *tdl, *dirlist = NULL; pstring mask; ZERO_ARRAY(status); @@ -385,10 +386,14 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - dirlist = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + tdl = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); - if (!dirlist) + if (!tdl) { + DEBUG(0,("cli_list_old: failed to expand dirlist")); + if (dirlist) free(dirlist); return 0; + } + else dirlist = tdl; p = smb_buf(cli->inbuf) + 3; -- cgit From 4da562d4dc6d197c3a7495672638e0f14838d38c Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Sun, 12 Aug 2001 23:53:26 +0000 Subject: Fixed crash bug when attempting to list contents of non-existent directory. (This used to be commit a7863f0f033b31838a53960e9f616d9a82081ecf) --- source3/libsmb/clilist.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 609f5f2331..a7ba1c07ad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -216,6 +216,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } + if (cli_is_error(cli)) + return -1; + if (total_received == -1) total_received = 0; /* parse out some important return info */ -- cgit From 11ce0f4d2d493702386c0bd49c8e2dd2aad84d56 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 20 Aug 2001 05:15:26 +0000 Subject: a bunch of fixes from the sflight to seattle in particular: - fixed NT status code for a bunch of ops - fixed handling of protocol levels in ms_fnmatch (This used to be commit 3eba9606f71f90bfd9820af26f8676277ed22390) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a7ba1c07ad..e727217628 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -216,7 +216,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } - if (cli_is_error(cli)) + if (cli_is_error(cli) || !rdata || !rparam) return -1; if (total_received == -1) total_received = 0; -- cgit From 8d9cdf0d749413c1575b6cc44bfeed3f0605a526 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 22 Aug 2001 02:47:38 +0000 Subject: a fix for directory listing with the dave/thursby client (This used to be commit 5a3fd3317e0fedd72450660f031b5ba42a11b875) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e727217628..6368674488 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -217,7 +217,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } if (cli_is_error(cli) || !rdata || !rparam) - return -1; + break; if (total_received == -1) total_received = 0; -- cgit From a350db7c7cc19876045f20a84b41953fd6a346ac Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 24 Aug 2001 04:53:39 +0000 Subject: fixed shortname length in trans2 list (This used to be commit ae669720d8f434a23397deaea3371998ab6f1f54) --- source3/libsmb/clilist.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 6368674488..562e1710d3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -71,6 +71,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; + /* check for unisys! */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), len, @@ -114,7 +115,7 @@ static int interpret_long_filename(struct cli_state *cli, if (p[1] == 0 && namelen > 1) flags |= STR_UNICODE; clistr_pull(cli, finfo->short_name, p, sizeof(finfo->short_name), - 24, flags); + slen, flags); } p += 24; /* short name? */ clistr_pull(cli, finfo->name, p, -- cgit From d53d5beeb29c0024556aae2f66f1d5bfe63960e5 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 5 Sep 2001 11:32:59 +0000 Subject: use cli_is_error() instead of looking in smb_rcls, otherwise NT status codes don't work correctly (This used to be commit 55d5828e608671f070a9e96938be0d16d50aeb26) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 562e1710d3..a99bc91bfb 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -408,7 +408,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, num_received += received; - if (CVAL(cli->inbuf,smb_rcls) != 0) break; + if (cli_is_error(cli)) break; } if (!first) { @@ -436,7 +436,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { - DEBUG(0,("Error closing search: %s\n",smb_errstr(cli->inbuf))); + DEBUG(0,("Error closing search: %s\n",cli_errstr(cli))); } } -- cgit From bcbd75f7add425ebee760ddbd2e80a1d4a51e619 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 17 Sep 2001 03:33:37 +0000 Subject: move to SAFE_FREE() (This used to be commit 48fc6a6cd52e01b287030fbbf0aa08a6814c5e11) --- source3/libsmb/clilist.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a99bc91bfb..a9212c9dba 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -283,9 +283,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, total_received += ff_searchcount; - if (rdata) free(rdata); rdata = NULL; - if (rparam) free(rparam); rparam = NULL; - + SAFE_FREE(rdata); + SAFE_FREE(rparam); + DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); @@ -300,7 +300,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* free up the dirlist buffer */ - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return(total_received); } @@ -394,7 +394,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_old: failed to expand dirlist")); - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return 0; } else dirlist = tdl; @@ -446,7 +446,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, fn(&finfo, Mask, state); } - if (dirlist) free(dirlist); + SAFE_FREE(dirlist); return(num_received); } -- cgit From d6823366b881612234ab0655adb11c594f864c4a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 11 Jan 2002 19:10:25 +0000 Subject: Same fix as went into 2.2 (I'm waiting for jerry to finish some code). Jeremy. (This used to be commit 01ff6ce4963e1daff019f2b936cef218e1c93f67) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a9212c9dba..0c80044b68 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -358,7 +358,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBsearch; + SCVAL(cli->outbuf,smb_com,SMBsearch); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); @@ -416,7 +416,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->inbuf,'\0',smb_size); set_message(cli->outbuf,2,0,True); - CVAL(cli->outbuf,smb_com) = SMBfclose; + SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libsmb/clilist.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0c80044b68..8b28e05a47 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. client directory list routines Copyright (C) Andrew Tridgell 1994-1998 -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libsmb/clilist.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8b28e05a47..17a759f9e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -54,10 +54,14 @@ static int interpret_long_filename(struct cli_state *cli, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + /* the len+2 below looks strange but it is + important to cope with the differences + between win2000 and win9x for this call + (tridge) */ p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_TERMINATE); + sizeof(finfo->name), + len+2, + STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libsmb/clilist.c | 48 +++++++++++++++++++++++------------------------- 1 file changed, 23 insertions(+), 25 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 17a759f9e3..3eacc25380 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,13 +22,13 @@ #include "includes.h" - /**************************************************************************** -interpret a long filename structure - this is mostly guesses at the moment -The length of the structure is returned -The structure of a long filename depends on the info level. 260 is used -by NT and 2 is used by OS/2 + Interpret a long filename structure - this is mostly guesses at the moment. + The length of the structure is returned + The structure of a long filename depends on the info level. 260 is used + by NT and 2 is used by OS/2 ****************************************************************************/ + static int interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { @@ -41,8 +41,7 @@ static int interpret_long_filename(struct cli_state *cli, memcpy(finfo,&def_finfo,sizeof(*finfo)); - switch (level) - { + switch (level) { case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ @@ -126,16 +125,16 @@ static int interpret_long_filename(struct cli_state *cli, namelen, 0); return SVAL(base, 0); } - } + } DEBUG(1,("Unknown long filename format %d\n",level)); return(SVAL(p,0)); } - /**************************************************************************** - do a directory listing, calling fn on each file found - ****************************************************************************/ + Do a directory listing, calling fn on each file found. +****************************************************************************/ + int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -307,12 +306,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, return(total_received); } - - /**************************************************************************** -interpret a short filename structure -The length of the structure is returned + Interpret a short filename structure. + The length of the structure is returned. ****************************************************************************/ + static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { extern file_info def_finfo; @@ -334,10 +332,11 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /**************************************************************************** - do a directory listing, calling fn on each file found - this uses the old SMBsearch interface. It is needed for testing Samba, - but should otherwise not be used - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + this uses the old SMBsearch interface. It is needed for testing Samba, + but should otherwise not be used. +****************************************************************************/ + int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { @@ -453,16 +452,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, return(num_received); } - /**************************************************************************** - do a directory listing, calling fn on each file found - this auto-switches between old and new style - ****************************************************************************/ + Do a directory listing, calling fn on each file found. + This auto-switches between old and new style. +****************************************************************************/ + int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - if (cli->protocol <= PROTOCOL_LANMAN1) { + if (cli->protocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); - } return cli_list_new(cli, Mask, attribute, fn, state); } -- cgit From e217ba0a701d668cc366c2d6f065094861ba0c36 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 3 Dec 2002 20:02:18 +0000 Subject: use the new IVAL_TO_SMB_OFF_T for file_info size member dir now shows correct size on large files (This used to be commit 172dccf55e972d4cc40b7e34ce433d49e738fba0) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3eacc25380..1616d46bf1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL(p,16); + finfo->size = IVAL_TO_SMB_OFF_T(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL(p,0); p += 8; + finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL(p,26); + finfo->size = IVAL_TO_SMB_OFF_T(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From 3fc4d88d99b8629e7e3f97d6e70254ef0865a5e5 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 10 Dec 2002 23:44:33 +0000 Subject: Fix client reporting of 64 bit files. Jeremy. (This used to be commit 8dcbfa4e770d74d4ce6faaf1a0597d07d0a5cc81) --- source3/libsmb/clilist.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1616d46bf1..4a1737af49 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -48,7 +48,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); p += 27; @@ -69,7 +69,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = make_unix_date2(p+4); finfo->atime = make_unix_date2(p+8); finfo->mtime = make_unix_date2(p+12); - finfo->size = IVAL_TO_SMB_OFF_T(p,16); + finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); p += 31; @@ -104,7 +104,7 @@ static int interpret_long_filename(struct cli_state *cli, finfo->ctime = interpret_long_date(p); p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL_TO_SMB_OFF_T(p,0); p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; p += 8; /* alloc size */ finfo->mode = CVAL(p,0); p += 4; namelen = IVAL(p,0); p += 4; @@ -322,7 +322,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi /* this date is converted to GMT by make_unix_date */ finfo->ctime = make_unix_date(p+22); finfo->mtime = finfo->atime = finfo->ctime; - finfo->size = IVAL_TO_SMB_OFF_T(p,26); + finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) fstrcpy(finfo->short_name,finfo->name); -- cgit From 4242eda183393b0535ac8ef880b4f441c60137af Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 17:22:48 +0000 Subject: merging some rpcclient and net functionality from HEAD (This used to be commit 7a4c87484237308cb3ad0d671687da7e0f6e733b) --- source3/libsmb/clilist.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4a1737af49..bf10be887a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -324,8 +324,10 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); - if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) - fstrcpy(finfo->short_name,finfo->name); + if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { + strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); + finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; + } return(DIR_STRUCT_SIZE); } -- cgit From 99cdb462083381c88689a4e698ca48b6ed4cf5ac Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 15 Jan 2003 18:57:41 +0000 Subject: *lots of small merges form HEAD *sync up configure.in *don't build torture tools in make all *make sure to remove torture tools as part of make clean (This used to be commit 0fb724b3216eeeb97e61ff12755ca3a31bcad6ef) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index bf10be887a..89ab5d6414 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -328,7 +328,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; } - + return(DIR_STRUCT_SIZE); } -- cgit From dbe2858b862232ede390fe0088f82d1e826612f9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 13 Mar 2003 00:51:05 +0000 Subject: Change size parameters from signed to unsigned to fix up warnings. Jeremy. (This used to be commit 33b11d5eb53bdeb9d279d221fd5c01579253e1c7) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 89ab5d6414..3884e4da82 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -154,7 +154,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; pstring param; -- cgit From d5ee9b2f480ddbda0b8f69409698d27c99384f9c Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 18 Mar 2003 11:22:52 +0000 Subject: Jeremy merged across my string parinoia fixes, but forgot to enable them! :-) This patch catches up on the rest of the work - as much string checking as is possible is done at compile time, and the rest at runtime. Lots of code converted to pstrcpy() etc, and other code reworked to correctly call sizeof(). Andrew Bartlett (This used to be commit c5b604e2ee67d74241ae2fa07ae904647d35a2be) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3884e4da82..5bd1283ab7 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -178,7 +178,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; @@ -188,7 +188,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, -1, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } -- cgit From 5ab2b1e9219a99b8e3b01a977e0703e76b57debb Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 18:57:37 +0000 Subject: Eliminate valgrind error when client gets bad sig on list. Some reformatting. Jeremy. (This used to be commit b8f6b836468b3a0ae75977dc65cae8400f74734c) --- source3/libsmb/clilist.c | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5bd1283ab7..608d740f83 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -101,13 +101,20 @@ static int interpret_long_filename(struct cli_state *cli, cheap to calculate, I suppose, as no DST tables will be needed */ - finfo->ctime = interpret_long_date(p); p += 8; - finfo->atime = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); p += 8; p += 8; - finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; + finfo->ctime = interpret_long_date(p); + p += 8; + finfo->atime = interpret_long_date(p); + p += 8; + finfo->mtime = interpret_long_date(p); + p += 8; + p += 8; + finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); + p += 8; p += 8; /* alloc size */ - finfo->mode = CVAL(p,0); p += 4; - namelen = IVAL(p,0); p += 4; + finfo->mode = CVAL(p,0); + p += 4; + namelen = IVAL(p,0); + p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); p += 2; @@ -214,7 +221,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, uint8 eclass; uint32 ecode; cli_dos_error(cli, &eclass, &ecode); - if (eclass != ERRSRV || ecode != ERRerror) break; + if (eclass != ERRSRV || ecode != ERRerror) + break; msleep(100); continue; } @@ -222,7 +230,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (cli_is_error(cli) || !rdata || !rparam) break; - if (total_received == -1) total_received = 0; + if (total_received == -1) + total_received = 0; /* parse out some important return info */ p = rparam; @@ -245,8 +254,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* we might need the lastname for continuations */ if (ff_lastname > 0) { - switch(info_level) - { + switch(info_level) { case 260: clistr_pull(cli, mask, p+ff_lastname, sizeof(mask), @@ -270,8 +278,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); break; + } else { + dirlist = tdl; } - else dirlist = tdl; /* put in a length for the last entry, to ensure we can chain entries into the next packet */ @@ -291,7 +300,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, DEBUG(3,("received %d entries (eos=%d)\n", ff_searchcount,ff_eos)); - if (ff_searchcount > 0) loop_count = 0; + if (ff_searchcount > 0) + loop_count = 0; First = False; } -- cgit From 9c49c4694885a0b173ac982877fc64385e4855b7 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 30 Jul 2003 19:00:52 +0000 Subject: Fix bug we discovered in W2K client signing on secondary trans2 packets. Use W2K parameters. tpot please re-test smbclient with your problem directory. Jeremy. (This used to be commit 677d3a3c4ca0b67148e5e56fa876773a067679bd) --- source3/libsmb/clilist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 608d740f83..2b56582700 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -145,7 +145,7 @@ static int interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { - int max_matches = 512; + int max_matches = 1366; /* Match W2k - was 512. */ int info_level; char *p, *p2; pstring mask; @@ -207,7 +207,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, - cli->max_xmit /* data, length, max */ + MIN(16384,cli->max_xmit) /* data, length, max. W2K server signing + has a bug unless this matches what W2K uses. */ )) { break; } -- cgit From 2443f7ffa20a683eabb792182cb0206402ad8059 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 2 Aug 2003 00:29:45 +0000 Subject: Correct fix (removed the earlier band-aid) for what I thought was a signing bug with w2k. Turns out that when we're doing a trans/trans2/nttrans call the MID and send_sequence_number and reply_sequence_number must remain constant. This was something we got very wrong in earlier versions of Samba. I can now get a directory listing from WINNT\SYSTEM32 with the older earlier parameters for clilist.c This still needs to be fixed for the server side of Samba, client appears to be working happily now (I'm doing a signed smbtar download of an entire W2K3 image to test this :-). Jeremy. (This used to be commit 2093a3130d4087d0659b497eebd580e7a66e5aa3) --- source3/libsmb/clilist.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2b56582700..7822987ada 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -145,7 +145,11 @@ static int interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(file_info *, const char *, void *), void *state) { +#if 0 int max_matches = 1366; /* Match W2k - was 512. */ +#else + int max_matches = 512; +#endif int info_level; char *p, *p2; pstring mask; @@ -207,8 +211,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ NULL, 0, - MIN(16384,cli->max_xmit) /* data, length, max. W2K server signing - has a bug unless this matches what W2K uses. */ +#if 0 + /* w2k value. */ + MIN(16384,cli->max_xmit) /* data, length, max. */ +#else + cli->max_xmit /* data, length, max. */ +#endif )) { break; } -- cgit From 231124ced9237cdbc3732a722c8f373ee760927b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 29 Oct 2003 21:28:00 +0000 Subject: Fixes to check for wraps which could cause coredumps. Jeremy. (This used to be commit ad06edd1bb58cc5e2c38a364b1af96a933b770af) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 7822987ada..2c1831ae99 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -82,7 +82,7 @@ static int interpret_long_filename(struct cli_state *cli, case 260: /* NT uses this, but also accepts 2 */ { - int namelen, slen; + size_t namelen, slen; p += 4; /* next entry offset */ p += 4; /* fileindex */ -- cgit From 24df38dbc6648261f86adcffd664ffc43f8f3346 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Mon, 23 Feb 2004 02:54:03 +0000 Subject: Janitor for tpot...bugzilla #1098, msleep already exists on aix (This used to be commit 4319df7fdc2d878c509381923cc1db4d731620ba) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2c1831ae99..ab157d48e9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -232,7 +232,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; - msleep(100); + smb_msleep(100); continue; } -- cgit From acf9d61421faa6c0055d57fdee7db300dc5431aa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Dec 2004 18:25:53 +0000 Subject: r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation functions so we can funnel through some well known functions. Should help greatly with malloc checking. HEAD patch to follow. Jeremy. (This used to be commit 620f2e608f70ba92f032720c031283d295c5c06a) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index ab157d48e9..8ab5854c8f 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -282,7 +282,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } /* and add them to the dirlist pool */ - tdl = Realloc(dirlist,dirlist_len + data_len); + tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); @@ -413,7 +413,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - tdl = Realloc(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + tdl = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!tdl) { DEBUG(0,("cli_list_old: failed to expand dirlist")); -- cgit From 1b0f75ddfb8ed296ca0166f0606bfc108584b833 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 23 Feb 2005 19:26:32 +0000 Subject: r5520: fix last remaining dfs issues with smbclient. * all the unix extension commands should work * send the correct TRANS2_FINDFIRST format to 2k to get a listing from a msdfs root share (tested against smbd as well). * mkdir, rmdir, etc... all seem ok. I'm sure bugs will pop up so keep testing. Last thing I plan on doing is to clean up the horrible mess with connection management in smbclient and global variables (so i can move the cli_cm_xx() routines to a separate file). (This used to be commit 53d6a5f9d16aef4afc60b4b37b296b256da00dfd) --- source3/libsmb/clilist.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8ab5854c8f..532fb3a772 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -171,8 +171,14 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(mask,Mask); + + /* when getting a directory listing from a 2k dfs root share, + we have to include the full path (\server\share\mask) here */ + + if ( cli->dfsroot ) + pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask ); + else + pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; -- cgit From 96572957fc3df956ec0fad242fc7d04ab6a6961f Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Sat, 26 Feb 2005 14:42:55 +0000 Subject: r5577: get recurse; dir working across single level dfs referrals (This used to be commit d4443807bc7a5a8615c69517365a92709db7ce29) --- source3/libsmb/clilist.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 532fb3a772..4e90a79719 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -143,7 +143,7 @@ static int interpret_long_filename(struct cli_state *cli, ****************************************************************************/ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, - void (*fn)(file_info *, const char *, void *), void *state) + void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 0 int max_matches = 1366; /* Match W2k - was 512. */ @@ -322,8 +322,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } for (p=dirlist,i=0;iprotocol <= PROTOCOL_LANMAN1) return cli_list_old(cli, Mask, attribute, fn, state); -- cgit From 9d23e37a6f9887fed08ba495555d23fefab585ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 9 Mar 2005 00:06:27 +0000 Subject: r5702: Fix bug #2271. Correctly pull out and use resume names in a directory listing (we were incorrectly understanding what was returned in the "last name" entry). Jeremy. (This used to be commit 4f2da9ecf1e5cee4749839ea1b35a942d27de09e) --- source3/libsmb/clilist.c | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 4e90a79719..d60739cf7c 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -268,24 +268,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, p = rdata; /* we might need the lastname for continuations */ - if (ff_lastname > 0) { - switch(info_level) { - case 260: - clistr_pull(cli, mask, p+ff_lastname, - sizeof(mask), - data_len-ff_lastname, - STR_TERMINATE); - break; - case 1: - clistr_pull(cli, mask, p+ff_lastname+1, - sizeof(mask), - -1, - STR_TERMINATE); - break; - } - } else { - pstrcpy(mask,""); - } /* and add them to the dirlist pool */ tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); @@ -299,10 +281,18 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) - p2 += interpret_long_filename(cli,info_level,p2,NULL); + for (p2=p,i=0;i<(ff_searchcount-1);i++) { + p2 += interpret_long_filename(cli,info_level,p2,&finfo); + } SSVAL(p2,0,data_len - PTR_DIFF(p2,p)); + /* we might need the lastname for continuations */ + if (ff_lastname > 0) { + pstrcpy(mask, finfo.name); + } else { + pstrcpy(mask,""); + } + /* grab the data for later use */ memcpy(dirlist+dirlist_len,p,data_len); dirlist_len += data_len; -- cgit From 4a62d418d9dbed3838dda871e4ead052fbe2bf0c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 10 Mar 2005 02:00:24 +0000 Subject: r5723: Add missing part of fix for #2271. After analysing the actions of a XP client against a Samba server. It never uses the "continue" flag, but always does "new search, continue from this file" instead. Change our client code to do the same (it appears that's all they test in W2K etc.). Jeremy. (This used to be commit 710bceee325005b8ca8e8ed04acc50bafa92b6e6) --- source3/libsmb/clilist.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d60739cf7c..dcac17d24a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -191,7 +191,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,4+2); /* resume required + close on end */ + SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; @@ -203,7 +203,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); SIVAL(param,6,0); /* ff_resume_key */ - SSVAL(param,10,8+4+2); /* continue + resume required + close on end */ + /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren + can miss filenames. Use last filename continue instead. JRA */ + SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); -- cgit From b360f556a5c1a6e9ed7a941451eca5d278a8a633 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 20:54:19 +0000 Subject: r5967: Fix typo bug where flags overwrote info level. Jeremy. (This used to be commit 214a2cbe5aed9f0540b03350b60d0eec1c61bad8) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index dcac17d24a..704babc919 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -205,7 +205,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SIVAL(param,6,0); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ - SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ + SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); -- cgit From f8f090ad2471056ae77705ce55eddf06419ada3d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 21:22:59 +0000 Subject: r5970: Fix old bug where ff_searchcount was being compared -1 ! This caused a filename to be processed twice. Jeremy. (This used to be commit 2ed7e30cbb3e194a08d5d9b46993652666193bec) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 704babc919..5138bca8df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -283,7 +283,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* put in a length for the last entry, to ensure we can chain entries into the next packet */ - for (p2=p,i=0;i<(ff_searchcount-1);i++) { + for (p2=p,i=0;i Date: Tue, 22 Mar 2005 21:43:51 +0000 Subject: r5973: Fix up overwrite of last 2 bytes on clilist (could cause coredump). Jeremy. (This used to be commit b0de2d761f6697ca1f4859ba098af6162ab42027) --- source3/libsmb/clilist.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5138bca8df..33bf32bb94 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -281,14 +281,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, dirlist = tdl; } - /* put in a length for the last entry, to ensure we can chain entries - into the next packet */ + /* we might need the lastname for continuations */ for (p2=p,i=0;i 0) { pstrcpy(mask, finfo.name); } else { -- cgit From 656140bf4b0c62e1bfdb4ea59db15808ae25edec Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 22 Mar 2005 22:04:01 +0000 Subject: r5975: Re-arrange code and comments to make more sense. Jeremy. (This used to be commit 08616ad80d96d1b7b558eec036bafb4bf3663942) --- source3/libsmb/clilist.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 33bf32bb94..eea4391e55 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -269,18 +269,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* point to the data bytes */ p = rdata; - /* we might need the lastname for continuations */ - - /* and add them to the dirlist pool */ - tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); - - if (!tdl) { - DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); - break; - } else { - dirlist = tdl; - } - /* we might need the lastname for continuations */ for (p2=p,i=0;i Date: Wed, 23 Mar 2005 03:55:02 +0000 Subject: r5991: Fixup last entry offset correctly for level 260. Should fix bug found by Derrell.Lipman@UnwiredUniverse.com. Jeremy. (This used to be commit 5ded615679e346d1ea155cde3413396d3e3c3a6b) --- source3/libsmb/clilist.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index eea4391e55..0f1b9efed0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -29,7 +29,7 @@ by NT and 2 is used by OS/2 ****************************************************************************/ -static int interpret_long_filename(struct cli_state *cli, +static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { extern file_info def_finfo; @@ -130,12 +130,12 @@ static int interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); - return SVAL(base, 0); + return (size_t)IVAL(base, 0); } } DEBUG(1,("Unknown long filename format %d\n",level)); - return(SVAL(p,0)); + return (size_t)IVAL(base,0); } /**************************************************************************** @@ -168,6 +168,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, unsigned int param_len, data_len; uint16 setup; pstring param; + const char *mnt; /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -271,6 +272,10 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* we might need the lastname for continuations */ for (p2=p,i=0;i Date: Wed, 6 Apr 2005 16:28:04 +0000 Subject: r6225: get rid of warnings from my compiler about nested externs (This used to be commit efea76ac71412f8622cd233912309e91b9ea52da) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 0f1b9efed0..79c2ef66a1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -22,6 +22,8 @@ #include "includes.h" +extern file_info def_finfo; + /**************************************************************************** Interpret a long filename structure - this is mostly guesses at the moment. The length of the structure is returned @@ -32,7 +34,6 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo) { - extern file_info def_finfo; file_info finfo2; int len; char *base = p; @@ -332,7 +333,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, static int interpret_short_filename(struct cli_state *cli, char *p,file_info *finfo) { - extern file_info def_finfo; *finfo = def_finfo; -- cgit From 45d03e327ae8b2b9b9761ed76161d4467b27f730 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 26 May 2005 19:39:40 +0000 Subject: r6994: Fix for bugid #2729 - it turns out resume keys are *mandatory* for a search when listing a W2K and above server from a FATxx filesystem only. Thanks to Steve Langasek for giving me the essential info that allowed me to reproduce and thus fix this. Jeremy. (This used to be commit 8227675d3dbcd4f8bb2a24ea7e3e05c428b7c929) --- source3/libsmb/clilist.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 79c2ef66a1..892a457255 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -32,7 +32,7 @@ extern file_info def_finfo; ****************************************************************************/ static size_t interpret_long_filename(struct cli_state *cli, - int level,char *p,file_info *finfo) + int level,char *p,file_info *finfo, uint32 *p_resume_key) { file_info finfo2; int len; @@ -40,6 +40,7 @@ static size_t interpret_long_filename(struct cli_state *cli, if (!finfo) finfo = &finfo2; + *p_resume_key = 0; memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { @@ -85,6 +86,8 @@ static size_t interpret_long_filename(struct cli_state *cli, { size_t namelen, slen; p += 4; /* next entry offset */ + + *p_resume_key = IVAL(p,0); p += 4; /* fileindex */ /* these dates appear to arrive in a @@ -146,7 +149,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { -#if 0 +#if 1 int max_matches = 1366; /* Match W2k - was 512. */ #else int max_matches = 512; @@ -170,6 +173,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, uint16 setup; pstring param; const char *mnt; + uint32 resume_key = 0; /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -204,7 +208,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,info_level); - SIVAL(param,6,0); /* ff_resume_key */ + /* For W2K servers serving out FAT filesystems we *must* set the + resume key. If it's not FAT then it's returned as zero. */ + SIVAL(param,6,resume_key); /* ff_resume_key */ /* NB. *DON'T* use continue here. If you do it seems that W2K and bretheren can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ @@ -277,7 +283,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli,info_level,p2,&finfo); + p2 += interpret_long_filename(cli,info_level,p2,&finfo,&resume_key); } if (ff_lastname > 0) { @@ -317,7 +323,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); for (p=dirlist,i=0;i Date: Tue, 31 May 2005 19:06:52 +0000 Subject: r7151: Fix for bug #2698. If a unicode to unix charset conversion fails (due to buggy iconv?) we can be left with a filename that doesn't exist on the remote machine. If we then do a findnext with this file the server gets confused and restarts from the beginning of the directory, causing directory listing loops. Fix this by keeping a copy of the "raw" filename data and length and using this as the argument to findnext. This won't fix the incorrect iconv conversion into the finfo struct but at least it ensures that directory listings always terminate. Tested against NTFS and FAT directories. Jeremy. (This used to be commit 848940d5a91b310e58d0631ead293418ea4186f0) --- source3/libsmb/clilist.c | 50 ++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 892a457255..a1434338c9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -31,16 +31,20 @@ extern file_info def_finfo; by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, - int level,char *p,file_info *finfo, uint32 *p_resume_key) +static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo, + uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len) { file_info finfo2; int len; char *base = p; - if (!finfo) finfo = &finfo2; + if (!finfo) { + finfo = &finfo2; + } - *p_resume_key = 0; + if (p_resume_key) { + *p_resume_key = 0; + } memcpy(finfo,&def_finfo,sizeof(*finfo)); switch (level) { @@ -87,7 +91,9 @@ static size_t interpret_long_filename(struct cli_state *cli, size_t namelen, slen; p += 4; /* next entry offset */ - *p_resume_key = IVAL(p,0); + if (p_resume_key) { + *p_resume_key = IVAL(p,0); + } p += 4; /* fileindex */ /* these dates appear to arrive in a @@ -134,6 +140,22 @@ static size_t interpret_long_filename(struct cli_state *cli, clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); + + /* To be robust in the face of unicode conversion failures + we need to copy the raw bytes of the last name seen here. + Namelen doesn't include the terminating unicode null, so + copy it here. */ + + if (p_last_name_raw && p_last_name_raw_len) { + if (namelen + 2 > p_last_name_raw->length) { + memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); + *p_last_name_raw_len = 0; + } else { + memcpy(p_last_name_raw->data, p, namelen); + SSVAL(p_last_name_raw->data, namelen, 0); + *p_last_name_raw_len = namelen + 2; + } + } return (size_t)IVAL(base, 0); } } @@ -174,6 +196,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring param; const char *mnt; uint32 resume_key = 0; + uint32 last_name_raw_len = 0; + DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; @@ -215,8 +239,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, - STR_TERMINATE); + if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { + memcpy(p, last_name_raw.data, last_name_raw_len); + p += last_name_raw_len; + } else { + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); + } } param_len = PTR_DIFF(p, param); @@ -283,7 +311,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli,info_level,p2,&finfo,&resume_key); + p2 += interpret_long_filename(cli,info_level,p2,&finfo, + &resume_key,&last_name_raw,&last_name_raw_len); } if (ff_lastname > 0) { @@ -323,12 +352,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); for (p=dirlist,i=0;i Date: Wed, 1 Jun 2005 00:00:07 +0000 Subject: r7157: Ensure we abort a directory listing if we see the same name twice between packets. Jeremy. (This used to be commit f9063b383ed2c53841ac27691b6a593b80c20b12) --- source3/libsmb/clilist.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a1434338c9..d9a6f4709d 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -313,6 +313,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } p2 += interpret_long_filename(cli,info_level,p2,&finfo, &resume_key,&last_name_raw,&last_name_raw_len); + + if (!First && *mask && strcsequal(finfo.name, mask)) { + DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", + finfo.name)); + ff_eos = 1; + break; + } } if (ff_lastname > 0) { -- cgit From ab398643a4e44211696ef5ce72b62ab7ecee7bc9 Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Tue, 19 Jul 2005 02:37:04 +0000 Subject: r8572: Remove crufty #define NO_SYSLOG as it's not used at all anymore. (This used to be commit 985dbb47d925e79c1195ca219f7ab5d6648b22b8) --- source3/libsmb/clilist.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d9a6f4709d..a0be40bdc9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -18,8 +18,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#define NO_SYSLOG - #include "includes.h" extern file_info def_finfo; -- cgit From 6d5757395a0e54245543794d0d6d6d6a32cd857a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 5 Nov 2005 04:21:55 +0000 Subject: r11511: A classic "friday night check-in" :-). This moves much of the Samba4 timezone handling code back into Samba3. Gets rid of "kludge-gmt" and removes the effectiveness of the parameter "time offset" (I can add this back in very easily if needed) - it's no longer being looked at. I'm hoping this will fix the problems people have been having with DST transitions. I'll start comprehensive testing tomorrow, but for now all modifications are done. Splits time get/set functions into srv_XXX and cli_XXX as they need to look at different timezone offsets. Get rid of much of the "efficiency" cruft that was added to Samba back in the day when the C library timezone handling functions were slow. Jeremy. (This used to be commit 414303bc0272f207046b471a0364fa296b67c1f8) --- source3/libsmb/clilist.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a0be40bdc9..e09a6514ad 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -49,9 +49,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); + finfo->ctime = cli_make_unix_date2(cli, p+4); + finfo->atime = cli_make_unix_date2(cli, p+8); + finfo->mtime = cli_make_unix_date2(cli, p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); @@ -70,9 +70,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date2(p+4); - finfo->atime = make_unix_date2(p+8); - finfo->mtime = make_unix_date2(p+12); + finfo->ctime = cli_make_unix_date2(cli, p+4); + finfo->atime = cli_make_unix_date2(cli, p+8); + finfo->mtime = cli_make_unix_date2(cli, p+12); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); @@ -380,7 +380,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ - finfo->ctime = make_unix_date(p+22); + finfo->ctime = cli_make_unix_date(cli, p+22); finfo->mtime = finfo->atime = finfo->ctime; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); -- cgit From 76796e212c0f1dc7587be138daac9c4ef093db4b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Dec 2005 00:10:59 +0000 Subject: r12275: Fix memory leak found by Mikhail Kshevetskiy and followed up by derrell@samba.org. Jeremy. (This used to be commit 5cab88f1444177129bb5521ccc4afd8869e9bf25) --- source3/libsmb/clilist.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e09a6514ad..252dafcfa8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -271,6 +271,10 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; + + SAFE_FREE(rdata); + SAFE_FREE(rparam); + cli_dos_error(cli, &eclass, &ecode); if (eclass != ERRSRV || ecode != ERRerror) break; @@ -278,8 +282,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, continue; } - if (cli_is_error(cli) || !rdata || !rparam) + if (cli_is_error(cli) || !rdata || !rparam) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; + } if (total_received == -1) total_received = 0; @@ -297,8 +304,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, ff_lastname = SVAL(p,6); } - if (ff_searchcount == 0) + if (ff_searchcount == 0) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; + } /* point to the data bytes */ p = rdata; @@ -332,6 +342,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, if (!tdl) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); + SAFE_FREE(rdata); + SAFE_FREE(rparam); break; } else { dirlist = tdl; -- cgit From f396e2248ad36e4ac24792f6278366b0c737f8d7 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sat, 7 Jan 2006 20:43:31 +0000 Subject: r12758: r12127@cabra: derrell | 2006-01-03 15:22:18 -0500 remove old superfluous comment and ifdef (This used to be commit ee7fcb43ad456929f1f005f47c52a4b4d46c5087) --- source3/libsmb/clilist.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 252dafcfa8..48780e28df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -169,11 +169,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { -#if 1 - int max_matches = 1366; /* Match W2k - was 512. */ -#else - int max_matches = 512; -#endif + int max_matches = 1366; int info_level; char *p, *p2; pstring mask; -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libsmb/clilist.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 48780e28df..252dafcfa8 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -169,7 +169,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { - int max_matches = 1366; +#if 1 + int max_matches = 1366; /* Match W2k - was 512. */ +#else + int max_matches = 512; +#endif int info_level; char *p, *p2; pstring mask; -- cgit From 894358a8f3e338b339b6c37233edef794b312087 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 7 Mar 2006 06:31:04 +0000 Subject: r13915: Fixed a very interesting class of realloc() bugs found by Coverity. realloc can return NULL in one of two cases - (1) the realloc failed, (2) realloc succeeded but the new size requested was zero, in which case this is identical to a free() call. The error paths dealing with these two cases should be different, but mostly weren't. Secondly the standard idiom for dealing with realloc when you know the new size is non-zero is the following : tmp = realloc(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } However, there were *many* *many* places in Samba where we were using the old (broken) idiom of : p = realloc(p, size) if (!p) { return error; } which will leak the memory pointed to by p on realloc fail. This commit (hopefully) fixes all these cases by moving to a standard idiom of : p = SMB_REALLOC(p, size) if (!p) { return error; } Where if the realloc returns null due to the realloc failing or size == 0 we *guarentee* that the storage pointed to by p has been freed. This allows me to remove a lot of code that was dealing with the standard (more verbose) method that required a tmp pointer. This is almost always what you want. When a realloc fails you never usually want the old memory, you want to free it and get into your error processing asap. For the 11 remaining cases where we really do need to keep the old pointer I have invented the new macro SMB_REALLOC_KEEP_OLD_ON_ERROR, which can be used as follows : tmp = SMB_REALLOC_KEEP_OLD_ON_ERROR(p, size); if (!tmp) { SAFE_FREE(p); return error; } else { p = tmp; } SMB_REALLOC_KEEP_OLD_ON_ERROR guarentees never to free the pointer p, even on size == 0 or realloc fail. All this is done by a hidden extra argument to Realloc(), BOOL free_old_on_error which is set appropriately by the SMB_REALLOC and SMB_REALLOC_KEEP_OLD_ON_ERROR macros (and their array counterparts). It remains to be seen what this will do to our Coverity bug count :-). Jeremy. (This used to be commit 1d710d06a214f3f1740e80e0bffd6aab44aac2b0) --- source3/libsmb/clilist.c | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 252dafcfa8..1bd30c36e3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -179,7 +179,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, pstring mask; file_info finfo; int i; - char *tdl, *dirlist = NULL; + char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; BOOL First = True; @@ -338,15 +338,13 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* grab the data for later use */ /* and add them to the dirlist pool */ - tdl = SMB_REALLOC(dirlist,dirlist_len + data_len); + dirlist = SMB_REALLOC(dirlist,dirlist_len + data_len); - if (!tdl) { + if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); SAFE_FREE(rdata); SAFE_FREE(rparam); break; - } else { - dirlist = tdl; } memcpy(dirlist+dirlist_len,p,data_len); @@ -421,7 +419,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; int i; - char *tdl, *dirlist = NULL; + char *dirlist = NULL; pstring mask; ZERO_ARRAY(status); @@ -466,14 +464,11 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - tdl = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); - - if (!tdl) { + dirlist = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); - SAFE_FREE(dirlist); return 0; } - else dirlist = tdl; p = smb_buf(cli->inbuf) + 3; -- cgit From 61d2dfcd30a0602c94e84dda7fe56b671934e66b Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 2 Jun 2006 00:52:11 +0000 Subject: r15997: Fix bug in OS/2 Warp - it doesn't set the ff_last offset correctly when doing info level 1 directory scans. Thanks to Guenter Kukkukk for reporting this problem and testing the fix. Jeremy. (This used to be commit 65d4dfbd6045a4e3f9eaf520c70ef29ff7ddee82) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 1bd30c36e3..9ab05d2b4a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -330,7 +330,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } } - if (ff_lastname > 0) { + if (ff_searchcount > 0) { pstrcpy(mask, finfo.name); } else { pstrcpy(mask,""); -- cgit From fe28eb2e411f3fd6b1b0d46ee0e5344592d7e49c Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 27 Jun 2006 00:15:00 +0000 Subject: r16541: Fix #3862 reported by jason@ncac.gwu.edu. Jeremy. (This used to be commit 09e11dcb2304eec9656e76c24921c82f4a870914) --- source3/libsmb/clilist.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 9ab05d2b4a..e18bb185d5 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -185,7 +185,6 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, BOOL First = True; int ff_searchcount=0; int ff_eos=0; - int ff_lastname=0; int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; @@ -297,11 +296,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, ff_dir_handle = SVAL(p,0); ff_searchcount = SVAL(p,2); ff_eos = SVAL(p,4); - ff_lastname = SVAL(p,8); } else { ff_searchcount = SVAL(p,0); ff_eos = SVAL(p,2); - ff_lastname = SVAL(p,6); } if (ff_searchcount == 0) { -- cgit From 02eea79624c85fb5ce6c3ffefe2d27e40c5ff97f Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 31 Jul 2006 03:53:39 +0000 Subject: r17333: Some C++ warnings (This used to be commit be9aaffdaccae06c8c035eaf31862e34b7cfbe38) --- source3/libsmb/clilist.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e18bb185d5..a006c47ae0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -335,7 +335,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* grab the data for later use */ /* and add them to the dirlist pool */ - dirlist = SMB_REALLOC(dirlist,dirlist_len + data_len); + dirlist = (char *)SMB_REALLOC(dirlist,dirlist_len + data_len); if (!dirlist) { DEBUG(0,("cli_list_new: Failed to expand dirlist\n")); @@ -461,7 +461,8 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, first = False; - dirlist = SMB_REALLOC(dirlist,(num_received + received)*DIR_STRUCT_SIZE); + dirlist = (char *)SMB_REALLOC( + dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); return 0; -- cgit From aee6b5942a3418b9d9a9a73fa33c21d5e4e18df8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 23 Aug 2006 22:33:50 +0000 Subject: r17761: Handle times consistently across all client utils. Fixes bugs reported in libsmbclient. Jeremy. (This used to be commit 42a417fb75313b093948602c3be8e2f386048b5f) --- source3/libsmb/clilist.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index a006c47ae0..b022a107d0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -94,27 +94,13 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f } p += 4; /* fileindex */ - /* these dates appear to arrive in a - weird way. It seems to be localtime - plus the serverzone given in the - initial connect. This is GMT when - DST is not in effect and one hour - from GMT otherwise. Can this really - be right?? - - I suppose this could be called - kludge-GMT. Is is the GMT you get - by using the current DST setting on - a different localtime. It will be - cheap to calculate, I suppose, as - no DST tables will be needed */ - - finfo->ctime = interpret_long_date(p); + /* Offset zero is "create time", not "change time". */ p += 8; finfo->atime = interpret_long_date(p); p += 8; finfo->mtime = interpret_long_date(p); p += 8; + finfo->ctime = interpret_long_date(p); p += 8; finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; -- cgit From a64925ddff467a47f7adfac4b1b977ddc0c7f4ef Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Aug 2006 16:44:00 +0000 Subject: r17800: Start using struct timespec internally for file times on the wire. This allows us to go to nsec resolution for systems that support it. It should also now be easy to add a correct "create time" (birth time) for systems that support it (*BSD). I'll be watching the build farm closely after this one for breakage :-). Jeremy. (This used to be commit 425280a1d23f97ef0b0be77462386d619f47b21d) --- source3/libsmb/clilist.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index b022a107d0..18c058f9df 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -49,9 +49,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date2(cli, p+4); - finfo->atime = cli_make_unix_date2(cli, p+8); - finfo->mtime = cli_make_unix_date2(cli, p+12); + finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); + finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); + finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 26); @@ -70,9 +70,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date2(cli, p+4); - finfo->atime = cli_make_unix_date2(cli, p+8); - finfo->mtime = cli_make_unix_date2(cli, p+12); + finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); + finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); + finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); finfo->size = IVAL(p,16); finfo->mode = CVAL(p,24); len = CVAL(p, 30); @@ -96,11 +96,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f /* Offset zero is "create time", not "change time". */ p += 8; - finfo->atime = interpret_long_date(p); + finfo->atime_ts = interpret_long_date(p); p += 8; - finfo->mtime = interpret_long_date(p); + finfo->mtime_ts = interpret_long_date(p); p += 8; - finfo->ctime = interpret_long_date(p); + finfo->ctime_ts = interpret_long_date(p); p += 8; finfo->size = IVAL2_TO_SMB_BIG_UINT(p,0); p += 8; @@ -373,8 +373,10 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ - finfo->ctime = cli_make_unix_date(cli, p+22); - finfo->mtime = finfo->atime = finfo->ctime; + finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22); + finfo->ctime_ts.tv_nsec = 0; + finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; + finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { -- cgit From 40665edf5e6043ad5a8f46731a79ec1d5835b62a Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Sun, 3 Sep 2006 00:50:34 +0000 Subject: r18011: Should fix bug 3835. Jeremy: requires your eyes... If the remote connection timed out while cli_list() was retrieving its list of files, the error was not returned to the user, e.g. via smbc_opendir(), so the user didn't have a way to know to set the timeout longer and try again. This problem would occur when a very large directory is being read with a too-small timeout on the cli. Jeremy, although there were a couple of areas that needed to be handled, I needed to make one change that you should bless, in libsmb/clientgen.c. It was setting cli->smb_rw_error = smb_read_error; but smb_read_error is zero, so this had no effect. I'm now doing cli->smb_rw_error = READ_TIMEOUT; instead, and according to the OP, these (cumulative) changes (in a slightly different form) solve the problem. Please confirm this smb_rw_error change will have no other adverse effects that you can see. Derrell (This used to be commit fa664b24b829f973156486896575c1007b6d7b01) --- source3/libsmb/clilist.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 18c058f9df..22cb5930c2 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -349,10 +349,17 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mnt = cli_cm_get_mntpoint( cli ); - for (p=dirlist,i=0;i Date: Thu, 8 Mar 2007 23:54:57 +0000 Subject: r21768: Fix the client dfs code such that smbclient can process deep dfs links (ie. links that go to non root parts of a share). Make the directory handling conanonical in POSIX and Windows pathname processing. dfs should not be fully working in client tools. Please bug me if not. Jeremy. (This used to be commit 1c9e10569cd97ee41de39f9f012bea4e4c932b5d) --- source3/libsmb/clilist.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 22cb5930c2..3e76cd4775 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -44,6 +44,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f *p_resume_key = 0; } memcpy(finfo,&def_finfo,sizeof(*finfo)); + finfo->cli = cli; switch (level) { case 1: /* OS/2 understands this */ @@ -185,13 +186,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - /* when getting a directory listing from a 2k dfs root share, - we have to include the full path (\server\share\mask) here */ - - if ( cli->dfsroot ) - pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask ); - else - pstrcpy(mask,Mask); + pstrcpy(mask,Mask); while (ff_eos == 0) { loop_count++; @@ -377,6 +372,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi *finfo = def_finfo; + finfo->cli = cli; finfo->mode = CVAL(p,21); /* this date is converted to GMT by make_unix_date */ -- cgit From 0829e1ad1c3646efecf50729f493b9ee72ef0517 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 19 Apr 2007 22:40:32 +0000 Subject: r22391: Looks bigger than it is. Make "inbuf" available to all callers of smb_setlen (via set_message() calls). This will allow the server to reflect back the correct encryption context. Jeremy. (This used to be commit 2d80a96120a5fe2fe726f00746d36d85044c4bdb) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 3e76cd4775..8290a57742 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -418,7 +418,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(NULL,cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -475,7 +475,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + set_message(NULL,cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 8290a57742..74aa35945e 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -5,7 +5,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/clilist.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 74aa35945e..31012e6011 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -14,8 +14,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From e5a951325a6cac8567af3a66de6d2df577508ae4 Mon Sep 17 00:00:00 2001 From: "Gerald (Jerry) Carter" Date: Wed, 10 Oct 2007 15:34:30 -0500 Subject: [GLUE] Rsync SAMBA_3_2_0 SVN r25598 in order to create the v3-2-test branch. (This used to be commit 5c6c8e1fe93f340005110a7833946191659d88ab) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 31012e6011..5da63096b1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -417,7 +417,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,2,0,True); + set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -474,7 +474,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(NULL,cli->outbuf,2,0,True); + set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 5da63096b1..fd0c380409 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -168,7 +168,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *dirlist = NULL; int dirlist_len = 0; int total_received = -1; - BOOL First = True; + bool First = True; int ff_searchcount=0; int ff_eos=0; int ff_dir_handle=0; @@ -401,7 +401,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, { char *p; int received = 0; - BOOL first = True; + bool first = True; char status[21]; int num_asked = (cli->max_xmit - 100)/DIR_STRUCT_SIZE; int num_received = 0; -- cgit From 42c87fe6e6036a56b178183b034275321949050d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 29 Nov 2007 13:24:14 -0800 Subject: Remove pstrings. Ensure we validate offsets. Jeremy. (This used to be commit ff06cc34e66a18ba71dd54f6c78b05a45b9f2d85) --- source3/libsmb/clilist.c | 196 +++++++++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 64 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index fd0c380409..64cb3e8fe3 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -1,18 +1,18 @@ -/* +/* Unix SMB/CIFS implementation. client directory list routines Copyright (C) Andrew Tridgell 1994-1998 - + This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. - + This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with this program. If not, see . */ @@ -21,6 +21,22 @@ extern file_info def_finfo; +/**************************************************************************** + Calculate a safe next_entry_offset. +****************************************************************************/ + +static size_t calc_next_entry_offset(const char *base, const char *pdata_end) +{ + size_t next_entry_offset = (size_t)IVAL(base,0); + + if (next_entry_offset == 0 || + base + next_entry_offset < base || + base + next_entry_offset > pdata_end) { + next_entry_offset = pdata_end - base; + } + return next_entry_offset; +} + /**************************************************************************** Interpret a long filename structure - this is mostly guesses at the moment. The length of the structure is returned @@ -28,12 +44,19 @@ extern file_info def_finfo; by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,file_info *finfo, - uint32 *p_resume_key, DATA_BLOB *p_last_name_raw, uint32 *p_last_name_raw_len) +static size_t interpret_long_filename(struct cli_state *cli, + int level, + const char *p, + const char *pdata_end, + file_info *finfo, + uint32 *p_resume_key, + DATA_BLOB *p_last_name_raw) { file_info finfo2; int len; - char *base = p; + const char *base = p; + + data_blob_free(p_last_name_raw); if (!finfo) { finfo = &finfo2; @@ -49,6 +72,9 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f case 1: /* OS/2 understands this */ /* these dates are converted to GMT by make_unix_date */ + if (pdata_end - base < 27) { + return pdata_end - base; + } finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); @@ -57,19 +83,25 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); + if (p + len + 2 > pdata_end) { + return pdata_end - base; + } /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call (tridge) */ p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - len+2, + len+2, STR_TERMINATE); return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ /* these dates are converted to GMT by make_unix_date */ + if (pdata_end - base < 31) { + return pdata_end - base; + } finfo->ctime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+4)); finfo->atime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+8)); finfo->mtime_ts = convert_time_t_to_timespec(cli_make_unix_date2(cli, p+12)); @@ -78,22 +110,30 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f len = CVAL(p, 30); p += 31; /* check for unisys! */ + if (p + len + 1 > pdata_end) { + return pdata_end - base; + } p += clistr_pull(cli, finfo->name, p, sizeof(finfo->name), - len, + len, STR_NOALIGN); return PTR_DIFF(p, base) + 1; - + case 260: /* NT uses this, but also accepts 2 */ { size_t namelen, slen; + + if (pdata_end - base < 94) { + return pdata_end - base; + } + p += 4; /* next entry offset */ if (p_resume_key) { *p_resume_key = IVAL(p,0); } p += 4; /* fileindex */ - + /* Offset zero is "create time", not "change time". */ p += 8; finfo->atime_ts = interpret_long_date(p); @@ -111,7 +151,11 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f p += 4; p += 4; /* EA size */ slen = SVAL(p, 0); - p += 2; + if (slen > 24) { + /* Bad short name length. */ + return pdata_end - base; + } + p += 2; { /* stupid NT bugs. grr */ int flags = 0; @@ -120,7 +164,10 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f sizeof(finfo->short_name), slen, flags); } - p += 24; /* short name? */ + p += 24; /* short name? */ + if (p + namelen < p || p + namelen > pdata_end) { + return pdata_end - base; + } clistr_pull(cli, finfo->name, p, sizeof(finfo->name), namelen, 0); @@ -130,29 +177,24 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f Namelen doesn't include the terminating unicode null, so copy it here. */ - if (p_last_name_raw && p_last_name_raw_len) { - if (namelen + 2 > p_last_name_raw->length) { - memset(p_last_name_raw->data, '\0', sizeof(p_last_name_raw->length)); - *p_last_name_raw_len = 0; - } else { - memcpy(p_last_name_raw->data, p, namelen); - SSVAL(p_last_name_raw->data, namelen, 0); - *p_last_name_raw_len = namelen + 2; - } + if (p_last_name_raw) { + *p_last_name_raw = data_blob(NULL, namelen+2); + memcpy(p_last_name_raw->data, p, namelen); + SSVAL(p_last_name_raw->data, namelen, 0); } - return (size_t)IVAL(base, 0); + return calc_next_entry_offset(base, pdata_end); } } - + DEBUG(1,("Unknown long filename format %d\n",level)); - return (size_t)IVAL(base,0); + return calc_next_entry_offset(base, pdata_end); } /**************************************************************************** Do a directory listing, calling fn on each file found. ****************************************************************************/ -int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { #if 1 @@ -161,8 +203,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int max_matches = 512; #endif int info_level; - char *p, *p2; - pstring mask; + char *p, *p2, *rdata_end; + char *mask = NULL; file_info finfo; int i; char *dirlist = NULL; @@ -174,19 +216,21 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, int ff_dir_handle=0; int loop_count = 0; char *rparam=NULL, *rdata=NULL; - unsigned int param_len, data_len; + unsigned int param_len, data_len; uint16 setup; - pstring param; + char param[1024]; const char *mnt; uint32 resume_key = 0; - uint32 last_name_raw_len = 0; - DATA_BLOB last_name_raw = data_blob(NULL, 2*sizeof(pstring)); + DATA_BLOB last_name_raw = data_blob(NULL, 0); /* NT uses 260, OS/2 uses 2. Both accept 1. */ info_level = (cli->capabilities&CAP_NT_SMBS)?260:1; - - pstrcpy(mask,Mask); - + + mask = SMB_STRDUP(Mask); + if (!mask) { + return -1; + } + while (ff_eos == 0) { loop_count++; if (loop_count > 200) { @@ -199,16 +243,16 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,0,attribute); /* attribute */ SSVAL(param,2,max_matches); /* max count */ SSVAL(param,4,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ - SSVAL(param,6,info_level); + SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, + p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); SSVAL(param,2,max_matches); /* max count */ - SSVAL(param,4,info_level); + SSVAL(param,4,info_level); /* For W2K servers serving out FAT filesystems we *must* set the resume key. If it's not FAT then it's returned as zero. */ SIVAL(param,6,resume_key); /* ff_resume_key */ @@ -216,9 +260,9 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - if (last_name_raw_len && (last_name_raw_len < (sizeof(param)-12))) { - memcpy(p, last_name_raw.data, last_name_raw_len); - p += last_name_raw_len; + if (last_name_raw.length && (last_name_raw.length < (sizeof(param)-12))) { + memcpy(p, last_name_raw.data, last_name_raw.length); + p += last_name_raw.length; } else { p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); } @@ -226,12 +270,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, param_len = PTR_DIFF(p, param); - if (!cli_send_trans(cli, SMBtrans2, + if (!cli_send_trans(cli, SMBtrans2, NULL, /* Name */ -1, 0, /* fid, flags */ &setup, 1, 0, /* setup, length, max */ param, param_len, 10, /* param, length, max */ - NULL, 0, + NULL, 0, #if 0 /* w2k value. */ MIN(16384,cli->max_xmit) /* data, length, max. */ @@ -242,7 +286,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - if (!cli_receive_trans(cli, SMBtrans2, + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { @@ -289,15 +333,21 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* point to the data bytes */ p = rdata; + rdata_end = rdata + data_len; /* we might need the lastname for continuations */ - for (p2=p,i=0;i 0) { - pstrcpy(mask, finfo.name); + mask = SMB_STRDUP(finfo.name); } else { - pstrcpy(mask,""); + mask = SMB_STRDUP(""); + } + if (!mask) { + SAFE_FREE(rdata); + SAFE_FREE(rparam); + break; } /* grab the data for later use */ @@ -348,9 +404,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, total_received = -1; } else { /* no connection problem. let user function add each entry */ + rdata_end = dirlist + dirlist_len; for (p=dirlist,i=0;icli = cli; finfo->mode = CVAL(p,21); - + /* this date is converted to GMT by make_unix_date */ finfo->ctime_ts.tv_sec = cli_make_unix_date(cli, p+22); finfo->ctime_ts.tv_nsec = 0; @@ -396,7 +459,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi but should otherwise not be used. ****************************************************************************/ -int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { char *p; @@ -407,12 +470,15 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int num_received = 0; int i; char *dirlist = NULL; - pstring mask; - + char *mask = NULL; + ZERO_ARRAY(status); - pstrcpy(mask,Mask); - + mask = SMB_STRDUP(Mask); + if (!mask) { + return -1; + } + while (1) { memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); @@ -426,10 +492,10 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(cli->outbuf,smb_vwv0,num_asked); SSVAL(cli->outbuf,smb_vwv1,attribute); - + p = smb_buf(cli->outbuf); *p++ = 4; - + p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); *p++ = 5; if (first) { @@ -455,6 +521,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, dirlist,(num_received + received)*DIR_STRUCT_SIZE); if (!dirlist) { DEBUG(0,("cli_list_old: failed to expand dirlist")); + SAFE_FREE(mask); return 0; } @@ -462,11 +529,11 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memcpy(dirlist+num_received*DIR_STRUCT_SIZE, p,received*DIR_STRUCT_SIZE); - + memcpy(status,p + ((received-1)*DIR_STRUCT_SIZE),21); - + num_received += received; - + if (cli_is_error(cli)) break; } @@ -491,7 +558,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p += 2; memcpy(p,status,21); p += 21; - + cli_setup_bcc(cli, p); cli_send_smb(cli); if (!cli_receive_smb(cli)) { @@ -505,6 +572,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, fn("\\", &finfo, Mask, state); } + SAFE_FREE(mask); SAFE_FREE(dirlist); return(num_received); } @@ -514,7 +582,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, This auto-switches between old and new style. ****************************************************************************/ -int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, +int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute, void (*fn)(const char *, file_info *, const char *, void *), void *state) { if (cli->protocol <= PROTOCOL_LANMAN1) -- cgit From 8ab33fc33593d829258990b208c4636e3fe321e0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 5 Dec 2007 16:56:19 -0800 Subject: Fix path length limits on cli_list (outgoing. Incoming will be fixed with pstring elimination). Jeremy. (This used to be commit cd43b93d405bf892d1d8941b2d1e64d7d53adf69) --- source3/libsmb/clilist.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 64cb3e8fe3..284538541a 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -218,7 +218,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *rparam=NULL, *rdata=NULL; unsigned int param_len, data_len; uint16 setup; - char param[1024]; + char *param; const char *mnt; uint32 resume_key = 0; DATA_BLOB last_name_raw = data_blob(NULL, 0); @@ -232,12 +232,19 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, } while (ff_eos == 0) { + size_t nlen = 2*(strlen(mask)+1); + loop_count++; if (loop_count > 200) { DEBUG(0,("Error: Looping in FIND_NEXT??\n")); break; } + param = SMB_MALLOC(12+nlen+last_name_raw.length+2); + if (!param) { + break; + } + if (First) { setup = TRANSACT2_FINDFIRST; SSVAL(param,0,attribute); /* attribute */ @@ -246,8 +253,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SSVAL(param,6,info_level); SIVAL(param,8,0); p = param+12; - p += clistr_push(cli, param+12, mask, sizeof(param)-12, - STR_TERMINATE); + p += clistr_push(cli, param+12, mask, + nlen, STR_TERMINATE); } else { setup = TRANSACT2_FINDNEXT; SSVAL(param,0,ff_dir_handle); @@ -260,11 +267,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, can miss filenames. Use last filename continue instead. JRA */ SSVAL(param,10,(FLAG_TRANS2_FIND_REQUIRE_RESUME|FLAG_TRANS2_FIND_CLOSE_IF_END)); /* resume required + close on end */ p = param+12; - if (last_name_raw.length && (last_name_raw.length < (sizeof(param)-12))) { + if (last_name_raw.length) { memcpy(p, last_name_raw.data, last_name_raw.length); p += last_name_raw.length; } else { - p += clistr_push(cli, param+12, mask, sizeof(param)-12, STR_TERMINATE); + p += clistr_push(cli, param+12, mask, + nlen, STR_TERMINATE); } } @@ -283,9 +291,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, cli->max_xmit /* data, length, max. */ #endif )) { + SAFE_FREE(param); break; } + SAFE_FREE(param); + if (!cli_receive_trans(cli, SMBtrans2, &rparam, ¶m_len, &rdata, &data_len) && -- cgit From 4acfce6b036ae1a0bf152a94bb5d6194e93f4004 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 6 Dec 2007 10:10:16 -0800 Subject: Don't understand this. I have no changes here.... Jeremy. (This used to be commit 49534432d4c63d0dfd7bf080c30adecef06deade) --- source3/libsmb/clilist.c | 97 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 64 insertions(+), 33 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 284538541a..fc47f94aa1 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -19,8 +19,6 @@ #include "includes.h" -extern file_info def_finfo; - /**************************************************************************** Calculate a safe next_entry_offset. ****************************************************************************/ @@ -44,7 +42,8 @@ static size_t calc_next_entry_offset(const char *base, const char *pdata_end) by NT and 2 is used by OS/2 ****************************************************************************/ -static size_t interpret_long_filename(struct cli_state *cli, +static size_t interpret_long_filename(TALLOC_CTX *ctx, + struct cli_state *cli, int level, const char *p, const char *pdata_end, @@ -52,20 +51,16 @@ static size_t interpret_long_filename(struct cli_state *cli, uint32 *p_resume_key, DATA_BLOB *p_last_name_raw) { - file_info finfo2; int len; + size_t ret; const char *base = p; data_blob_free(p_last_name_raw); - if (!finfo) { - finfo = &finfo2; - } - if (p_resume_key) { *p_resume_key = 0; } - memcpy(finfo,&def_finfo,sizeof(*finfo)); + ZERO_STRUCTP(finfo); finfo->cli = cli; switch (level) { @@ -90,10 +85,16 @@ static size_t interpret_long_filename(struct cli_state *cli, important to cope with the differences between win2000 and win9x for this call (tridge) */ - p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len+2, - STR_TERMINATE); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + len+2, + STR_TERMINATE); + if (ret == (size_t)-1) { + return pdata_end - base; + } + p += ret; return PTR_DIFF(p, base); case 2: /* this is what OS/2 uses mostly */ @@ -113,10 +114,16 @@ static size_t interpret_long_filename(struct cli_state *cli, if (p + len + 1 > pdata_end) { return pdata_end - base; } - p += clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - len, - STR_NOALIGN); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + len, + STR_NOALIGN); + if (ret == (size_t)-1) { + return pdata_end - base; + } + p += ret; return PTR_DIFF(p, base) + 1; case 260: /* NT uses this, but also accepts 2 */ @@ -168,9 +175,15 @@ static size_t interpret_long_filename(struct cli_state *cli, if (p + namelen < p || p + namelen > pdata_end) { return pdata_end - base; } - clistr_pull(cli, finfo->name, p, - sizeof(finfo->name), - namelen, 0); + ret = clistr_pull_talloc(ctx, + cli, + &finfo->name, + p, + namelen, + 0); + if (ret == (size_t)-1) { + return pdata_end - base; + } /* To be robust in the face of unicode conversion failures we need to copy the raw bytes of the last name seen here. @@ -221,6 +234,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, char *param; const char *mnt; uint32 resume_key = 0; + TALLOC_CTX *frame = talloc_stackframe(); DATA_BLOB last_name_raw = data_blob(NULL, 0); /* NT uses 260, OS/2 uses 2. Both accept 1. */ @@ -228,6 +242,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, mask = SMB_STRDUP(Mask); if (!mask) { + TALLOC_FREE(frame); return -1; } @@ -292,6 +307,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, #endif )) { SAFE_FREE(param); + TALLOC_FREE(frame); break; } @@ -352,7 +368,8 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* Last entry - fixup the last offset length. */ SIVAL(p2,0,PTR_DIFF((rdata + data_len),p2)); } - p2 += interpret_long_filename(cli, + p2 += interpret_long_filename(frame, + cli, info_level, p2, rdata_end, @@ -417,14 +434,15 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, /* no connection problem. let user function add each entry */ rdata_end = dirlist + dirlist_len; for (p=dirlist,i=0;icli = cli; finfo->mode = CVAL(p,21); @@ -454,16 +475,21 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); - clistr_pull(cli, finfo->name, p+30, sizeof(finfo->name), 12, STR_ASCII); - if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { - strncpy(finfo->short_name,finfo->name, sizeof(finfo->short_name)-1); - finfo->short_name[sizeof(finfo->short_name)-1] = '\0'; + clistr_pull_talloc(ctx, + cli, + &finfo->name, + p+30, + 12, + STR_ASCII); + if (!finfo->name) { + finfo->name = talloc_strdup(ctx, finfo->short_name); + } else if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { + finfo->name = talloc_strdup(ctx, finfo->short_name); } return(DIR_STRUCT_SIZE); } - /**************************************************************************** Do a directory listing, calling fn on each file found. this uses the old SMBsearch interface. It is needed for testing Samba, @@ -482,6 +508,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, int i; char *dirlist = NULL; char *mask = NULL; + TALLOC_CTX *frame = NULL; ZERO_ARRAY(status); @@ -507,7 +534,9 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, p = smb_buf(cli->outbuf); *p++ = 4; - p += clistr_push(cli, p, first?mask:"", -1, STR_TERMINATE); + p += clistr_push(cli, p, first?mask:"", + cli->bufsize - PTR_DIFF(p,cli->outbuf), + STR_TERMINATE); *p++ = 5; if (first) { SSVAL(p,0,0); @@ -577,11 +606,13 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, } } + frame = talloc_stackframe(); for (p=dirlist,i=0;i Date: Sat, 8 Dec 2007 11:21:08 +0100 Subject: Fix C++ warnings (This used to be commit 01a5c3ea4bf18d99ca1c35e8c38367046e4c867b) --- source3/libsmb/clilist.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index fc47f94aa1..2e4c360507 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -255,7 +255,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, break; } - param = SMB_MALLOC(12+nlen+last_name_raw.length+2); + param = SMB_MALLOC_ARRAY(char, 12+nlen+last_name_raw.length+2); if (!param) { break; } -- cgit From afc93255d183eefb68e45b8ec6275f6a62cf9795 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 26 Dec 2007 17:12:36 -0800 Subject: Add SMB encryption. Still fixing client decrypt but negotiation works. Jeremy. (This used to be commit d78045601af787731f0737b8627450018902b104) --- source3/libsmb/clilist.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2e4c360507..d5c7db09e9 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -521,7 +521,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + cli_set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBsearch); @@ -581,7 +581,7 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, memset(cli->outbuf,'\0',smb_size); memset(cli->inbuf,'\0',smb_size); - set_message(cli->outbuf,2,0,True); + cli_set_message(cli->outbuf,2,0,True); SCVAL(cli->outbuf,smb_com,SMBfclose); SSVAL(cli->outbuf,smb_tid,cli->cnum); cli_setup_packet(cli); -- cgit From 48ea5852b6854f051754574b27807972426ebbbe Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 11:22:53 -0800 Subject: Try and fix length and finfo calls for older clients. Working on issues reported by kukks. Jeremy. (This used to be commit dcd77dd4f480db3273a56c5740b6e5d78f8be4a9) --- source3/libsmb/clilist.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d5c7db09e9..2bad3e508b 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -459,11 +459,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, The length of the structure is returned. ****************************************************************************/ -static int interpret_short_filename(TALLOC_CTX *ctx, +static bool interpret_short_filename(TALLOC_CTX *ctx, struct cli_state *cli, char *p, file_info *finfo) { + size_t ret; ZERO_STRUCTP(finfo); finfo->cli = cli; @@ -475,18 +476,22 @@ static int interpret_short_filename(TALLOC_CTX *ctx, finfo->mtime_ts.tv_sec = finfo->atime_ts.tv_sec = finfo->ctime_ts.tv_sec; finfo->mtime_ts.tv_nsec = finfo->atime_ts.tv_nsec = 0; finfo->size = IVAL(p,26); - clistr_pull_talloc(ctx, + ret = clistr_pull_talloc(ctx, cli, &finfo->name, p+30, 12, STR_ASCII); - if (!finfo->name) { - finfo->name = talloc_strdup(ctx, finfo->short_name); - } else if (strcmp(finfo->name, "..") && strcmp(finfo->name, ".")) { - finfo->name = talloc_strdup(ctx, finfo->short_name); + if (ret == (size_t)-1) { + return false; } + if (finfo->name) { + strlcpy(finfo->short_name, + finfo->name, + sizeof(finfo->short_name)); + } + return true; return(DIR_STRUCT_SIZE); } @@ -555,6 +560,12 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, received = SVAL(cli->inbuf,smb_vwv0); if (received <= 0) break; + /* Ensure we received enough data. */ + if ((cli->inbuf+4+smb_len(cli->inbuf) - (smb_buf(cli->inbuf)+3)) < + received*DIR_STRUCT_SIZE) { + break; + } + first = False; dirlist = (char *)SMB_REALLOC( @@ -609,7 +620,10 @@ int cli_list_old(struct cli_state *cli,const char *Mask,uint16 attribute, frame = talloc_stackframe(); for (p=dirlist,i=0;i Date: Fri, 8 Feb 2008 18:44:33 -0800 Subject: From kukks - prevent crashes if finfo.name == NULL. Jeremy. (This used to be commit 101f194795f87c709abfdfbcde710131a88f9d20) --- source3/libsmb/clilist.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2bad3e508b..2b5e7518c5 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -377,6 +377,12 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &resume_key, &last_name_raw); + if (!finfo.name) { + DEBUG(0,("cli_list_new: Error: unable to parse name from info level %d\n", + info_level)); + ff_eos = 1; + break; + } if (!First && *mask && strcsequal(finfo.name, mask)) { DEBUG(0,("Error: Looping in FIND_NEXT as name %s has already been seen?\n", finfo.name)); @@ -442,6 +448,11 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &finfo, NULL, NULL); + if (!finfo.name) { + DEBUG(0,("cli_list_new: unable to parse name from info level %d\n", + info_level)); + break; + } fn(mnt,&finfo, Mask, state); } } -- cgit From 0b583e4329a4a47918329d9022feb6ab8c54bb33 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 19:02:49 -0800 Subject: Make clilist work again with OS/2 (kukks help!). Jeremy. (This used to be commit 2e27309401faa554620886b0e369db9d9c08e4fd) --- source3/libsmb/clilist.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index 2b5e7518c5..d913096b12 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -78,9 +78,25 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, len = CVAL(p, 26); p += 27; p += clistr_align_in(cli, p, 0); - if (p + len + 2 > pdata_end) { + + /* We can safely use +1 here (which is required by OS/2) + * instead of +2 as the STR_TERMINATE flag below is + * actually used as the length calculation. + * The len+2 is merely an upper bound. + * We ensure we don't get a one byte overread by + * doing a zero termination at pdata_end[-1]; + * JRA + kukks */ + + if (p + len + 1 > pdata_end) { return pdata_end - base; } + + /* Ensure the null termination (see above). */ + { + char *pend = CONST_DISCARD(char *, pdata_end); + pend[-1] = '\0'; + } + /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call -- cgit From 20d6ebe813955866e70c0b91ef316830e1612437 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 8 Feb 2008 22:02:00 -0800 Subject: We don't need the extra null termination - we've already got this in the cli_receive_trans calls. Jeremy. (This used to be commit 99424bba7bb45b05d970bab4a5e93f2cb636fcbb) --- source3/libsmb/clilist.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index d913096b12..e1b16154f2 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -83,20 +83,15 @@ static size_t interpret_long_filename(TALLOC_CTX *ctx, * instead of +2 as the STR_TERMINATE flag below is * actually used as the length calculation. * The len+2 is merely an upper bound. - * We ensure we don't get a one byte overread by - * doing a zero termination at pdata_end[-1]; - * JRA + kukks */ + * Due to the explicit 2 byte null termination + * in cli_receive_trans/cli_receive_nt_trans + * we know this is safe. JRA + kukks + */ if (p + len + 1 > pdata_end) { return pdata_end - base; } - /* Ensure the null termination (see above). */ - { - char *pend = CONST_DISCARD(char *, pdata_end); - pend[-1] = '\0'; - } - /* the len+2 below looks strange but it is important to cope with the differences between win2000 and win9x for this call -- cgit From 1d940490e815bbdb7e4af23ace05ec9ac8fddae8 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 28 Feb 2008 02:22:13 -0800 Subject: Fix from Guenter Kukkukk to fix listing against OS/2 servers. OS/2 returns eclass == ERRDOS && ecode == ERRnofiles for a zero entry directory listing. Jeremy. (This used to be commit b34da627053581a9584367e177566d4a2cef7e82) --- source3/libsmb/clilist.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clilist.c') diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c index e1b16154f2..50918458b0 100644 --- a/source3/libsmb/clilist.c +++ b/source3/libsmb/clilist.c @@ -328,7 +328,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, &rparam, ¶m_len, &rdata, &data_len) && cli_is_dos_error(cli)) { - /* we need to work around a Win95 bug - sometimes + /* We need to work around a Win95 bug - sometimes it gives ERRSRV/ERRerror temprarily */ uint8 eclass; uint32 ecode; @@ -337,6 +337,20 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute, SAFE_FREE(rparam); cli_dos_error(cli, &eclass, &ecode); + + /* + * OS/2 might return "no more files", + * which just tells us, that searchcount is zero + * in this search. + * Guenter Kukkukk + */ + + if (eclass == ERRDOS && ecode == ERRnofiles) { + ff_searchcount = 0; + cli_reset_error(cli); + break; + } + if (eclass != ERRSRV || ecode != ERRerror) break; smb_msleep(100); -- cgit