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