2b4989e48b00ece2498a0f1b37ee14e470a63003
[vlendec/samba-autobuild/.git] / source3 / torture / test_cleanup.c
1 /*
2    Unix SMB/CIFS implementation.
3    Test cleanup behaviour
4    Copyright (C) Volker Lendecke 2011
5
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "includes.h"
21 #include "torture/proto.h"
22 #include "system/filesys.h"
23 #include "libsmb/libsmb.h"
24 #include "libcli/smb/smbXcli_base.h"
25 #include "libcli/security/security.h"
26
27 bool run_cleanup1(int dummy)
28 {
29         struct cli_state *cli;
30         const char *fname = "\\cleanup1";
31         uint16_t fnum;
32         NTSTATUS status;
33
34         printf("CLEANUP1: Checking that a conflicting share mode is cleaned "
35                "up\n");
36
37         if (!torture_open_connection(&cli, 0)) {
38                 return false;
39         }
40         status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, &fnum);
41         if (!NT_STATUS_IS_OK(status)) {
42                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
43                 return false;
44         }
45         status = smbXcli_conn_samba_suicide(cli->conn, 1);
46         if (!NT_STATUS_IS_OK(status)) {
47                 printf("smbXcli_conn_samba_suicide failed: %s\n",
48                        nt_errstr(status));
49                 return false;
50         }
51
52         if (!torture_open_connection(&cli, 1)) {
53                 return false;
54         }
55         status = cli_openx(cli, fname, O_RDWR|O_CREAT, DENY_ALL, &fnum);
56         if (!NT_STATUS_IS_OK(status)) {
57                 printf("2nd open of %s failed (%s)\n", fname,
58                        nt_errstr(status));
59                 return false;
60         }
61         cli_close(cli, fnum);
62
63         status = cli_unlink(cli, fname, 0);
64         if (!NT_STATUS_IS_OK(status)) {
65                 printf("cli_unlink failed: %s\n", nt_errstr(status));
66                 goto done;
67         }
68 done:
69         torture_close_connection(cli);
70         return NT_STATUS_IS_OK(status);
71 }
72
73 bool run_cleanup2(int dummy)
74 {
75         struct cli_state *cli1, *cli2;
76         const char *fname = "\\cleanup2";
77         uint16_t fnum1, fnum2;
78         NTSTATUS status;
79         char buf;
80
81         printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n");
82
83         if (!torture_open_connection(&cli1, 0)) {
84                 return false;
85         }
86         status = cli_ntcreate(
87                 cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
88                 FILE_ATTRIBUTE_NORMAL,
89                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
90                 FILE_OVERWRITE_IF, 0, 0, &fnum1);
91         if (!NT_STATUS_IS_OK(status)) {
92                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
93                 return false;
94         }
95         status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK);
96         if (!NT_STATUS_IS_OK(status)) {
97                 printf("lock failed (%s)\n", nt_errstr(status));
98                 return false;
99         }
100
101         /*
102          * Check the file is indeed locked
103          */
104         if (!torture_open_connection(&cli2, 0)) {
105                 return false;
106         }
107         status = cli_ntcreate(
108                 cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
109                 FILE_ATTRIBUTE_NORMAL,
110                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
111                 FILE_OPEN, 0, 0, &fnum2);
112         if (!NT_STATUS_IS_OK(status)) {
113                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
114                 return false;
115         }
116         buf = 'x';
117         status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
118         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
119                 printf("write succeeded\n");
120                 return false;
121         }
122
123         /*
124          * Kill the lock holder
125          */
126         status = smbXcli_conn_samba_suicide(cli1->conn, 1);
127         if (!NT_STATUS_IS_OK(status)) {
128                 printf("smbXcli_conn_samba_suicide failed: %s\n",
129                        nt_errstr(status));
130                 return false;
131         }
132
133         /*
134          * Right now we don't clean up immediately. Re-open the 2nd connection.
135          */
136 #if 1
137         cli_shutdown(cli2);
138         if (!torture_open_connection(&cli2, 0)) {
139                 return false;
140         }
141         status = cli_ntcreate(
142                 cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
143                 FILE_ATTRIBUTE_NORMAL,
144                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
145                 FILE_OPEN, 0, 0, &fnum2);
146         if (!NT_STATUS_IS_OK(status)) {
147                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
148                 return false;
149         }
150 #endif
151         status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
152         if (!NT_STATUS_IS_OK(status)) {
153                 printf("write failed: %s\n", nt_errstr(status));
154                 return false;
155         }
156         return true;
157 }