import HEAD into svn+ssh://svn.samba.org/home/svn/samba/trunk
[metze/old/v3-2-winbind-ndr.git] / source / 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 = (uint32*)talloc(mem_ctx, sizeof(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 = (char**)talloc(mem_ctx, sizeof(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) = (struct acct_info *)
935               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_groups))) {
936                 result = NT_STATUS_NO_MEMORY;
937                 goto done;
938         }
939
940         memset(*dom_groups, 0, sizeof(struct acct_info) * (*num_dom_groups));
941
942         name_idx = 0;
943
944         for (i = 0; i < *num_dom_groups; i++) {
945
946                 (*dom_groups)[i].rid = r.sam[i].rid;
947
948                 if (r.sam[i].hdr_name.buffer) {
949                         unistr2_to_ascii((*dom_groups)[i].acct_name,
950                                          &r.uni_grp_name[name_idx],
951                                          sizeof(fstring) - 1);
952                         name_idx++;
953                 }
954
955                 *start_idx = r.next_idx;
956         }
957
958  done:
959         prs_mem_free(&qbuf);
960         prs_mem_free(&rbuf);
961
962         return result;
963 }
964
965 /* Enumerate domain groups */
966
967 NTSTATUS cli_samr_enum_als_groups(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
968                                   POLICY_HND *pol, uint32 *start_idx, 
969                                   uint32 size, struct acct_info **dom_aliases,
970                                   uint32 *num_dom_aliases)
971 {
972         prs_struct qbuf, rbuf;
973         SAMR_Q_ENUM_DOM_ALIASES q;
974         SAMR_R_ENUM_DOM_ALIASES r;
975         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
976         uint32 name_idx, i;
977
978         DEBUG(10,("cli_samr_enum_als_groups starting at index %u\n", (unsigned int)*start_idx));
979
980         ZERO_STRUCT(q);
981         ZERO_STRUCT(r);
982
983         /* Initialise parse structures */
984
985         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
986         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
987
988         /* Marshall data and send request */
989
990         init_samr_q_enum_dom_aliases(&q, pol, *start_idx, size);
991
992         if (!samr_io_q_enum_dom_aliases("", &q, &qbuf, 0) ||
993             !rpc_api_pipe_req(cli, SAMR_ENUM_DOM_ALIASES, &qbuf, &rbuf)) {
994                 goto done;
995         }
996
997         /* Unmarshall response */
998
999         if (!samr_io_r_enum_dom_aliases("", &r, &rbuf, 0)) {
1000                 goto done;
1001         }
1002
1003         /* Return output parameters */
1004
1005         result = r.status;
1006
1007         if (!NT_STATUS_IS_OK(result) &&
1008             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1009                 goto done;
1010         }
1011
1012         *num_dom_aliases = r.num_entries2;
1013
1014         if (*num_dom_aliases == 0)
1015                 goto done;
1016
1017         if (!((*dom_aliases) = (struct acct_info *)
1018               talloc(mem_ctx, sizeof(struct acct_info) * *num_dom_aliases))) {
1019                 result = NT_STATUS_NO_MEMORY;
1020                 goto done;
1021         }
1022
1023         memset(*dom_aliases, 0, sizeof(struct acct_info) * *num_dom_aliases);
1024
1025         name_idx = 0;
1026
1027         for (i = 0; i < *num_dom_aliases; i++) {
1028
1029                 (*dom_aliases)[i].rid = r.sam[i].rid;
1030
1031                 if (r.sam[i].hdr_name.buffer) {
1032                         unistr2_to_ascii((*dom_aliases)[i].acct_name,
1033                                          &r.uni_grp_name[name_idx],
1034                                          sizeof(fstring) - 1);
1035                         name_idx++;
1036                 }
1037
1038                 *start_idx = r.next_idx;
1039         }
1040
1041  done:
1042         prs_mem_free(&qbuf);
1043         prs_mem_free(&rbuf);
1044
1045         return result;
1046 }
1047
1048 /* Query alias members */
1049
1050 NTSTATUS cli_samr_query_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1051                                  POLICY_HND *alias_pol, uint32 *num_mem, 
1052                                  DOM_SID **sids)
1053 {
1054         prs_struct qbuf, rbuf;
1055         SAMR_Q_QUERY_ALIASMEM q;
1056         SAMR_R_QUERY_ALIASMEM r;
1057         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1058         uint32 i;
1059
1060         DEBUG(10,("cli_samr_query_aliasmem\n"));
1061
1062         ZERO_STRUCT(q);
1063         ZERO_STRUCT(r);
1064
1065         /* Initialise parse structures */
1066
1067         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1068         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1069
1070         /* Marshall data and send request */
1071
1072         init_samr_q_query_aliasmem(&q, alias_pol);
1073
1074         if (!samr_io_q_query_aliasmem("", &q, &qbuf, 0) ||
1075             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASMEM, &qbuf, &rbuf)) {
1076                 goto done;
1077         }
1078
1079         /* Unmarshall response */
1080
1081         if (!samr_io_r_query_aliasmem("", &r, &rbuf, 0)) {
1082                 goto done;
1083         }
1084
1085         /* Return output parameters */
1086
1087         if (!NT_STATUS_IS_OK(result = r.status)) {
1088                 goto done;
1089         }
1090
1091         *num_mem = r.num_sids;
1092
1093         if (*num_mem == 0) {
1094                 *sids = NULL;
1095                 result = NT_STATUS_OK;
1096                 goto done;
1097         }
1098
1099         if (!(*sids = talloc(mem_ctx, sizeof(DOM_SID) * *num_mem))) {
1100                 result = NT_STATUS_UNSUCCESSFUL;
1101                 goto done;
1102         }
1103
1104         for (i = 0; i < *num_mem; i++) {
1105                 (*sids)[i] = r.sid[i].sid;
1106         }
1107
1108  done:
1109         prs_mem_free(&qbuf);
1110         prs_mem_free(&rbuf);
1111
1112         return result;
1113 }
1114
1115 /* Open handle on an alias */
1116
1117 NTSTATUS cli_samr_open_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1118                              POLICY_HND *domain_pol, uint32 access_mask, 
1119                              uint32 alias_rid, POLICY_HND *alias_pol)
1120 {
1121         prs_struct qbuf, rbuf;
1122         SAMR_Q_OPEN_ALIAS q;
1123         SAMR_R_OPEN_ALIAS r;
1124         NTSTATUS result;
1125
1126         DEBUG(10,("cli_samr_open_alias with rid 0x%x\n", alias_rid));
1127
1128         ZERO_STRUCT(q);
1129         ZERO_STRUCT(r);
1130
1131         /* Initialise parse structures */
1132
1133         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1134         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1135
1136         /* Marshall data and send request */
1137
1138         init_samr_q_open_alias(&q, domain_pol, access_mask, alias_rid);
1139
1140         if (!samr_io_q_open_alias("", &q, &qbuf, 0) ||
1141             !rpc_api_pipe_req(cli, SAMR_OPEN_ALIAS, &qbuf, &rbuf)) {
1142                 result = NT_STATUS_UNSUCCESSFUL;
1143                 goto done;
1144         }
1145
1146         /* Unmarshall response */
1147
1148         if (!samr_io_r_open_alias("", &r, &rbuf, 0)) {
1149                 result = NT_STATUS_UNSUCCESSFUL;
1150                 goto done;
1151         }
1152
1153         /* Return output parameters */
1154
1155         if (NT_STATUS_IS_OK(result = r.status)) {
1156                 *alias_pol = r.pol;
1157 #ifdef __INSURE__
1158                 alias_pol->marker = malloc(1);
1159 #endif
1160         }
1161
1162  done:
1163         prs_mem_free(&qbuf);
1164         prs_mem_free(&rbuf);
1165
1166         return result;
1167 }
1168
1169 /* Create an alias */
1170
1171 NTSTATUS cli_samr_create_dom_alias(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1172                                    POLICY_HND *domain_pol, const char *name,
1173                                    POLICY_HND *alias_pol)
1174 {
1175         prs_struct qbuf, rbuf;
1176         SAMR_Q_CREATE_DOM_ALIAS q;
1177         SAMR_R_CREATE_DOM_ALIAS r;
1178         NTSTATUS result;
1179
1180         DEBUG(10,("cli_samr_create_dom_alias named %s\n", name));
1181
1182         ZERO_STRUCT(q);
1183         ZERO_STRUCT(r);
1184
1185         /* Initialise parse structures */
1186
1187         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1188         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1189
1190         /* Marshall data and send request */
1191
1192         init_samr_q_create_dom_alias(&q, domain_pol, name);
1193
1194         if (!samr_io_q_create_dom_alias("", &q, &qbuf, 0) ||
1195             !rpc_api_pipe_req(cli, SAMR_CREATE_DOM_ALIAS, &qbuf, &rbuf)) {
1196                 result = NT_STATUS_UNSUCCESSFUL;
1197                 goto done;
1198         }
1199
1200         /* Unmarshall response */
1201
1202         if (!samr_io_r_create_dom_alias("", &r, &rbuf, 0)) {
1203                 result = NT_STATUS_UNSUCCESSFUL;
1204                 goto done;
1205         }
1206
1207         /* Return output parameters */
1208
1209         if (NT_STATUS_IS_OK(result = r.status)) {
1210                 *alias_pol = r.alias_pol;
1211         }
1212
1213  done:
1214         prs_mem_free(&qbuf);
1215         prs_mem_free(&rbuf);
1216
1217         return result;
1218 }
1219
1220 /* Add an alias member */
1221
1222 NTSTATUS cli_samr_add_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1223                                POLICY_HND *alias_pol, DOM_SID *member)
1224 {
1225         prs_struct qbuf, rbuf;
1226         SAMR_Q_ADD_ALIASMEM q;
1227         SAMR_R_ADD_ALIASMEM r;
1228         NTSTATUS result;
1229
1230         DEBUG(10,("cli_samr_add_aliasmem"));
1231
1232         ZERO_STRUCT(q);
1233         ZERO_STRUCT(r);
1234
1235         /* Initialise parse structures */
1236
1237         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1238         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1239
1240         /* Marshall data and send request */
1241
1242         init_samr_q_add_aliasmem(&q, alias_pol, member);
1243
1244         if (!samr_io_q_add_aliasmem("", &q, &qbuf, 0) ||
1245             !rpc_api_pipe_req(cli, SAMR_ADD_ALIASMEM, &qbuf, &rbuf)) {
1246                 result = NT_STATUS_UNSUCCESSFUL;
1247                 goto done;
1248         }
1249
1250         /* Unmarshall response */
1251
1252         if (!samr_io_r_add_aliasmem("", &r, &rbuf, 0)) {
1253                 result = NT_STATUS_UNSUCCESSFUL;
1254                 goto done;
1255         }
1256
1257         result = r.status;
1258
1259  done:
1260         prs_mem_free(&qbuf);
1261         prs_mem_free(&rbuf);
1262
1263         return result;
1264 }
1265
1266 /* Delete an alias member */
1267
1268 NTSTATUS cli_samr_del_aliasmem(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1269                                POLICY_HND *alias_pol, DOM_SID *member)
1270 {
1271         prs_struct qbuf, rbuf;
1272         SAMR_Q_DEL_ALIASMEM q;
1273         SAMR_R_DEL_ALIASMEM r;
1274         NTSTATUS result;
1275
1276         DEBUG(10,("cli_samr_del_aliasmem"));
1277
1278         ZERO_STRUCT(q);
1279         ZERO_STRUCT(r);
1280
1281         /* Initialise parse structures */
1282
1283         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1284         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1285
1286         /* Marshall data and send request */
1287
1288         init_samr_q_del_aliasmem(&q, alias_pol, member);
1289
1290         if (!samr_io_q_del_aliasmem("", &q, &qbuf, 0) ||
1291             !rpc_api_pipe_req(cli, SAMR_DEL_ALIASMEM, &qbuf, &rbuf)) {
1292                 result = NT_STATUS_UNSUCCESSFUL;
1293                 goto done;
1294         }
1295
1296         /* Unmarshall response */
1297
1298         if (!samr_io_r_del_aliasmem("", &r, &rbuf, 0)) {
1299                 result = NT_STATUS_UNSUCCESSFUL;
1300                 goto done;
1301         }
1302
1303         result = r.status;
1304
1305  done:
1306         prs_mem_free(&qbuf);
1307         prs_mem_free(&rbuf);
1308
1309         return result;
1310 }
1311
1312 /* Query alias info */
1313
1314 NTSTATUS cli_samr_query_alias_info(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1315                                    POLICY_HND *alias_pol, uint16 switch_value,
1316                                    ALIAS_INFO_CTR *ctr)
1317 {
1318         prs_struct qbuf, rbuf;
1319         SAMR_Q_QUERY_ALIASINFO q;
1320         SAMR_R_QUERY_ALIASINFO r;
1321         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1322
1323         DEBUG(10,("cli_samr_query_dom_info\n"));
1324
1325         ZERO_STRUCT(q);
1326         ZERO_STRUCT(r);
1327
1328         /* Initialise parse structures */
1329
1330         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1331         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1332
1333         /* Marshall data and send request */
1334
1335         init_samr_q_query_aliasinfo(&q, alias_pol, switch_value);
1336
1337         if (!samr_io_q_query_aliasinfo("", &q, &qbuf, 0) ||
1338             !rpc_api_pipe_req(cli, SAMR_QUERY_ALIASINFO, &qbuf, &rbuf)) {
1339                 goto done;
1340         }
1341
1342         /* Unmarshall response */
1343
1344         if (!samr_io_r_query_aliasinfo("", &r, &rbuf, 0)) {
1345                 goto done;
1346         }
1347
1348         /* Return output parameters */
1349
1350         if (!NT_STATUS_IS_OK(result = r.status)) {
1351                 goto done;
1352         }
1353
1354         *ctr = r.ctr;
1355
1356  done:
1357         prs_mem_free(&qbuf);
1358         prs_mem_free(&rbuf);
1359
1360         return result;
1361 }
1362
1363 /* Query domain info */
1364
1365 NTSTATUS cli_samr_query_dom_info(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1366                                  POLICY_HND *domain_pol, uint16 switch_value,
1367                                  SAM_UNK_CTR *ctr)
1368 {
1369         prs_struct qbuf, rbuf;
1370         SAMR_Q_QUERY_DOMAIN_INFO q;
1371         SAMR_R_QUERY_DOMAIN_INFO r;
1372         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1373
1374         DEBUG(10,("cli_samr_query_dom_info\n"));
1375
1376         ZERO_STRUCT(q);
1377         ZERO_STRUCT(r);
1378
1379         /* Initialise parse structures */
1380
1381         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1382         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1383
1384         /* Marshall data and send request */
1385
1386         init_samr_q_query_dom_info(&q, domain_pol, switch_value);
1387
1388         if (!samr_io_q_query_dom_info("", &q, &qbuf, 0) ||
1389             !rpc_api_pipe_req(cli, SAMR_QUERY_DOMAIN_INFO, &qbuf, &rbuf)) {
1390                 goto done;
1391         }
1392
1393         /* Unmarshall response */
1394
1395         r.ctr = ctr;
1396
1397         if (!samr_io_r_query_dom_info("", &r, &rbuf, 0)) {
1398                 goto done;
1399         }
1400
1401         /* Return output parameters */
1402
1403         if (!NT_STATUS_IS_OK(result = r.status)) {
1404                 goto done;
1405         }
1406
1407  done:
1408         prs_mem_free(&qbuf);
1409         prs_mem_free(&rbuf);
1410
1411         return result;
1412 }
1413
1414 /* User change password */
1415
1416 NTSTATUS cli_samr_chgpasswd_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1417                                  const char *username, 
1418                                  const char *newpassword, 
1419                                  const char *oldpassword )
1420 {
1421         prs_struct qbuf, rbuf;
1422         SAMR_Q_CHGPASSWD_USER q;
1423         SAMR_R_CHGPASSWD_USER r;
1424         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1425
1426         uchar new_nt_password[516];
1427         uchar new_lm_password[516];
1428         uchar old_nt_hash[16];
1429         uchar old_lanman_hash[16];
1430         uchar old_nt_hash_enc[16];
1431         uchar old_lanman_hash_enc[16];
1432
1433         uchar new_nt_hash[16];
1434         uchar new_lanman_hash[16];
1435
1436         DEBUG(10,("cli_samr_query_dom_info\n"));
1437
1438         ZERO_STRUCT(q);
1439         ZERO_STRUCT(r);
1440
1441         /* Calculate the MD4 hash (NT compatible) of the password */
1442         E_md4hash(oldpassword, old_nt_hash);
1443         E_md4hash(newpassword, new_nt_hash);
1444
1445         if (lp_client_lanman_auth() 
1446             && E_deshash(newpassword, new_lanman_hash) 
1447             && E_deshash(oldpassword, old_lanman_hash)) {
1448                 /* E_deshash returns false for 'long' passwords (> 14
1449                    DOS chars).  This allows us to match Win2k, which
1450                    does not store a LM hash for these passwords (which
1451                    would reduce the effective password length to 14) */
1452
1453                 encode_pw_buffer(new_lm_password, newpassword, STR_UNICODE);
1454
1455                 SamOEMhash( new_lm_password, old_nt_hash, 516);
1456                 E_old_pw_hash( new_nt_hash, old_lanman_hash, old_lanman_hash_enc);
1457         } else {
1458                 ZERO_STRUCT(new_lm_password);
1459                 ZERO_STRUCT(old_lanman_hash_enc);
1460         }
1461
1462         encode_pw_buffer(new_nt_password, newpassword, STR_UNICODE);
1463         
1464         SamOEMhash( new_nt_password, old_nt_hash, 516);
1465         E_old_pw_hash( new_nt_hash, old_nt_hash, old_nt_hash_enc);
1466
1467         /* Initialise parse structures */
1468
1469         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1470         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1471
1472         /* Marshall data and send request */
1473
1474         init_samr_q_chgpasswd_user(&q, cli->srv_name_slash, username, 
1475                                    new_nt_password, 
1476                                    old_nt_hash_enc, 
1477                                    new_lm_password,
1478                                    old_lanman_hash_enc);
1479
1480         if (!samr_io_q_chgpasswd_user("", &q, &qbuf, 0) ||
1481             !rpc_api_pipe_req(cli, SAMR_CHGPASSWD_USER, &qbuf, &rbuf)) {
1482                 goto done;
1483         }
1484
1485         /* Unmarshall response */
1486
1487         if (!samr_io_r_chgpasswd_user("", &r, &rbuf, 0)) {
1488                 goto done;
1489         }
1490
1491         /* Return output parameters */
1492
1493         if (!NT_STATUS_IS_OK(result = r.status)) {
1494                 goto done;
1495         }
1496
1497  done:
1498         prs_mem_free(&qbuf);
1499         prs_mem_free(&rbuf);
1500
1501         return result;
1502 }
1503
1504 /* This function returns the bizzare set of (max_entries, max_size) required
1505    for the QueryDisplayInfo RPC to actually work against a domain controller
1506    with large (10k and higher) numbers of users.  These values were 
1507    obtained by inspection using ethereal and NT4 running User Manager. */
1508
1509 void get_query_dispinfo_params(int loop_count, uint32 *max_entries,
1510                                uint32 *max_size)
1511 {
1512         switch(loop_count) {
1513         case 0:
1514                 *max_entries = 512;
1515                 *max_size = 16383;
1516                 break;
1517         case 1:
1518                 *max_entries = 1024;
1519                 *max_size = 32766;
1520                 break;
1521         case 2:
1522                 *max_entries = 2048;
1523                 *max_size = 65532;
1524                 break;
1525         case 3:
1526                 *max_entries = 4096;
1527                 *max_size = 131064;
1528                 break;
1529         default:              /* loop_count >= 4 */
1530                 *max_entries = 4096;
1531                 *max_size = 131071;
1532                 break;
1533         }
1534 }                    
1535
1536 /* Query display info */
1537
1538 NTSTATUS cli_samr_query_dispinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1539                                  POLICY_HND *domain_pol, uint32 *start_idx,
1540                                  uint16 switch_value, uint32 *num_entries,
1541                                  uint32 max_entries, uint32 max_size,
1542                                  SAM_DISPINFO_CTR *ctr)
1543 {
1544         prs_struct qbuf, rbuf;
1545         SAMR_Q_QUERY_DISPINFO q;
1546         SAMR_R_QUERY_DISPINFO r;
1547         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1548
1549         DEBUG(10,("cli_samr_query_dispinfo for start_idx = %u\n", *start_idx));
1550
1551         ZERO_STRUCT(q);
1552         ZERO_STRUCT(r);
1553
1554         *num_entries = 0;
1555
1556         /* Initialise parse structures */
1557
1558         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1559         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1560
1561         /* Marshall data and send request */
1562
1563         init_samr_q_query_dispinfo(&q, domain_pol, switch_value,
1564                                    *start_idx, max_entries, max_size);
1565
1566         if (!samr_io_q_query_dispinfo("", &q, &qbuf, 0) ||
1567             !rpc_api_pipe_req(cli, SAMR_QUERY_DISPINFO, &qbuf, &rbuf)) {
1568                 goto done;
1569         }
1570
1571         /* Unmarshall response */
1572
1573         r.ctr = ctr;
1574
1575         if (!samr_io_r_query_dispinfo("", &r, &rbuf, 0)) {
1576                 goto done;
1577         }
1578
1579         /* Return output parameters */
1580
1581         result = r.status;
1582
1583         if (!NT_STATUS_IS_OK(result) &&
1584             NT_STATUS_V(result) != NT_STATUS_V(STATUS_MORE_ENTRIES)) {
1585                 goto done;
1586         }
1587
1588         *num_entries = r.num_entries;
1589         *start_idx += r.num_entries;  /* No next_idx in this structure! */
1590
1591  done:
1592         prs_mem_free(&qbuf);
1593         prs_mem_free(&rbuf);
1594
1595         return result;
1596 }
1597
1598 /* Lookup rids.  Note that NT4 seems to crash if more than ~1000 rids are
1599    looked up in one packet. */
1600
1601 NTSTATUS cli_samr_lookup_rids(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1602                               POLICY_HND *domain_pol, uint32 flags,
1603                               uint32 num_rids, uint32 *rids, 
1604                               uint32 *num_names, char ***names,
1605                               uint32 **name_types)
1606 {
1607         prs_struct qbuf, rbuf;
1608         SAMR_Q_LOOKUP_RIDS q;
1609         SAMR_R_LOOKUP_RIDS r;
1610         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1611         uint32 i;
1612
1613         DEBUG(10,("cli_samr_lookup_rids\n"));
1614
1615         if (num_rids > 1000) {
1616                 DEBUG(2, ("cli_samr_lookup_rids: warning: NT4 can crash if "
1617                           "more than ~1000 rids are looked up at once.\n"));
1618         }
1619
1620         ZERO_STRUCT(q);
1621         ZERO_STRUCT(r);
1622
1623         /* Initialise parse structures */
1624
1625         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1626         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1627
1628         /* Marshall data and send request */
1629
1630         init_samr_q_lookup_rids(mem_ctx, &q, domain_pol, flags,
1631                                 num_rids, rids);
1632
1633         if (!samr_io_q_lookup_rids("", &q, &qbuf, 0) ||
1634             !rpc_api_pipe_req(cli, SAMR_LOOKUP_RIDS, &qbuf, &rbuf)) {
1635                 goto done;
1636         }
1637
1638         /* Unmarshall response */
1639
1640         if (!samr_io_r_lookup_rids("", &r, &rbuf, 0)) {
1641                 goto done;
1642         }
1643
1644         /* Return output parameters */
1645
1646         if (!NT_STATUS_IS_OK(result = r.status)) {
1647                 goto done;
1648         }
1649
1650         if (r.num_names1 == 0) {
1651                 *num_names = 0;
1652                 *names = NULL;
1653                 goto done;
1654         }
1655
1656         *num_names = r.num_names1;
1657         *names = talloc(mem_ctx, sizeof(char *) * r.num_names1);
1658         *name_types = talloc(mem_ctx, sizeof(uint32) * r.num_names1);
1659
1660         for (i = 0; i < r.num_names1; i++) {
1661                 fstring tmp;
1662
1663                 unistr2_to_ascii(tmp, &r.uni_name[i], sizeof(tmp) - 1);
1664                 (*names)[i] = talloc_strdup(mem_ctx, tmp);
1665                 (*name_types)[i] = r.type[i];
1666         }
1667
1668  done:
1669         prs_mem_free(&qbuf);
1670         prs_mem_free(&rbuf);
1671
1672         return result;
1673 }
1674
1675 /* Lookup names */
1676
1677 NTSTATUS cli_samr_lookup_names(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1678                                POLICY_HND *domain_pol, uint32 flags,
1679                                uint32 num_names, const char **names,
1680                                uint32 *num_rids, uint32 **rids,
1681                                uint32 **rid_types)
1682 {
1683         prs_struct qbuf, rbuf;
1684         SAMR_Q_LOOKUP_NAMES q;
1685         SAMR_R_LOOKUP_NAMES r;
1686         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1687         uint32 i;
1688
1689         DEBUG(10,("cli_samr_lookup_names\n"));
1690
1691         ZERO_STRUCT(q);
1692         ZERO_STRUCT(r);
1693
1694         /* Initialise parse structures */
1695
1696         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1697         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1698
1699         /* Marshall data and send request */
1700
1701         init_samr_q_lookup_names(mem_ctx, &q, domain_pol, flags,
1702                                  num_names, names);
1703
1704         if (!samr_io_q_lookup_names("", &q, &qbuf, 0) ||
1705             !rpc_api_pipe_req(cli, SAMR_LOOKUP_NAMES, &qbuf, &rbuf)) {
1706                 goto done;
1707         }
1708
1709         /* Unmarshall response */
1710
1711         if (!samr_io_r_lookup_names("", &r, &rbuf, 0)) {
1712                 goto done;
1713         }
1714
1715         /* Return output parameters */
1716
1717         if (!NT_STATUS_IS_OK(result = r.status)) {
1718                 goto done;
1719         }
1720
1721         if (r.num_rids1 == 0) {
1722                 *num_rids = 0;
1723                 goto done;
1724         }
1725
1726         *num_rids = r.num_rids1;
1727         *rids = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1728         *rid_types = talloc(mem_ctx, sizeof(uint32) * r.num_rids1);
1729
1730         for (i = 0; i < r.num_rids1; i++) {
1731                 (*rids)[i] = r.rids[i];
1732                 (*rid_types)[i] = r.types[i];
1733         }
1734
1735  done:
1736         prs_mem_free(&qbuf);
1737         prs_mem_free(&rbuf);
1738
1739         return result;
1740 }
1741
1742 /* Create a domain user */
1743
1744 NTSTATUS cli_samr_create_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1745                                   POLICY_HND *domain_pol, const char *acct_name,
1746                                   uint32 acb_info, uint32 unknown, 
1747                                   POLICY_HND *user_pol, uint32 *rid)
1748 {
1749         prs_struct qbuf, rbuf;
1750         SAMR_Q_CREATE_USER q;
1751         SAMR_R_CREATE_USER r;
1752         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1753
1754         DEBUG(10,("cli_samr_create_dom_user %s\n", acct_name));
1755
1756         ZERO_STRUCT(q);
1757         ZERO_STRUCT(r);
1758
1759         /* Initialise parse structures */
1760
1761         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1762         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1763
1764         /* Marshall data and send request */
1765
1766         init_samr_q_create_user(&q, domain_pol, acct_name, acb_info, unknown);
1767
1768         if (!samr_io_q_create_user("", &q, &qbuf, 0) ||
1769             !rpc_api_pipe_req(cli, SAMR_CREATE_USER, &qbuf, &rbuf)) {
1770                 goto done;
1771         }
1772
1773         /* Unmarshall response */
1774
1775         if (!samr_io_r_create_user("", &r, &rbuf, 0)) {
1776                 goto done;
1777         }
1778
1779         /* Return output parameters */
1780
1781         if (!NT_STATUS_IS_OK(result = r.status)) {
1782                 goto done;
1783         }
1784
1785         if (user_pol)
1786                 *user_pol = r.user_pol;
1787
1788         if (rid)
1789                 *rid = r.user_rid;
1790
1791  done:
1792         prs_mem_free(&qbuf);
1793         prs_mem_free(&rbuf);
1794
1795         return result;
1796 }
1797
1798 /* Set userinfo */
1799
1800 NTSTATUS cli_samr_set_userinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1801                                POLICY_HND *user_pol, uint16 switch_value,
1802                                DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1803 {
1804         prs_struct qbuf, rbuf;
1805         SAMR_Q_SET_USERINFO q;
1806         SAMR_R_SET_USERINFO r;
1807         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1808
1809         DEBUG(10,("cli_samr_set_userinfo\n"));
1810
1811         ZERO_STRUCT(q);
1812         ZERO_STRUCT(r);
1813
1814         if (!sess_key->length) {
1815                 DEBUG(1, ("No user session key\n"));
1816                 return NT_STATUS_NO_USER_SESSION_KEY;
1817         }
1818
1819         /* Initialise parse structures */
1820
1821         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1822         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1823
1824         /* Marshall data and send request */
1825
1826         q.ctr = ctr;
1827
1828         init_samr_q_set_userinfo(&q, user_pol, sess_key, switch_value, 
1829                                  ctr->info.id);
1830
1831         if (!samr_io_q_set_userinfo("", &q, &qbuf, 0) ||
1832             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO, &qbuf, &rbuf)) {
1833                 goto done;
1834         }
1835
1836         /* Unmarshall response */
1837
1838         if (!samr_io_r_set_userinfo("", &r, &rbuf, 0)) {
1839                 goto done;
1840         }
1841
1842         /* Return output parameters */
1843
1844         if (!NT_STATUS_IS_OK(result = r.status)) {
1845                 goto done;
1846         }
1847
1848  done:
1849         prs_mem_free(&qbuf);
1850         prs_mem_free(&rbuf);
1851
1852         return result;
1853 }
1854
1855 /* Set userinfo2 */
1856
1857 NTSTATUS cli_samr_set_userinfo2(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1858                                 POLICY_HND *user_pol, uint16 switch_value,
1859                                 DATA_BLOB *sess_key, SAM_USERINFO_CTR *ctr)
1860 {
1861         prs_struct qbuf, rbuf;
1862         SAMR_Q_SET_USERINFO2 q;
1863         SAMR_R_SET_USERINFO2 r;
1864         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1865
1866         DEBUG(10,("cli_samr_set_userinfo2\n"));
1867
1868         if (!sess_key->length) {
1869                 DEBUG(1, ("No user session key\n"));
1870                 return NT_STATUS_NO_USER_SESSION_KEY;
1871         }
1872
1873         ZERO_STRUCT(q);
1874         ZERO_STRUCT(r);
1875
1876         /* Initialise parse structures */
1877
1878         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1879         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1880
1881         /* Marshall data and send request */
1882
1883         init_samr_q_set_userinfo2(&q, user_pol, sess_key, switch_value, ctr);
1884
1885         if (!samr_io_q_set_userinfo2("", &q, &qbuf, 0) ||
1886             !rpc_api_pipe_req(cli, SAMR_SET_USERINFO2, &qbuf, &rbuf)) {
1887                 goto done;
1888         }
1889
1890         /* Unmarshall response */
1891
1892         if (!samr_io_r_set_userinfo2("", &r, &rbuf, 0)) {
1893                 goto done;
1894         }
1895
1896         /* Return output parameters */
1897
1898         if (!NT_STATUS_IS_OK(result = r.status)) {
1899                 goto done;
1900         }
1901
1902  done:
1903         prs_mem_free(&qbuf);
1904         prs_mem_free(&rbuf);
1905
1906         return result;
1907 }
1908
1909 /* Delete domain user */
1910
1911 NTSTATUS cli_samr_delete_dom_user(struct cli_state *cli, TALLOC_CTX *mem_ctx, 
1912                                   POLICY_HND *user_pol)
1913 {
1914         prs_struct qbuf, rbuf;
1915         SAMR_Q_DELETE_DOM_USER q;
1916         SAMR_R_DELETE_DOM_USER r;
1917         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1918
1919         DEBUG(10,("cli_samr_delete_dom_user\n"));
1920
1921         ZERO_STRUCT(q);
1922         ZERO_STRUCT(r);
1923
1924         /* Initialise parse structures */
1925
1926         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1927         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1928
1929         /* Marshall data and send request */
1930
1931         init_samr_q_delete_dom_user(&q, user_pol);
1932
1933         if (!samr_io_q_delete_dom_user("", &q, &qbuf, 0) ||
1934             !rpc_api_pipe_req(cli, SAMR_DELETE_DOM_USER, &qbuf, &rbuf)) {
1935                 goto done;
1936         }
1937
1938         /* Unmarshall response */
1939
1940         if (!samr_io_r_delete_dom_user("", &r, &rbuf, 0)) {
1941                 goto done;
1942         }
1943
1944         /* Return output parameters */
1945
1946         result = r.status;
1947
1948  done:
1949         prs_mem_free(&qbuf);
1950         prs_mem_free(&rbuf);
1951
1952         return result;
1953 }
1954
1955 /* Query user security object */
1956
1957 NTSTATUS cli_samr_query_sec_obj(struct cli_state *cli, TALLOC_CTX *mem_ctx,
1958                                  POLICY_HND *user_pol, uint16 switch_value, 
1959                                  TALLOC_CTX *ctx, SEC_DESC_BUF **sec_desc_buf)
1960 {
1961         prs_struct qbuf, rbuf;
1962         SAMR_Q_QUERY_SEC_OBJ q;
1963         SAMR_R_QUERY_SEC_OBJ r;
1964         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
1965
1966         DEBUG(10,("cli_samr_query_sec_obj\n"));
1967
1968         ZERO_STRUCT(q);
1969         ZERO_STRUCT(r);
1970
1971         /* Initialise parse structures */
1972
1973         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
1974         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
1975
1976         /* Marshall data and send request */
1977
1978         init_samr_q_query_sec_obj(&q, user_pol, switch_value);
1979
1980         if (!samr_io_q_query_sec_obj("", &q, &qbuf, 0) ||
1981             !rpc_api_pipe_req(cli, SAMR_QUERY_SEC_OBJECT, &qbuf, &rbuf)) {
1982                 goto done;
1983         }
1984
1985         /* Unmarshall response */
1986
1987         if (!samr_io_r_query_sec_obj("", &r, &rbuf, 0)) {
1988                 goto done;
1989         }
1990
1991         /* Return output parameters */
1992
1993         result = r.status;
1994         *sec_desc_buf=dup_sec_desc_buf(ctx, r.buf);
1995
1996  done:
1997         prs_mem_free(&qbuf);
1998         prs_mem_free(&rbuf);
1999
2000         return result;
2001 }
2002
2003 /* Get domain password info */
2004
2005 NTSTATUS cli_samr_get_dom_pwinfo(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2006                                  uint16 *unk_0, uint16 *unk_1, uint16 *unk_2)
2007 {
2008         prs_struct qbuf, rbuf;
2009         SAMR_Q_GET_DOM_PWINFO q;
2010         SAMR_R_GET_DOM_PWINFO r;
2011         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2012
2013         DEBUG(10,("cli_samr_get_dom_pwinfo\n"));
2014
2015         ZERO_STRUCT(q);
2016         ZERO_STRUCT(r);
2017
2018         /* Initialise parse structures */
2019
2020         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2021         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2022
2023         /* Marshall data and send request */
2024
2025         init_samr_q_get_dom_pwinfo(&q, cli->desthost);
2026
2027         if (!samr_io_q_get_dom_pwinfo("", &q, &qbuf, 0) ||
2028             !rpc_api_pipe_req(cli, SAMR_GET_DOM_PWINFO, &qbuf, &rbuf))
2029                 goto done;
2030
2031         /* Unmarshall response */
2032
2033         if (!samr_io_r_get_dom_pwinfo("", &r, &rbuf, 0))
2034                 goto done;
2035
2036         /* Return output parameters */
2037
2038         result = r.status;
2039
2040         if (NT_STATUS_IS_OK(result)) {
2041                 if (unk_0)
2042                         *unk_0 = r.unk_0;
2043                 if (unk_1)
2044                         *unk_1 = r.unk_1;
2045                 if (unk_2)
2046                         *unk_2 = r.unk_2;
2047         }
2048
2049  done:
2050         prs_mem_free(&qbuf);
2051         prs_mem_free(&rbuf);
2052
2053         return result;
2054 }
2055
2056 /* Lookup Domain Name */
2057
2058 NTSTATUS cli_samr_lookup_domain(struct cli_state *cli, TALLOC_CTX *mem_ctx,
2059                                 POLICY_HND *user_pol, char *domain_name, 
2060                                 DOM_SID *sid)
2061 {
2062         prs_struct qbuf, rbuf;
2063         SAMR_Q_LOOKUP_DOMAIN q;
2064         SAMR_R_LOOKUP_DOMAIN r;
2065         NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
2066
2067         DEBUG(10,("cli_samr_lookup_domain\n"));
2068
2069         ZERO_STRUCT(q);
2070         ZERO_STRUCT(r);
2071
2072         /* Initialise parse structures */
2073
2074         prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL);
2075         prs_init(&rbuf, 0, mem_ctx, UNMARSHALL);
2076
2077         /* Marshall data and send request */
2078
2079         init_samr_q_lookup_domain(&q, user_pol, domain_name);
2080
2081         if (!samr_io_q_lookup_domain("", &q, &qbuf, 0) ||
2082             !rpc_api_pipe_req(cli, SAMR_LOOKUP_DOMAIN, &qbuf, &rbuf))
2083                 goto done;
2084
2085         /* Unmarshall response */
2086
2087         if (!samr_io_r_lookup_domain("", &r, &rbuf, 0))
2088                 goto done;
2089
2090         /* Return output parameters */
2091
2092         result = r.status;
2093
2094         if (NT_STATUS_IS_OK(result))
2095                 sid_copy(sid, &r.dom_sid.sid);
2096
2097  done:
2098         prs_mem_free(&qbuf);
2099         prs_mem_free(&rbuf);
2100
2101         return result;
2102 }