source: vendor/3.6.0/source4/libcli/smb2/util.c

Last change on this file was 740, checked in by Silvan Scherrer, 13 years ago

Samba Server: update vendor to 3.6.0

File size: 5.9 KB
Line 
1/*
2 Unix SMB/CIFS implementation.
3
4 SMB2 client utility functions
5
6 Copyright (C) Andrew Tridgell 2005
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
20*/
21
22#include "includes.h"
23#include "libcli/raw/libcliraw.h"
24#include "libcli/raw/raw_proto.h"
25#include "libcli/smb2/smb2.h"
26#include "libcli/smb2/smb2_calls.h"
27#include "libcli/smb_composite/smb_composite.h"
28#include "librpc/gen_ndr/ndr_security.h"
29
30/*
31 simple close wrapper with SMB2
32*/
33NTSTATUS smb2_util_close(struct smb2_tree *tree, struct smb2_handle h)
34{
35 struct smb2_close c;
36
37 ZERO_STRUCT(c);
38 c.in.file.handle = h;
39
40 return smb2_close(tree, &c);
41}
42
43/*
44 unlink a file with SMB2
45*/
46NTSTATUS smb2_util_unlink(struct smb2_tree *tree, const char *fname)
47{
48 union smb_unlink io;
49
50 ZERO_STRUCT(io);
51 io.unlink.in.pattern = fname;
52
53 return smb2_composite_unlink(tree, &io);
54}
55
56
57/*
58 rmdir with SMB2
59*/
60NTSTATUS smb2_util_rmdir(struct smb2_tree *tree, const char *dname)
61{
62 struct smb_rmdir io;
63
64 ZERO_STRUCT(io);
65 io.in.path = dname;
66
67 return smb2_composite_rmdir(tree, &io);
68}
69
70
71/*
72 mkdir with SMB2
73*/
74NTSTATUS smb2_util_mkdir(struct smb2_tree *tree, const char *dname)
75{
76 union smb_mkdir io;
77
78 ZERO_STRUCT(io);
79 io.mkdir.level = RAW_MKDIR_MKDIR;
80 io.mkdir.in.path = dname;
81
82 return smb2_composite_mkdir(tree, &io);
83}
84
85
86/*
87 set file attribute with SMB2
88*/
89NTSTATUS smb2_util_setatr(struct smb2_tree *tree, const char *name, uint32_t attrib)
90{
91 union smb_setfileinfo io;
92
93 ZERO_STRUCT(io);
94 io.basic_info.level = RAW_SFILEINFO_BASIC_INFORMATION;
95 io.basic_info.in.file.path = name;
96 io.basic_info.in.attrib = attrib;
97
98 return smb2_composite_setpathinfo(tree, &io);
99}
100
101
102
103
104/*
105 recursively descend a tree deleting all files
106 returns the number of files deleted, or -1 on error
107*/
108int smb2_deltree(struct smb2_tree *tree, const char *dname)
109{
110 NTSTATUS status;
111 uint32_t total_deleted = 0;
112 unsigned int count, i;
113 union smb_search_data *list;
114 TALLOC_CTX *tmp_ctx = talloc_new(tree);
115 struct smb2_find f;
116 struct smb2_create create_parm;
117 bool did_delete;
118
119 /* it might be a file */
120 status = smb2_util_unlink(tree, dname);
121 if (NT_STATUS_IS_OK(status)) {
122 talloc_free(tmp_ctx);
123 return 1;
124 }
125 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
126 NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_PATH_NOT_FOUND) ||
127 NT_STATUS_EQUAL(status, NT_STATUS_NO_SUCH_FILE)) {
128 talloc_free(tmp_ctx);
129 return 0;
130 }
131
132 if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
133 /* it could be read-only */
134 status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
135 status = smb2_util_unlink(tree, dname);
136 }
137 if (NT_STATUS_IS_OK(status)) {
138 talloc_free(tmp_ctx);
139 return 1;
140 }
141
142 ZERO_STRUCT(create_parm);
143 create_parm.in.desired_access = SEC_FILE_READ_DATA;
144 create_parm.in.share_access =
145 NTCREATEX_SHARE_ACCESS_READ|
146 NTCREATEX_SHARE_ACCESS_WRITE;
147 create_parm.in.create_options = NTCREATEX_OPTIONS_DIRECTORY;
148 create_parm.in.create_disposition = NTCREATEX_DISP_OPEN;
149 create_parm.in.fname = dname;
150
151 status = smb2_create(tree, tmp_ctx, &create_parm);
152 if (NT_STATUS_IS_ERR(status)) {
153 DEBUG(2,("Failed to open %s - %s\n", dname, nt_errstr(status)));
154 talloc_free(tmp_ctx);
155 return -1;
156 }
157
158
159 do {
160 did_delete = false;
161
162 ZERO_STRUCT(f);
163 f.in.file.handle = create_parm.out.file.handle;
164 f.in.max_response_size = 0x10000;
165 f.in.level = SMB2_FIND_NAME_INFO;
166 f.in.pattern = "*";
167
168 status = smb2_find_level(tree, tmp_ctx, &f, &count, &list);
169 if (NT_STATUS_IS_ERR(status)) {
170 DEBUG(2,("Failed to list %s - %s\n",
171 dname, nt_errstr(status)));
172 smb2_util_close(tree, create_parm.out.file.handle);
173 talloc_free(tmp_ctx);
174 return -1;
175 }
176
177 for (i=0;i<count;i++) {
178 char *name;
179 if (strcmp(".", list[i].name_info.name.s) == 0 ||
180 strcmp("..", list[i].name_info.name.s) == 0) {
181 continue;
182 }
183 name = talloc_asprintf(tmp_ctx, "%s\\%s", dname, list[i].name_info.name.s);
184 status = smb2_util_unlink(tree, name);
185 if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
186 /* it could be read-only */
187 status = smb2_util_setatr(tree, name, FILE_ATTRIBUTE_NORMAL);
188 status = smb2_util_unlink(tree, name);
189 }
190
191 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
192 int ret;
193 ret = smb2_deltree(tree, name);
194 if (ret > 0) total_deleted += ret;
195 }
196 talloc_free(name);
197 if (NT_STATUS_IS_OK(status)) {
198 total_deleted++;
199 did_delete = true;
200 }
201 }
202 } while (did_delete);
203
204 smb2_util_close(tree, create_parm.out.file.handle);
205
206 status = smb2_util_rmdir(tree, dname);
207 if (NT_STATUS_EQUAL(status, NT_STATUS_CANNOT_DELETE)) {
208 /* it could be read-only */
209 status = smb2_util_setatr(tree, dname, FILE_ATTRIBUTE_NORMAL);
210 status = smb2_util_rmdir(tree, dname);
211 }
212
213 if (NT_STATUS_IS_ERR(status)) {
214 DEBUG(2,("Failed to delete %s - %s\n",
215 dname, nt_errstr(status)));
216 talloc_free(tmp_ctx);
217 return -1;
218 }
219
220 talloc_free(tmp_ctx);
221
222 return total_deleted;
223}
224
225/*
226 check if two SMB2 file handles are the same
227*/
228bool smb2_util_handle_equal(const struct smb2_handle h1,
229 const struct smb2_handle h2)
230{
231 return (h1.data[0] == h2.data[0]) && (h1.data[1] == h2.data[1]);
232}
Note: See TracBrowser for help on using the repository browser.