diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/include/proto.h | 7 | ||||
-rw-r--r-- | source3/libsmb/clientgen.c | 10 | ||||
-rw-r--r-- | source3/utils/torture.c | 150 |
3 files changed, 140 insertions, 27 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h index 0388ef6911..2db1f3ed02 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -587,8 +587,10 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname); int cli_nt_create(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); +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype); +BOOL cli_unlock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype); size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t size); ssize_t cli_write(struct cli_state *cli, int fnum, uint16 write_mode, @@ -2972,6 +2974,7 @@ int smbw_stat(const char *fname, struct stat *st); /*The following definitions come from tdb/tdb.c */ +char *tdb_error(TDB_CONTEXT *tdb); int tdb_update(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf); TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key); int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key); diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index 3b6403fe73..bf610a7ff7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -1344,7 +1344,8 @@ BOOL cli_close(struct cli_state *cli, int fnum) /**************************************************************************** lock a file ****************************************************************************/ -BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int timeout) +BOOL cli_lock(struct cli_state *cli, int fnum, + uint32 offset, uint32 len, int timeout, int locktype) { char *p; int saved_timeout = cli->timeout; @@ -1360,7 +1361,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,0); SSVAL(cli->outbuf,smb_vwv7,1); @@ -1390,7 +1391,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti /**************************************************************************** unlock a file ****************************************************************************/ -BOOL cli_unlock(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 locktype) { char *p; @@ -1405,7 +1407,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int CVAL(cli->outbuf,smb_vwv0) = 0xFF; SSVAL(cli->outbuf,smb_vwv2,fnum); - CVAL(cli->outbuf,smb_vwv3) = 0; + CVAL(cli->outbuf,smb_vwv3) = (locktype == F_RDLCK? 1 : 0); SIVALS(cli->outbuf, smb_vwv4, timeout); SSVAL(cli->outbuf,smb_vwv6,1); SSVAL(cli->outbuf,smb_vwv7,0); diff --git a/source3/utils/torture.c b/source3/utils/torture.c index 4375cbe231..b9f0d76581 100644 --- a/source3/utils/torture.c +++ b/source3/utils/torture.c @@ -168,7 +168,7 @@ static BOOL check_error(struct cli_state *c, static BOOL wait_lock(struct cli_state *c, int fnum, uint32 offset, uint32 len) { - while (!cli_lock(c, fnum, offset, len, -1)) { + while (!cli_lock(c, fnum, offset, len, -1, F_WRLCK)) { if (!check_error(c, ERRDOS, ERRlock, 0)) return False; } return True; @@ -242,7 +242,7 @@ static BOOL rw_torture(struct cli_state *c) printf("unlink failed (%s)\n", cli_errstr(c)); } - if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1)) { + if (!cli_unlock(c, fnum2, n*sizeof(int), sizeof(int), -1, F_WRLCK)) { printf("unlock failed (%s)\n", cli_errstr(c)); } } @@ -436,13 +436,13 @@ static void run_locktest1(int dummy) return; } - if (!cli_lock(&cli1, fnum1, 0, 4, 0)) { + if (!cli_lock(&cli1, fnum1, 0, 4, 0, F_WRLCK)) { printf("lock1 failed (%s)\n", cli_errstr(&cli1)); return; } - if (cli_lock(&cli2, fnum3, 0, 4, 0)) { + if (cli_lock(&cli2, fnum3, 0, 4, 0, F_WRLCK)) { printf("lock2 succeeded! This is a locking bug\n"); return; } else { @@ -452,7 +452,7 @@ static void run_locktest1(int dummy) printf("Testing lock timeouts\n"); t1 = time(NULL); - if (cli_lock(&cli2, fnum3, 0, 4, 10*1000)) { + if (cli_lock(&cli2, fnum3, 0, 4, 10*1000, F_WRLCK)) { printf("lock3 succeeded! This is a locking bug\n"); return; } else { @@ -469,7 +469,7 @@ static void run_locktest1(int dummy) return; } - if (cli_lock(&cli2, fnum3, 0, 4, 0)) { + if (cli_lock(&cli2, fnum3, 0, 4, 0, F_WRLCK)) { printf("lock4 succeeded! This is a locking bug\n"); return; } else { @@ -550,12 +550,12 @@ static void run_locktest2(int dummy) cli_setpid(&cli, 1); - if (!cli_lock(&cli, fnum1, 0, 4, 0)) { + if (!cli_lock(&cli, fnum1, 0, 4, 0, F_WRLCK)) { printf("lock1 failed (%s)\n", cli_errstr(&cli)); return; } - if (cli_lock(&cli, fnum2, 0, 4, 0)) { + if (cli_lock(&cli, fnum2, 0, 4, 0, F_WRLCK)) { printf("lock2 succeeded! This is a locking bug\n"); } else { if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; @@ -563,11 +563,11 @@ static void run_locktest2(int dummy) cli_setpid(&cli, 2); - if (cli_unlock(&cli, fnum1, 0, 4, 0)) { + if (cli_unlock(&cli, fnum1, 0, 4, 0, F_WRLCK)) { printf("unlock1 succeeded! This is a locking bug\n"); } - if (cli_lock(&cli, fnum3, 0, 4, 0)) { + if (cli_lock(&cli, fnum3, 0, 4, 0, F_WRLCK)) { printf("lock3 succeeded! This is a locking bug\n"); } else { if (!check_error(&cli, ERRDOS, ERRlock, 0)) return; @@ -633,14 +633,14 @@ static void run_locktest3(int dummy) for (offset=i=0;i<numops;i++) { NEXT_OFFSET; - if (!cli_lock(&cli1, fnum1, offset-1, 1, 0)) { + if (!cli_lock(&cli1, fnum1, offset-1, 1, 0, F_WRLCK)) { printf("lock1 %d failed (%s)\n", i, cli_errstr(&cli1)); return; } - if (!cli_lock(&cli2, fnum2, offset-2, 1, 0)) { + if (!cli_lock(&cli2, fnum2, offset-2, 1, 0, F_WRLCK)) { printf("lock2 %d failed (%s)\n", i, cli_errstr(&cli1)); @@ -651,22 +651,22 @@ static void run_locktest3(int dummy) for (offset=i=0;i<numops;i++) { NEXT_OFFSET; - if (cli_lock(&cli1, fnum1, offset-2, 1, 0)) { + if (cli_lock(&cli1, fnum1, offset-2, 1, 0, F_WRLCK)) { printf("error: lock1 %d succeeded!\n", i); return; } - if (cli_lock(&cli2, fnum2, offset-1, 1, 0)) { + if (cli_lock(&cli2, fnum2, offset-1, 1, 0, F_WRLCK)) { printf("error: lock2 %d succeeded!\n", i); return; } - if (cli_lock(&cli1, fnum1, offset-1, 1, 0)) { + if (cli_lock(&cli1, fnum1, offset-1, 1, 0, F_WRLCK)) { printf("error: lock3 %d succeeded!\n", i); return; } - if (cli_lock(&cli2, fnum2, offset-2, 1, 0)) { + if (cli_lock(&cli2, fnum2, offset-2, 1, 0, F_WRLCK)) { printf("error: lock4 %d succeeded!\n", i); return; } @@ -675,14 +675,14 @@ static void run_locktest3(int dummy) for (offset=i=0;i<numops;i++) { NEXT_OFFSET; - if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0)) { + if (!cli_unlock(&cli1, fnum1, offset-1, 1, 0, F_WRLCK)) { printf("unlock1 %d failed (%s)\n", i, cli_errstr(&cli1)); return; } - if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0)) { + if (!cli_unlock(&cli2, fnum2, offset-2, 1, 0, F_WRLCK)) { printf("unlock2 %d failed (%s)\n", i, cli_errstr(&cli1)); @@ -711,6 +711,114 @@ static void run_locktest3(int dummy) /* + looks at overlapping locks +*/ +static void run_locktest4(int dummy) +{ + static struct cli_state cli1, cli2; + char *fname = "\\lockt4.lck"; + int fnum1, fnum2; + BOOL ret; + char buf[1000]; + + if (!open_connection(&cli1) || !open_connection(&cli2)) { + return; + } + cli_sockopt(&cli1, sockops); + cli_sockopt(&cli2, sockops); + + printf("starting locktest4\n"); + + cli_unlink(&cli1, fname); + + fnum1 = cli_open(&cli1, fname, O_RDWR|O_CREAT|O_EXCL, DENY_NONE); + fnum2 = cli_open(&cli2, fname, O_RDWR, DENY_NONE); + + memset(buf, 0, sizeof(buf)); + + if (cli_write(&cli1, fnum1, 0, buf, 0, sizeof(buf)) != sizeof(buf)) { + printf("Failed to create file\n"); + goto fail; + } + + cli_lock(&cli1, fnum1, 0, 4, 0, F_WRLCK); + ret = cli_lock(&cli1, fnum1, 2, 4, 0, F_WRLCK); + printf("the same process %s set overlapping write locks\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 10, 4, 0, F_RDLCK); + ret = cli_lock(&cli1, fnum1, 12, 4, 0, F_RDLCK); + printf("the same process %s set overlapping read locks\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 20, 4, 0, F_WRLCK); + ret = cli_lock(&cli2, fnum2, 22, 4, 0, F_WRLCK); + printf("a different connection %s set overlapping write locks\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 30, 4, 0, F_RDLCK); + ret = cli_lock(&cli2, fnum2, 32, 4, 0, F_RDLCK); + printf("a different connection %s set overlapping read locks\n", ret?"can":"cannot"); + + cli_setpid(&cli1, 1); + cli_lock(&cli1, fnum1, 40, 4, 0, F_WRLCK); + cli_setpid(&cli1, 2); + ret = cli_lock(&cli1, fnum1, 42, 4, 0, F_WRLCK); + printf("a different pid %s set overlapping write locks\n", ret?"can":"cannot"); + + cli_setpid(&cli1, 1); + cli_lock(&cli1, fnum1, 50, 4, 0, F_RDLCK); + cli_setpid(&cli1, 2); + ret = cli_lock(&cli1, fnum1, 52, 4, 0, F_RDLCK); + printf("a different pid %s set overlapping read locks\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 60, 4, 0, F_RDLCK); + ret = cli_lock(&cli1, fnum1, 60, 4, 0, F_RDLCK); + printf("the same process %s set the same read lock twice\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 70, 4, 0, F_WRLCK); + ret = cli_lock(&cli1, fnum1, 70, 4, 0, F_WRLCK); + printf("the same process %s set the same write lock twice\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 80, 4, 0, F_RDLCK); + ret = cli_lock(&cli1, fnum1, 80, 4, 0, F_WRLCK); + printf("the same process %s override a read lock with a write lock\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 90, 4, 0, F_WRLCK); + ret = cli_lock(&cli1, fnum1, 90, 4, 0, F_RDLCK); + printf("the same process %s override a write lock with a read lock\n", ret?"can":"cannot"); + + cli_setpid(&cli1, 1); + cli_lock(&cli1, fnum1, 100, 4, 0, F_WRLCK); + cli_setpid(&cli1, 2); + ret = cli_lock(&cli1, fnum1, 100, 4, 0, F_RDLCK); + printf("a different pid %s override a write lock with a read lock\n", ret?"can":"cannot"); + + cli_lock(&cli1, fnum1, 110, 4, 0, F_RDLCK); + cli_lock(&cli1, fnum1, 112, 4, 0, F_RDLCK); + ret = cli_unlock(&cli1, fnum1, 110, 6, 0, F_RDLCK); + printf("the same process %s coalesce read locks\n", ret?"can":"cannot"); + + + cli_lock(&cli1, fnum1, 120, 4, 0, F_WRLCK); + ret = (cli_read(&cli2, fnum2, buf, 120, 4) == 4); + printf("this server %s strict write locking\n", ret?"doesn't do":"does"); + + cli_lock(&cli1, fnum1, 130, 4, 0, F_RDLCK); + ret = (cli_write(&cli2, fnum2, 0, buf, 130, 4) == 4); + printf("this server %s strict read locking\n", ret?"doesn't do":"does"); + + + + fail: + cli_close(&cli1, fnum1); + cli_close(&cli1, fnum2); + cli_unlink(&cli1, fname); + close_connection(&cli1); + close_connection(&cli2); + + printf("finished locktest4\n"); +} + + +/* this produces a matrix of deny mode behaviour */ static void run_denytest(int dummy) @@ -1190,10 +1298,9 @@ static void run_trans2test(int dummy) */ static void run_oplock(int dummy) { - static struct cli_state cli1, cli2; + static struct cli_state cli1; char *fname = "\\lockt1.lck"; - char *fname2 = "\\lockt2.lck"; - int fnum1, fnum2; + int fnum1; printf("starting oplock test\n"); @@ -1380,6 +1487,7 @@ static struct { {"LOCK1", run_locktest1, 0}, {"LOCK2", run_locktest2, 0}, {"LOCK3", run_locktest3, 0}, + {"LOCK4", run_locktest4, 0}, {"UNLINK", run_unlinktest, 0}, {"BROWSE", run_browsetest, 0}, {"ATTR", run_attrtest, 0}, |