/src/samba/source3/lib/netapi/file.c
Line | Count | Source |
1 | | /* |
2 | | * Unix SMB/CIFS implementation. |
3 | | * NetApi File Support |
4 | | * Copyright (C) Guenther Deschner 2008 |
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 | | |
22 | | #include "librpc/gen_ndr/libnetapi.h" |
23 | | #include "lib/netapi/netapi.h" |
24 | | #include "lib/netapi/netapi_private.h" |
25 | | #include "lib/netapi/libnetapi.h" |
26 | | #include "../librpc/gen_ndr/ndr_srvsvc_c.h" |
27 | | |
28 | | /**************************************************************** |
29 | | ****************************************************************/ |
30 | | |
31 | | WERROR NetFileClose_r(struct libnetapi_ctx *ctx, |
32 | | struct NetFileClose *r) |
33 | 0 | { |
34 | 0 | WERROR werr; |
35 | 0 | NTSTATUS status; |
36 | 0 | struct dcerpc_binding_handle *b; |
37 | |
|
38 | 0 | werr = libnetapi_get_binding_handle(ctx, r->in.server_name, |
39 | 0 | &ndr_table_srvsvc, |
40 | 0 | &b); |
41 | 0 | if (!W_ERROR_IS_OK(werr)) { |
42 | 0 | goto done; |
43 | 0 | } |
44 | | |
45 | 0 | status = dcerpc_srvsvc_NetFileClose(b, talloc_tos(), |
46 | 0 | r->in.server_name, |
47 | 0 | r->in.fileid, |
48 | 0 | &werr); |
49 | 0 | if (!NT_STATUS_IS_OK(status)) { |
50 | 0 | werr = ntstatus_to_werror(status); |
51 | 0 | goto done; |
52 | 0 | } |
53 | | |
54 | 0 | done: |
55 | 0 | return werr; |
56 | 0 | } |
57 | | |
58 | | /**************************************************************** |
59 | | ****************************************************************/ |
60 | | |
61 | | WERROR NetFileClose_l(struct libnetapi_ctx *ctx, |
62 | | struct NetFileClose *r) |
63 | 0 | { |
64 | 0 | LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetFileClose); |
65 | 0 | } |
66 | | |
67 | | /**************************************************************** |
68 | | ****************************************************************/ |
69 | | |
70 | | static NTSTATUS map_srvsvc_FileInfo_to_FILE_INFO_buffer(TALLOC_CTX *mem_ctx, |
71 | | uint32_t level, |
72 | | union srvsvc_NetFileInfo *info, |
73 | | uint8_t **buffer, |
74 | | uint32_t *num_entries) |
75 | 0 | { |
76 | 0 | struct FILE_INFO_2 i2; |
77 | 0 | struct FILE_INFO_3 i3; |
78 | |
|
79 | 0 | switch (level) { |
80 | 0 | case 2: |
81 | 0 | i2.fi2_id = info->info2->fid; |
82 | |
|
83 | 0 | ADD_TO_ARRAY(mem_ctx, struct FILE_INFO_2, i2, |
84 | 0 | (struct FILE_INFO_2 **)buffer, |
85 | 0 | num_entries); |
86 | 0 | break; |
87 | 0 | case 3: |
88 | 0 | i3.fi3_id = info->info3->fid; |
89 | 0 | i3.fi3_permissions = info->info3->permissions; |
90 | 0 | i3.fi3_num_locks = info->info3->num_locks; |
91 | 0 | i3.fi3_pathname = talloc_strdup(mem_ctx, info->info3->path); |
92 | 0 | i3.fi3_username = talloc_strdup(mem_ctx, info->info3->user); |
93 | |
|
94 | 0 | NT_STATUS_HAVE_NO_MEMORY(i3.fi3_pathname); |
95 | 0 | NT_STATUS_HAVE_NO_MEMORY(i3.fi3_username); |
96 | | |
97 | 0 | ADD_TO_ARRAY(mem_ctx, struct FILE_INFO_3, i3, |
98 | 0 | (struct FILE_INFO_3 **)buffer, |
99 | 0 | num_entries); |
100 | 0 | break; |
101 | 0 | default: |
102 | 0 | return NT_STATUS_INVALID_INFO_CLASS; |
103 | 0 | } |
104 | | |
105 | 0 | return NT_STATUS_OK; |
106 | 0 | } |
107 | | |
108 | | /**************************************************************** |
109 | | ****************************************************************/ |
110 | | |
111 | | WERROR NetFileGetInfo_r(struct libnetapi_ctx *ctx, |
112 | | struct NetFileGetInfo *r) |
113 | 0 | { |
114 | 0 | WERROR werr; |
115 | 0 | NTSTATUS status; |
116 | 0 | union srvsvc_NetFileInfo info; |
117 | 0 | uint32_t num_entries = 0; |
118 | 0 | struct dcerpc_binding_handle *b; |
119 | |
|
120 | 0 | if (!r->out.buffer) { |
121 | 0 | return WERR_INVALID_PARAMETER; |
122 | 0 | } |
123 | | |
124 | 0 | switch (r->in.level) { |
125 | 0 | case 2: |
126 | 0 | case 3: |
127 | 0 | break; |
128 | 0 | default: |
129 | 0 | return WERR_INVALID_LEVEL; |
130 | 0 | } |
131 | | |
132 | 0 | werr = libnetapi_get_binding_handle(ctx, r->in.server_name, |
133 | 0 | &ndr_table_srvsvc, |
134 | 0 | &b); |
135 | 0 | if (!W_ERROR_IS_OK(werr)) { |
136 | 0 | goto done; |
137 | 0 | } |
138 | | |
139 | 0 | status = dcerpc_srvsvc_NetFileGetInfo(b, talloc_tos(), |
140 | 0 | r->in.server_name, |
141 | 0 | r->in.fileid, |
142 | 0 | r->in.level, |
143 | 0 | &info, |
144 | 0 | &werr); |
145 | 0 | if (!NT_STATUS_IS_OK(status)) { |
146 | 0 | werr = ntstatus_to_werror(status); |
147 | 0 | goto done; |
148 | 0 | } |
149 | | |
150 | 0 | if (!W_ERROR_IS_OK(werr)) { |
151 | 0 | goto done; |
152 | 0 | } |
153 | | |
154 | 0 | status = map_srvsvc_FileInfo_to_FILE_INFO_buffer(ctx, |
155 | 0 | r->in.level, |
156 | 0 | &info, |
157 | 0 | r->out.buffer, |
158 | 0 | &num_entries); |
159 | 0 | if (!NT_STATUS_IS_OK(status)) { |
160 | 0 | werr = ntstatus_to_werror(status); |
161 | 0 | goto done; |
162 | 0 | } |
163 | 0 | done: |
164 | 0 | return werr; |
165 | 0 | } |
166 | | |
167 | | /**************************************************************** |
168 | | ****************************************************************/ |
169 | | |
170 | | WERROR NetFileGetInfo_l(struct libnetapi_ctx *ctx, |
171 | | struct NetFileGetInfo *r) |
172 | 0 | { |
173 | 0 | LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetFileGetInfo); |
174 | 0 | } |
175 | | |
176 | | /**************************************************************** |
177 | | ****************************************************************/ |
178 | | |
179 | | WERROR NetFileEnum_r(struct libnetapi_ctx *ctx, |
180 | | struct NetFileEnum *r) |
181 | 0 | { |
182 | 0 | WERROR werr; |
183 | 0 | NTSTATUS status; |
184 | 0 | struct srvsvc_NetFileInfoCtr info_ctr; |
185 | 0 | struct srvsvc_NetFileCtr2 ctr2; |
186 | 0 | struct srvsvc_NetFileCtr3 ctr3; |
187 | 0 | uint32_t num_entries = 0; |
188 | 0 | uint32_t i; |
189 | 0 | struct dcerpc_binding_handle *b; |
190 | |
|
191 | 0 | if (!r->out.buffer) { |
192 | 0 | return WERR_INVALID_PARAMETER; |
193 | 0 | } |
194 | | |
195 | 0 | switch (r->in.level) { |
196 | 0 | case 2: |
197 | 0 | case 3: |
198 | 0 | break; |
199 | 0 | default: |
200 | 0 | return WERR_INVALID_LEVEL; |
201 | 0 | } |
202 | | |
203 | 0 | werr = libnetapi_get_binding_handle(ctx, r->in.server_name, |
204 | 0 | &ndr_table_srvsvc, |
205 | 0 | &b); |
206 | 0 | if (!W_ERROR_IS_OK(werr)) { |
207 | 0 | goto done; |
208 | 0 | } |
209 | | |
210 | 0 | ZERO_STRUCT(info_ctr); |
211 | |
|
212 | 0 | info_ctr.level = r->in.level; |
213 | 0 | switch (r->in.level) { |
214 | 0 | case 2: |
215 | 0 | ZERO_STRUCT(ctr2); |
216 | 0 | info_ctr.ctr.ctr2 = &ctr2; |
217 | 0 | break; |
218 | 0 | case 3: |
219 | 0 | ZERO_STRUCT(ctr3); |
220 | 0 | info_ctr.ctr.ctr3 = &ctr3; |
221 | 0 | break; |
222 | 0 | } |
223 | | |
224 | 0 | status = dcerpc_srvsvc_NetFileEnum(b, talloc_tos(), |
225 | 0 | r->in.server_name, |
226 | 0 | r->in.base_path, |
227 | 0 | r->in.user_name, |
228 | 0 | &info_ctr, |
229 | 0 | r->in.prefmaxlen, |
230 | 0 | r->out.total_entries, |
231 | 0 | r->out.resume_handle, |
232 | 0 | &werr); |
233 | 0 | if (!NT_STATUS_IS_OK(status)) { |
234 | 0 | werr = ntstatus_to_werror(status); |
235 | 0 | goto done; |
236 | 0 | } |
237 | | |
238 | 0 | if (!W_ERROR_IS_OK(werr) && !W_ERROR_EQUAL(werr, WERR_MORE_DATA)) { |
239 | 0 | goto done; |
240 | 0 | } |
241 | | |
242 | 0 | for (i=0; i < info_ctr.ctr.ctr2->count; i++) { |
243 | 0 | union srvsvc_NetFileInfo _i = {0}; |
244 | 0 | switch (r->in.level) { |
245 | 0 | case 2: |
246 | 0 | _i.info2 = &info_ctr.ctr.ctr2->array[i]; |
247 | 0 | break; |
248 | 0 | case 3: |
249 | 0 | _i.info3 = &info_ctr.ctr.ctr3->array[i]; |
250 | 0 | break; |
251 | 0 | } |
252 | | |
253 | 0 | status = map_srvsvc_FileInfo_to_FILE_INFO_buffer(ctx, |
254 | 0 | r->in.level, |
255 | 0 | &_i, |
256 | 0 | r->out.buffer, |
257 | 0 | &num_entries); |
258 | 0 | if (!NT_STATUS_IS_OK(status)) { |
259 | 0 | werr = ntstatus_to_werror(status); |
260 | 0 | goto done; |
261 | 0 | } |
262 | 0 | } |
263 | | |
264 | 0 | if (r->out.entries_read) { |
265 | 0 | *r->out.entries_read = num_entries; |
266 | 0 | } |
267 | |
|
268 | 0 | if (r->out.total_entries) { |
269 | 0 | *r->out.total_entries = num_entries; |
270 | 0 | } |
271 | |
|
272 | 0 | done: |
273 | 0 | return werr; |
274 | 0 | } |
275 | | |
276 | | /**************************************************************** |
277 | | ****************************************************************/ |
278 | | |
279 | | WERROR NetFileEnum_l(struct libnetapi_ctx *ctx, |
280 | | struct NetFileEnum *r) |
281 | 0 | { |
282 | 0 | LIBNETAPI_REDIRECT_TO_LOCALHOST(ctx, r, NetFileEnum); |
283 | 0 | } |