s3: Use DELETE_ON_CLOSE instead of unlink
[samba.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_ntcreate(
56                 cli, fname, 0,
57                 FILE_GENERIC_READ|FILE_GENERIC_WRITE|DELETE_ACCESS,
58                 FILE_ATTRIBUTE_NORMAL,
59                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
60                 FILE_OPEN, FILE_DELETE_ON_CLOSE, 0, &fnum);
61         if (!NT_STATUS_IS_OK(status)) {
62                 printf("2nd open of %s failed (%s)\n", fname,
63                        nt_errstr(status));
64                 return false;
65         }
66         cli_close(cli, fnum);
67
68         torture_close_connection(cli);
69         return NT_STATUS_IS_OK(status);
70 }
71
72 bool run_cleanup2(int dummy)
73 {
74         struct cli_state *cli1, *cli2;
75         const char *fname = "\\cleanup2";
76         uint16_t fnum1, fnum2;
77         NTSTATUS status;
78         char buf;
79
80         printf("CLEANUP2: Checking that a conflicting brlock is cleaned up\n");
81
82         if (!torture_open_connection(&cli1, 0)) {
83                 return false;
84         }
85         status = cli_ntcreate(
86                 cli1, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
87                 FILE_ATTRIBUTE_NORMAL,
88                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
89                 FILE_OVERWRITE_IF, 0, 0, &fnum1);
90         if (!NT_STATUS_IS_OK(status)) {
91                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
92                 return false;
93         }
94         status = cli_lock32(cli1, fnum1, 0, 1, 0, WRITE_LOCK);
95         if (!NT_STATUS_IS_OK(status)) {
96                 printf("lock failed (%s)\n", nt_errstr(status));
97                 return false;
98         }
99
100         /*
101          * Check the file is indeed locked
102          */
103         if (!torture_open_connection(&cli2, 0)) {
104                 return false;
105         }
106         status = cli_ntcreate(
107                 cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
108                 FILE_ATTRIBUTE_NORMAL,
109                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
110                 FILE_OPEN, 0, 0, &fnum2);
111         if (!NT_STATUS_IS_OK(status)) {
112                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
113                 return false;
114         }
115         buf = 'x';
116         status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
117         if (!NT_STATUS_EQUAL(status, NT_STATUS_FILE_LOCK_CONFLICT)) {
118                 printf("write succeeded\n");
119                 return false;
120         }
121
122         /*
123          * Kill the lock holder
124          */
125         status = smbXcli_conn_samba_suicide(cli1->conn, 1);
126         if (!NT_STATUS_IS_OK(status)) {
127                 printf("smbXcli_conn_samba_suicide failed: %s\n",
128                        nt_errstr(status));
129                 return false;
130         }
131
132         /*
133          * Right now we don't clean up immediately. Re-open the 2nd connection.
134          */
135 #if 1
136         cli_shutdown(cli2);
137         if (!torture_open_connection(&cli2, 0)) {
138                 return false;
139         }
140         status = cli_ntcreate(
141                 cli2, fname, 0, FILE_GENERIC_READ|FILE_GENERIC_WRITE,
142                 FILE_ATTRIBUTE_NORMAL,
143                 FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
144                 FILE_OPEN, 0, 0, &fnum2);
145         if (!NT_STATUS_IS_OK(status)) {
146                 printf("open of %s failed (%s)\n", fname, nt_errstr(status));
147                 return false;
148         }
149 #endif
150         status = cli_smbwrite(cli2, fnum2, &buf, 0, 1, NULL);
151         if (!NT_STATUS_IS_OK(status)) {
152                 printf("write failed: %s\n", nt_errstr(status));
153                 return false;
154         }
155         return true;
156 }