diff options
author | Andrew Tridgell <tridge@samba.org> | 2001-06-18 08:26:15 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2001-06-18 08:26:15 +0000 |
commit | e324e21457b232acb13a06fa5a4b8f363b3dec7c (patch) | |
tree | 33deb696bc796fe963c19505943d127430eee6a1 /source3/libsmb | |
parent | 7b01c627c62ef6be519110fcd6cb88c86c5cd0ab (diff) | |
download | samba-e324e21457b232acb13a06fa5a4b8f363b3dec7c.tar.gz samba-e324e21457b232acb13a06fa5a4b8f363b3dec7c.tar.xz samba-e324e21457b232acb13a06fa5a4b8f363b3dec7c.zip |
added a oplock break handler hook to the client code, this allows for more complete testing of oplocks from smbtorture and would also be essential if a client app ever really did want to use oplocks properly
(This used to be commit 3d4a3bfacd9ef225aeaab801e5a216d12814b60a)
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/clientgen.c | 54 | ||||
-rw-r--r-- | source3/libsmb/clioplock.c | 72 |
2 files changed, 79 insertions, 47 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 8e00bca82a9..e9f55850ac1 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -25,7 +25,6 @@ extern int DEBUGLEVEL; -static void cli_process_oplock(struct cli_state *cli); /* * Change the port number used to call on @@ -53,7 +52,11 @@ BOOL cli_receive_smb(struct cli_state *cli) CVAL(cli->inbuf,smb_com) == SMBlockingX && SVAL(cli->inbuf,smb_vwv6) == 0 && SVAL(cli->inbuf,smb_vwv7) == 0) { - if (cli->use_oplocks) cli_process_oplock(cli); + if (cli->oplock_handler) { + int fnum = SVAL(cli->inbuf,smb_vwv2); + unsigned char level = CVAL(cli->inbuf,smb_vwv3+1); + if (!cli->oplock_handler(cli, fnum, level)) return False; + } /* try to prevent loops */ CVAL(cli->inbuf,smb_com) = 0xFF; goto again; @@ -125,51 +128,6 @@ void cli_setup_bcc(struct cli_state *cli, void *p) } -/**************************************************************************** -process an oplock break request from the server -****************************************************************************/ -static void cli_process_oplock(struct cli_state *cli) -{ - char *oldbuf = cli->outbuf; - pstring buf; - int fnum; - unsigned char level; - - fnum = SVAL(cli->inbuf,smb_vwv2); - level = CVAL(cli->inbuf,smb_vwv3+1); - - /* damn, we really need to keep a record of open files so we - can detect a oplock break and a close crossing on the - wire. for now this swallows the errors */ - if (fnum == 0) return; - - /* Ignore level II break to none's. */ - if (level == OPLOCKLEVEL_NONE) - return; - - cli->outbuf = buf; - - memset(buf,'\0',smb_size); - set_message(buf,8,0,True); - - CVAL(buf,smb_com) = SMBlockingX; - SSVAL(buf,smb_tid, cli->cnum); - cli_setup_packet(cli); - SSVAL(buf,smb_vwv0,0xFF); - SSVAL(buf,smb_vwv1,0); - SSVAL(buf,smb_vwv2,fnum); - if (cli->use_level_II_oplocks) - SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ - else - SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ - SIVAL(buf,smb_vwv4,0); /* timoeut */ - SSVAL(buf,smb_vwv6,0); /* unlockcount */ - SSVAL(buf,smb_vwv7,0); /* lockcount */ - - cli_send_smb(cli); - - cli->outbuf = oldbuf; -} /**************************************************************************** initialise a client structure @@ -219,6 +177,8 @@ struct cli_state *cli_initialise(struct cli_state *cli) cli->max_xmit = cli->bufsize; cli->outbuf = (char *)malloc(cli->bufsize); cli->inbuf = (char *)malloc(cli->bufsize); + cli->oplock_handler = cli_oplock_ack; + if (!cli->outbuf || !cli->inbuf) { return NULL; diff --git a/source3/libsmb/clioplock.c b/source3/libsmb/clioplock.c new file mode 100644 index 00000000000..a52dcf3a3e3 --- /dev/null +++ b/source3/libsmb/clioplock.c @@ -0,0 +1,72 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + SMB client oplock functions + Copyright (C) Andrew Tridgell 2001 + + 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" +extern int DEBUGLEVEL; + + +/**************************************************************************** +send an ack for an oplock break request +****************************************************************************/ +BOOL cli_oplock_ack(struct cli_state *cli, int fnum, unsigned char level) +{ + char *oldbuf = cli->outbuf; + pstring buf; + BOOL ret; + + cli->outbuf = buf; + + memset(buf,'\0',smb_size); + set_message(buf,8,0,True); + + CVAL(buf,smb_com) = SMBlockingX; + SSVAL(buf,smb_tid, cli->cnum); + cli_setup_packet(cli); + SSVAL(buf,smb_vwv0,0xFF); + SSVAL(buf,smb_vwv1,0); + SSVAL(buf,smb_vwv2,fnum); + if (level == 1) + SSVAL(buf,smb_vwv3,0x102); /* levelII oplock break ack */ + else + SSVAL(buf,smb_vwv3,2); /* exclusive oplock break ack */ + SIVAL(buf,smb_vwv4,0); /* timoeut */ + SSVAL(buf,smb_vwv6,0); /* unlockcount */ + SSVAL(buf,smb_vwv7,0); /* lockcount */ + + ret = cli_send_smb(cli); + + cli->outbuf = oldbuf; + + return ret; +} + + +/**************************************************************************** +set the oplock handler for a connection +****************************************************************************/ +void cli_oplock_handler(struct cli_state *cli, + BOOL (*handler)(struct cli_state *, int, unsigned char)) +{ + cli->oplock_handler = handler; +} + |