r10656: BIG merge from trunk. Features not copied over
[vlendec/samba-autobuild/.git] / source3 / rpc_client / cli_srvsvc.c
1 /* 
2    Unix SMB/CIFS implementation.
3    NT Domain Authentication SMB / MSRPC client
4    Copyright (C) Andrew Tridgell 1994-2000
5    Copyright (C) Tim Potter 2001
6    Copyright (C) Jim McDonough <jmcd@us.ibm.com> 2002
7    Copyright (C) Jeremy Allison  2005.
8
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 2 of the License, or
12    (at your option) any later version.
13    
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18    
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24 #include "includes.h"
25
26 WERROR rpccli_srvsvc_net_srv_get_info(struct rpc_pipe_client *cli, 
27                                    TALLOC_CTX *mem_ctx,
28                                    uint32 switch_value, SRV_INFO_CTR *ctr)
29 {
30         prs_struct qbuf, rbuf;
31         SRV_Q_NET_SRV_GET_INFO q;
32         SRV_R_NET_SRV_GET_INFO r;
33         WERROR result = W_ERROR(ERRgeneral);
34         fstring server;
35
36         ZERO_STRUCT(q);
37         ZERO_STRUCT(r);
38
39         /* Initialise input parameters */
40
41         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
42         strupper_m(server);
43
44         init_srv_q_net_srv_get_info(&q, server, switch_value);
45         r.ctr = ctr;
46
47         /* Marshall data and send request */
48
49         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SRV_GET_INFO,
50                 q, r,
51                 qbuf, rbuf,
52                 srv_io_q_net_srv_get_info,
53                 srv_io_r_net_srv_get_info,
54                 WERR_GENERAL_FAILURE);
55
56         result = r.status;
57         return result;
58 }
59
60 WERROR rpccli_srvsvc_net_share_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
61                                  uint32 info_level, SRV_SHARE_INFO_CTR *ctr,
62                                  int preferred_len, ENUM_HND *hnd)
63 {
64         prs_struct qbuf, rbuf;
65         SRV_Q_NET_SHARE_ENUM q;
66         SRV_R_NET_SHARE_ENUM r;
67         WERROR result = W_ERROR(ERRgeneral);
68         fstring server;
69         int i;
70
71         ZERO_STRUCT(q);
72         ZERO_STRUCT(r);
73
74         /* Initialise input parameters */
75
76         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
77         strupper_m(server);
78
79         init_srv_q_net_share_enum(&q, server, info_level, preferred_len, hnd);
80
81         /* Marshall data and send request */
82
83         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_ENUM_ALL,
84                 q, r,
85                 qbuf, rbuf,
86                 srv_io_q_net_share_enum,
87                 srv_io_r_net_share_enum,
88                 WERR_GENERAL_FAILURE);
89
90         result = r.status;
91
92         if (!W_ERROR_IS_OK(result))
93                 goto done;
94
95         /* Oh yuck yuck yuck - we have to copy all the info out of the
96            SRV_SHARE_INFO_CTR in the SRV_R_NET_SHARE_ENUM as when we do a
97            prs_mem_free() it will all be invalidated.  The various share
98            info structures suck badly too.  This really is gross. */
99
100         ZERO_STRUCTP(ctr);
101
102         if (!r.ctr.num_entries)
103                 goto done;
104
105         ctr->info_level = info_level;
106         ctr->num_entries = r.ctr.num_entries;
107
108         switch(info_level) {
109         case 1:
110                 ctr->share.info1 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_1, ctr->num_entries);
111                 
112                 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
113
114                 for (i = 0; i < ctr->num_entries; i++) {
115                         SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
116                         char *s;
117                         
118                         /* Copy pointer crap */
119
120                         memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, 
121                                sizeof(SH_INFO_1));
122
123                         /* Duplicate strings */
124
125                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
126                         if (s)
127                                 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
128                 
129                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
130                         if (s)
131                                 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
132
133                 }               
134
135                 break;
136         case 2:
137                 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, ctr->num_entries);
138                 
139                 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
140
141                 for (i = 0; i < ctr->num_entries; i++) {
142                         SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
143                         char *s;
144                         
145                         /* Copy pointer crap */
146
147                         memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, 
148                                sizeof(SH_INFO_2));
149
150                         /* Duplicate strings */
151
152                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname);
153                         if (s)
154                                 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
155
156                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark);
157                         if (s)
158                                 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
159
160                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path);
161                         if (s)
162                                 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
163
164                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd);
165                         if (s)
166                                 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
167                 }
168                 break;
169         /* adding info-level 502 here */
170         case 502:
171                 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, ctr->num_entries);
172                 
173                 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
174
175                 for (i = 0; i < ctr->num_entries; i++) {
176                         SRV_SHARE_INFO_502 *info502 = &ctr->share.info502[i];
177                         char *s;
178                         
179                         /* Copy pointer crap */
180                         memcpy(&info502->info_502, &r.ctr.share.info502[i].info_502, 
181                                sizeof(SH_INFO_502));
182
183                         /* Duplicate strings */
184
185                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_netname);
186                         if (s)
187                                 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
188
189                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_remark);
190                         if (s)
191                                 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
192
193                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_path);
194                         if (s)
195                                 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
196
197                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_passwd);
198                         if (s)
199                                 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
200                 
201                         info502->info_502_str.sd = dup_sec_desc(mem_ctx, r.ctr.share.info502[i].info_502_str.sd);
202                 }
203                 break;
204         }
205
206   done:
207
208         return result;
209 }
210
211 WERROR rpccli_srvsvc_net_share_get_info(struct rpc_pipe_client *cli,
212                                      TALLOC_CTX *mem_ctx,
213                                      const char *sharename,
214                                      uint32 info_level,
215                                      SRV_SHARE_INFO *info)
216 {
217         prs_struct qbuf, rbuf;
218         SRV_Q_NET_SHARE_GET_INFO q;
219         SRV_R_NET_SHARE_GET_INFO r;
220         WERROR result = W_ERROR(ERRgeneral);
221         fstring server;
222
223         ZERO_STRUCT(q);
224         ZERO_STRUCT(r);
225
226         /* Initialise input parameters */
227
228         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
229         strupper_m(server);
230
231         init_srv_q_net_share_get_info(&q, server, sharename, info_level);
232
233         /* Marshall data and send request */
234
235         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_GET_INFO,
236                 q, r,
237                 qbuf, rbuf,
238                 srv_io_q_net_share_get_info,
239                 srv_io_r_net_share_get_info,
240                 WERR_GENERAL_FAILURE);
241
242         result = r.status;
243
244         if (!W_ERROR_IS_OK(result))
245                 goto done;
246
247         ZERO_STRUCTP(info);
248
249         info->switch_value = info_level;
250
251         switch(info_level) {
252         case 1:
253         {
254                 SRV_SHARE_INFO_1 *info1 = &info->share.info1;
255                 SH_INFO_1_STR *info1_str = &info1->info_1_str;
256                 
257                 char *s;
258
259                 info->share.info1 = r.info.share.info1;
260
261                 /* Duplicate strings */
262
263                 s = unistr2_tdup(mem_ctx, &info1_str->uni_netname);
264                 if (s)
265                         init_unistr2(&info1_str->uni_netname,
266                                      s, UNI_STR_TERMINATE);
267
268                 s = unistr2_tdup(mem_ctx, &info1_str->uni_remark);
269                 if (s)
270                         init_unistr2(&info1_str->uni_remark,
271                                      s, UNI_STR_TERMINATE);
272
273                 break;
274         }
275         case 2:
276         {
277                 SRV_SHARE_INFO_2 *info2 = &info->share.info2;
278                 SH_INFO_2_STR *info2_str = &info2->info_2_str;
279                 
280                 char *s;
281
282                 info->share.info2 = r.info.share.info2;
283
284                 /* Duplicate strings */
285
286                 s = unistr2_tdup(mem_ctx, &info2_str->uni_netname);
287                 if (s)
288                         init_unistr2(&info2_str->uni_netname,
289                                      s, UNI_STR_TERMINATE);
290
291                 s = unistr2_tdup(mem_ctx, &info2_str->uni_remark);
292                 if (s)
293                         init_unistr2(&info2_str->uni_remark,
294                                      s, UNI_STR_TERMINATE);
295
296                 s = unistr2_tdup(mem_ctx, &info2_str->uni_path);
297                 if (s)
298                         init_unistr2(&info2_str->uni_path,
299                                      s, UNI_STR_TERMINATE);
300
301                 s = unistr2_tdup(mem_ctx, &info2_str->uni_passwd);
302                 if (s)
303                         init_unistr2(&info2_str->uni_passwd,
304                                      s, UNI_STR_TERMINATE);
305
306
307                 break;
308         }
309         case 502:
310         {
311                 SRV_SHARE_INFO_502 *info502 = &info->share.info502;
312                 SH_INFO_502_STR *info502_str = &info502->info_502_str;
313                 
314                 char *s;
315
316                 info->share.info502 = r.info.share.info502;
317
318                 /* Duplicate strings */
319
320                 s = unistr2_tdup(mem_ctx, &info502_str->uni_netname);
321                 if (s)
322                         init_unistr2(&info502_str->uni_netname,
323                                      s, UNI_STR_TERMINATE);
324
325                 s = unistr2_tdup(mem_ctx, &info502_str->uni_remark);
326                 if (s)
327                         init_unistr2(&info502_str->uni_remark,
328                                      s, UNI_STR_TERMINATE);
329
330                 s = unistr2_tdup(mem_ctx, &info502_str->uni_path);
331                 if (s)
332                         init_unistr2(&info502_str->uni_path,
333                                      s, UNI_STR_TERMINATE);
334
335                 s = unistr2_tdup(mem_ctx, &info502_str->uni_passwd);
336                 if (s)
337                         init_unistr2(&info502_str->uni_passwd,
338                                      s, UNI_STR_TERMINATE);
339
340                 info502_str->sd = dup_sec_desc(mem_ctx, info502_str->sd);
341                 break;
342         }
343         default:
344                 DEBUG(0,("unimplemented info-level: %d\n", info_level));
345                 break;
346         }
347
348   done:
349
350         return result;
351 }
352
353 WERROR rpccli_srvsvc_net_share_set_info(struct rpc_pipe_client *cli,
354                                      TALLOC_CTX *mem_ctx,
355                                      const char *sharename,
356                                      uint32 info_level,
357                                      SRV_SHARE_INFO *info)
358 {
359         prs_struct qbuf, rbuf;
360         SRV_Q_NET_SHARE_SET_INFO q;
361         SRV_R_NET_SHARE_SET_INFO r;
362         WERROR result = W_ERROR(ERRgeneral);
363         fstring server;
364
365         ZERO_STRUCT(q);
366         ZERO_STRUCT(r);
367
368         /* Initialise input parameters */
369
370         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
371         strupper_m(server);
372
373         init_srv_q_net_share_set_info(&q, server, sharename, info_level, info);
374
375         /* Marshall data and send request */
376
377         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_SET_INFO,
378                 q, r,
379                 qbuf, rbuf,
380                 srv_io_q_net_share_set_info,
381                 srv_io_r_net_share_set_info,
382                 WERR_GENERAL_FAILURE);
383
384         result = r.status;
385         return result;
386 }
387
388 WERROR rpccli_srvsvc_net_share_del(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
389                                 const char *sharename)
390 {
391         prs_struct qbuf, rbuf;
392         SRV_Q_NET_SHARE_DEL q;
393         SRV_R_NET_SHARE_DEL r;
394         WERROR result = W_ERROR(ERRgeneral);
395         fstring server;
396
397         ZERO_STRUCT(q);
398         ZERO_STRUCT(r);
399
400         /* Initialise input parameters */
401
402         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
403         strupper_m(server);
404
405         init_srv_q_net_share_del(&q, server, sharename);
406
407         /* Marshall data and send request */
408
409         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_DEL,
410                 q, r,
411                 qbuf, rbuf,
412                 srv_io_q_net_share_del,
413                 srv_io_r_net_share_del,
414                 WERR_GENERAL_FAILURE);
415
416         result = r.status;
417         return result;
418 }
419
420 WERROR rpccli_srvsvc_net_share_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
421                                 const char *netname, uint32 type, 
422                                 const char *remark, uint32 perms, 
423                                 uint32 max_uses, uint32 num_uses, 
424                                 const char *path, const char *passwd,
425                                 int level, SEC_DESC *sd)
426 {
427         prs_struct qbuf, rbuf;
428         SRV_Q_NET_SHARE_ADD q;
429         SRV_R_NET_SHARE_ADD r;
430         WERROR result = W_ERROR(ERRgeneral);
431         fstring server;
432
433         ZERO_STRUCT(q);
434         ZERO_STRUCT(r);
435
436         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
437         strupper_m(server);
438
439         init_srv_q_net_share_add(&q,server, netname, type, remark,
440                                  perms, max_uses, num_uses, path, passwd, 
441                                  level, sd);
442
443         /* Marshall data and send request */
444
445         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_ADD,
446                 q, r,
447                 qbuf, rbuf,
448                 srv_io_q_net_share_add,
449                 srv_io_r_net_share_add,
450                 WERR_GENERAL_FAILURE);
451
452         result = r.status;
453         return result;  
454 }
455
456 WERROR rpccli_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
457                                  char *server, TIME_OF_DAY_INFO *tod)
458 {
459         prs_struct qbuf, rbuf;
460         SRV_Q_NET_REMOTE_TOD q;
461         SRV_R_NET_REMOTE_TOD r;
462         WERROR result = W_ERROR(ERRgeneral);
463         fstring server_slash;
464
465         ZERO_STRUCT(q);
466         ZERO_STRUCT(r);
467
468         /* Initialise input parameters */
469
470         slprintf(server_slash, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
471         strupper_m(server_slash);
472
473         init_srv_q_net_remote_tod(&q, server_slash);
474         r.tod = tod;
475
476         /* Marshall data and send request */
477
478         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_REMOTE_TOD,
479                 q, r,
480                 qbuf, rbuf,
481                 srv_io_q_net_remote_tod,
482                 srv_io_r_net_remote_tod,
483                 WERR_GENERAL_FAILURE);
484
485         result = r.status;
486         return result;  
487 }
488
489 WERROR rpccli_srvsvc_net_file_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
490                                 uint32 file_level, const char *user_name,
491                                 SRV_FILE_INFO_CTR *ctr, int preferred_len,
492                                 ENUM_HND *hnd)
493 {
494         prs_struct qbuf, rbuf;
495         SRV_Q_NET_FILE_ENUM q;
496         SRV_R_NET_FILE_ENUM r;
497         WERROR result = W_ERROR(ERRgeneral);
498         fstring server;
499         int i;
500
501         ZERO_STRUCT(q);
502         ZERO_STRUCT(r);
503
504         /* Initialise input parameters */
505
506         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
507         strupper_m(server);
508
509         init_srv_q_net_file_enum(&q, server, NULL, user_name, 
510                                  file_level, ctr, preferred_len, hnd);
511
512         /* Marshall data and send request */
513
514         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_ENUM,
515                 q, r,
516                 qbuf, rbuf,
517                 srv_io_q_net_file_enum,
518                 srv_io_r_net_file_enum,
519                 WERR_GENERAL_FAILURE);
520
521         result = r.status;
522
523         if (!W_ERROR_IS_OK(result))
524                 goto done;
525
526         /* copy the data over to the ctr */
527
528         ZERO_STRUCTP(ctr);
529
530         ctr->switch_value = file_level;
531
532         ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries;
533         
534         switch(file_level) {
535         case 3:
536                 ctr->file.info3 = TALLOC_ARRAY(mem_ctx, SRV_FILE_INFO_3, ctr->num_entries);
537
538                 memset(ctr->file.info3, 0, 
539                        sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
540
541                 for (i = 0; i < r.ctr.num_entries; i++) {
542                         SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i];
543                         char *s;
544                         
545                         /* Copy pointer crap */
546
547                         memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, 
548                                sizeof(FILE_INFO_3));
549
550                         /* Duplicate strings */
551
552                         s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name);
553                         if (s)
554                                 init_unistr2(&info3->info_3_str.uni_path_name, s, UNI_STR_TERMINATE);
555                 
556                         s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name);
557                         if (s)
558                                 init_unistr2(&info3->info_3_str.uni_user_name, s, UNI_STR_TERMINATE);
559
560                 }               
561
562                 break;
563         }
564
565   done:
566         return result;
567 }
568
569 WERROR rpccli_srvsvc_net_file_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
570                                  uint32 file_id)
571 {
572         prs_struct qbuf, rbuf;
573         SRV_Q_NET_FILE_CLOSE q;
574         SRV_R_NET_FILE_CLOSE r;
575         WERROR result = W_ERROR(ERRgeneral);
576         fstring server;
577
578         ZERO_STRUCT(q);
579         ZERO_STRUCT(r);
580
581         /* Initialise input parameters */
582
583         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
584         strupper_m(server);
585
586         init_srv_q_net_file_close(&q, server, file_id);
587
588         /* Marshall data and send request */
589
590         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_CLOSE,
591                 q, r,
592                 qbuf, rbuf,
593                 srv_io_q_net_file_close,
594                 srv_io_r_net_file_close,
595                 WERR_GENERAL_FAILURE);
596
597         result = r.status;
598         return result;
599 }