r5591: Implement "net rpc trustdom del", including client side of
[tprouty/samba.git] / source3 / rpc_client / cli_samr.c
1 /* 
2    Unix SMB/CIFS implementation.
3    RPC pipe client
4    Copyright (C) Tim Potter                        2000-2001,
5    Copyright (C) Andrew Tridgell              1992-1997,2000,
6    Copyright (C) Luke Kenneth Casson Leighton 1996-1997,2000,
7    Copyright (C) Paul Ashton                       1997,2000,
8    Copyright (C) Elrond                                 2000,
9    Copyright (C) Rafal Szczesniak                       2002.
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 2 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, write to the Free Software
23    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24 */
25
26 #include "includes.h"
27
28 /* Connect to SAMR database */
29
30 NTSTATUS cli_samr_connect(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
31                           uint32 access_mask, POLICY_HND *connect_pol)
32 {
33         prs_struct qbuf, rbuf;
34         SAMR_Q_CONNECT q;
35         SAMR_R_CONNECT r;
36         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
37
38         DEBUG(10,("cli_samr_connect to %s\n", cli->desthost));
39
40         ZERO_STRUCT(q);
41         ZERO_STRUCT(r);
42
43         /* Initialise parse structures */
44
45         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
46         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
47
48         /* Marshall data and send request */
49
50         init_samr_q_connect(&q, cli->desthost, access_mask);
51
52         if (!samr_io_q_connect("", &q, &qbuf, 0) ||
53             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT, &qbuf, &rbuf))
54                 goto done;
55
56         /* Unmarshall response */
57
58         if (!samr_io_r_connect("", &r, &rbuf, 0))
59                 goto done;
60
61         /* Return output parameters */
62
63         if (NT_STATUS_IS_OK(result = r.status)) {
64                 *connect_pol = r.connect_pol;
65 #ifdef __INSURE__
66                 connect_pol->marker = malloc(1);
67 #endif
68         }
69
70  done:
71         prs_mem_free(&qbuf);
72         prs_mem_free(&rbuf);
73
74         return result;
75 }
76
77 /* Connect to SAMR database */
78
79 NTSTATUS cli_samr_connect4(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
80                            uint32 access_mask, POLICY_HND *connect_pol)
81 {
82         prs_struct qbuf, rbuf;
83         SAMR_Q_CONNECT4 q;
84         SAMR_R_CONNECT4 r;
85         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
86
87         DEBUG(10,("cli_samr_connect4 to %s\n", cli->desthost));
88
89         ZERO_STRUCT(q);
90         ZERO_STRUCT(r);
91
92         /* Initialise parse structures */
93
94         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
95         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
96
97         /* Marshall data and send request */
98
99         init_samr_q_connect4(&q, cli->desthost, access_mask);
100
101         if (!samr_io_q_connect4("", &q, &qbuf, 0) ||
102             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CONNECT4, &qbuf, &rbuf))
103                 goto done;
104
105         /* Unmarshall response */
106
107         if (!samr_io_r_connect4("", &r, &rbuf, 0))
108                 goto done;
109
110         /* Return output parameters */
111
112         if (NT_STATUS_IS_OK(result = r.status)) {
113                 *connect_pol = r.connect_pol;
114 #ifdef __INSURE__
115                 connect_pol->marker = malloc(1);
116 #endif
117         }
118
119  done:
120         prs_mem_free(&qbuf);
121         prs_mem_free(&rbuf);
122
123         return result;
124 }
125
126 /* Close SAMR handle */
127
128 NTSTATUS cli_samr_close(struct cli_state *cli, TALLOC_CTX *mem_ctx,
129                         POLICY_HND *connect_pol)
130 {
131         prs_struct qbuf, rbuf;
132         SAMR_Q_CLOSE_HND q;
133         SAMR_R_CLOSE_HND r;
134         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
135
136         DEBUG(10,("cli_samr_close\n"));
137
138         ZERO_STRUCT(q);
139         ZERO_STRUCT(r);
140
141         /* Initialise parse structures */
142
143         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
144         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
145
146         /* Marshall data and send request */
147
148         init_samr_q_close_hnd(&q, connect_pol);
149
150         if (!samr_io_q_close_hnd("", &q, &qbuf, 0) ||
151             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CLOSE_HND, &qbuf, &rbuf))
152                 goto done;
153
154         /* Unmarshall response */
155
156         if (!samr_io_r_close_hnd("", &r, &rbuf, 0))
157                 goto done;
158
159         /* Return output parameters */
160
161         if (NT_STATUS_IS_OK(result = r.status)) {
162 #ifdef __INSURE__
163                 SAFE_FREE(connect_pol->marker);
164 #endif
165                 *connect_pol = r.pol;
166         }
167
168  done:
169         prs_mem_free(&qbuf);
170         prs_mem_free(&rbuf);
171
172         return result;
173 }
174
175 /* Open handle on a domain */
176
177 NTSTATUS cli_samr_open_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
178                               POLICY_HND *connect_pol, uint32 access_mask, 
179                               const DOM_SID *domain_sid, POLICY_HND *domain_pol)
180 {
181         prs_struct qbuf, rbuf;
182         SAMR_Q_OPEN_DOMAIN q;
183         SAMR_R_OPEN_DOMAIN r;
184         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
185
186         DEBUG(10,("cli_samr_open_domain with sid %s\n", sid_string_static(domain_sid) ));
187
188         ZERO_STRUCT(q);
189         ZERO_STRUCT(r);
190
191         /* Initialise parse structures */
192
193         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
194         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
195
196         /* Marshall data and send request */
197
198         init_samr_q_open_domain(&q, connect_pol, access_mask, domain_sid);
199
200         if (!samr_io_q_open_domain("", &q, &qbuf, 0) ||
201             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_DOMAIN, &qbuf, &rbuf))
202                 goto done;
203
204         /* Unmarshall response */
205
206         if (!samr_io_r_open_domain("", &r, &rbuf, 0))
207                 goto done;
208
209         /* Return output parameters */
210
211         if (NT_STATUS_IS_OK(result = r.status)) {
212                 *domain_pol = r.domain_pol;
213 #ifdef __INSURE__
214                 domain_pol->marker = malloc(1);
215 #endif
216         }
217
218  done:
219         prs_mem_free(&qbuf);
220         prs_mem_free(&rbuf);
221
222         return result;
223 }
224
225 /* Open handle on a user */
226
227 NTSTATUS cli_samr_open_user(struct cli_state *cli, TALLOC_CTX *mem_ctx,
228                             POLICY_HND *domain_pol, uint32 access_mask, 
229                             uint32 user_rid, POLICY_HND *user_pol)
230 {
231         prs_struct qbuf, rbuf;
232         SAMR_Q_OPEN_USER q;
233         SAMR_R_OPEN_USER r;
234         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
235
236         DEBUG(10,("cli_samr_open_user with rid 0x%x\n", user_rid ));
237
238         ZERO_STRUCT(q);
239         ZERO_STRUCT(r);
240
241         /* Initialise parse structures */
242
243         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
244         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
245
246         /* Marshall data and send request */
247
248         init_samr_q_open_user(&q, domain_pol, access_mask, user_rid);
249
250         if (!samr_io_q_open_user("", &q, &qbuf, 0) ||
251             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_USER, &qbuf, &rbuf))
252                 goto done;
253
254         /* Unmarshall response */
255
256         if (!samr_io_r_open_user("", &r, &rbuf, 0))
257                 goto done;
258
259         /* Return output parameters */
260
261         if (NT_STATUS_IS_OK(result = r.status)) {
262                 *user_pol = r.user_pol;
263 #ifdef __INSURE__
264                 user_pol->marker = malloc(1);
265 #endif
266         }
267
268  done:
269         prs_mem_free(&qbuf);
270         prs_mem_free(&rbuf);
271
272         return result;
273 }
274
275 /* Open handle on a group */
276
277 NTSTATUS cli_samr_open_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
278                              POLICY_HND *domain_pol, uint32 access_mask, 
279                              uint32 group_rid, POLICY_HND *group_pol)
280 {
281         prs_struct qbuf, rbuf;
282         SAMR_Q_OPEN_GROUP q;
283         SAMR_R_OPEN_GROUP r;
284         NTSTATUS result =  NT_STATUS_UNSUCCESSFUL;
285
286         DEBUG(10,("cli_samr_open_group with rid 0x%x\n", group_rid ));
287
288         ZERO_STRUCT(q);
289         ZERO_STRUCT(r);
290
291         /* Initialise parse structures */
292
293         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
294         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
295
296         /* Marshall data and send request */
297
298         init_samr_q_open_group(&q, domain_pol, access_mask, group_rid);
299
300         if (!samr_io_q_open_group("", &q, &qbuf, 0) ||
301             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_GROUP, &qbuf, &rbuf))
302                 goto done;
303
304         /* Unmarshall response */
305
306         if (!samr_io_r_open_group("", &r, &rbuf, 0))
307                 goto done;
308
309         /* Return output parameters */
310
311         if (NT_STATUS_IS_OK(result = r.status)) {
312                 *group_pol = r.pol;
313 #ifdef __INSURE__
314                 group_pol->marker = malloc(1);
315 #endif
316         }
317
318  done:
319         prs_mem_free(&qbuf);
320         prs_mem_free(&rbuf);
321
322         return result;
323 }
324
325 /* Create domain group */
326
327 NTSTATUS cli_samr_create_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx,
328                                    POLICY_HND *domain_pol,
329                                    const char *group_name,
330                                    uint32 access_mask, POLICY_HND *group_pol)
331 {
332         prs_struct qbuf, rbuf;
333         SAMR_Q_CREATE_DOM_GROUP q;
334         SAMR_R_CREATE_DOM_GROUP r;
335         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
336
337         DEBUG(10,("cli_samr_create_dom_group\n"));
338
339         ZERO_STRUCT(q);
340         ZERO_STRUCT(r);
341
342         /* Initialise parse structures */
343
344         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
345         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
346
347         /* Marshall data and send request */
348
349         init_samr_q_create_dom_group(&q, domain_pol, group_name, access_mask);
350
351         if (!samr_io_q_create_dom_group("", &q, &qbuf, 0) ||
352             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_GROUP, &qbuf, &rbuf))
353                 goto done;
354
355         /* Unmarshall response */
356
357         if (!samr_io_r_create_dom_group("", &r, &rbuf, 0))
358                 goto done;
359
360         /* Return output parameters */
361
362         result = r.status;
363
364         if (NT_STATUS_IS_OK(result))
365                 *group_pol = r.pol;
366
367  done:
368         prs_mem_free(&qbuf);
369         prs_mem_free(&rbuf);
370
371         return result;
372 }
373
374 /* Add a domain group member */
375
376 NTSTATUS cli_samr_add_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
377                                POLICY_HND *group_pol, uint32 rid)
378 {
379         prs_struct qbuf, rbuf;
380         SAMR_Q_ADD_GROUPMEM q;
381         SAMR_R_ADD_GROUPMEM r;
382         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
383
384         DEBUG(10,("cli_samr_add_groupmem\n"));
385
386         ZERO_STRUCT(q);
387         ZERO_STRUCT(r);
388
389         /* Initialise parse structures */
390
391         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
392         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
393
394         /* Marshall data and send request */
395
396         init_samr_q_add_groupmem(&q, group_pol, rid);
397
398         if (!samr_io_q_add_groupmem("", &q, &qbuf, 0) ||
399             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_GROUPMEM, &qbuf, &rbuf))
400                 goto done;
401
402         /* Unmarshall response */
403
404         if (!samr_io_r_add_groupmem("", &r, &rbuf, 0))
405                 goto done;
406
407         /* Return output parameters */
408
409         result = r.status;
410
411  done:
412         prs_mem_free(&qbuf);
413         prs_mem_free(&rbuf);
414
415         return result;
416 }
417
418 /* Delete a domain group member */
419
420 NTSTATUS cli_samr_del_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
421                                POLICY_HND *group_pol, uint32 rid)
422 {
423         prs_struct qbuf, rbuf;
424         SAMR_Q_DEL_GROUPMEM q;
425         SAMR_R_DEL_GROUPMEM r;
426         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
427
428         DEBUG(10,("cli_samr_del_groupmem\n"));
429
430         ZERO_STRUCT(q);
431         ZERO_STRUCT(r);
432
433         /* Initialise parse structures */
434
435         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
436         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
437
438         /* Marshall data and send request */
439
440         init_samr_q_del_groupmem(&q, group_pol, rid);
441
442         if (!samr_io_q_del_groupmem("", &q, &qbuf, 0) ||
443             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_GROUPMEM, &qbuf, &rbuf))
444                 goto done;
445
446         /* Unmarshall response */
447
448         if (!samr_io_r_del_groupmem("", &r, &rbuf, 0))
449                 goto done;
450
451         /* Return output parameters */
452
453         result = r.status;
454
455  done:
456         prs_mem_free(&qbuf);
457         prs_mem_free(&rbuf);
458
459         return result;
460 }
461
462 /* Query user info */
463
464 NTSTATUS cli_samr_query_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
465                                  POLICY_HND *user_pol, uint16 switch_value, 
466                                  SAM_USERINFO_CTR **ctr)
467 {
468         prs_struct qbuf, rbuf;
469         SAMR_Q_QUERY_USERINFO q;
470         SAMR_R_QUERY_USERINFO r;
471         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
472
473         DEBUG(10,("cli_samr_query_userinfo\n"));
474
475         ZERO_STRUCT(q);
476         ZERO_STRUCT(r);
477
478         /* Initialise parse structures */
479
480         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
481         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
482
483         /* Marshall data and send request */
484
485         init_samr_q_query_userinfo(&q, user_pol, switch_value);
486
487         if (!samr_io_q_query_userinfo("", &q, &qbuf, 0) ||
488             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERINFO, &qbuf, &rbuf))
489                 goto done;
490
491         /* Unmarshall response */
492
493         if (!samr_io_r_query_userinfo("", &r, &rbuf, 0))
494                 goto done;
495
496         /* Return output parameters */
497
498         result = r.status;
499         *ctr = r.ctr;
500
501  done:
502         prs_mem_free(&qbuf);
503         prs_mem_free(&rbuf);
504
505         return result;
506 }
507
508 /* Set group info */
509
510 NTSTATUS cli_samr_set_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
511                                 POLICY_HND *group_pol, GROUP_INFO_CTR *ctr)
512 {
513         prs_struct qbuf, rbuf;
514         SAMR_Q_SET_GROUPINFO q;
515         SAMR_R_SET_GROUPINFO r;
516         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
517
518         DEBUG(10,("cli_samr_set_groupinfo\n"));
519
520         ZERO_STRUCT(q);
521         ZERO_STRUCT(r);
522
523         /* Initialise parse structures */
524
525         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
526         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
527
528         /* Marshall data and send request */
529
530         init_samr_q_set_groupinfo(&q, group_pol, ctr);
531
532         if (!samr_io_q_set_groupinfo("", &q, &qbuf, 0) ||
533             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_GROUPINFO, &qbuf, &rbuf))
534                 goto done;
535
536         /* Unmarshall response */
537
538         if (!samr_io_r_set_groupinfo("", &r, &rbuf, 0))
539                 goto done;
540
541         /* Return output parameters */
542
543         result = r.status;
544
545  done:
546         prs_mem_free(&qbuf);
547         prs_mem_free(&rbuf);
548
549         return result;
550 }
551
552 /* Query group info */
553
554 NTSTATUS cli_samr_query_groupinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
555                                   POLICY_HND *group_pol, uint32 info_level, 
556                                   GROUP_INFO_CTR **ctr)
557 {
558         prs_struct qbuf, rbuf;
559         SAMR_Q_QUERY_GROUPINFO q;
560         SAMR_R_QUERY_GROUPINFO r;
561         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
562
563         DEBUG(10,("cli_samr_query_groupinfo\n"));
564
565         ZERO_STRUCT(q);
566         ZERO_STRUCT(r);
567
568         /* Initialise parse structures */
569
570         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
571         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
572
573         /* Marshall data and send request */
574
575         init_samr_q_query_groupinfo(&q, group_pol, info_level);
576
577         if (!samr_io_q_query_groupinfo("", &q, &qbuf, 0) ||
578             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPINFO, &qbuf, &rbuf))
579                 goto done;
580
581         /* Unmarshall response */
582
583         if (!samr_io_r_query_groupinfo("", &r, &rbuf, 0))
584                 goto done;
585
586         *ctr = r.ctr;
587
588         /* Return output parameters */
589
590         result = r.status;
591
592  done:
593         prs_mem_free(&qbuf);
594         prs_mem_free(&rbuf);
595
596         return result;
597 }
598
599 /* Query user groups */
600
601 NTSTATUS cli_samr_query_usergroups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
602                                    POLICY_HND *user_pol, uint32 *num_groups, 
603                                    DOM_GID **gid)
604 {
605         prs_struct qbuf, rbuf;
606         SAMR_Q_QUERY_USERGROUPS q;
607         SAMR_R_QUERY_USERGROUPS r;
608         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
609
610         DEBUG(10,("cli_samr_query_usergroups\n"));
611
612         ZERO_STRUCT(q);
613         ZERO_STRUCT(r);
614
615         /* Initialise parse structures */
616
617         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
618         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
619
620         /* Marshall data and send request */
621
622         init_samr_q_query_usergroups(&q, user_pol);
623
624         if (!samr_io_q_query_usergroups("", &q, &qbuf, 0) ||
625             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERGROUPS, &qbuf, &rbuf))
626                 goto done;
627
628         /* Unmarshall response */
629
630         if (!samr_io_r_query_usergroups("", &r, &rbuf, 0))
631                 goto done;
632
633         /* Return output parameters */
634
635         if (NT_STATUS_IS_OK(result = r.status)) {
636                 *num_groups = r.num_entries;
637                 *gid = r.gid;
638         }
639
640  done:
641         prs_mem_free(&qbuf);
642         prs_mem_free(&rbuf);
643
644         return result;
645 }
646
647 /* Set alias info */
648
649 NTSTATUS cli_samr_set_aliasinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
650                                 POLICY_HND *alias_pol, ALIAS_INFO_CTR *ctr)
651 {
652         prs_struct qbuf, rbuf;
653         SAMR_Q_SET_ALIASINFO q;
654         SAMR_R_SET_ALIASINFO r;
655         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
656
657         DEBUG(10,("cli_samr_set_aliasinfo\n"));
658
659         ZERO_STRUCT(q);
660         ZERO_STRUCT(r);
661
662         /* Initialise parse structures */
663
664         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
665         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
666
667         /* Marshall data and send request */
668
669         init_samr_q_set_aliasinfo(&q, alias_pol, ctr);
670
671         if (!samr_io_q_set_aliasinfo("", &q, &qbuf, 0) ||
672             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_ALIASINFO, &qbuf, &rbuf))
673                 goto done;
674
675         /* Unmarshall response */
676
677         if (!samr_io_r_set_aliasinfo("", &r, &rbuf, 0))
678                 goto done;
679
680         /* Return output parameters */
681
682         result = r.status;
683
684  done:
685         prs_mem_free(&qbuf);
686         prs_mem_free(&rbuf);
687
688         return result;
689 }
690
691 /* Query user aliases */
692
693 NTSTATUS cli_samr_query_useraliases(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
694                                    POLICY_HND *dom_pol, uint32 num_sids, DOM_SID2 *sid,
695                                    uint32 *num_aliases, uint32 **als_rids)
696 {
697         prs_struct qbuf, rbuf;
698         SAMR_Q_QUERY_USERALIASES q;
699         SAMR_R_QUERY_USERALIASES r;
700         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
701         int i;
702         uint32 *sid_ptrs;
703         
704         DEBUG(10,("cli_samr_query_useraliases\n"));
705
706         ZERO_STRUCT(q);
707         ZERO_STRUCT(r);
708
709         /* Initialise parse structures */
710
711         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
712         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
713
714         sid_ptrs = TALLOC_ARRAY(mem_ctx, uint32, num_sids);
715         if (sid_ptrs == NULL)
716                 return NT_STATUS_NO_MEMORY;
717
718         for (i=0; i<num_sids; i++)
719                 sid_ptrs[i] = 1;
720
721         /* Marshall data and send request */
722
723         init_samr_q_query_useraliases(&q, dom_pol, num_sids, sid_ptrs, sid);
724
725         if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
726             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
727                 goto done;
728
729         /* Unmarshall response */
730
731         if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
732                 goto done;
733
734         /* Return output parameters */
735
736         if (NT_STATUS_IS_OK(result = r.status)) {
737                 *num_aliases = r.num_entries;
738                 *als_rids = r.rid;
739         }
740
741  done:
742         prs_mem_free(&qbuf);
743         prs_mem_free(&rbuf);
744
745         return result;
746 }
747
748 /* Query user groups */
749
750 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
751                                  POLICY_HND *group_pol, uint32 *num_mem, 
752                                  uint32 **rid, uint32 **attr)
753 {
754         prs_struct qbuf, rbuf;
755         SAMR_Q_QUERY_GROUPMEM q;
756         SAMR_R_QUERY_GROUPMEM r;
757         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
758
759         DEBUG(10,("cli_samr_query_groupmem\n"));
760
761         ZERO_STRUCT(q);
762         ZERO_STRUCT(r);
763
764         /* Initialise parse structures */
765
766         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
767         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
768
769         /* Marshall data and send request */
770
771         init_samr_q_query_groupmem(&q, group_pol);
772
773         if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
774             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
775                 goto done;
776
777         /* Unmarshall response */
778
779         if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
780                 goto done;
781
782         /* Return output parameters */
783
784         if (NT_STATUS_IS_OK(result = r.status)) {
785                 *num_mem = r.num_entries;
786                 *rid = r.rid;
787                 *attr = r.attr;
788         }
789
790  done:
791         prs_mem_free(&qbuf);
792         prs_mem_free(&rbuf);
793
794         return result;
795 }
796
797 /**
798  * Enumerate domain users
799  *
800  * @param cli client state structure
801  * @param mem_ctx talloc context
802  * @param pol opened domain policy handle
803  * @param start_idx starting index of enumeration, returns context for
804                     next enumeration
805  * @param acb_mask account control bit mask (to enumerate some particular
806  *                 kind of accounts)
807  * @param size max acceptable size of response
808  * @param dom_users returned array of domain user names
809  * @param rids returned array of domain user RIDs
810  * @param num_dom_users numer returned entries
811  * 
812  * @return NTSTATUS returned in rpc response
813  **/
814 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
815                                  POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
816                                  uint32 size, char ***dom_users, uint32 **rids,
817                                  uint32 *num_dom_users)
818 {
819         prs_struct qbuf;
820         prs_struct rbuf;
821         SAMR_Q_ENUM_DOM_USERS q;
822         SAMR_R_ENUM_DOM_USERS r;
823         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
824         int i;
825         
826         DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
827
828         ZERO_STRUCT(q);
829         ZERO_STRUCT(r);
830         
831         /* always init this */
832         *num_dom_users = 0;
833         
834         /* Initialise parse structures */
835
836         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
837         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
838         
839         /* Fill query structure with parameters */
840
841         init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
842         
843         if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
844             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
845                 goto done;
846         }
847
848         /* unpack received stream */
849
850         if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
851                 goto done;
852         
853         result = r.status;
854
855         if (!NT_STATUS_IS_OK(result) &&
856             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
857                 goto done;
858         
859         *start_idx = r.next_idx;
860         *num_dom_users = r.num_entries2;
861
862         if (r.num_entries2) {
863                 /* allocate memory needed to return received data */    
864                 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
865                 if (!*rids) {
866                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
867                         return NT_STATUS_NO_MEMORY;
868                 }
869                 
870                 *dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
871                 if (!*dom_users) {
872                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
873                         return NT_STATUS_NO_MEMORY;
874                 }
875                 
876                 /* fill output buffers with rpc response */
877                 for (i = 0; i < r.num_entries2; i++) {
878                         fstring conv_buf;
879                         
880                         (*rids)[i] = r.sam[i].rid;
881                         unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
882                         (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
883                 }
884         }
885         
886 done:
887         prs_mem_free(&qbuf);
888         prs_mem_free(&rbuf);
889         
890         return result;
891 }
892
893 /* Enumerate domain groups */
894
895 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
896                                   POLICY_HND *pol, uint32 *start_idx, 
897                                   uint32 size, struct acct_info **dom_groups,
898                                   uint32 *num_dom_groups)
899 {
900         prs_struct qbuf, rbuf;
901         SAMR_Q_ENUM_DOM_GROUPS q;
902         SAMR_R_ENUM_DOM_GROUPS r;
903         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
904         uint32 name_idx, i;
905
906         DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
907
908         ZERO_STRUCT(q);
909         ZERO_STRUCT(r);
910
911         /* Initialise parse structures */
912
913         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
914         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
915
916         /* Marshall data and send request */
917
918         init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
919
920         if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
921             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
922                 goto done;
923
924         /* Unmarshall response */
925
926         if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
927                 goto done;
928
929         /* Return output parameters */
930
931         result = r.status;
932
933         if (!NT_STATUS_IS_OK(result) &&
934             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
935                 goto done;
936
937         *num_dom_groups = r.num_entries2;
938
939         if (*num_dom_groups == 0)
940                 goto done;
941
942         if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
943                 result = NT_STATUS_NO_MEMORY;
944                 goto done;
945         }
946
947         memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
948
949         name_idx = 0;
950
951         for (i = 0; i < *num_dom_groups; i++) {
952
953                 (*dom_groups)[i].rid = r.sam[i].rid;
954
955                 if (r.sam[i].hdr_name.buffer) {
956                         unistr2_to_ascii((*dom_groups)[i].acct_name,
957                                          &r.uni_grp_name[name_idx],
958                                          sizeof(fstring) - 1);
959                         name_idx++;
960                 }
961
962                 *start_idx = r.next_idx;
963         }
964
965  done:
966         prs_mem_free(&qbuf);
967         prs_mem_free(&rbuf);
968
969         return result;
970 }
971
972 /* Enumerate domain groups */
973
974 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
975                                   POLICY_HND *pol, uint32 *start_idx, 
976                                   uint32 size, struct acct_info **dom_aliases,
977                                   uint32 *num_dom_aliases)
978 {
979         prs_struct qbuf, rbuf;
980         SAMR_Q_ENUM_DOM_ALIASES q;
981         SAMR_R_ENUM_DOM_ALIASES r;
982         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
983         uint32 name_idx, i;
984
985         DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
986
987         ZERO_STRUCT(q);
988         ZERO_STRUCT(r);
989
990         /* Initialise parse structures */
991
992         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
993         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
994
995         /* Marshall data and send request */
996
997         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
998
999         if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
1000             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
1001                 goto done;
1002         }
1003
1004         /* Unmarshall response */
1005
1006         if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1007                 goto done;
1008         }
1009
1010         /* Return output parameters */
1011
1012         result = r.status;
1013
1014         if (!NT_STATUS_IS_OK(result) &&
1015             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1016                 goto done;
1017         }
1018
1019         *num_dom_aliases = r.num_entries2;
1020
1021         if (*num_dom_aliases == 0)
1022                 goto done;
1023
1024         if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
1025                 result = NT_STATUS_NO_MEMORY;
1026                 goto done;
1027         }
1028
1029         memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1030
1031         name_idx = 0;
1032
1033         for (i = 0; i < *num_dom_aliases; i++) {
1034
1035                 (*dom_aliases)[i].rid = r.sam[i].rid;
1036
1037                 if (r.sam[i].hdr_name.buffer) {
1038                         unistr2_to_ascii((*dom_aliases)[i].acct_name,
1039                                          &r.uni_grp_name[name_idx],
1040                                          sizeof(fstring) - 1);
1041                         name_idx++;
1042                 }
1043
1044                 *start_idx = r.next_idx;
1045         }
1046
1047  done:
1048         prs_mem_free(&qbuf);
1049         prs_mem_free(&rbuf);
1050
1051         return result;
1052 }
1053
1054 /* Query alias members */
1055
1056 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1057                                  POLICY_HND *alias_pol, uint32 *num_mem, 
1058                                  DOM_SID **sids)
1059 {
1060         prs_struct qbuf, rbuf;
1061         SAMR_Q_QUERY_ALIASMEM q;
1062         SAMR_R_QUERY_ALIASMEM r;
1063         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1064         uint32 i;
1065
1066         DEBUG(10,("cli_samr_query_aliasmem\n"));
1067
1068         ZERO_STRUCT(q);
1069         ZERO_STRUCT(r);
1070
1071         /* Initialise parse structures */
1072
1073         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1074         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1075
1076         /* Marshall data and send request */
1077
1078         init_samr_q_query_aliasmem(&q, alias_pol);
1079
1080         if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1081             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1082                 goto done;
1083         }
1084
1085         /* Unmarshall response */
1086
1087         if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1088                 goto done;
1089         }
1090
1091         /* Return output parameters */
1092
1093         if (!NT_STATUS_IS_OK(result = r.status)) {
1094                 goto done;
1095         }
1096
1097         *num_mem = r.num_sids;
1098
1099         if (*num_mem == 0) {
1100                 *sids = NULL;
1101                 result = NT_STATUS_OK;
1102                 goto done;
1103         }
1104
1105         if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
1106                 result = NT_STATUS_UNSUCCESSFUL;
1107                 goto done;
1108         }
1109
1110         for (i = 0; i < *num_mem; i++) {
1111                 (*sids)[i] = r.sid[i].sid;
1112         }
1113
1114  done:
1115         prs_mem_free(&qbuf);
1116         prs_mem_free(&rbuf);
1117
1118         return result;
1119 }
1120
1121 /* Open handle on an alias */
1122
1123 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1124                              POLICY_HND *domain_pol, uint32 access_mask, 
1125                              uint32 alias_rid, POLICY_HND *alias_pol)
1126 {
1127         prs_struct qbuf, rbuf;
1128         SAMR_Q_OPEN_ALIAS q;
1129         SAMR_R_OPEN_ALIAS r;
1130         NTSTATUS result;
1131
1132         DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1133
1134         ZERO_STRUCT(q);
1135         ZERO_STRUCT(r);
1136
1137         /* Initialise parse structures */
1138
1139         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1140         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1141
1142         /* Marshall data and send request */
1143
1144         init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1145
1146         if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1147             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1148                 result = NT_STATUS_UNSUCCESSFUL;
1149                 goto done;
1150         }
1151
1152         /* Unmarshall response */
1153
1154         if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1155                 result = NT_STATUS_UNSUCCESSFUL;
1156                 goto done;
1157         }
1158
1159         /* Return output parameters */
1160
1161         if (NT_STATUS_IS_OK(result = r.status)) {
1162                 *alias_pol = r.pol;
1163 #ifdef __INSURE__
1164                 alias_pol->marker = malloc(1);
1165 #endif
1166         }
1167
1168  done:
1169         prs_mem_free(&qbuf);
1170         prs_mem_free(&rbuf);
1171
1172         return result;
1173 }
1174
1175 /* Create an alias */
1176
1177 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1178                                    POLICY_HND *domain_pol, const char *name,
1179                                    POLICY_HND *alias_pol)
1180 {
1181         prs_struct qbuf, rbuf;
1182         SAMR_Q_CREATE_DOM_ALIAS q;
1183         SAMR_R_CREATE_DOM_ALIAS r;
1184         NTSTATUS result;
1185
1186         DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1187
1188         ZERO_STRUCT(q);
1189         ZERO_STRUCT(r);
1190
1191         /* Initialise parse structures */
1192
1193         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1194         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1195
1196         /* Marshall data and send request */
1197
1198         init_samr_q_create_dom_alias(&q, domain_pol, name);
1199
1200         if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1201             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1202                 result = NT_STATUS_UNSUCCESSFUL;
1203                 goto done;
1204         }
1205
1206         /* Unmarshall response */
1207
1208         if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1209                 result = NT_STATUS_UNSUCCESSFUL;
1210                 goto done;
1211         }
1212
1213         /* Return output parameters */
1214
1215         if (NT_STATUS_IS_OK(result = r.status)) {
1216                 *alias_pol = r.alias_pol;
1217         }
1218
1219  done:
1220         prs_mem_free(&qbuf);
1221         prs_mem_free(&rbuf);
1222
1223         return result;
1224 }
1225
1226 /* Add an alias member */
1227
1228 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1229                                POLICY_HND *alias_pol, DOM_SID *member)
1230 {
1231         prs_struct qbuf, rbuf;
1232         SAMR_Q_ADD_ALIASMEM q;
1233         SAMR_R_ADD_ALIASMEM r;
1234         NTSTATUS result;
1235
1236         DEBUG(10,("cli_samr_add_aliasmem"));
1237
1238         ZERO_STRUCT(q);
1239         ZERO_STRUCT(r);
1240
1241         /* Initialise parse structures */
1242
1243         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1244         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1245
1246         /* Marshall data and send request */
1247
1248         init_samr_q_add_aliasmem(&q, alias_pol, member);
1249
1250         if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1251             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1252                 result = NT_STATUS_UNSUCCESSFUL;
1253                 goto done;
1254         }
1255
1256         /* Unmarshall response */
1257
1258         if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1259                 result = NT_STATUS_UNSUCCESSFUL;
1260                 goto done;
1261         }
1262
1263         result = r.status;
1264
1265  done:
1266         prs_mem_free(&qbuf);
1267         prs_mem_free(&rbuf);
1268
1269         return result;
1270 }
1271
1272 /* Delete an alias member */
1273
1274 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1275                                POLICY_HND *alias_pol, DOM_SID *member)
1276 {
1277         prs_struct qbuf, rbuf;
1278         SAMR_Q_DEL_ALIASMEM q;
1279         SAMR_R_DEL_ALIASMEM r;
1280         NTSTATUS result;
1281
1282         DEBUG(10,("cli_samr_del_aliasmem"));
1283
1284         ZERO_STRUCT(q);
1285         ZERO_STRUCT(r);
1286
1287         /* Initialise parse structures */
1288
1289         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1290         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1291
1292         /* Marshall data and send request */
1293
1294         init_samr_q_del_aliasmem(&q, alias_pol, member);
1295
1296         if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1297             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1298                 result = NT_STATUS_UNSUCCESSFUL;
1299                 goto done;
1300         }
1301
1302         /* Unmarshall response */
1303
1304         if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1305                 result = NT_STATUS_UNSUCCESSFUL;
1306                 goto done;
1307         }
1308
1309         result = r.status;
1310
1311  done:
1312         prs_mem_free(&qbuf);
1313         prs_mem_free(&rbuf);
1314
1315         return result;
1316 }
1317
1318 /* Query alias info */
1319
1320 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1321                                    POLICY_HND *alias_pol, uint16 switch_value,
1322                                    ALIAS_INFO_CTR *ctr)
1323 {
1324         prs_struct qbuf, rbuf;
1325         SAMR_Q_QUERY_ALIASINFO q;
1326         SAMR_R_QUERY_ALIASINFO r;
1327         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1328
1329         DEBUG(10,("cli_samr_query_dom_info\n"));
1330
1331         ZERO_STRUCT(q);
1332         ZERO_STRUCT(r);
1333
1334         /* Initialise parse structures */
1335
1336         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1337         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1338
1339         /* Marshall data and send request */
1340
1341         init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1342
1343         if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1344             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1345                 goto done;
1346         }
1347
1348         /* Unmarshall response */
1349
1350         if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1351                 goto done;
1352         }
1353
1354         /* Return output parameters */
1355
1356         if (!NT_STATUS_IS_OK(result = r.status)) {
1357                 goto done;
1358         }
1359
1360         *ctr = r.ctr;
1361
1362  done:
1363         prs_mem_free(&qbuf);
1364         prs_mem_free(&rbuf);
1365
1366         return result;
1367 }
1368
1369 /* Query domain info */
1370
1371 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1372                                  POLICY_HND *domain_pol, uint16 switch_value,
1373                                  SAM_UNK_CTR *ctr)
1374 {
1375         prs_struct qbuf, rbuf;
1376         SAMR_Q_QUERY_DOMAIN_INFO q;
1377         SAMR_R_QUERY_DOMAIN_INFO r;
1378         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1379
1380         DEBUG(10,("cli_samr_query_dom_info\n"));
1381
1382         ZERO_STRUCT(q);
1383         ZERO_STRUCT(r);
1384
1385         /* Initialise parse structures */
1386
1387         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1388         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1389
1390         /* Marshall data and send request */
1391
1392         init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1393
1394         if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1395             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1396                 goto done;
1397         }
1398
1399         /* Unmarshall response */
1400
1401         r.ctr = ctr;
1402
1403         if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1404                 goto done;
1405         }
1406
1407         /* Return output parameters */
1408
1409         if (!NT_STATUS_IS_OK(result = r.status)) {
1410                 goto done;
1411         }
1412
1413  done:
1414         prs_mem_free(&qbuf);
1415         prs_mem_free(&rbuf);
1416
1417         return result;
1418 }
1419
1420 /* User change password */
1421
1422 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1423                                  const char *username, 
1424                                  const char *newpassword, 
1425                                  const char *oldpassword )
1426 {
1427         prs_struct qbuf, rbuf;
1428         SAMR_Q_CHGPASSWD_USER q;
1429         SAMR_R_CHGPASSWD_USER r;
1430         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1431
1432         uchar new_nt_password[516];
1433         uchar new_lm_password[516];
1434         uchar old_nt_hash[16];
1435         uchar old_lanman_hash[16];
1436         uchar old_nt_hash_enc[16];
1437         uchar old_lanman_hash_enc[16];
1438
1439         uchar new_nt_hash[16];
1440         uchar new_lanman_hash[16];
1441
1442         DEBUG(10,("cli_samr_query_dom_info\n"));
1443
1444         ZERO_STRUCT(q);
1445         ZERO_STRUCT(r);
1446
1447         /* Calculate the MD4 hash (NT compatible) of the password */
1448         E_md4hash(oldpassword, old_nt_hash);
1449         E_md4hash(newpassword, new_nt_hash);
1450
1451         if (lp_client_lanman_auth() 
1452             && E_deshash(newpassword, new_lanman_hash) 
1453             && E_deshash(oldpassword, old_lanman_hash)) {
1454                 /* E_deshash returns false for 'long' passwords (> 14
1455                    DOS chars).  This allows us to match Win2k, which
1456                    does not store a LM hash for these passwords (which
1457                    would reduce the effective password length to 14) */
1458
1459                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1460
1461                 SamOEMhash( new_lm_password, old_nt_hash, 516);
1462                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1463         } else {
1464                 ZERO_STRUCT(new_lm_password);
1465                 ZERO_STRUCT(old_lanman_hash_enc);
1466         }
1467
1468         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1469         
1470         SamOEMhash( new_nt_password, old_nt_hash, 516);
1471         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1472
1473         /* Initialise parse structures */
1474
1475         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1476         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1477
1478         /* Marshall data and send request */
1479
1480         init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, 
1481                                    new_nt_password, 
1482                                    old_nt_hash_enc, 
1483                                    new_lm_password,
1484                                    old_lanman_hash_enc);
1485
1486         if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1487             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1488                 goto done;
1489         }
1490
1491         /* Unmarshall response */
1492
1493         if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1494                 goto done;
1495         }
1496
1497         /* Return output parameters */
1498
1499         if (!NT_STATUS_IS_OK(result = r.status)) {
1500                 goto done;
1501         }
1502
1503  done:
1504         prs_mem_free(&qbuf);
1505         prs_mem_free(&rbuf);
1506
1507         return result;
1508 }
1509
1510 /* This function returns the bizzare set of (max_entries, max_size) required
1511    for the QueryDisplayInfo RPC to actually work against a domain controller
1512    with large (10k and higher) numbers of users.  These values were 
1513    obtained by inspection using ethereal and NT4 running User Manager. */
1514
1515 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1516                                uint32 *max_size)
1517 {
1518         switch(loop_count) {
1519         case 0:
1520                 *max_entries = 512;
1521                 *max_size = 16383;
1522                 break;
1523         case 1:
1524                 *max_entries = 1024;
1525                 *max_size = 32766;
1526                 break;
1527         case 2:
1528                 *max_entries = 2048;
1529                 *max_size = 65532;
1530                 break;
1531         case 3:
1532                 *max_entries = 4096;
1533                 *max_size = 131064;
1534                 break;
1535         default:              /* loop_count >= 4 */
1536                 *max_entries = 4096;
1537                 *max_size = 131071;
1538                 break;
1539         }
1540 }                    
1541
1542 /* Query display info */
1543
1544 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1545                                  POLICY_HND *domain_pol, uint32 *start_idx,
1546                                  uint16 switch_value, uint32 *num_entries,
1547                                  uint32 max_entries, uint32 max_size,
1548                                  SAM_DISPINFO_CTR *ctr)
1549 {
1550         prs_struct qbuf, rbuf;
1551         SAMR_Q_QUERY_DISPINFO q;
1552         SAMR_R_QUERY_DISPINFO r;
1553         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1554
1555         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1556
1557         ZERO_STRUCT(q);
1558         ZERO_STRUCT(r);
1559
1560         *num_entries = 0;
1561
1562         /* Initialise parse structures */
1563
1564         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1565         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1566
1567         /* Marshall data and send request */
1568
1569         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1570                                    *start_idx, max_entries, max_size);
1571
1572         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1573             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1574                 goto done;
1575         }
1576
1577         /* Unmarshall response */
1578
1579         r.ctr = ctr;
1580
1581         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1582                 goto done;
1583         }
1584
1585         /* Return output parameters */
1586
1587         result = r.status;
1588
1589         if (!NT_STATUS_IS_OK(result) &&
1590             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1591                 goto done;
1592         }
1593
1594         *num_entries = r.num_entries;
1595         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1596
1597  done:
1598         prs_mem_free(&qbuf);
1599         prs_mem_free(&rbuf);
1600
1601         return result;
1602 }
1603
1604 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1605    looked up in one packet. */
1606
1607 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1608                               POLICY_HND *domain_pol,
1609                               uint32 num_rids, uint32 *rids, 
1610                               uint32 *num_names, char ***names,
1611                               uint32 **name_types)
1612 {
1613         prs_struct qbuf, rbuf;
1614         SAMR_Q_LOOKUP_RIDS q;
1615         SAMR_R_LOOKUP_RIDS r;
1616         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1617         uint32 i;
1618
1619         DEBUG(10,("cli_samr_lookup_rids\n"));
1620
1621         if (num_rids > 1000) {
1622                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1623                           "more than ~1000 rids are looked up at once.\n"));
1624         }
1625
1626         ZERO_STRUCT(q);
1627         ZERO_STRUCT(r);
1628
1629         /* Initialise parse structures */
1630
1631         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1632         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1633
1634         /* Marshall data and send request */
1635
1636         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, 1000, num_rids, rids);
1637
1638         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1639             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1640                 goto done;
1641         }
1642
1643         /* Unmarshall response */
1644
1645         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1646                 goto done;
1647         }
1648
1649         /* Return output parameters */
1650
1651         result = r.status;
1652
1653         if (!NT_STATUS_IS_OK(result) &&
1654             !NT_STATUS_EQUAL(result, STATUS_SOME_UNMAPPED))
1655                 goto done;
1656
1657         if (r.num_names1 == 0) {
1658                 *num_names = 0;
1659                 *names = NULL;
1660                 goto done;
1661         }
1662
1663         *num_names = r.num_names1;
1664         *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1665         *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1666
1667         for (i = 0; i < r.num_names1; i++) {
1668                 fstring tmp;
1669
1670                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1671                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1672                 (*name_types)[i] = r.type[i];
1673         }
1674
1675  done:
1676         prs_mem_free(&qbuf);
1677         prs_mem_free(&rbuf);
1678
1679         return result;
1680 }
1681
1682 /* Lookup names */
1683
1684 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1685                                POLICY_HND *domain_pol, uint32 flags,
1686                                uint32 num_names, const char **names,
1687                                uint32 *num_rids, uint32 **rids,
1688                                uint32 **rid_types)
1689 {
1690         prs_struct qbuf, rbuf;
1691         SAMR_Q_LOOKUP_NAMES q;
1692         SAMR_R_LOOKUP_NAMES r;
1693         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1694         uint32 i;
1695
1696         DEBUG(10,("cli_samr_lookup_names\n"));
1697
1698         ZERO_STRUCT(q);
1699         ZERO_STRUCT(r);
1700
1701         /* Initialise parse structures */
1702
1703         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1704         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1705
1706         /* Marshall data and send request */
1707
1708         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1709                                  num_names, names);
1710
1711         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1712             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1713                 goto done;
1714         }
1715
1716         /* Unmarshall response */
1717
1718         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1719                 goto done;
1720         }
1721
1722         /* Return output parameters */
1723
1724         if (!NT_STATUS_IS_OK(result = r.status)) {
1725                 goto done;
1726         }
1727
1728         if (r.num_rids1 == 0) {
1729                 *num_rids = 0;
1730                 goto done;
1731         }
1732
1733         *num_rids = r.num_rids1;
1734         *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1735         *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1736
1737         for (i = 0; i < r.num_rids1; i++) {
1738                 (*rids)[i] = r.rids[i];
1739                 (*rid_types)[i] = r.types[i];
1740         }
1741
1742  done:
1743         prs_mem_free(&qbuf);
1744         prs_mem_free(&rbuf);
1745
1746         return result;
1747 }
1748
1749 /* Create a domain user */
1750
1751 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1752                                   POLICY_HND *domain_pol, const char *acct_name,
1753                                   uint32 acb_info, uint32 unknown, 
1754                                   POLICY_HND *user_pol, uint32 *rid)
1755 {
1756         prs_struct qbuf, rbuf;
1757         SAMR_Q_CREATE_USER q;
1758         SAMR_R_CREATE_USER r;
1759         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1760
1761         DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1762
1763         ZERO_STRUCT(q);
1764         ZERO_STRUCT(r);
1765
1766         /* Initialise parse structures */
1767
1768         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1769         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1770
1771         /* Marshall data and send request */
1772
1773         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1774
1775         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1776             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1777                 goto done;
1778         }
1779
1780         /* Unmarshall response */
1781
1782         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1783                 goto done;
1784         }
1785
1786         /* Return output parameters */
1787
1788         if (!NT_STATUS_IS_OK(result = r.status)) {
1789                 goto done;
1790         }
1791
1792         if (user_pol)
1793                 *user_pol = r.user_pol;
1794
1795         if (rid)
1796                 *rid = r.user_rid;
1797
1798  done:
1799         prs_mem_free(&qbuf);
1800         prs_mem_free(&rbuf);
1801
1802         return result;
1803 }
1804
1805 /* Set userinfo */
1806
1807 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1808                                POLICY_HND *user_pol, uint16 switch_value,
1809                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1810 {
1811         prs_struct qbuf, rbuf;
1812         SAMR_Q_SET_USERINFO q;
1813         SAMR_R_SET_USERINFO r;
1814         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1815
1816         DEBUG(10,("cli_samr_set_userinfo\n"));
1817
1818         ZERO_STRUCT(q);
1819         ZERO_STRUCT(r);
1820
1821         if (!sess_key->length) {
1822                 DEBUG(1, ("No user session key\n"));
1823                 return NT_STATUS_NO_USER_SESSION_KEY;
1824         }
1825
1826         /* Initialise parse structures */
1827
1828         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1829         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1830
1831         /* Marshall data and send request */
1832
1833         q.ctr = ctr;
1834
1835         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1836                                  ctr->info.id);
1837
1838         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1839             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1840                 goto done;
1841         }
1842
1843         /* Unmarshall response */
1844
1845         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1846                 goto done;
1847         }
1848
1849         /* Return output parameters */
1850
1851         if (!NT_STATUS_IS_OK(result = r.status)) {
1852                 goto done;
1853         }
1854
1855  done:
1856         prs_mem_free(&qbuf);
1857         prs_mem_free(&rbuf);
1858
1859         return result;
1860 }
1861
1862 /* Set userinfo2 */
1863
1864 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1865                                 POLICY_HND *user_pol, uint16 switch_value,
1866                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1867 {
1868         prs_struct qbuf, rbuf;
1869         SAMR_Q_SET_USERINFO2 q;
1870         SAMR_R_SET_USERINFO2 r;
1871         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1872
1873         DEBUG(10,("cli_samr_set_userinfo2\n"));
1874
1875         if (!sess_key->length) {
1876                 DEBUG(1, ("No user session key\n"));
1877                 return NT_STATUS_NO_USER_SESSION_KEY;
1878         }
1879
1880         ZERO_STRUCT(q);
1881         ZERO_STRUCT(r);
1882
1883         /* Initialise parse structures */
1884
1885         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1886         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1887
1888         /* Marshall data and send request */
1889
1890         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1891
1892         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1893             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1894                 goto done;
1895         }
1896
1897         /* Unmarshall response */
1898
1899         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1900                 goto done;
1901         }
1902
1903         /* Return output parameters */
1904
1905         if (!NT_STATUS_IS_OK(result = r.status)) {
1906                 goto done;
1907         }
1908
1909  done:
1910         prs_mem_free(&qbuf);
1911         prs_mem_free(&rbuf);
1912
1913         return result;
1914 }
1915
1916 /* Delete domain group */
1917
1918 NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1919                                   POLICY_HND *group_pol)
1920 {
1921         prs_struct qbuf, rbuf;
1922         SAMR_Q_DELETE_DOM_GROUP q;
1923         SAMR_R_DELETE_DOM_GROUP r;
1924         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1925
1926         DEBUG(10,("cli_samr_delete_dom_group\n"));
1927
1928         ZERO_STRUCT(q);
1929         ZERO_STRUCT(r);
1930
1931         /* Initialise parse structures */
1932
1933         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1934         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1935
1936         /* Marshall data and send request */
1937
1938         init_samr_q_delete_dom_group(&q, group_pol);
1939
1940         if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
1941             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
1942                 goto done;
1943         }
1944
1945         /* Unmarshall response */
1946
1947         if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
1948                 goto done;
1949         }
1950
1951         /* Return output parameters */
1952
1953         result = r.status;
1954
1955  done:
1956         prs_mem_free(&qbuf);
1957         prs_mem_free(&rbuf);
1958
1959         return result;
1960 }
1961
1962 /* Delete domain alias */
1963
1964 NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1965                                   POLICY_HND *alias_pol)
1966 {
1967         prs_struct qbuf, rbuf;
1968         SAMR_Q_DELETE_DOM_ALIAS q;
1969         SAMR_R_DELETE_DOM_ALIAS r;
1970         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1971
1972         DEBUG(10,("cli_samr_delete_dom_alias\n"));
1973
1974         ZERO_STRUCT(q);
1975         ZERO_STRUCT(r);
1976
1977         /* Initialise parse structures */
1978
1979         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1980         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1981
1982         /* Marshall data and send request */
1983
1984         init_samr_q_delete_dom_alias(&q, alias_pol);
1985
1986         if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
1987             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
1988                 goto done;
1989         }
1990
1991         /* Unmarshall response */
1992
1993         if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
1994                 goto done;
1995         }
1996
1997         /* Return output parameters */
1998
1999         result = r.status;
2000
2001  done:
2002         prs_mem_free(&qbuf);
2003         prs_mem_free(&rbuf);
2004
2005         return result;
2006 }
2007
2008 /* Delete domain user */
2009
2010 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
2011                                   POLICY_HND *user_pol)
2012 {
2013         prs_struct qbuf, rbuf;
2014         SAMR_Q_DELETE_DOM_USER q;
2015         SAMR_R_DELETE_DOM_USER r;
2016         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2017
2018         DEBUG(10,("cli_samr_delete_dom_user\n"));
2019
2020         ZERO_STRUCT(q);
2021         ZERO_STRUCT(r);
2022
2023         /* Initialise parse structures */
2024
2025         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2026         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2027
2028         /* Marshall data and send request */
2029
2030         init_samr_q_delete_dom_user(&q, user_pol);
2031
2032         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
2033             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
2034                 goto done;
2035         }
2036
2037         /* Unmarshall response */
2038
2039         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
2040                 goto done;
2041         }
2042
2043         /* Return output parameters */
2044
2045         result = r.status;
2046
2047  done:
2048         prs_mem_free(&qbuf);
2049         prs_mem_free(&rbuf);
2050
2051         return result;
2052 }
2053
2054 /* Remove foreign SID */
2055
2056 NTSTATUS cli_samr_remove_sid_foreign_domain(struct cli_state *cli, 
2057                                             TALLOC_CTX *mem_ctx, 
2058                                             POLICY_HND *user_pol,
2059                                             DOM_SID *sid)
2060 {
2061         prs_struct qbuf, rbuf;
2062         SAMR_Q_REMOVE_SID_FOREIGN_DOMAIN q;
2063         SAMR_R_REMOVE_SID_FOREIGN_DOMAIN r;
2064         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2065
2066         DEBUG(10,("cli_samr_remove_sid_foreign_domain\n"));
2067
2068         ZERO_STRUCT(q);
2069         ZERO_STRUCT(r);
2070
2071         /* Initialise parse structures */
2072
2073         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2074         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2075
2076         /* Marshall data and send request */
2077
2078         init_samr_q_remove_sid_foreign_domain(&q, user_pol, sid);
2079
2080         if (!samr_io_q_remove_sid_foreign_domain("", &q, &qbuf, 0) ||
2081             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_REMOVE_SID_FOREIGN_DOMAIN, &qbuf, &rbuf)) {
2082                 goto done;
2083         }
2084
2085         /* Unmarshall response */
2086
2087         if (!samr_io_r_remove_sid_foreign_domain("", &r, &rbuf, 0)) {
2088                 goto done;
2089         }
2090
2091         /* Return output parameters */
2092
2093         result = r.status;
2094
2095  done:
2096         prs_mem_free(&qbuf);
2097         prs_mem_free(&rbuf);
2098
2099         return result;
2100 }
2101
2102 /* Query user security object */
2103
2104 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2105                                  POLICY_HND *user_pol, uint16 switch_value, 
2106                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
2107 {
2108         prs_struct qbuf, rbuf;
2109         SAMR_Q_QUERY_SEC_OBJ q;
2110         SAMR_R_QUERY_SEC_OBJ r;
2111         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2112
2113         DEBUG(10,("cli_samr_query_sec_obj\n"));
2114
2115         ZERO_STRUCT(q);
2116         ZERO_STRUCT(r);
2117
2118         /* Initialise parse structures */
2119
2120         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2121         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2122
2123         /* Marshall data and send request */
2124
2125         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
2126
2127         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
2128             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
2129                 goto done;
2130         }
2131
2132         /* Unmarshall response */
2133
2134         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
2135                 goto done;
2136         }
2137
2138         /* Return output parameters */
2139
2140         result = r.status;
2141         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
2142
2143  done:
2144         prs_mem_free(&qbuf);
2145         prs_mem_free(&rbuf);
2146
2147         return result;
2148 }
2149
2150 /* Get domain password info */
2151
2152 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2153                                  uint16 *unk_0, uint16 *unk_1)
2154 {
2155         prs_struct qbuf, rbuf;
2156         SAMR_Q_GET_DOM_PWINFO q;
2157         SAMR_R_GET_DOM_PWINFO r;
2158         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2159
2160         DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2161
2162         ZERO_STRUCT(q);
2163         ZERO_STRUCT(r);
2164
2165         /* Initialise parse structures */
2166
2167         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2168         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2169
2170         /* Marshall data and send request */
2171
2172         init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2173
2174         if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2175             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2176                 goto done;
2177
2178         /* Unmarshall response */
2179
2180         if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2181                 goto done;
2182
2183         /* Return output parameters */
2184
2185         result = r.status;
2186
2187         if (NT_STATUS_IS_OK(result)) {
2188                 if (unk_0)
2189                         *unk_0 = r.unk_0;
2190                 if (unk_1)
2191                         *unk_1 = r.unk_1;
2192         }
2193
2194  done:
2195         prs_mem_free(&qbuf);
2196         prs_mem_free(&rbuf);
2197
2198         return result;
2199 }
2200
2201 /* Lookup Domain Name */
2202
2203 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2204                                 POLICY_HND *user_pol, char *domain_name, 
2205                                 DOM_SID *sid)
2206 {
2207         prs_struct qbuf, rbuf;
2208         SAMR_Q_LOOKUP_DOMAIN q;
2209         SAMR_R_LOOKUP_DOMAIN r;
2210         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2211
2212         DEBUG(10,("cli_samr_lookup_domain\n"));
2213
2214         ZERO_STRUCT(q);
2215         ZERO_STRUCT(r);
2216
2217         /* Initialise parse structures */
2218
2219         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2220         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2221
2222         /* Marshall data and send request */
2223
2224         init_samr_q_lookup_domain(&q, user_pol, domain_name);
2225
2226         if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2227             !rpc_api_pipe_req(cli, PI_SAMR, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2228                 goto done;
2229
2230         /* Unmarshall response */
2231
2232         if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2233                 goto done;
2234
2235         /* Return output parameters */
2236
2237         result = r.status;
2238
2239         if (NT_STATUS_IS_OK(result))
2240                 sid_copy(sid, &r.dom_sid.sid);
2241
2242  done:
2243         prs_mem_free(&qbuf);
2244         prs_mem_free(&rbuf);
2245
2246         return result;
2247 }