0d50e94d5777014c6635e9c0b58ca50a6ca9c1f1
[samba.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                 if (ctr->share.info1 == NULL) {
112                         return WERR_NOMEM;
113                 }
114                 
115                 memset(ctr->share.info1, 0, sizeof(SRV_SHARE_INFO_1));
116
117                 for (i = 0; i < ctr->num_entries; i++) {
118                         SRV_SHARE_INFO_1 *info1 = &ctr->share.info1[i];
119                         char *s;
120                         
121                         /* Copy pointer crap */
122
123                         memcpy(&info1->info_1, &r.ctr.share.info1[i].info_1, 
124                                sizeof(SH_INFO_1));
125
126                         /* Duplicate strings */
127
128                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_netname);
129                         if (s)
130                                 init_unistr2(&info1->info_1_str.uni_netname, s, UNI_STR_TERMINATE);
131                 
132                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info1[i].info_1_str.uni_remark);
133                         if (s)
134                                 init_unistr2(&info1->info_1_str.uni_remark, s, UNI_STR_TERMINATE);
135
136                 }               
137
138                 break;
139         case 2:
140                 ctr->share.info2 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_2, ctr->num_entries);
141                 if (ctr->share.info2 == NULL) {
142                         return WERR_NOMEM;
143                 }
144                 
145                 memset(ctr->share.info2, 0, sizeof(SRV_SHARE_INFO_2));
146
147                 for (i = 0; i < ctr->num_entries; i++) {
148                         SRV_SHARE_INFO_2 *info2 = &ctr->share.info2[i];
149                         char *s;
150                         
151                         /* Copy pointer crap */
152
153                         memcpy(&info2->info_2, &r.ctr.share.info2[i].info_2, 
154                                sizeof(SH_INFO_2));
155
156                         /* Duplicate strings */
157
158                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_netname);
159                         if (s)
160                                 init_unistr2(&info2->info_2_str.uni_netname, s, UNI_STR_TERMINATE);
161
162                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_remark);
163                         if (s)
164                                 init_unistr2(&info2->info_2_str.uni_remark, s, UNI_STR_TERMINATE);
165
166                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_path);
167                         if (s)
168                                 init_unistr2(&info2->info_2_str.uni_path, s, UNI_STR_TERMINATE);
169
170                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info2[i].info_2_str.uni_passwd);
171                         if (s)
172                                 init_unistr2(&info2->info_2_str.uni_passwd, s, UNI_STR_TERMINATE);
173                 }
174                 break;
175         /* adding info-level 502 here */
176         case 502:
177                 ctr->share.info502 = TALLOC_ARRAY(mem_ctx, SRV_SHARE_INFO_502, ctr->num_entries);
178
179                 if (ctr->share.info502 == NULL) {
180                         return WERR_NOMEM;
181                 }
182                 
183                 memset(ctr->share.info502, 0, sizeof(SRV_SHARE_INFO_502));
184
185                 for (i = 0; i < ctr->num_entries; i++) {
186                         SRV_SHARE_INFO_502 *info502 = &ctr->share.info502[i];
187                         char *s;
188                         
189                         /* Copy pointer crap */
190                         memcpy(&info502->info_502, &r.ctr.share.info502[i].info_502, 
191                                sizeof(SH_INFO_502));
192
193                         /* Duplicate strings */
194
195                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_netname);
196                         if (s)
197                                 init_unistr2(&info502->info_502_str.uni_netname, s, UNI_STR_TERMINATE);
198
199                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_remark);
200                         if (s)
201                                 init_unistr2(&info502->info_502_str.uni_remark, s, UNI_STR_TERMINATE);
202
203                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_path);
204                         if (s)
205                                 init_unistr2(&info502->info_502_str.uni_path, s, UNI_STR_TERMINATE);
206
207                         s = unistr2_tdup(mem_ctx, &r.ctr.share.info502[i].info_502_str.uni_passwd);
208                         if (s)
209                                 init_unistr2(&info502->info_502_str.uni_passwd, s, UNI_STR_TERMINATE);
210                 
211                         info502->info_502_str.sd = dup_sec_desc(mem_ctx, r.ctr.share.info502[i].info_502_str.sd);
212                 }
213                 break;
214         }
215
216   done:
217
218         return result;
219 }
220
221 WERROR rpccli_srvsvc_net_share_get_info(struct rpc_pipe_client *cli,
222                                      TALLOC_CTX *mem_ctx,
223                                      const char *sharename,
224                                      uint32 info_level,
225                                      SRV_SHARE_INFO *info)
226 {
227         prs_struct qbuf, rbuf;
228         SRV_Q_NET_SHARE_GET_INFO q;
229         SRV_R_NET_SHARE_GET_INFO r;
230         WERROR result = W_ERROR(ERRgeneral);
231         fstring server;
232
233         ZERO_STRUCT(q);
234         ZERO_STRUCT(r);
235
236         /* Initialise input parameters */
237
238         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
239         strupper_m(server);
240
241         init_srv_q_net_share_get_info(&q, server, sharename, info_level);
242
243         /* Marshall data and send request */
244
245         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_GET_INFO,
246                 q, r,
247                 qbuf, rbuf,
248                 srv_io_q_net_share_get_info,
249                 srv_io_r_net_share_get_info,
250                 WERR_GENERAL_FAILURE);
251
252         result = r.status;
253
254         if (!W_ERROR_IS_OK(result))
255                 goto done;
256
257         ZERO_STRUCTP(info);
258
259         info->switch_value = info_level;
260
261         switch(info_level) {
262         case 1:
263         {
264                 SRV_SHARE_INFO_1 *info1 = &info->share.info1;
265                 SH_INFO_1_STR *info1_str = &info1->info_1_str;
266                 
267                 char *s;
268
269                 info->share.info1 = r.info.share.info1;
270
271                 /* Duplicate strings */
272
273                 s = unistr2_tdup(mem_ctx, &info1_str->uni_netname);
274                 if (s)
275                         init_unistr2(&info1_str->uni_netname,
276                                      s, UNI_STR_TERMINATE);
277
278                 s = unistr2_tdup(mem_ctx, &info1_str->uni_remark);
279                 if (s)
280                         init_unistr2(&info1_str->uni_remark,
281                                      s, UNI_STR_TERMINATE);
282
283                 break;
284         }
285         case 2:
286         {
287                 SRV_SHARE_INFO_2 *info2 = &info->share.info2;
288                 SH_INFO_2_STR *info2_str = &info2->info_2_str;
289                 
290                 char *s;
291
292                 info->share.info2 = r.info.share.info2;
293
294                 /* Duplicate strings */
295
296                 s = unistr2_tdup(mem_ctx, &info2_str->uni_netname);
297                 if (s)
298                         init_unistr2(&info2_str->uni_netname,
299                                      s, UNI_STR_TERMINATE);
300
301                 s = unistr2_tdup(mem_ctx, &info2_str->uni_remark);
302                 if (s)
303                         init_unistr2(&info2_str->uni_remark,
304                                      s, UNI_STR_TERMINATE);
305
306                 s = unistr2_tdup(mem_ctx, &info2_str->uni_path);
307                 if (s)
308                         init_unistr2(&info2_str->uni_path,
309                                      s, UNI_STR_TERMINATE);
310
311                 s = unistr2_tdup(mem_ctx, &info2_str->uni_passwd);
312                 if (s)
313                         init_unistr2(&info2_str->uni_passwd,
314                                      s, UNI_STR_TERMINATE);
315
316
317                 break;
318         }
319         case 502:
320         {
321                 SRV_SHARE_INFO_502 *info502 = &info->share.info502;
322                 SH_INFO_502_STR *info502_str = &info502->info_502_str;
323                 
324                 char *s;
325
326                 info->share.info502 = r.info.share.info502;
327
328                 /* Duplicate strings */
329
330                 s = unistr2_tdup(mem_ctx, &info502_str->uni_netname);
331                 if (s)
332                         init_unistr2(&info502_str->uni_netname,
333                                      s, UNI_STR_TERMINATE);
334
335                 s = unistr2_tdup(mem_ctx, &info502_str->uni_remark);
336                 if (s)
337                         init_unistr2(&info502_str->uni_remark,
338                                      s, UNI_STR_TERMINATE);
339
340                 s = unistr2_tdup(mem_ctx, &info502_str->uni_path);
341                 if (s)
342                         init_unistr2(&info502_str->uni_path,
343                                      s, UNI_STR_TERMINATE);
344
345                 s = unistr2_tdup(mem_ctx, &info502_str->uni_passwd);
346                 if (s)
347                         init_unistr2(&info502_str->uni_passwd,
348                                      s, UNI_STR_TERMINATE);
349
350                 info502_str->sd = dup_sec_desc(mem_ctx, info502_str->sd);
351                 break;
352         }
353         default:
354                 DEBUG(0,("unimplemented info-level: %d\n", info_level));
355                 break;
356         }
357
358   done:
359
360         return result;
361 }
362
363 WERROR rpccli_srvsvc_net_share_set_info(struct rpc_pipe_client *cli,
364                                      TALLOC_CTX *mem_ctx,
365                                      const char *sharename,
366                                      uint32 info_level,
367                                      SRV_SHARE_INFO *info)
368 {
369         prs_struct qbuf, rbuf;
370         SRV_Q_NET_SHARE_SET_INFO q;
371         SRV_R_NET_SHARE_SET_INFO r;
372         WERROR result = W_ERROR(ERRgeneral);
373         fstring server;
374
375         ZERO_STRUCT(q);
376         ZERO_STRUCT(r);
377
378         /* Initialise input parameters */
379
380         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
381         strupper_m(server);
382
383         init_srv_q_net_share_set_info(&q, server, sharename, info_level, info);
384
385         /* Marshall data and send request */
386
387         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_SET_INFO,
388                 q, r,
389                 qbuf, rbuf,
390                 srv_io_q_net_share_set_info,
391                 srv_io_r_net_share_set_info,
392                 WERR_GENERAL_FAILURE);
393
394         result = r.status;
395         return result;
396 }
397
398 WERROR rpccli_srvsvc_net_share_del(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
399                                 const char *sharename)
400 {
401         prs_struct qbuf, rbuf;
402         SRV_Q_NET_SHARE_DEL q;
403         SRV_R_NET_SHARE_DEL r;
404         WERROR result = W_ERROR(ERRgeneral);
405         fstring server;
406
407         ZERO_STRUCT(q);
408         ZERO_STRUCT(r);
409
410         /* Initialise input parameters */
411
412         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
413         strupper_m(server);
414
415         init_srv_q_net_share_del(&q, server, sharename);
416
417         /* Marshall data and send request */
418
419         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_DEL,
420                 q, r,
421                 qbuf, rbuf,
422                 srv_io_q_net_share_del,
423                 srv_io_r_net_share_del,
424                 WERR_GENERAL_FAILURE);
425
426         result = r.status;
427         return result;
428 }
429
430 WERROR rpccli_srvsvc_net_share_add(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
431                                 const char *netname, uint32 type, 
432                                 const char *remark, uint32 perms, 
433                                 uint32 max_uses, uint32 num_uses, 
434                                 const char *path, const char *passwd,
435                                 int level, SEC_DESC *sd)
436 {
437         prs_struct qbuf, rbuf;
438         SRV_Q_NET_SHARE_ADD q;
439         SRV_R_NET_SHARE_ADD r;
440         WERROR result = W_ERROR(ERRgeneral);
441         fstring server;
442
443         ZERO_STRUCT(q);
444         ZERO_STRUCT(r);
445
446         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
447         strupper_m(server);
448
449         init_srv_q_net_share_add(&q,server, netname, type, remark,
450                                  perms, max_uses, num_uses, path, passwd, 
451                                  level, sd);
452
453         /* Marshall data and send request */
454
455         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_SHARE_ADD,
456                 q, r,
457                 qbuf, rbuf,
458                 srv_io_q_net_share_add,
459                 srv_io_r_net_share_add,
460                 WERR_GENERAL_FAILURE);
461
462         result = r.status;
463         return result;  
464 }
465
466 WERROR rpccli_srvsvc_net_remote_tod(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
467                                  char *server, TIME_OF_DAY_INFO *tod)
468 {
469         prs_struct qbuf, rbuf;
470         SRV_Q_NET_REMOTE_TOD q;
471         SRV_R_NET_REMOTE_TOD r;
472         WERROR result = W_ERROR(ERRgeneral);
473         fstring server_slash;
474
475         ZERO_STRUCT(q);
476         ZERO_STRUCT(r);
477
478         /* Initialise input parameters */
479
480         slprintf(server_slash, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
481         strupper_m(server_slash);
482
483         init_srv_q_net_remote_tod(&q, server_slash);
484         r.tod = tod;
485
486         /* Marshall data and send request */
487
488         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_REMOTE_TOD,
489                 q, r,
490                 qbuf, rbuf,
491                 srv_io_q_net_remote_tod,
492                 srv_io_r_net_remote_tod,
493                 WERR_GENERAL_FAILURE);
494
495         result = r.status;
496         return result;  
497 }
498
499 WERROR rpccli_srvsvc_net_file_enum(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
500                                 uint32 file_level, const char *user_name,
501                                 SRV_FILE_INFO_CTR *ctr, int preferred_len,
502                                 ENUM_HND *hnd)
503 {
504         prs_struct qbuf, rbuf;
505         SRV_Q_NET_FILE_ENUM q;
506         SRV_R_NET_FILE_ENUM r;
507         WERROR result = W_ERROR(ERRgeneral);
508         fstring server;
509         int i;
510
511         ZERO_STRUCT(q);
512         ZERO_STRUCT(r);
513
514         /* Initialise input parameters */
515
516         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
517         strupper_m(server);
518
519         init_srv_q_net_file_enum(&q, server, NULL, user_name, 
520                                  file_level, ctr, preferred_len, hnd);
521
522         /* Marshall data and send request */
523
524         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_ENUM,
525                 q, r,
526                 qbuf, rbuf,
527                 srv_io_q_net_file_enum,
528                 srv_io_r_net_file_enum,
529                 WERR_GENERAL_FAILURE);
530
531         result = r.status;
532
533         if (!W_ERROR_IS_OK(result))
534                 goto done;
535
536         /* copy the data over to the ctr */
537
538         ZERO_STRUCTP(ctr);
539
540         ctr->switch_value = file_level;
541
542         ctr->num_entries = ctr->num_entries2 = r.ctr.num_entries;
543         
544         switch(file_level) {
545         case 3:
546                 ctr->file.info3 = TALLOC_ARRAY(mem_ctx, SRV_FILE_INFO_3, ctr->num_entries);
547                 if (ctr->file.info3 == NULL) {
548                         return WERR_NOMEM;
549                 }
550
551                 memset(ctr->file.info3, 0, 
552                        sizeof(SRV_FILE_INFO_3) * ctr->num_entries);
553
554                 for (i = 0; i < r.ctr.num_entries; i++) {
555                         SRV_FILE_INFO_3 *info3 = &ctr->file.info3[i];
556                         char *s;
557                         
558                         /* Copy pointer crap */
559
560                         memcpy(&info3->info_3, &r.ctr.file.info3[i].info_3, 
561                                sizeof(FILE_INFO_3));
562
563                         /* Duplicate strings */
564
565                         s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_path_name);
566                         if (s)
567                                 init_unistr2(&info3->info_3_str.uni_path_name, s, UNI_STR_TERMINATE);
568                 
569                         s = unistr2_tdup(mem_ctx, &r.ctr.file.info3[i].info_3_str.uni_user_name);
570                         if (s)
571                                 init_unistr2(&info3->info_3_str.uni_user_name, s, UNI_STR_TERMINATE);
572
573                 }               
574
575                 break;
576         }
577
578   done:
579         return result;
580 }
581
582 WERROR rpccli_srvsvc_net_file_close(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx,
583                                  uint32 file_id)
584 {
585         prs_struct qbuf, rbuf;
586         SRV_Q_NET_FILE_CLOSE q;
587         SRV_R_NET_FILE_CLOSE r;
588         WERROR result = W_ERROR(ERRgeneral);
589         fstring server;
590
591         ZERO_STRUCT(q);
592         ZERO_STRUCT(r);
593
594         /* Initialise input parameters */
595
596         slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost);
597         strupper_m(server);
598
599         init_srv_q_net_file_close(&q, server, file_id);
600
601         /* Marshall data and send request */
602
603         CLI_DO_RPC_WERR(cli, mem_ctx, PI_SRVSVC, SRV_NET_FILE_CLOSE,
604                 q, r,
605                 qbuf, rbuf,
606                 srv_io_q_net_file_close,
607                 srv_io_r_net_file_close,
608                 WERR_GENERAL_FAILURE);
609
610         result = r.status;
611         return result;
612 }