r4088: Get medieval on our ass about malloc.... :-). Take control of all our allocation
[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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 *user_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         unsigned int ptr=1;
702         
703         DEBUG(10,("cli_samr_query_useraliases\n"));
704
705         ZERO_STRUCT(q);
706         ZERO_STRUCT(r);
707
708         /* Initialise parse structures */
709
710         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
711         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
712
713         /* Marshall data and send request */
714
715         init_samr_q_query_useraliases(&q, user_pol, num_sids, &ptr, sid);
716
717         if (!samr_io_q_query_useraliases("", &q, &qbuf, 0) ||
718             !rpc_api_pipe_req(cli, SAMR_QUERY_USERALIASES, &qbuf, &rbuf))
719                 goto done;
720
721         /* Unmarshall response */
722
723         if (!samr_io_r_query_useraliases("", &r, &rbuf, 0))
724                 goto done;
725
726         /* Return output parameters */
727
728         if (NT_STATUS_IS_OK(result = r.status)) {
729                 *num_aliases = r.num_entries;
730                 *als_rids = r.rid;
731         }
732
733  done:
734         prs_mem_free(&qbuf);
735         prs_mem_free(&rbuf);
736
737         return result;
738 }
739
740 /* Query user groups */
741
742 NTSTATUS cli_samr_query_groupmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
743                                  POLICY_HND *group_pol, uint32 *num_mem, 
744                                  uint32 **rid, uint32 **attr)
745 {
746         prs_struct qbuf, rbuf;
747         SAMR_Q_QUERY_GROUPMEM q;
748         SAMR_R_QUERY_GROUPMEM r;
749         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
750
751         DEBUG(10,("cli_samr_query_groupmem\n"));
752
753         ZERO_STRUCT(q);
754         ZERO_STRUCT(r);
755
756         /* Initialise parse structures */
757
758         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
759         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
760
761         /* Marshall data and send request */
762
763         init_samr_q_query_groupmem(&q, group_pol);
764
765         if (!samr_io_q_query_groupmem("", &q, &qbuf, 0) ||
766             !rpc_api_pipe_req(cli, SAMR_QUERY_GROUPMEM, &qbuf, &rbuf))
767                 goto done;
768
769         /* Unmarshall response */
770
771         if (!samr_io_r_query_groupmem("", &r, &rbuf, 0))
772                 goto done;
773
774         /* Return output parameters */
775
776         if (NT_STATUS_IS_OK(result = r.status)) {
777                 *num_mem = r.num_entries;
778                 *rid = r.rid;
779                 *attr = r.attr;
780         }
781
782  done:
783         prs_mem_free(&qbuf);
784         prs_mem_free(&rbuf);
785
786         return result;
787 }
788
789 /**
790  * Enumerate domain users
791  *
792  * @param cli client state structure
793  * @param mem_ctx talloc context
794  * @param pol opened domain policy handle
795  * @param start_idx starting index of enumeration, returns context for
796                     next enumeration
797  * @param acb_mask account control bit mask (to enumerate some particular
798  *                 kind of accounts)
799  * @param size max acceptable size of response
800  * @param dom_users returned array of domain user names
801  * @param rids returned array of domain user RIDs
802  * @param num_dom_users numer returned entries
803  * 
804  * @return NTSTATUS returned in rpc response
805  **/
806 NTSTATUS cli_samr_enum_dom_users(struct cli_state *cli, TALLOC_CTX *mem_ctx,
807                                  POLICY_HND *pol, uint32 *start_idx, uint16 acb_mask,
808                                  uint32 size, char ***dom_users, uint32 **rids,
809                                  uint32 *num_dom_users)
810 {
811         prs_struct qbuf;
812         prs_struct rbuf;
813         SAMR_Q_ENUM_DOM_USERS q;
814         SAMR_R_ENUM_DOM_USERS r;
815         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
816         int i;
817         
818         DEBUG(10,("cli_samr_enum_dom_users starting at index %u\n", (unsigned int)*start_idx));
819
820         ZERO_STRUCT(q);
821         ZERO_STRUCT(r);
822         
823         /* always init this */
824         *num_dom_users = 0;
825         
826         /* Initialise parse structures */
827
828         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
829         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
830         
831         /* Fill query structure with parameters */
832
833         init_samr_q_enum_dom_users(&q, pol, *start_idx, acb_mask, 0, size);
834         
835         if (!samr_io_q_enum_dom_users("", &q, &qbuf, 0) ||
836             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_USERS, &qbuf, &rbuf)) {
837                 goto done;
838         }
839
840         /* unpack received stream */
841
842         if(!samr_io_r_enum_dom_users("", &r, &rbuf, 0))
843                 goto done;
844         
845         result = r.status;
846
847         if (!NT_STATUS_IS_OK(result) &&
848             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
849                 goto done;
850         
851         *start_idx = r.next_idx;
852         *num_dom_users = r.num_entries2;
853
854         if (r.num_entries2) {
855                 /* allocate memory needed to return received data */    
856                 *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_entries2);
857                 if (!*rids) {
858                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
859                         return NT_STATUS_NO_MEMORY;
860                 }
861                 
862                 *dom_users = TALLOC_ARRAY(mem_ctx, char*, r.num_entries2);
863                 if (!*dom_users) {
864                         DEBUG(0, ("Error in cli_samr_enum_dom_users(): out of memory\n"));
865                         return NT_STATUS_NO_MEMORY;
866                 }
867                 
868                 /* fill output buffers with rpc response */
869                 for (i = 0; i < r.num_entries2; i++) {
870                         fstring conv_buf;
871                         
872                         (*rids)[i] = r.sam[i].rid;
873                         unistr2_to_ascii(conv_buf, &(r.uni_acct_name[i]), sizeof(conv_buf) - 1);
874                         (*dom_users)[i] = talloc_strdup(mem_ctx, conv_buf);
875                 }
876         }
877         
878 done:
879         prs_mem_free(&qbuf);
880         prs_mem_free(&rbuf);
881         
882         return result;
883 }
884
885 /* Enumerate domain groups */
886
887 NTSTATUS cli_samr_enum_dom_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
888                                   POLICY_HND *pol, uint32 *start_idx, 
889                                   uint32 size, struct acct_info **dom_groups,
890                                   uint32 *num_dom_groups)
891 {
892         prs_struct qbuf, rbuf;
893         SAMR_Q_ENUM_DOM_GROUPS q;
894         SAMR_R_ENUM_DOM_GROUPS r;
895         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
896         uint32 name_idx, i;
897
898         DEBUG(10,("cli_samr_enum_dom_groups starting at index %u\n", (unsigned int)*start_idx));
899
900         ZERO_STRUCT(q);
901         ZERO_STRUCT(r);
902
903         /* Initialise parse structures */
904
905         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
906         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
907
908         /* Marshall data and send request */
909
910         init_samr_q_enum_dom_groups(&q, pol, *start_idx, size);
911
912         if (!samr_io_q_enum_dom_groups("", &q, &qbuf, 0) ||
913             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_GROUPS, &qbuf, &rbuf))
914                 goto done;
915
916         /* Unmarshall response */
917
918         if (!samr_io_r_enum_dom_groups("", &r, &rbuf, 0))
919                 goto done;
920
921         /* Return output parameters */
922
923         result = r.status;
924
925         if (!NT_STATUS_IS_OK(result) &&
926             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES))
927                 goto done;
928
929         *num_dom_groups = r.num_entries2;
930
931         if (*num_dom_groups == 0)
932                 goto done;
933
934         if (!((*dom_groups) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_groups))) {
935                 result = NT_STATUS_NO_MEMORY;
936                 goto done;
937         }
938
939         memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
940
941         name_idx = 0;
942
943         for (i = 0; i < *num_dom_groups; i++) {
944
945                 (*dom_groups)[i].rid = r.sam[i].rid;
946
947                 if (r.sam[i].hdr_name.buffer) {
948                         unistr2_to_ascii((*dom_groups)[i].acct_name,
949                                          &r.uni_grp_name[name_idx],
950                                          sizeof(fstring) - 1);
951                         name_idx++;
952                 }
953
954                 *start_idx = r.next_idx;
955         }
956
957  done:
958         prs_mem_free(&qbuf);
959         prs_mem_free(&rbuf);
960
961         return result;
962 }
963
964 /* Enumerate domain groups */
965
966 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
967                                   POLICY_HND *pol, uint32 *start_idx, 
968                                   uint32 size, struct acct_info **dom_aliases,
969                                   uint32 *num_dom_aliases)
970 {
971         prs_struct qbuf, rbuf;
972         SAMR_Q_ENUM_DOM_ALIASES q;
973         SAMR_R_ENUM_DOM_ALIASES r;
974         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
975         uint32 name_idx, i;
976
977         DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
978
979         ZERO_STRUCT(q);
980         ZERO_STRUCT(r);
981
982         /* Initialise parse structures */
983
984         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
985         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
986
987         /* Marshall data and send request */
988
989         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
990
991         if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
992             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
993                 goto done;
994         }
995
996         /* Unmarshall response */
997
998         if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
999                 goto done;
1000         }
1001
1002         /* Return output parameters */
1003
1004         result = r.status;
1005
1006         if (!NT_STATUS_IS_OK(result) &&
1007             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1008                 goto done;
1009         }
1010
1011         *num_dom_aliases = r.num_entries2;
1012
1013         if (*num_dom_aliases == 0)
1014                 goto done;
1015
1016         if (!((*dom_aliases) = TALLOC_ARRAY(mem_ctx, struct acct_info, *num_dom_aliases))) {
1017                 result = NT_STATUS_NO_MEMORY;
1018                 goto done;
1019         }
1020
1021         memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1022
1023         name_idx = 0;
1024
1025         for (i = 0; i < *num_dom_aliases; i++) {
1026
1027                 (*dom_aliases)[i].rid = r.sam[i].rid;
1028
1029                 if (r.sam[i].hdr_name.buffer) {
1030                         unistr2_to_ascii((*dom_aliases)[i].acct_name,
1031                                          &r.uni_grp_name[name_idx],
1032                                          sizeof(fstring) - 1);
1033                         name_idx++;
1034                 }
1035
1036                 *start_idx = r.next_idx;
1037         }
1038
1039  done:
1040         prs_mem_free(&qbuf);
1041         prs_mem_free(&rbuf);
1042
1043         return result;
1044 }
1045
1046 /* Query alias members */
1047
1048 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1049                                  POLICY_HND *alias_pol, uint32 *num_mem, 
1050                                  DOM_SID **sids)
1051 {
1052         prs_struct qbuf, rbuf;
1053         SAMR_Q_QUERY_ALIASMEM q;
1054         SAMR_R_QUERY_ALIASMEM r;
1055         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1056         uint32 i;
1057
1058         DEBUG(10,("cli_samr_query_aliasmem\n"));
1059
1060         ZERO_STRUCT(q);
1061         ZERO_STRUCT(r);
1062
1063         /* Initialise parse structures */
1064
1065         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1066         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1067
1068         /* Marshall data and send request */
1069
1070         init_samr_q_query_aliasmem(&q, alias_pol);
1071
1072         if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1073             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1074                 goto done;
1075         }
1076
1077         /* Unmarshall response */
1078
1079         if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1080                 goto done;
1081         }
1082
1083         /* Return output parameters */
1084
1085         if (!NT_STATUS_IS_OK(result = r.status)) {
1086                 goto done;
1087         }
1088
1089         *num_mem = r.num_sids;
1090
1091         if (*num_mem == 0) {
1092                 *sids = NULL;
1093                 result = NT_STATUS_OK;
1094                 goto done;
1095         }
1096
1097         if (!(*sids = TALLOC_ARRAY(mem_ctx, DOM_SID, *num_mem))) {
1098                 result = NT_STATUS_UNSUCCESSFUL;
1099                 goto done;
1100         }
1101
1102         for (i = 0; i < *num_mem; i++) {
1103                 (*sids)[i] = r.sid[i].sid;
1104         }
1105
1106  done:
1107         prs_mem_free(&qbuf);
1108         prs_mem_free(&rbuf);
1109
1110         return result;
1111 }
1112
1113 /* Open handle on an alias */
1114
1115 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1116                              POLICY_HND *domain_pol, uint32 access_mask, 
1117                              uint32 alias_rid, POLICY_HND *alias_pol)
1118 {
1119         prs_struct qbuf, rbuf;
1120         SAMR_Q_OPEN_ALIAS q;
1121         SAMR_R_OPEN_ALIAS r;
1122         NTSTATUS result;
1123
1124         DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1125
1126         ZERO_STRUCT(q);
1127         ZERO_STRUCT(r);
1128
1129         /* Initialise parse structures */
1130
1131         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1132         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1133
1134         /* Marshall data and send request */
1135
1136         init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1137
1138         if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1139             !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1140                 result = NT_STATUS_UNSUCCESSFUL;
1141                 goto done;
1142         }
1143
1144         /* Unmarshall response */
1145
1146         if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1147                 result = NT_STATUS_UNSUCCESSFUL;
1148                 goto done;
1149         }
1150
1151         /* Return output parameters */
1152
1153         if (NT_STATUS_IS_OK(result = r.status)) {
1154                 *alias_pol = r.pol;
1155 #ifdef __INSURE__
1156                 alias_pol->marker = malloc(1);
1157 #endif
1158         }
1159
1160  done:
1161         prs_mem_free(&qbuf);
1162         prs_mem_free(&rbuf);
1163
1164         return result;
1165 }
1166
1167 /* Create an alias */
1168
1169 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1170                                    POLICY_HND *domain_pol, const char *name,
1171                                    POLICY_HND *alias_pol)
1172 {
1173         prs_struct qbuf, rbuf;
1174         SAMR_Q_CREATE_DOM_ALIAS q;
1175         SAMR_R_CREATE_DOM_ALIAS r;
1176         NTSTATUS result;
1177
1178         DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1179
1180         ZERO_STRUCT(q);
1181         ZERO_STRUCT(r);
1182
1183         /* Initialise parse structures */
1184
1185         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1186         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1187
1188         /* Marshall data and send request */
1189
1190         init_samr_q_create_dom_alias(&q, domain_pol, name);
1191
1192         if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1193             !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1194                 result = NT_STATUS_UNSUCCESSFUL;
1195                 goto done;
1196         }
1197
1198         /* Unmarshall response */
1199
1200         if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1201                 result = NT_STATUS_UNSUCCESSFUL;
1202                 goto done;
1203         }
1204
1205         /* Return output parameters */
1206
1207         if (NT_STATUS_IS_OK(result = r.status)) {
1208                 *alias_pol = r.alias_pol;
1209         }
1210
1211  done:
1212         prs_mem_free(&qbuf);
1213         prs_mem_free(&rbuf);
1214
1215         return result;
1216 }
1217
1218 /* Add an alias member */
1219
1220 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1221                                POLICY_HND *alias_pol, DOM_SID *member)
1222 {
1223         prs_struct qbuf, rbuf;
1224         SAMR_Q_ADD_ALIASMEM q;
1225         SAMR_R_ADD_ALIASMEM r;
1226         NTSTATUS result;
1227
1228         DEBUG(10,("cli_samr_add_aliasmem"));
1229
1230         ZERO_STRUCT(q);
1231         ZERO_STRUCT(r);
1232
1233         /* Initialise parse structures */
1234
1235         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1236         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1237
1238         /* Marshall data and send request */
1239
1240         init_samr_q_add_aliasmem(&q, alias_pol, member);
1241
1242         if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1243             !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1244                 result = NT_STATUS_UNSUCCESSFUL;
1245                 goto done;
1246         }
1247
1248         /* Unmarshall response */
1249
1250         if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1251                 result = NT_STATUS_UNSUCCESSFUL;
1252                 goto done;
1253         }
1254
1255         result = r.status;
1256
1257  done:
1258         prs_mem_free(&qbuf);
1259         prs_mem_free(&rbuf);
1260
1261         return result;
1262 }
1263
1264 /* Delete an alias member */
1265
1266 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1267                                POLICY_HND *alias_pol, DOM_SID *member)
1268 {
1269         prs_struct qbuf, rbuf;
1270         SAMR_Q_DEL_ALIASMEM q;
1271         SAMR_R_DEL_ALIASMEM r;
1272         NTSTATUS result;
1273
1274         DEBUG(10,("cli_samr_del_aliasmem"));
1275
1276         ZERO_STRUCT(q);
1277         ZERO_STRUCT(r);
1278
1279         /* Initialise parse structures */
1280
1281         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1282         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1283
1284         /* Marshall data and send request */
1285
1286         init_samr_q_del_aliasmem(&q, alias_pol, member);
1287
1288         if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1289             !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1290                 result = NT_STATUS_UNSUCCESSFUL;
1291                 goto done;
1292         }
1293
1294         /* Unmarshall response */
1295
1296         if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1297                 result = NT_STATUS_UNSUCCESSFUL;
1298                 goto done;
1299         }
1300
1301         result = r.status;
1302
1303  done:
1304         prs_mem_free(&qbuf);
1305         prs_mem_free(&rbuf);
1306
1307         return result;
1308 }
1309
1310 /* Query alias info */
1311
1312 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1313                                    POLICY_HND *alias_pol, uint16 switch_value,
1314                                    ALIAS_INFO_CTR *ctr)
1315 {
1316         prs_struct qbuf, rbuf;
1317         SAMR_Q_QUERY_ALIASINFO q;
1318         SAMR_R_QUERY_ALIASINFO r;
1319         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1320
1321         DEBUG(10,("cli_samr_query_dom_info\n"));
1322
1323         ZERO_STRUCT(q);
1324         ZERO_STRUCT(r);
1325
1326         /* Initialise parse structures */
1327
1328         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1329         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1330
1331         /* Marshall data and send request */
1332
1333         init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1334
1335         if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1336             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1337                 goto done;
1338         }
1339
1340         /* Unmarshall response */
1341
1342         if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1343                 goto done;
1344         }
1345
1346         /* Return output parameters */
1347
1348         if (!NT_STATUS_IS_OK(result = r.status)) {
1349                 goto done;
1350         }
1351
1352         *ctr = r.ctr;
1353
1354  done:
1355         prs_mem_free(&qbuf);
1356         prs_mem_free(&rbuf);
1357
1358         return result;
1359 }
1360
1361 /* Query domain info */
1362
1363 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1364                                  POLICY_HND *domain_pol, uint16 switch_value,
1365                                  SAM_UNK_CTR *ctr)
1366 {
1367         prs_struct qbuf, rbuf;
1368         SAMR_Q_QUERY_DOMAIN_INFO q;
1369         SAMR_R_QUERY_DOMAIN_INFO r;
1370         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1371
1372         DEBUG(10,("cli_samr_query_dom_info\n"));
1373
1374         ZERO_STRUCT(q);
1375         ZERO_STRUCT(r);
1376
1377         /* Initialise parse structures */
1378
1379         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1380         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1381
1382         /* Marshall data and send request */
1383
1384         init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1385
1386         if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1387             !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1388                 goto done;
1389         }
1390
1391         /* Unmarshall response */
1392
1393         r.ctr = ctr;
1394
1395         if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1396                 goto done;
1397         }
1398
1399         /* Return output parameters */
1400
1401         if (!NT_STATUS_IS_OK(result = r.status)) {
1402                 goto done;
1403         }
1404
1405  done:
1406         prs_mem_free(&qbuf);
1407         prs_mem_free(&rbuf);
1408
1409         return result;
1410 }
1411
1412 /* User change password */
1413
1414 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1415                                  const char *username, 
1416                                  const char *newpassword, 
1417                                  const char *oldpassword )
1418 {
1419         prs_struct qbuf, rbuf;
1420         SAMR_Q_CHGPASSWD_USER q;
1421         SAMR_R_CHGPASSWD_USER r;
1422         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1423
1424         uchar new_nt_password[516];
1425         uchar new_lm_password[516];
1426         uchar old_nt_hash[16];
1427         uchar old_lanman_hash[16];
1428         uchar old_nt_hash_enc[16];
1429         uchar old_lanman_hash_enc[16];
1430
1431         uchar new_nt_hash[16];
1432         uchar new_lanman_hash[16];
1433
1434         DEBUG(10,("cli_samr_query_dom_info\n"));
1435
1436         ZERO_STRUCT(q);
1437         ZERO_STRUCT(r);
1438
1439         /* Calculate the MD4 hash (NT compatible) of the password */
1440         E_md4hash(oldpassword, old_nt_hash);
1441         E_md4hash(newpassword, new_nt_hash);
1442
1443         if (lp_client_lanman_auth() 
1444             && E_deshash(newpassword, new_lanman_hash) 
1445             && E_deshash(oldpassword, old_lanman_hash)) {
1446                 /* E_deshash returns false for 'long' passwords (> 14
1447                    DOS chars).  This allows us to match Win2k, which
1448                    does not store a LM hash for these passwords (which
1449                    would reduce the effective password length to 14) */
1450
1451                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1452
1453                 SamOEMhash( new_lm_password, old_nt_hash, 516);
1454                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1455         } else {
1456                 ZERO_STRUCT(new_lm_password);
1457                 ZERO_STRUCT(old_lanman_hash_enc);
1458         }
1459
1460         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1461         
1462         SamOEMhash( new_nt_password, old_nt_hash, 516);
1463         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1464
1465         /* Initialise parse structures */
1466
1467         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1468         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1469
1470         /* Marshall data and send request */
1471
1472         init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, 
1473                                    new_nt_password, 
1474                                    old_nt_hash_enc, 
1475                                    new_lm_password,
1476                                    old_lanman_hash_enc);
1477
1478         if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1479             !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1480                 goto done;
1481         }
1482
1483         /* Unmarshall response */
1484
1485         if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1486                 goto done;
1487         }
1488
1489         /* Return output parameters */
1490
1491         if (!NT_STATUS_IS_OK(result = r.status)) {
1492                 goto done;
1493         }
1494
1495  done:
1496         prs_mem_free(&qbuf);
1497         prs_mem_free(&rbuf);
1498
1499         return result;
1500 }
1501
1502 /* This function returns the bizzare set of (max_entries, max_size) required
1503    for the QueryDisplayInfo RPC to actually work against a domain controller
1504    with large (10k and higher) numbers of users.  These values were 
1505    obtained by inspection using ethereal and NT4 running User Manager. */
1506
1507 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1508                                uint32 *max_size)
1509 {
1510         switch(loop_count) {
1511         case 0:
1512                 *max_entries = 512;
1513                 *max_size = 16383;
1514                 break;
1515         case 1:
1516                 *max_entries = 1024;
1517                 *max_size = 32766;
1518                 break;
1519         case 2:
1520                 *max_entries = 2048;
1521                 *max_size = 65532;
1522                 break;
1523         case 3:
1524                 *max_entries = 4096;
1525                 *max_size = 131064;
1526                 break;
1527         default:              /* loop_count >= 4 */
1528                 *max_entries = 4096;
1529                 *max_size = 131071;
1530                 break;
1531         }
1532 }                    
1533
1534 /* Query display info */
1535
1536 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1537                                  POLICY_HND *domain_pol, uint32 *start_idx,
1538                                  uint16 switch_value, uint32 *num_entries,
1539                                  uint32 max_entries, uint32 max_size,
1540                                  SAM_DISPINFO_CTR *ctr)
1541 {
1542         prs_struct qbuf, rbuf;
1543         SAMR_Q_QUERY_DISPINFO q;
1544         SAMR_R_QUERY_DISPINFO r;
1545         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1546
1547         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1548
1549         ZERO_STRUCT(q);
1550         ZERO_STRUCT(r);
1551
1552         *num_entries = 0;
1553
1554         /* Initialise parse structures */
1555
1556         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1557         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1558
1559         /* Marshall data and send request */
1560
1561         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1562                                    *start_idx, max_entries, max_size);
1563
1564         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1565             !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1566                 goto done;
1567         }
1568
1569         /* Unmarshall response */
1570
1571         r.ctr = ctr;
1572
1573         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1574                 goto done;
1575         }
1576
1577         /* Return output parameters */
1578
1579         result = r.status;
1580
1581         if (!NT_STATUS_IS_OK(result) &&
1582             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1583                 goto done;
1584         }
1585
1586         *num_entries = r.num_entries;
1587         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1588
1589  done:
1590         prs_mem_free(&qbuf);
1591         prs_mem_free(&rbuf);
1592
1593         return result;
1594 }
1595
1596 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1597    looked up in one packet. */
1598
1599 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1600                               POLICY_HND *domain_pol, uint32 flags,
1601                               uint32 num_rids, uint32 *rids, 
1602                               uint32 *num_names, char ***names,
1603                               uint32 **name_types)
1604 {
1605         prs_struct qbuf, rbuf;
1606         SAMR_Q_LOOKUP_RIDS q;
1607         SAMR_R_LOOKUP_RIDS r;
1608         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1609         uint32 i;
1610
1611         DEBUG(10,("cli_samr_lookup_rids\n"));
1612
1613         if (num_rids > 1000) {
1614                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1615                           "more than ~1000 rids are looked up at once.\n"));
1616         }
1617
1618         ZERO_STRUCT(q);
1619         ZERO_STRUCT(r);
1620
1621         /* Initialise parse structures */
1622
1623         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1624         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1625
1626         /* Marshall data and send request */
1627
1628         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1629                                 num_rids, rids);
1630
1631         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1632             !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1633                 goto done;
1634         }
1635
1636         /* Unmarshall response */
1637
1638         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1639                 goto done;
1640         }
1641
1642         /* Return output parameters */
1643
1644         if (!NT_STATUS_IS_OK(result = r.status)) {
1645                 goto done;
1646         }
1647
1648         if (r.num_names1 == 0) {
1649                 *num_names = 0;
1650                 *names = NULL;
1651                 goto done;
1652         }
1653
1654         *num_names = r.num_names1;
1655         *names = TALLOC_ARRAY(mem_ctx, char *, r.num_names1);
1656         *name_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_names1);
1657
1658         for (i = 0; i < r.num_names1; i++) {
1659                 fstring tmp;
1660
1661                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1662                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1663                 (*name_types)[i] = r.type[i];
1664         }
1665
1666  done:
1667         prs_mem_free(&qbuf);
1668         prs_mem_free(&rbuf);
1669
1670         return result;
1671 }
1672
1673 /* Lookup names */
1674
1675 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1676                                POLICY_HND *domain_pol, uint32 flags,
1677                                uint32 num_names, const char **names,
1678                                uint32 *num_rids, uint32 **rids,
1679                                uint32 **rid_types)
1680 {
1681         prs_struct qbuf, rbuf;
1682         SAMR_Q_LOOKUP_NAMES q;
1683         SAMR_R_LOOKUP_NAMES r;
1684         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1685         uint32 i;
1686
1687         DEBUG(10,("cli_samr_lookup_names\n"));
1688
1689         ZERO_STRUCT(q);
1690         ZERO_STRUCT(r);
1691
1692         /* Initialise parse structures */
1693
1694         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1695         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1696
1697         /* Marshall data and send request */
1698
1699         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1700                                  num_names, names);
1701
1702         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1703             !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1704                 goto done;
1705         }
1706
1707         /* Unmarshall response */
1708
1709         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1710                 goto done;
1711         }
1712
1713         /* Return output parameters */
1714
1715         if (!NT_STATUS_IS_OK(result = r.status)) {
1716                 goto done;
1717         }
1718
1719         if (r.num_rids1 == 0) {
1720                 *num_rids = 0;
1721                 goto done;
1722         }
1723
1724         *num_rids = r.num_rids1;
1725         *rids = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1726         *rid_types = TALLOC_ARRAY(mem_ctx, uint32, r.num_rids1);
1727
1728         for (i = 0; i < r.num_rids1; i++) {
1729                 (*rids)[i] = r.rids[i];
1730                 (*rid_types)[i] = r.types[i];
1731         }
1732
1733  done:
1734         prs_mem_free(&qbuf);
1735         prs_mem_free(&rbuf);
1736
1737         return result;
1738 }
1739
1740 /* Create a domain user */
1741
1742 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1743                                   POLICY_HND *domain_pol, const char *acct_name,
1744                                   uint32 acb_info, uint32 unknown, 
1745                                   POLICY_HND *user_pol, uint32 *rid)
1746 {
1747         prs_struct qbuf, rbuf;
1748         SAMR_Q_CREATE_USER q;
1749         SAMR_R_CREATE_USER r;
1750         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1751
1752         DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1753
1754         ZERO_STRUCT(q);
1755         ZERO_STRUCT(r);
1756
1757         /* Initialise parse structures */
1758
1759         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1760         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1761
1762         /* Marshall data and send request */
1763
1764         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1765
1766         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1767             !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1768                 goto done;
1769         }
1770
1771         /* Unmarshall response */
1772
1773         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1774                 goto done;
1775         }
1776
1777         /* Return output parameters */
1778
1779         if (!NT_STATUS_IS_OK(result = r.status)) {
1780                 goto done;
1781         }
1782
1783         if (user_pol)
1784                 *user_pol = r.user_pol;
1785
1786         if (rid)
1787                 *rid = r.user_rid;
1788
1789  done:
1790         prs_mem_free(&qbuf);
1791         prs_mem_free(&rbuf);
1792
1793         return result;
1794 }
1795
1796 /* Set userinfo */
1797
1798 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1799                                POLICY_HND *user_pol, uint16 switch_value,
1800                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1801 {
1802         prs_struct qbuf, rbuf;
1803         SAMR_Q_SET_USERINFO q;
1804         SAMR_R_SET_USERINFO r;
1805         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1806
1807         DEBUG(10,("cli_samr_set_userinfo\n"));
1808
1809         ZERO_STRUCT(q);
1810         ZERO_STRUCT(r);
1811
1812         if (!sess_key->length) {
1813                 DEBUG(1, ("No user session key\n"));
1814                 return NT_STATUS_NO_USER_SESSION_KEY;
1815         }
1816
1817         /* Initialise parse structures */
1818
1819         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1820         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1821
1822         /* Marshall data and send request */
1823
1824         q.ctr = ctr;
1825
1826         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1827                                  ctr->info.id);
1828
1829         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1830             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1831                 goto done;
1832         }
1833
1834         /* Unmarshall response */
1835
1836         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1837                 goto done;
1838         }
1839
1840         /* Return output parameters */
1841
1842         if (!NT_STATUS_IS_OK(result = r.status)) {
1843                 goto done;
1844         }
1845
1846  done:
1847         prs_mem_free(&qbuf);
1848         prs_mem_free(&rbuf);
1849
1850         return result;
1851 }
1852
1853 /* Set userinfo2 */
1854
1855 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1856                                 POLICY_HND *user_pol, uint16 switch_value,
1857                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1858 {
1859         prs_struct qbuf, rbuf;
1860         SAMR_Q_SET_USERINFO2 q;
1861         SAMR_R_SET_USERINFO2 r;
1862         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1863
1864         DEBUG(10,("cli_samr_set_userinfo2\n"));
1865
1866         if (!sess_key->length) {
1867                 DEBUG(1, ("No user session key\n"));
1868                 return NT_STATUS_NO_USER_SESSION_KEY;
1869         }
1870
1871         ZERO_STRUCT(q);
1872         ZERO_STRUCT(r);
1873
1874         /* Initialise parse structures */
1875
1876         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1877         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1878
1879         /* Marshall data and send request */
1880
1881         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1882
1883         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1884             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1885                 goto done;
1886         }
1887
1888         /* Unmarshall response */
1889
1890         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1891                 goto done;
1892         }
1893
1894         /* Return output parameters */
1895
1896         if (!NT_STATUS_IS_OK(result = r.status)) {
1897                 goto done;
1898         }
1899
1900  done:
1901         prs_mem_free(&qbuf);
1902         prs_mem_free(&rbuf);
1903
1904         return result;
1905 }
1906
1907 /* Delete domain group */
1908
1909 NTSTATUS cli_samr_delete_dom_group(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1910                                   POLICY_HND *group_pol)
1911 {
1912         prs_struct qbuf, rbuf;
1913         SAMR_Q_DELETE_DOM_GROUP q;
1914         SAMR_R_DELETE_DOM_GROUP r;
1915         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1916
1917         DEBUG(10,("cli_samr_delete_dom_group\n"));
1918
1919         ZERO_STRUCT(q);
1920         ZERO_STRUCT(r);
1921
1922         /* Initialise parse structures */
1923
1924         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1925         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1926
1927         /* Marshall data and send request */
1928
1929         init_samr_q_delete_dom_group(&q, group_pol);
1930
1931         if (!samr_io_q_delete_dom_group("", &q, &qbuf, 0) ||
1932             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_GROUP, &qbuf, &rbuf)) {
1933                 goto done;
1934         }
1935
1936         /* Unmarshall response */
1937
1938         if (!samr_io_r_delete_dom_group("", &r, &rbuf, 0)) {
1939                 goto done;
1940         }
1941
1942         /* Return output parameters */
1943
1944         result = r.status;
1945
1946  done:
1947         prs_mem_free(&qbuf);
1948         prs_mem_free(&rbuf);
1949
1950         return result;
1951 }
1952
1953 /* Delete domain alias */
1954
1955 NTSTATUS cli_samr_delete_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1956                                   POLICY_HND *alias_pol)
1957 {
1958         prs_struct qbuf, rbuf;
1959         SAMR_Q_DELETE_DOM_ALIAS q;
1960         SAMR_R_DELETE_DOM_ALIAS r;
1961         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1962
1963         DEBUG(10,("cli_samr_delete_dom_alias\n"));
1964
1965         ZERO_STRUCT(q);
1966         ZERO_STRUCT(r);
1967
1968         /* Initialise parse structures */
1969
1970         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1971         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1972
1973         /* Marshall data and send request */
1974
1975         init_samr_q_delete_dom_alias(&q, alias_pol);
1976
1977         if (!samr_io_q_delete_dom_alias("", &q, &qbuf, 0) ||
1978             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_ALIAS, &qbuf, &rbuf)) {
1979                 goto done;
1980         }
1981
1982         /* Unmarshall response */
1983
1984         if (!samr_io_r_delete_dom_alias("", &r, &rbuf, 0)) {
1985                 goto done;
1986         }
1987
1988         /* Return output parameters */
1989
1990         result = r.status;
1991
1992  done:
1993         prs_mem_free(&qbuf);
1994         prs_mem_free(&rbuf);
1995
1996         return result;
1997 }
1998
1999 /* Delete domain user */
2000
2001 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
2002                                   POLICY_HND *user_pol)
2003 {
2004         prs_struct qbuf, rbuf;
2005         SAMR_Q_DELETE_DOM_USER q;
2006         SAMR_R_DELETE_DOM_USER r;
2007         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2008
2009         DEBUG(10,("cli_samr_delete_dom_user\n"));
2010
2011         ZERO_STRUCT(q);
2012         ZERO_STRUCT(r);
2013
2014         /* Initialise parse structures */
2015
2016         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2017         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2018
2019         /* Marshall data and send request */
2020
2021         init_samr_q_delete_dom_user(&q, user_pol);
2022
2023         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
2024             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
2025                 goto done;
2026         }
2027
2028         /* Unmarshall response */
2029
2030         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
2031                 goto done;
2032         }
2033
2034         /* Return output parameters */
2035
2036         result = r.status;
2037
2038  done:
2039         prs_mem_free(&qbuf);
2040         prs_mem_free(&rbuf);
2041
2042         return result;
2043 }
2044
2045 /* Query user security object */
2046
2047 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2048                                  POLICY_HND *user_pol, uint16 switch_value, 
2049                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
2050 {
2051         prs_struct qbuf, rbuf;
2052         SAMR_Q_QUERY_SEC_OBJ q;
2053         SAMR_R_QUERY_SEC_OBJ r;
2054         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2055
2056         DEBUG(10,("cli_samr_query_sec_obj\n"));
2057
2058         ZERO_STRUCT(q);
2059         ZERO_STRUCT(r);
2060
2061         /* Initialise parse structures */
2062
2063         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2064         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2065
2066         /* Marshall data and send request */
2067
2068         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
2069
2070         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
2071             !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
2072                 goto done;
2073         }
2074
2075         /* Unmarshall response */
2076
2077         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
2078                 goto done;
2079         }
2080
2081         /* Return output parameters */
2082
2083         result = r.status;
2084         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
2085
2086  done:
2087         prs_mem_free(&qbuf);
2088         prs_mem_free(&rbuf);
2089
2090         return result;
2091 }
2092
2093 /* Get domain password info */
2094
2095 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2096                                  uint16 *unk_0, uint16 *unk_1)
2097 {
2098         prs_struct qbuf, rbuf;
2099         SAMR_Q_GET_DOM_PWINFO q;
2100         SAMR_R_GET_DOM_PWINFO r;
2101         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2102
2103         DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2104
2105         ZERO_STRUCT(q);
2106         ZERO_STRUCT(r);
2107
2108         /* Initialise parse structures */
2109
2110         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2111         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2112
2113         /* Marshall data and send request */
2114
2115         init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2116
2117         if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2118             !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2119                 goto done;
2120
2121         /* Unmarshall response */
2122
2123         if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2124                 goto done;
2125
2126         /* Return output parameters */
2127
2128         result = r.status;
2129
2130         if (NT_STATUS_IS_OK(result)) {
2131                 if (unk_0)
2132                         *unk_0 = r.unk_0;
2133                 if (unk_1)
2134                         *unk_1 = r.unk_1;
2135         }
2136
2137  done:
2138         prs_mem_free(&qbuf);
2139         prs_mem_free(&rbuf);
2140
2141         return result;
2142 }
2143
2144 /* Lookup Domain Name */
2145
2146 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2147                                 POLICY_HND *user_pol, char *domain_name, 
2148                                 DOM_SID *sid)
2149 {
2150         prs_struct qbuf, rbuf;
2151         SAMR_Q_LOOKUP_DOMAIN q;
2152         SAMR_R_LOOKUP_DOMAIN r;
2153         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2154
2155         DEBUG(10,("cli_samr_lookup_domain\n"));
2156
2157         ZERO_STRUCT(q);
2158         ZERO_STRUCT(r);
2159
2160         /* Initialise parse structures */
2161
2162         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2163         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2164
2165         /* Marshall data and send request */
2166
2167         init_samr_q_lookup_domain(&q, user_pol, domain_name);
2168
2169         if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2170             !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2171                 goto done;
2172
2173         /* Unmarshall response */
2174
2175         if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2176                 goto done;
2177
2178         /* Return output parameters */
2179
2180         result = r.status;
2181
2182         if (NT_STATUS_IS_OK(result))
2183                 sid_copy(sid, &r.dom_sid.sid);
2184
2185  done:
2186         prs_mem_free(&qbuf);
2187         prs_mem_free(&rbuf);
2188
2189         return result;
2190 }