From 8bf0f359f3ec440ace0bba6c12ca65d25ba45fd9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 23 Nov 1997 02:41:22 +0000 Subject: added a test for the NT SMBgetatr bug in smbtorture added support for choosing the protocol level in smbtorture (-m option) use -1 for null date in cli_close() get the attributes right in cli_open() (This used to be commit d64d40a6ec57a4a999ae1f39175bcfd86ccb196e) --- source3/include/proto.h | 13 ++++++++ source3/libsmb/clientgen.c | 78 +++++++++++++++++++++++++++++++++++----------- source3/utils/torture.c | 44 +++++++++++++++++++++++++- 3 files changed, 115 insertions(+), 20 deletions(-) (limited to 'source3') diff --git a/source3/include/proto.h b/source3/include/proto.h index d69aa61e72..81868f5e12 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -16,6 +16,18 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n); +/*The following definitions come from cgi.c */ + +void cgi_load_variables(FILE *f1); +char *cgi_variable(char *name); +char *cgi_vnum(int i, char **name); +int cgi_boolean(char *name, int def); +char *quotedup(char *s); +char *urlquote(char *s); +char *quotequotes(char *s); +void quote_spaces(char *buf); +void cgi_setup(char *rootdir); + /*The following definitions come from charcnv.c */ char *unix2dos_format(char *str,BOOL overwrite); @@ -60,6 +72,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size); int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size); +BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st); BOOL cli_negprot(struct cli_state *cli); BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, char *myname); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 66d54a9b99..031c0c10de 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -368,8 +368,9 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype, for (i = 0;i < count;i++, p += 26) { char *sname = p; - int comment_offset = IVAL(p,22) & 0xFFFF; - char *cmnt = comment_offset?(rdata+comment_offset-converter):""; + int comment_offset = (IVAL(p,22) & 0xFFFF)-converter; + char *cmnt = comment_offset?(rdata+comment_offset):""; + if (comment_offset < 0 || comment_offset > rdrcnt) continue; stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY; @@ -418,7 +419,7 @@ BOOL cli_session_setup(struct cli_state *cli, fstring pword; if (cli->protocol < PROTOCOL_LANMAN1) - return False; + return True; if (passlen > sizeof(pword)-1) { return False; @@ -647,7 +648,7 @@ int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */ SSVAL(cli->outbuf,smb_vwv3,accessmode); SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN); - SSVAL(cli->outbuf,smb_vwv5,aSYSTEM | aHIDDEN); + SSVAL(cli->outbuf,smb_vwv5,0); SSVAL(cli->outbuf,smb_vwv8,openfn); p = smb_buf(cli->outbuf); @@ -684,8 +685,7 @@ BOOL cli_close(struct cli_state *cli, int fnum) cli_setup_packet(cli); SSVAL(cli->outbuf,smb_vwv0,fnum); - SSVAL(cli->outbuf,smb_vwv1,0); - SSVAL(cli->outbuf,smb_vwv2,0); + SIVALS(cli->outbuf,smb_vwv1,-1); send_smb(cli->fd,cli->outbuf); if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { @@ -860,6 +860,44 @@ int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 } +/**************************************************************************** +stat a file (actually a SMBgetattr call) +This only fills in a few of the stat fields +****************************************************************************/ +BOOL cli_stat(struct cli_state *cli, char *fname, struct stat *st) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,0,strlen(fname)+2,True); + + CVAL(cli->outbuf,smb_com) = SMBgetatr; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + p = smb_buf(cli->outbuf); + *p = 4; + strcpy(p+1, fname); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return False; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return False; + } + + memset(st, 0, sizeof(*st)); + st->st_size = IVAL(cli->inbuf, smb_vwv3); + + st->st_mtime = make_unix_date3(cli->inbuf+smb_vwv1); + return True; +} + + /**************************************************************************** send a negprot command ****************************************************************************/ @@ -907,19 +945,7 @@ BOOL cli_negprot(struct cli_state *cli) cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot; - if (cli->protocol < PROTOCOL_NT1) { - cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); - cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); - cli->sesskey = IVAL(cli->inbuf,smb_vwv6); - cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; - /* this time is converted to GMT by make_unix_date */ - cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); - if (cli->protocol >= PROTOCOL_COREPLUS) { - cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); - cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); - } - memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); - } else { + if (cli->protocol >= PROTOCOL_NT1) { /* NT protocol */ cli->sec_mode = CVAL(cli->inbuf,smb_vwv1); cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1); @@ -931,6 +957,20 @@ BOOL cli_negprot(struct cli_state *cli) if (IVAL(cli->inbuf,smb_vwv9+1) & 1) cli->readbraw_supported = cli->writebraw_supported = True; + } else if (cli->protocol >= PROTOCOL_LANMAN1) { + cli->sec_mode = SVAL(cli->inbuf,smb_vwv1); + cli->max_xmit = SVAL(cli->inbuf,smb_vwv2); + cli->sesskey = IVAL(cli->inbuf,smb_vwv6); + cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60; + /* this time is converted to GMT by make_unix_date */ + cli->servertime = make_unix_date(cli->inbuf+smb_vwv8); + cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0); + cli->writebraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x2) != 0); + memcpy(cli->cryptkey,smb_buf(cli->inbuf),8); + } else { + /* the old core protocol */ + cli->sec_mode = 0; + cli->serverzone = TimeDiff(time(NULL)); } return True; diff --git a/source3/utils/torture.c b/source3/utils/torture.c index 1e284fb93d..06f9f5f1fb 100644 --- a/source3/utils/torture.c +++ b/source3/utils/torture.c @@ -26,6 +26,7 @@ #include "includes.h" static fstring host, workgroup, share, password, username, myname; +static int max_protocol = PROTOCOL_NT1; static char *sockops=""; @@ -57,6 +58,8 @@ static BOOL open_connection(struct cli_state *c) return False; } + c->protocol = max_protocol; + if (!cli_negprot(c)) { printf("%s rejected the negprot (%s)\n",host, cli_errstr(c)); cli_shutdown(c); @@ -184,6 +187,7 @@ static void usage(void) printf("\t-W workgroup\n"); printf("\t-o num_operations\n"); printf("\t-O socket_options\n"); + printf("\t-m maximum protocol\n"); printf("\n"); exit(1); @@ -626,6 +630,40 @@ static void run_browsetest(void) } +/* + This checks how the getatr calls works +*/ +static void run_attrtest(void) +{ + static struct cli_state cli; + int fnum; + struct stat st; + char *fname = "\\attrib.tst"; + + printf("staring attrib test\n"); + + if (!open_connection(&cli)) { + return; + } + + cli_unlink(&cli, fname); + fnum = cli_open(&cli, fname, + O_RDWR | O_CREAT | O_TRUNC, DENY_NONE); + cli_close(&cli, fnum); + if (!cli_stat(&cli, fname, &st)) { + printf("getatr failed (%s)\n", cli_errstr(&cli)); + } + + if (abs(st.st_mtime - time(NULL)) > 2) { + printf("ERROR: SMBgetatr bug. time is %s", + ctime(&st.st_mtime)); + } + + close_connection(&cli); + + printf("attrib test finished\n"); +} + static void create_procs(int nprocs, int numops) { @@ -689,11 +727,14 @@ static void create_procs(int nprocs, int numops) argv++; - while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:")) != EOF) { + while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:m:")) != EOF) { switch (opt) { case 'W': fstrcpy(workgroup,optarg); break; + case 'm': + max_protocol = interpret_protocol(optarg, max_protocol); + break; case 'N': nprocs = atoi(optarg); break; @@ -742,6 +783,7 @@ static void create_procs(int nprocs, int numops) run_locktest3(numops); run_unlinktest(); run_browsetest(); + run_attrtest(); return(0); } -- cgit