diff options
author | Andrew Tridgell <tridge@samba.org> | 1997-11-01 13:22:16 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1997-11-01 13:22:16 +0000 |
commit | 224c40a52335bf1afc7662183900e143307aa5be (patch) | |
tree | c137653f344bf5e3f0e9f78745144c03eb367119 | |
parent | 00247250052d0f7b76b0478eb08f63844cd13dc5 (diff) | |
download | samba-224c40a52335bf1afc7662183900e143307aa5be.tar.gz samba-224c40a52335bf1afc7662183900e143307aa5be.tar.bz2 samba-224c40a52335bf1afc7662183900e143307aa5be.zip |
a simple SMB torture tester. This will allow us to evaluate locking
techniques more accurately.
(This used to be commit 054e3b2ae3a8cfb98fde72becef9b05de34d2ba7)
-rw-r--r-- | source3/client/client.c | 2 | ||||
-rw-r--r-- | source3/client/clientutil.c | 154 | ||||
-rw-r--r-- | source3/include/proto.h | 17 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 334 | ||||
-rw-r--r-- | source3/libsmb/smberr.c | 182 | ||||
-rw-r--r-- | source3/nmbsync.c | 5 | ||||
-rw-r--r-- | source3/smbd/password.c | 5 | ||||
-rw-r--r-- | source3/utils/torture.c | 316 |
8 files changed, 847 insertions, 168 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 6528919051..f1ab4410a9 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -1102,7 +1102,7 @@ static void do_get(char *rname,char *lname,file_info *finfo1) cli_setup_pkt(outbuf); SSVAL(outbuf,smb_vwv0,0xFF); - SSVAL(outbuf,smb_vwv2,1); + SSVAL(outbuf,smb_vwv2,1); /* return additional info */ SSVAL(outbuf,smb_vwv3,(DENY_NONE<<4)); SSVAL(outbuf,smb_vwv4,aSYSTEM | aHIDDEN); SSVAL(outbuf,smb_vwv5,aSYSTEM | aHIDDEN); diff --git a/source3/client/clientutil.c b/source3/client/clientutil.c index d05be8ae9b..8924e692aa 100644 --- a/source3/client/clientutil.c +++ b/source3/client/clientutil.c @@ -943,157 +943,3 @@ BOOL cli_reopen_connection(char *inbuf,char *outbuf) return(cli_send_login(inbuf,outbuf,True,True)); } -/* error code stuff - put together by Merik Karman - merik@blackadder.dsh.oz.au */ - -typedef struct -{ - char *name; - int code; - char *message; -} err_code_struct; - -/* Dos Error Messages */ -err_code_struct dos_msgs[] = { - {"ERRbadfunc",1,"Invalid function."}, - {"ERRbadfile",2,"File not found."}, - {"ERRbadpath",3,"Directory invalid."}, - {"ERRnofids",4,"No file descriptors available"}, - {"ERRnoaccess",5,"Access denied."}, - {"ERRbadfid",6,"Invalid file handle."}, - {"ERRbadmcb",7,"Memory control blocks destroyed."}, - {"ERRnomem",8,"Insufficient server memory to perform the requested function."}, - {"ERRbadmem",9,"Invalid memory block address."}, - {"ERRbadenv",10,"Invalid environment."}, - {"ERRbadformat",11,"Invalid format."}, - {"ERRbadaccess",12,"Invalid open mode."}, - {"ERRbaddata",13,"Invalid data."}, - {"ERR",14,"reserved."}, - {"ERRbaddrive",15,"Invalid drive specified."}, - {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, - {"ERRdiffdevice",17,"Not same device."}, - {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, - {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRnosuchshare", 67, "You specified an invalid share name"}, - {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, - {"ERRbadpipe",230,"Pipe invalid."}, - {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, - {"ERRpipeclosing",232,"Pipe close in progress."}, - {"ERRnotconnected",233,"No process on other end of pipe."}, - {"ERRmoredata",234,"There is more data to be returned."}, - {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, - {NULL,-1,NULL}}; - -/* Server Error Messages */ -err_code_struct server_msgs[] = { - {"ERRerror",1,"Non-specific error code."}, - {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, - {"ERRbadtype",3,"reserved."}, - {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, - {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, - {"ERRinvnetname",6,"Invalid network name in tree connect."}, - {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, - {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, - {"ERRqtoobig",50,"Print queue full -- no space."}, - {"ERRqeof",51,"EOF on print queue dump."}, - {"ERRinvpfid",52,"Invalid print file FID."}, - {"ERRsmbcmd",64,"The server did not recognize the command received."}, - {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, - {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, - {"ERRreserved",68,"reserved."}, - {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, - {"ERRreserved",70,"reserved."}, - {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, - {"ERRpaused",81,"Server is paused."}, - {"ERRmsgoff",82,"Not receiving messages."}, - {"ERRnoroom",83,"No room to buffer message."}, - {"ERRrmuns",87,"Too many remote user names."}, - {"ERRtimeout",88,"Operation timed out."}, - {"ERRnoresource",89,"No resources currently available for request."}, - {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, - {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, - {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, - {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, - {"ERRcontmpx",252,"Continue in MPX mode."}, - {"ERRreserved",253,"reserved."}, - {"ERRreserved",254,"reserved."}, - {"ERRnosupport",0xFFFF,"Function not supported."}, - {NULL,-1,NULL}}; - -/* Hard Error Messages */ -err_code_struct hard_msgs[] = { - {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, - {"ERRbadunit",20,"Unknown unit."}, - {"ERRnotready",21,"Drive not ready."}, - {"ERRbadcmd",22,"Unknown command."}, - {"ERRdata",23,"Data error (CRC)."}, - {"ERRbadreq",24,"Bad request structure length."}, - {"ERRseek",25 ,"Seek error."}, - {"ERRbadmedia",26,"Unknown media type."}, - {"ERRbadsector",27,"Sector not found."}, - {"ERRnopaper",28,"Printer out of paper."}, - {"ERRwrite",29,"Write fault."}, - {"ERRread",30,"Read fault."}, - {"ERRgeneral",31,"General failure."}, - {"ERRbadshare",32,"An open conflicts with an existing open."}, - {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, - {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, - {"ERRFCBUnavail",35,"No FCBs are available to process request."}, - {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, - {NULL,-1,NULL}}; - - -struct -{ - int code; - char *class; - err_code_struct *err_msgs; -} err_classes[] = { - {0,"SUCCESS",NULL}, - {0x01,"ERRDOS",dos_msgs}, - {0x02,"ERRSRV",server_msgs}, - {0x03,"ERRHRD",hard_msgs}, - {0x04,"ERRXOS",NULL}, - {0xE1,"ERRRMX1",NULL}, - {0xE2,"ERRRMX2",NULL}, - {0xE3,"ERRRMX3",NULL}, - {0xFF,"ERRCMD",NULL}, - {-1,NULL,NULL}}; - - -/**************************************************************************** -return a SMB error string from a SMB buffer -****************************************************************************/ -char *smb_errstr(char *inbuf) -{ - static pstring ret; - int class = CVAL(inbuf,smb_rcls); - int num = SVAL(inbuf,smb_err); - int i,j; - - for (i=0;err_classes[i].class;i++) - if (err_classes[i].code == class) - { - if (err_classes[i].err_msgs) - { - err_code_struct *err = err_classes[i].err_msgs; - for (j=0;err[j].name;j++) - if (num == err[j].code) - { - if (DEBUGLEVEL > 0) - sprintf(ret,"%s - %s (%s)",err_classes[i].class, - err[j].name,err[j].message); - else - sprintf(ret,"%s - %s",err_classes[i].class,err[j].name); - return ret; - } - } - - sprintf(ret,"%s - %d",err_classes[i].class,num); - return ret; - } - - sprintf(ret,"Error: Unknown error (%d,%d)",class,num); - return(ret); -} diff --git a/source3/include/proto.h b/source3/include/proto.h index 949d2472a9..7e4ed43aa0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -51,14 +51,24 @@ BOOL cli_session_setup(struct cli_state *cli, char *ntpass, int ntpasslen, char *workgroup); BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pword, int passlen); + char *share, char *dev, char *pass, int passlen); BOOL cli_tdis(struct cli_state *cli); +BOOL cli_unlink(struct cli_state *cli, char *fname); +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode); +BOOL cli_close(struct cli_state *cli, int fnum); +BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout); +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_negprot(struct cli_state *cli); BOOL cli_session_request(struct cli_state *cli, char *host, int name_type, char *myname); BOOL cli_connect(struct cli_state *cli, char *host, struct in_addr *ip); BOOL cli_initialise(struct cli_state *cli); void cli_shutdown(struct cli_state *cli); +char *cli_errstr(struct cli_state *cli); +void cli_error(struct cli_state *cli, int *eclass, int *num); +void cli_sockopt(struct cli_state *cli, char *options); /*The following definitions come from clientutil.c */ @@ -81,7 +91,6 @@ BOOL cli_send_login(char *inbuf,char *outbuf,BOOL start_session,BOOL use_setup); void cli_send_logout(void ); BOOL cli_open_sockets(int port ); BOOL cli_reopen_connection(char *inbuf,char *outbuf); -char *smb_errstr(char *inbuf); /*The following definitions come from clitar.c */ @@ -1030,6 +1039,10 @@ void E_md4hash(uchar *passwd, uchar *p16); void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24); void nt_lm_owf_gen(char *pwd, char *nt_p16, char *p16); +/*The following definitions come from smberr.c */ + +char *smb_errstr(char *inbuf); + /*The following definitions come from smbpass.c */ int pw_file_lock(char *name, int type, int secs); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index b6ad1611ac..b2ecb07ded 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -502,14 +502,29 @@ BOOL cli_session_setup(struct cli_state *cli, send a tconX ****************************************************************************/ BOOL cli_send_tconX(struct cli_state *cli, - char *share, char *dev, char *pword, int passlen) + char *share, char *dev, char *pass, int passlen) { + fstring fullshare, pword; char *p; bzero(cli->outbuf,smb_size); bzero(cli->inbuf,smb_size); + if (cli->sec_mode & 1) { + passlen = 1; + pass = ""; + } + + if ((cli->sec_mode & 2) && *pass && passlen != 24) { + passlen = 24; + SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword); + } else { + memcpy(pword, pass, passlen); + } + + sprintf(fullshare, "\\\\%s\\%s", cli->desthost, share); + set_message(cli->outbuf,4, - 2 + strlen(share) + passlen + strlen(dev),True); + 2 + strlen(fullshare) + passlen + strlen(dev),True); CVAL(cli->outbuf,smb_com) = SMBtconX; cli_setup_packet(cli); @@ -519,7 +534,7 @@ BOOL cli_send_tconX(struct cli_state *cli, p = smb_buf(cli->outbuf); memcpy(p,pword,passlen); p += passlen; - strcpy(p,share); + strcpy(p,fullshare); p = skip_string(p,1); strcpy(p,dev); @@ -556,6 +571,294 @@ BOOL cli_tdis(struct cli_state *cli) return CVAL(cli->inbuf,smb_rcls) == 0; } +/**************************************************************************** +delete a file +****************************************************************************/ +BOOL cli_unlink(struct cli_state *cli, char *fname) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,1, 2 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBunlink; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,aSYSTEM | aHIDDEN); + + p = smb_buf(cli->outbuf); + *p++ = 4; + strcpy(p,fname); + p = skip_string(p,1); + + 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; + } + + return True; +} + + + +/**************************************************************************** +open a file +****************************************************************************/ +int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode) +{ + char *p; + unsigned openfn=0; + unsigned accessmode=0; + + if (flags & O_CREAT) + openfn |= (1<<4); + if (!(flags & O_EXCL)) { + if (flags & O_TRUNC) + openfn |= (1<<1); + else + openfn |= (1<<0); + } + + accessmode = (share_mode<<4); + + if ((flags & O_RDWR) == O_RDWR) { + accessmode |= 2; + } else if ((flags & O_WRONLY) == O_WRONLY) { + accessmode |= 1; + } + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,15,1 + strlen(fname),True); + + CVAL(cli->outbuf,smb_com) = SMBopenX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,0xFF); + 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_vwv8,openfn); + + p = smb_buf(cli->outbuf); + strcpy(p,fname); + p = skip_string(p,1); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf,smb_vwv2); +} + + + + +/**************************************************************************** + close a file +****************************************************************************/ +BOOL cli_close(struct cli_state *cli, int fnum) +{ + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,3,0,True); + + CVAL(cli->outbuf,smb_com) = SMBclose; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + SSVAL(cli->outbuf,smb_vwv0,fnum); + SSVAL(cli->outbuf,smb_vwv1,0); + SSVAL(cli->outbuf,smb_vwv2,0); + + 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; + } + + return True; +} + + +/**************************************************************************** + lock a file +****************************************************************************/ +BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,0); + SSVAL(cli->outbuf,smb_vwv7,1); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + 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; + } + + return True; +} + +/**************************************************************************** + unlock a file +****************************************************************************/ +BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,8,10,True); + + CVAL(cli->outbuf,smb_com) = SMBlockingX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + CVAL(cli->outbuf,smb_vwv3) = 0; + SIVALS(cli->outbuf, smb_vwv4, timeout); + SSVAL(cli->outbuf,smb_vwv6,1); + SSVAL(cli->outbuf,smb_vwv7,0); + + p = smb_buf(cli->outbuf); + SSVAL(p, 0, cli->pid); + SIVAL(p, 2, offset); + SIVAL(p, 6, len); + + 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; + } + + return True; +} + + +/**************************************************************************** + read from a file +****************************************************************************/ +int cli_read(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,10,0,True); + + CVAL(cli->outbuf,smb_com) = SMBreadX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + SSVAL(cli->outbuf,smb_vwv5,size); + SSVAL(cli->outbuf,smb_vwv6,size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + size = SVAL(cli->inbuf, smb_vwv5); + p = smb_base(cli->inbuf) + SVAL(cli->inbuf,smb_vwv6); + + memcpy(buf, p, size); + + return size; +} + + +/**************************************************************************** + write to a file +****************************************************************************/ +int cli_write(struct cli_state *cli, int fnum, char *buf, uint32 offset, uint16 size) +{ + char *p; + + bzero(cli->outbuf,smb_size); + bzero(cli->inbuf,smb_size); + + set_message(cli->outbuf,12,size,True); + + CVAL(cli->outbuf,smb_com) = SMBwriteX; + SSVAL(cli->outbuf,smb_tid,cli->cnum); + cli_setup_packet(cli); + + CVAL(cli->outbuf,smb_vwv0) = 0xFF; + SSVAL(cli->outbuf,smb_vwv2,fnum); + SIVAL(cli->outbuf,smb_vwv3,offset); + + SSVAL(cli->outbuf,smb_vwv10,size); + SSVAL(cli->outbuf,smb_vwv11,smb_buf(cli->outbuf) - smb_base(cli->outbuf)); + + p = smb_base(cli->outbuf) + SVAL(cli->outbuf,smb_vwv11); + memcpy(p, buf, size); + + send_smb(cli->fd,cli->outbuf); + if (!receive_smb(cli->fd,cli->inbuf,cli->timeout)) { + return -1; + } + + if (CVAL(cli->inbuf,smb_rcls) != 0) { + return -1; + } + + return SVAL(cli->inbuf, smb_vwv2); +} + /**************************************************************************** send a negprot command @@ -744,3 +1047,28 @@ void cli_shutdown(struct cli_state *cli) if (cli->fd != -1) close(cli->fd); memset(cli, 0, sizeof(*cli)); } + +/**************************************************************************** + return a description of the error +****************************************************************************/ +char *cli_errstr(struct cli_state *cli) +{ + return smb_errstr(cli->inbuf); +} + +/**************************************************************************** + return error codes for the last packet +****************************************************************************/ +void cli_error(struct cli_state *cli, int *eclass, int *num) +{ + *eclass = CVAL(cli->inbuf,smb_rcls); + *num = SVAL(cli->inbuf,smb_err); +} + +/**************************************************************************** +set socket options on a open connection +****************************************************************************/ +void cli_sockopt(struct cli_state *cli, char *options) +{ + set_socket_options(cli->fd, options); +} diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c new file mode 100644 index 0000000000..5149568c04 --- /dev/null +++ b/source3/libsmb/smberr.c @@ -0,0 +1,182 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + Copyright (C) Andrew Tridgell 1997 + + 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. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +extern int DEBUGLEVEL; + +/* error code stuff - put together by Merik Karman + merik@blackadder.dsh.oz.au */ + +typedef struct +{ + char *name; + int code; + char *message; +} err_code_struct; + +/* Dos Error Messages */ +err_code_struct dos_msgs[] = { + {"ERRbadfunc",1,"Invalid function."}, + {"ERRbadfile",2,"File not found."}, + {"ERRbadpath",3,"Directory invalid."}, + {"ERRnofids",4,"No file descriptors available"}, + {"ERRnoaccess",5,"Access denied."}, + {"ERRbadfid",6,"Invalid file handle."}, + {"ERRbadmcb",7,"Memory control blocks destroyed."}, + {"ERRnomem",8,"Insufficient server memory to perform the requested function."}, + {"ERRbadmem",9,"Invalid memory block address."}, + {"ERRbadenv",10,"Invalid environment."}, + {"ERRbadformat",11,"Invalid format."}, + {"ERRbadaccess",12,"Invalid open mode."}, + {"ERRbaddata",13,"Invalid data."}, + {"ERR",14,"reserved."}, + {"ERRbaddrive",15,"Invalid drive specified."}, + {"ERRremcd",16,"A Delete Directory request attempted to remove the server's current directory."}, + {"ERRdiffdevice",17,"Not same device."}, + {"ERRnofiles",18,"A File Search command can find no more files matching the specified criteria."}, + {"ERRbadshare",32,"The sharing mode specified for an Open conflicts with existing FIDs on the file."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRnosuchshare", 67, "You specified an invalid share name"}, + {"ERRfilexists",80,"The file named in a Create Directory, Make New File or Link request already exists."}, + {"ERRbadpipe",230,"Pipe invalid."}, + {"ERRpipebusy",231,"All instances of the requested pipe are busy."}, + {"ERRpipeclosing",232,"Pipe close in progress."}, + {"ERRnotconnected",233,"No process on other end of pipe."}, + {"ERRmoredata",234,"There is more data to be returned."}, + {"ERRinvgroup",2455,"Invalid workgroup (try the -W option)"}, + {NULL,-1,NULL}}; + +/* Server Error Messages */ +err_code_struct server_msgs[] = { + {"ERRerror",1,"Non-specific error code."}, + {"ERRbadpw",2,"Bad password - name/password pair in a Tree Connect or Session Setup are invalid."}, + {"ERRbadtype",3,"reserved."}, + {"ERRaccess",4,"The requester does not have the necessary access rights within the specified context for the requested function. The context is defined by the TID or the UID."}, + {"ERRinvnid",5,"The tree ID (TID) specified in a command was invalid."}, + {"ERRinvnetname",6,"Invalid network name in tree connect."}, + {"ERRinvdevice",7,"Invalid device - printer request made to non-printer connection or non-printer request made to printer connection."}, + {"ERRqfull",49,"Print queue full (files) -- returned by open print file."}, + {"ERRqtoobig",50,"Print queue full -- no space."}, + {"ERRqeof",51,"EOF on print queue dump."}, + {"ERRinvpfid",52,"Invalid print file FID."}, + {"ERRsmbcmd",64,"The server did not recognize the command received."}, + {"ERRsrverror",65,"The server encountered an internal error, e.g., system file unavailable."}, + {"ERRfilespecs",67,"The file handle (FID) and pathname parameters contained an invalid combination of values."}, + {"ERRreserved",68,"reserved."}, + {"ERRbadpermits",69,"The access permissions specified for a file or directory are not a valid combination. The server cannot set the requested attribute."}, + {"ERRreserved",70,"reserved."}, + {"ERRsetattrmode",71,"The attribute mode in the Set File Attribute request is invalid."}, + {"ERRpaused",81,"Server is paused."}, + {"ERRmsgoff",82,"Not receiving messages."}, + {"ERRnoroom",83,"No room to buffer message."}, + {"ERRrmuns",87,"Too many remote user names."}, + {"ERRtimeout",88,"Operation timed out."}, + {"ERRnoresource",89,"No resources currently available for request."}, + {"ERRtoomanyuids",90,"Too many UIDs active on this session."}, + {"ERRbaduid",91,"The UID is not known as a valid ID on this session."}, + {"ERRusempx",250,"Temp unable to support Raw, use MPX mode."}, + {"ERRusestd",251,"Temp unable to support Raw, use standard read/write."}, + {"ERRcontmpx",252,"Continue in MPX mode."}, + {"ERRreserved",253,"reserved."}, + {"ERRreserved",254,"reserved."}, + {"ERRnosupport",0xFFFF,"Function not supported."}, + {NULL,-1,NULL}}; + +/* Hard Error Messages */ +err_code_struct hard_msgs[] = { + {"ERRnowrite",19,"Attempt to write on write-protected diskette."}, + {"ERRbadunit",20,"Unknown unit."}, + {"ERRnotready",21,"Drive not ready."}, + {"ERRbadcmd",22,"Unknown command."}, + {"ERRdata",23,"Data error (CRC)."}, + {"ERRbadreq",24,"Bad request structure length."}, + {"ERRseek",25 ,"Seek error."}, + {"ERRbadmedia",26,"Unknown media type."}, + {"ERRbadsector",27,"Sector not found."}, + {"ERRnopaper",28,"Printer out of paper."}, + {"ERRwrite",29,"Write fault."}, + {"ERRread",30,"Read fault."}, + {"ERRgeneral",31,"General failure."}, + {"ERRbadshare",32,"An open conflicts with an existing open."}, + {"ERRlock",33,"A Lock request conflicted with an existing lock or specified an invalid mode, or an Unlock requested attempted to remove a lock held by another process."}, + {"ERRwrongdisk",34,"The wrong disk was found in a drive."}, + {"ERRFCBUnavail",35,"No FCBs are available to process request."}, + {"ERRsharebufexc",36,"A sharing buffer has been exceeded."}, + {NULL,-1,NULL}}; + + +struct +{ + int code; + char *class; + err_code_struct *err_msgs; +} err_classes[] = { + {0,"SUCCESS",NULL}, + {0x01,"ERRDOS",dos_msgs}, + {0x02,"ERRSRV",server_msgs}, + {0x03,"ERRHRD",hard_msgs}, + {0x04,"ERRXOS",NULL}, + {0xE1,"ERRRMX1",NULL}, + {0xE2,"ERRRMX2",NULL}, + {0xE3,"ERRRMX3",NULL}, + {0xFF,"ERRCMD",NULL}, + {-1,NULL,NULL}}; + + +/**************************************************************************** +return a SMB error string from a SMB buffer +****************************************************************************/ +char *smb_errstr(char *inbuf) +{ + static pstring ret; + int class = CVAL(inbuf,smb_rcls); + int num = SVAL(inbuf,smb_err); + int i,j; + + for (i=0;err_classes[i].class;i++) + if (err_classes[i].code == class) + { + if (err_classes[i].err_msgs) + { + err_code_struct *err = err_classes[i].err_msgs; + for (j=0;err[j].name;j++) + if (num == err[j].code) + { + if (DEBUGLEVEL > 0) + sprintf(ret,"%s - %s (%s)",err_classes[i].class, + err[j].name,err[j].message); + else + sprintf(ret,"%s - %s",err_classes[i].class,err[j].name); + return ret; + } + } + + sprintf(ret,"%s - %d",err_classes[i].class,num); + return ret; + } + + sprintf(ret,"Error: Unknown error (%d,%d)",class,num); + return(ret); +} diff --git a/source3/nmbsync.c b/source3/nmbsync.c index 5fa41e127a..c1db37ff5c 100644 --- a/source3/nmbsync.c +++ b/source3/nmbsync.c @@ -60,7 +60,6 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, char *name, int nm_type, struct in_addr ip, BOOL local) { extern fstring local_machine; - fstring share; static struct cli_state cli; uint32 local_type = local ? SV_TYPE_LOCAL_LIST_ONLY : 0; @@ -97,9 +96,7 @@ void sync_browse_lists(struct subnet_record *d, struct work_record *work, return; } - sprintf(share,"\\\\%s\\IPC$", name); - - if (!cli_send_tconX(&cli, share, "IPC", "", 1)) { + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { DEBUG(1,("%s refused browse sync IPC$ connect\n", name)); cli_shutdown(&cli); return; diff --git a/source3/smbd/password.c b/source3/smbd/password.c index 24ee52ed69..b759f68430 100644 --- a/source3/smbd/password.c +++ b/source3/smbd/password.c @@ -1560,7 +1560,6 @@ BOOL server_validate(char *user, char *domain, char *ntpass, int ntpasslen) { extern fstring local_machine; - fstring share; if (!cli.initialised) { DEBUG(1,("password server %s is not connected\n", cli.desthost)); @@ -1579,9 +1578,7 @@ BOOL server_validate(char *user, char *domain, } - sprintf(share,"\\\\%s\\IPC$", cli.desthost); - - if (!cli_send_tconX(&cli, share, "IPC", "", 1)) { + if (!cli_send_tconX(&cli, "IPC$", "IPC", "", 1)) { DEBUG(1,("password server %s refused IPC$ connect\n", cli.desthost)); return False; } diff --git a/source3/utils/torture.c b/source3/utils/torture.c new file mode 100644 index 0000000000..bc7ebfb335 --- /dev/null +++ b/source3/utils/torture.c @@ -0,0 +1,316 @@ +/* + Unix SMB/Netbios implementation. + Version 1.9. + SMB torture tester + Copyright (C) Andrew Tridgell 1997 + + 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. +*/ + +#ifdef SYSLOG +#undef SYSLOG +#endif + +#include "includes.h" + +static struct cli_state cli; +static fstring host, workgroup, share, password, username, myname; +static char *sockops=""; + + +static struct timeval tp1,tp2; + +static void start_timer() +{ + gettimeofday(&tp1,NULL); +} + +static double end_timer() +{ + gettimeofday(&tp2,NULL); + return((tp2.tv_sec - tp1.tv_sec) + + (tp2.tv_usec - tp1.tv_usec)*1.0e-6); +} + + +static int open_connection(void) +{ + if (!cli_initialise(&cli) || !cli_connect(&cli, host, NULL)) { + printf("Failed to connect with %s\n", host); + } + + if (!cli_session_request(&cli, host, 0x20, myname)) { + printf("%s rejected the session\n",host); + cli_shutdown(&cli); + return -1; + } + + if (!cli_negprot(&cli)) { + printf("%s rejected the negprot (%s)\n",host, cli_errstr(&cli)); + cli_shutdown(&cli); + return -1; + } + + if (!cli_session_setup(&cli, username, password, strlen(password), + "", 0, workgroup)) { + printf("%s rejected the sessionsetup (%s)\n", host, cli_errstr(&cli)); + cli_shutdown(&cli); + return -1; + } + + if (!cli_send_tconX(&cli, share, "A:", password, strlen(password)+1)) { + printf("%s refused tree connect (%s)\n", host, cli_errstr(&cli)); + cli_shutdown(&cli); + return -1; + } + + return 0; +} + + + +static void close_connection(void) +{ + if (!cli_tdis(&cli)) { + printf("tdis failed (%s)\n", cli_errstr(&cli)); + } + + cli_shutdown(&cli); +} + + + + +static BOOL wait_lock(int fnum, uint32 offset, uint32 len) +{ + while (!cli_lock(&cli, fnum, offset, len, -1)) { + int eclass, num; + cli_error(&cli, &eclass, &num); + if (eclass != ERRDOS || num != ERRlock) { + printf("lock failed (%s)\n", + cli_errstr(&cli)); + return False; + } + } + return True; +} + + +static int rw_torture(int numops) +{ + char *lockfname = "\\torture.lck"; + fstring fname; + int fnum; + int fnum2; + int pid2, pid = getpid(); + int i; + + fnum2 = cli_open(&cli, lockfname, O_RDWR | O_EXCL, DENY_NONE); + if (fnum2 == -1) + fnum2 = cli_open(&cli, lockfname, O_RDWR, DENY_NONE); + if (fnum2 == -1) { + printf("open of %s failed (%s)\n", lockfname, cli_errstr(&cli)); + return -1; + } + + + for (i=0;i<numops;i++) { + unsigned n = (unsigned)random()%10; + printf("%d\r", i); fflush(stdout); + sprintf(fname,"\\torture.%u", n); + + if (!wait_lock(fnum2, n*sizeof(int), sizeof(int))) { + return -1; + } + + fnum = cli_open(&cli, fname, O_RDWR | O_CREAT | O_TRUNC, DENY_ALL); + if (fnum == -1) { + printf("open failed (%s)\n", cli_errstr(&cli)); + break; + } + + if (cli_write(&cli, fnum, (char *)&pid, 0, sizeof(pid)) != sizeof(pid)) { + printf("write failed (%s)\n", cli_errstr(&cli)); + } + + pid2 = 0; + + if (cli_read(&cli, fnum, (char *)&pid2, 0, sizeof(pid)) != sizeof(pid)) { + printf("read failed (%s)\n", cli_errstr(&cli)); + } + + if (pid2 != pid) { + printf("data corruption!\n"); + } + + if (!cli_close(&cli, fnum)) { + printf("close failed (%s)\n", cli_errstr(&cli)); + } + + if (!cli_unlink(&cli, fname)) { + printf("unlink failed (%s)\n", cli_errstr(&cli)); + } + + if (!cli_unlock(&cli, fnum2, n*sizeof(int), sizeof(int), -1)) { + printf("unlock failed (%s)\n", cli_errstr(&cli)); + } + } + + printf("%d\n", i); + + return 0; +} + +static void usage(void) +{ + printf("Usage: smbtorture \\\\server\\share <options>\n"); + + printf("\t-U user%%pass\n"); + printf("\t-N numprocs\n"); + printf("\t-n my_netbios_name\n"); + printf("\t-W workgroup\n"); + printf("\t-o num_operations\n"); + printf("\t-O socket_options\n"); + printf("\n"); + + exit(1); +} + + + +static void run_torture(int numops) +{ + if (open_connection() == 0) { + cli_sockopt(&cli, sockops); + + printf("pid %d OK\n", getpid()); + + rw_torture(numops); + + close_connection(); + } +} + + +static void create_procs(int nprocs, int numops) +{ + int i, status; + + for (i=0;i<nprocs;i++) { + if (fork() == 0) { + int mypid = getpid(); + srandom(mypid ^ time(NULL)); + run_torture(numops); + _exit(0); + } + } + + for (i=0;i<nprocs;i++) + waitpid(0, &status, 0); +} + + + +/**************************************************************************** + main program +****************************************************************************/ + int main(int argc,char *argv[]) +{ + int nprocs=1, numops=100; + int opt; + char *p; + int gotpass = 0; + extern char *optarg; + extern int optind; + extern FILE *dbf; + + dbf = stdout; + + charset_initialise(); + + if (argc < 2) { + usage(); + } + + if (strncmp(argv[1], "\\\\", 2)) { + usage(); + } + + fstrcpy(host, &argv[1][2]); + p = strchr(&host[2],'\\'); + if (!p) { + usage(); + } + *p = 0; + fstrcpy(share, p+1); + + get_myname(myname,NULL); + + argc--; + argv++; + + + while ((opt = getopt(argc, argv, "hW:U:n:N:O:o:")) != EOF) { + switch (opt) { + case 'W': + fstrcpy(workgroup,optarg); + break; + case 'N': + nprocs = atoi(optarg); + break; + case 'o': + numops = atoi(optarg); + break; + case 'O': + sockops = optarg; + break; + case 'n': + fstrcpy(myname, optarg); + break; + case 'U': + strcpy(username,optarg); + p = strchr(username,'%'); + if (p) { + *p = 0; + strcpy(password, p+1); + gotpass = 1; + } + break; + default: + printf("Unknown option %c (%d)\n", (char)opt, opt); + usage(); + } + } + + + while (!gotpass) { + p = getpass("Password:"); + if (p) { + strcpy(password, p); + gotpass = 1; + } + } + + printf("host=%s share=%s user=%s myname=%s\n", + host, share, username, myname); + + start_timer(); + create_procs(nprocs, numops); + printf("rw_torture: %g secs\n", end_timer()); + + return(0); +} + + |