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