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